How to refactor very large legacy JavaScript code? [closed]

I have a large JavaScript file with over 20,000 lines of code. The code is organized into objects, with functions like so:

let module1 = {
 fun1:function() {
  console.log("module1 fun1 called");
 },
 fun2:function() {
  module2.fun1();
 },
}
let module2 = {
 fun1:function() {
  console.log("module2 fun1 called");
 },
 fun2:function() {
  module1.fun1();
 },
}

And this pattern continues for other objects. These objects and their functions depend on each other, leading to a lot of circular dependencies. Since everything is currently in a single file, this is not an issue, but I want to refactor this code by separating it into multiple files for better maintainability.

The challenge I’m facing is how to break the code into separate modules without running into circular dependency issues during the refactor. I also need to ensure the structure remains flexible and scalable as I may need to organize modules into sub-modules.

How can I refactor this file?

Strange behavior when deep cloning dynamic objects

I have been trying to deep clone a dynamic object in typescript and all methods just return an empty {} object for this specific scenario!!

Here is the type of object I am trying to deep clone

fullValues: { [key : string ] : Array<string> },

NOTE: fullValues is passed to a react component and the below mentioned operations happen in this react component! fullValues is NEVER directly mutated throughout the lifecycle of the program and it is initially a state in the parent component as shown below:

const facetValues: { [key: string ] : Array<string> } = {};

// Type => facetedData?: FacetCollectionType
if (facetedData) {
    Object.entries(facetedData).forEach(([key, value]) => {
        Object.defineProperty(facetValues, key, { value: [] as string[]});
    });
}

const [ facets, setFacets ] = useState<{ [key: string ] : Array<string> }>(facetValues);


{facetedData && 
                            
    Object.keys(facetedData).length !== 0 ?
        Object.entries(facetedData).map(([key, options]) => (
            <DataTableFacetedFilter
                key={key}
                options={options}
                mainKey={key}
                title={key}
                fullValues={facets}
                setSelectedValues={setFacets}
            />
        ))
        :
        null
}

Random example of how this object can be structured:

{
   status: [],
   plan: [],
}

I tried the following methods for deepcloning:

Using lodash deepclone

console.log(fullValues); // outputs { status: [], plan: [] }
console.log("after deep clone => ");
console.log(_cloneDeep(fullValues)); // outputs {}

Using JSON stringify method

console.log(fullValues); // outputs { status: [], plan: [] }
console.log("after deep clone => ");
console.log(JSON.parse(JSON.stringify(fullValues))); // outputs {}

However if I do this

let fullValues: { [key : string ] : Array<string> }  = { status: [], plan: [] };
console.log(fullValues); // outputs { status: [], plan: [] }
console.log("after deep clone => ");
console.log(_cloneDeep(fullValues)); // outputs { status: [], plan: [] }

It works here.

There seems to be no logic to why this is happening? It makes no sense!

How to load chrome instance in development mode in React

I am building a chrome extension and using chrome.bookmarks api. When I do

console.log(chrome.bookmarks)

it logs undefined in normal development mode. When I load using load unpacked extensions, it shows up correctly.

Is there a way to have chrome instance available in development mode else it becomes very tedious to develop, like making changes and console log it, building it, then open extension popup and inspecting the console of the popup.

"permissions": ["bookmarks"],

Is there a workaround this?

Highcharts live data using SignalR

I’m trying to create some linear charts using highcharts library. The charts are made dynamically based on data given from server with the first values.

Then using SignalR when got new data, it appends data to related chart.

Showing the first data is fine but the problem is that when updating charts in SignalR function, it makes a new line instead of appending point to existing line.

enter image description here

Page refresh on token-authenticated route redirects to 404 page in React

I have a simple app where there is a login page and upon submitting the form, it makes a request to the backend which returns a token upon successful authentication, which then redirects to internal dashboard page. There is also another page called settings and another is the NotFound (404) page.

After logging in, when I’m in dashboard page or settings page, if I refresh, it takes me to 404 page whereas it should stay at the page I’m in. Does anybody know what the issue could be?

Here’s the code:

App.js

const App = () => {
    const [isAuthenticated, setIsAuthenticated] = useState(false);

    const handleLogin = (token) => {
        localStorage.setItem('token', token);

        setIsAuthenticated(true);
    };

    useEffect(() => {
        const token = localStorage.getItem('token');

        setIsAuthenticated(!!token);
    }, []);

    return (
        <Router>
            {
                isAuthenticated ? (
                    <Routes>
                        <Route path="/dashboard" element={
                            <Layout>
                                <Dashboard />
                            </Layout>
                        } />
                        <Route path="/settings" element={
                            <Layout>
                                <Settings />
                            </Layout>
                        } />
                        <Route path="*" element={<Layout><NotFound /></Layout>} />
                    </Routes>
                ) : (
                    <Routes>
                        <Route path="/" element={<Login onLogin={handleLogin} />} />
                        <Route path="*" element={<Navigate to="/" />} />
                    </Routes>
                )
            }
        </Router>
    );
}
Login.js

const Login = ({ onLogin }) => {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const navigate = useNavigate();

    const handleSubmit = async (e) => {
        e.preventDefault();

        const response = await fetch('/api/login', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ username, password }),
        });

        if (response.ok) {
            const result = await response.json();

            if (result.success) {
                localStorage.setItem('token', result.token);

                onLogin(result.token);
                navigate('/dashboard');
            }
        }
    };

    return (
        <div class="container">
            <div class="formContainer">
                <h1>LOGIN</h1>

                <form onSubmit={handleSubmit}>
                    <input
                        type="text"
                        value={username}
                        placeholder="username"
                        onChange={(e) => setUsername(e.target.value)}
                        required
                    />

                    <input
                        type="password"
                        value={password}
                        placeholder="password"
                        onChange={(e) => setPassword(e.target.value)}
                        required
                    />

                    <button type="submit" className="login-button">
                        Login
                    </button>
                </form>
            </div>
        </div>
    );
}

Blazor.BrowserExtension: Issues Adding Razor Components to Gmail DOM in Chrome Extension

I am developing a Chrome extension using the Blazor.BrowserExtension package. The goal is to manipulate Gmail’s DOM by injecting Razor components and invoking C# methods from custom.js (content script). Below are the relevant parts of my implementation:

manifest.json:

{
  "manifest_version": 3,
  "name": "Test Extension",
  "description": "My browser extension built with Blazor WebAssembly",
  "version": "0.1",
  "background": {
    "service_worker": "content/BackgroundWorker.js",
    "type": "module"
  },
  "permissions": [
    "activeTab",
    "scripting",
    "storage"
  ],
  "host_permissions": [
    "https://mail.google.com/*"
  ],
  "action": {
    "default_popup": "popup.html"
  },
  "options_ui": {
    "page": "options.html",
    "open_in_tab": true
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'",
     "script-src": "'self' 'unsafe-inline' 'unsafe-eval'",
    "object-src": "'self'"
  },
  "content_scripts": [
    {
      "matches": ["https://mail.google.com/mail/*"],
      "js": ["framework/blazor.webassembly.js","content/custom.js"],
      "run_at": "document_idle"
    }
  ],
  "web_accessible_resources": [
    {
      "resources": [
        "framework/*",
        "content/*",
        "wwwroot/*"
      ],
      "matches": [ "https://mail.google.com/*" ]
    }
  ]
}

Program.cs:

using Blazor.BrowserExtension;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Test.Components;

namespace Test
{
    public static class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            
            builder.UseBrowserExtension(browserExtension =>
            {
                if (browserExtension.Mode == BrowserExtensionMode.ContentScript)
                {
                    builder.RootComponents.RegisterForJavaScript<ButtonComponent>("CustomButton");
                }
                if (browserExtension.Mode == BrowserExtensionMode.Background)
                {
                    builder.RootComponents.AddBackgroundWorker<BackgroundWorker>();
                }
                else
                {
                    builder.RootComponents.Add<App>("#app");
                    builder.RootComponents.Add<HeadOutlet>("head::after");
                }
            });

            builder.Services.AddScoped<ITestService, TestService>();
            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
            await builder.Build().RunAsync();
        }
    }
}

ButtonComponent.razor:

@page "/button.html"
@inject IJSRuntime JSRuntime

 <button @onclick="HandleClick" class="gmail-button">
    @ButtonText
</button>

<style>
    .gmail-button { /* styling here */ }
</style>

@code {
    [Parameter]
    public string ButtonText { get; set; } = "Click Me";

    private async Task HandleClick()
    {
        await JSRuntime.InvokeVoidAsync("alert", "Blazor Button Clicked!");
    }
}

custom.js:

(async () => {
    const sendButtonContainer = document.querySelector(".dC");
    if (!sendButtonContainer) {
        console.error("Send button container not found.");
    }

    const blazorScript = document.createElement("script");
    blazorScript.src = chrome.runtime.getURL("framework/blazor.webassembly.js");
    blazorScript.type = "text/javascript";
    blazorScript.onload = async () => {
        console.log("Blazor WebAssembly script loaded.");
        await Blazor.start();

        const blazorContainer = document.createElement("div");
        blazorContainer.id = "blazor-custom-container";
        sendButtonContainer.appendChild(blazorContainer);

        Blazor.rootComponents.add(blazorContainer, 'CustomButton', {
            ButtonText: "Blazor Action"
        });

        console.log("Blazor component added.");
    };

    blazorScript.onerror = () => {
        console.error("Failed to load Blazor WebAssembly script.");
    };

    document.head.appendChild(blazorScript);
})();

When I run this, I encounter the following errors:

  • blazor.webassembly.js:1 Refused to load the script ‘https://mail.google.com/mail/u/0/framework/dotnet.js’ because it violates the Content Security Policy directive: “script-src ‘self’ ‘wasm-unsafe-eval’ …”
  • Uncaught (in promise) Error: Failed to start platform. Reason: TypeError: Failed to fetch dynamically imported module: https://mail.google.com/mail/u/0/framework/dotnet.js
  • Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of “text/html”.
  • blazor.webassembly.js:1 Uncaught (in promise) Error: Failed to start platform.

My Question:

  1. Is it possible to use Blazor.BrowserExtension to inject Razor components into Gmail’s DOM?
  2. Are these errors related to limitations with Blazor.BrowserExtension in handling Gmail’s CSP or resource restrictions?
  3. Should I switch to a pure JavaScript implementation for DOM manipulation in this case?

Any guidance would be appreciated.

Automating LeetCode Solution Post Creation and Submission: Challenges with DOM Manipulation, Clipboard API, and Monaco Editor

I’m building a Chrome extension to automate solution post creation on LeetCode after a solution is accepted. The goal is to:1. Open the “Post Solution” page.2. Automatically populate the “Title” input field with a custom string.3. Populate the Monaco Editor with a formatted solution template.

The Setup
1. Environment:
• Chrome Extension (Manifest V3) using Plasmo Framework.
• The extension includes:
• A background script to handle tab creation and messaging.
• A content script for DOM interaction on the “Post Solution” page.
2. Approach:
• The background script opens the solution post page and sends a message to the content script with the template to paste.
• The content script handles DOM manipulation, including:
• Typing text into the input field.
• Copying and pasting content into the Monaco Editor.

Challenges and What We’ve Tried

  1. Populating the Title Input Field

Problem:
The input field sometimes partially updates (e.g., “Automated Title” becomes “tomated Title”) or doesn’t update at all.

Attempts:
1. Directly setting value:

inputElement.value = "Automated Title";
inputElement.dispatchEvent(new Event("input", { bubbles: true }));
inputElement.dispatchEvent(new Event("change", { bubbles: true }));

•Result: Sometimes works, but often doesn’t update the field properly or triggers listeners that reset the value.

2.Simulating Keypress Events:

for (const char of text) {
  inputElement.value += char;
  inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char }));
  inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char }));
  inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char }));
}

•Result: This works better but occasionally results in incomplete text. It seems that external event listeners or DOM updates interfere with the process.

  1. Copying Text to Clipboard and Pasting:
await navigator.clipboard.writeText("Automated Title");
const pasteEvent = new ClipboardEvent("paste", { bubbles: true });
inputElement.dispatchEvent(pasteEvent);

•Result: The clipboard API fails with a NotAllowedError unless triggered by a user interaction (e.g., button click).

  1. Populating the Monaco Editor

Problem:
The Monaco Editor relies on its monaco.editor.getModels()[0] API, which isn’t directly accessible from the content script due to the script running in a different execution context.

Attempts:
1. Using Monaco API:

const model = monaco.editor.getModels()[0];
model.setValue(template);

•Result: Works perfectly in the browser console but fails in the content script with monaco is undefined.

2.Injecting Code into Main World:
• Injected a function using chrome.scripting.executeScript:

chrome.scripting.executeScript({
  target: { tabId: tab.id },
  world: "MAIN",
  func: pasteTemplateIntoPage,
  args: [template],
});

•Result: monaco is undefined in the main world due to CSP restrictions.

  1. Handling Rate Limiting (429 Errors)

Problem:
Occasionally, setting the title triggers LeetCode’s backend requests that result in 429 Too Many Requests.

Attempts:
1. Added delays between actions.
2. Reduced unnecessary event dispatching.
3. Used debounce to avoid rapid interactions.

•Result: Rate limiting persists when actions are too frequent.

Code Snippets

Background Script:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === "openSubmissionPage") {
    chrome.tabs.create({ url: message.url, active: true }, (tab) => {
      if (tab?.id) {
        chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
      if (tabId === tab.id && changeInfo.status === "complete") {
        chrome.tabs.onUpdated.removeListener(listener);
        chrome.tabs.sendMessage(tab.id, { action: "pasteTemplate", template:            message.template });
      }
    });
  }
});

Content Script:

async function typeIntoInputField(selector, text) {
  const inputElement = document.querySelector(selector);
  if (!inputElement) return;

  inputElement.value = "";
  for (const char of text) {
    inputElement.value += char;
    inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char }));
    inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char }));
    inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char }));
    await new Promise((r) => setTimeout(r, 100));
  }
}

What We Need Help With:
1. How can we reliably set the title input field’s value (e.g., “Automated Title”) while avoiding partial updates or resets?
2. What’s the best way to access and manipulate the Monaco Editor in a Chrome extension?
3. How can we avoid triggering LeetCode’s rate limiting (429 errors) during DOM manipulation?
4. Are there other robust methods to simulate user interaction (typing, pasting) programmatically?

What We’ve Tried:
• Direct DOM manipulation (value, setAttribute).
• Simulating keystrokes using KeyboardEvent.
• Copying to clipboard and pasting using ClipboardEvent.
• Injecting code into the main world to access the Monaco API.

Despite all these attempts, I still face issues with reliability and compatibility. Any advice, insights, or alternative approaches would be greatly appreciated!

Feel free to copy and paste this plain-text version into Stack Overflow!

Javascript looselyequal algorithm

Since NaN is unequal to any other value, including to another NaN, why does not the looselyequal algorithm in Javascript Specification check if any one of the operands is NaN first? If any one of the operands is NaN, the result is false, no need more processing.
The following is the == algorithm in the Javascript specification:

  1. If SameType(x, y) is true, then
    a. Return IsStrictlyEqual(x, y).
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. NOTE: This step is replaced in section B.3.6.2.
  5. If x is a Number and y is a String, return ! IsLooselyEqual(x, ! ToNumber(y)).
  6. If x is a String and y is a Number, return ! IsLooselyEqual(! ToNumber(x), y).
  7. If x is a BigInt and y is a String, then
    a. Let n be StringToBigInt(y).
    b. If n is undefined, return false.
    c. Return ! IsLooselyEqual(x, n).
  8. If x is a String and y is a BigInt, return ! IsLooselyEqual(y, x).
  9. If x is a Boolean, return ! IsLooselyEqual(! ToNumber(x), y).
  10. If y is a Boolean, return ! IsLooselyEqual(x, ! ToNumber(y)).
  11. If x is either a String, a Number, a BigInt, or a Symbol and y is an Object, return ! IsLooselyEqual(x, ? ToPrimitive(y)).
  12. If x is an Object and y is either a String, a Number, a BigInt, or a Symbol, return ! IsLooselyEqual(? ToPrimitive(x), y).
  13. If x is a BigInt and y is a Number, or if x is a Number and y is a BigInt, then
    a. If x is not finite or y is not finite, return false.
    b. If ℝ(x) = ℝ(y), return true; otherwise return false.
  14. Return false.

According to this algorithm, if either x or y is NaN, step 5, 6, 9, 10, 11, 12 will cost running time, and the result must be false.
If the first step is:

1.if x or y is NaN, return false.

the algorithm can get and return this result immediately.

Spotify OAuth with React not working properly

I am new to React in general and am trying to build a simple application. I want to build an application where users can sign in using their Spotify Account. I have the following files:

App.js:

import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import './App.css';
import OAuthSignInPage from './components/oauth';
import Callback from './components/callback';
import Welcome from './components/Welcome';
import Options from './components/Options';
import Header from './components/Header';
import { AuthProvider, useAuth } from './hooks/useAuth';

const ProtectedRoute = ({ children }) => {
  const { user } = useAuth();
  if (!user) {
    return <Navigate to="/" />;
  }
  return children;
};

function App() {
  return (
    <Router>
      <AuthProvider>
        <div className="App">
          <Header />
          <div className="content">
            <Routes>
              <Route path="/" element={<OAuthSignInPage />} />
              <Route path="/callback" element={<Callback />} />
              <Route path="/welcome" element={
                <ProtectedRoute>
                  <Welcome />
                </ProtectedRoute>
              } />
              <Route path="/options" element={
                <ProtectedRoute>
                  <Options />
                </ProtectedRoute>
              } />
            </Routes>
          </div>
        </div>
      </AuthProvider>
    </Router>
  );
}

export default App;

oauth.js

import * as React from 'react';
import { AppProvider } from '@toolpad/core/AppProvider';
import { SignInPage } from '@toolpad/core/SignInPage';
import { useTheme } from '@mui/material/styles';
import { useAuth } from "../hooks/useAuth";
import { useNavigate } from 'react-router-dom';

const providers = [
  { id: 'spotify', name: 'Spotify' }
];

const signIn = async (provider) => {
  
  if (provider.id === 'spotify') {
    // Redirect to Spotify login
    const clientId = process.env.REACT_APP_SPOTIFY_CLIENT_ID;
    const redirectUri = encodeURIComponent(`${window.location.origin}/callback`);
    const scope = 'user-read-private user-read-email user-top-read';
    const spotifyAuthUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&scope=${scope}`;
    
    window.location.href = spotifyAuthUrl;
    return new Promise(() => {}); // Promise won't resolve due to redirect
  }
  
  return { error: 'Invalid provider' };
};

export default function OAuthSignInPage() {
  const { user } = useAuth();
  const navigate = useNavigate();

  React.useEffect(() => {
    if (user) {
      navigate('/options');
    }
  }, [user, navigate]);

  const theme = useTheme();
  return (
    <AppProvider theme={theme}>
      <SignInPage signIn={signIn} providers={providers} />
    </AppProvider>
  );
}

protectedRoute.js:

import { Navigate } from "react-router-dom";
import { useAuth } from "../hooks/useAuth";

export const ProtectedRoute = ({ children }) => {
  const { user } = useAuth();
  if (!user) {
    // user is not authenticated
    return <Navigate to="/" />;
  }
  return children;
};

Callback.js

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth';

function Callback() {
  const { login } = useAuth();
  const location = useLocation();

  useEffect(() => {
    const code = new URLSearchParams(location.search).get('code');
    if (code) {
      login({ code });
    }
  }, [location, login]);

  // No need for loading state since login handles navigation
  return null;
}

export default Callback;

useAuth.jsx

import { createContext, useContext, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { useLocalStorage } from "./useLocalStorage";
const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useLocalStorage("code", null);
  const navigate = useNavigate();

  // call this function when you want to authenticate the user
  const login = async (data) => {
    setUser(data);
  };

  // call this function to sign out logged in user
  const logout = () => {
    setUser(null);
    navigate("/", { replace: true });
  };

  const value = useMemo(
    () => ({
      user,
      login,
      logout,
    }),
    [user]
  );
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

export const useAuth = () => {
  return useContext(AuthContext);
};

Now the issue is, the OAuth part is working fine. I can login and Spotify is calling my /callback endpoint with the code. But the redirection is not working properly. After login it’s going to the /options route but it is a blank component. The error is:

Cannot update a component (`AuthProvider`) while rendering a different component (`Callback`). To locate the bad setState() call inside `Callback`, follow the stack trace as described in https://react.dev/link/setstate-in-render

And this error is being called in an infinite loop.

I just can’t figure out how to solve this. One more thing is when I manually type in the URL /welcome after login, it works. Help would be really appreciated.

Spin the wheel and stop at specific sector?

I’m trying to create a wheelspin component in Vue.js but I have absolutely no clue on how to detect on what sector is currently indicator pointing at.

And how to stop at specific index after the spin is launched ?

WheelSpin component code https://playcode.io/2211878:

<template>
  <div class="wof-wrapper">
    <div class="wof-indicator"></div>
    <div class="wof-container">
      <div class="wof-sectors" :class="{ spinning }">
        <div
          class="sector"
          v-for="(item, index) in sectors"
          :class="item.code"
          :key="item.code"
          :style="{
            '--i': index,
          }"
        >
          <div class="content">
            <div class="inner">
              <div class="title">{{ item.code }}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="wof-center" @click="onBtnSpin">SPIN!</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

/* prettier-ignore */
const sectors = ref([
  { code: 'product1' },
  { code: 'product2' },
  { code: 'product3' },
  { code: 'product4' },
  { code: 'product5' },
  { code: 'product6' },
  { code: 'product7' },
  { code: 'product8' },
  { code: 'product9' },
  { code: 'product10' },
  { code: 'product11' },
  { code: 'product12' },
]);

const spinning = ref(false);

const onBtnSpin = () => {
  console.log('Start spinning the wheel');
  const randomRotation = Math.floor(Math.random() * (10 - 3 + 1) + 5);

  spinning.value = true;

  const totalRotation = randomRotation * 360;
  let currentRotation = 0;
  const sectorElement = document.querySelector('.wof-sectors') as HTMLElement;

  const rotateWheel = () => {
    if (currentRotation < totalRotation) {
      currentRotation += 360;
      sectorElement.style.transform = `rotate(${currentRotation}deg)`;
      requestAnimationFrame(rotateWheel);
    } else {
      spinning.value = false;
    }
  };

  rotateWheel();
};
</script>

<style>
.wof-container {
  width: 400px;
  height: 400px;
  border: 2px solid #000;
  border-radius: 50%;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

.wof-sectors {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transition: transform 3s cubic-bezier(0.33, 1, 0.68, 1);
}

.wof-sectors .sector {
  width: 200px;
  height: 200px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  background: #555;
  color: #fff;
  font-weight: bold;
  padding: 10px;
  transform: rotate(calc(360deg / 12 * var(--i))) skew(60deg);
  transform-origin: 100% 100%;
  position: absolute;
  top: 0;
  left: 0;
  position: absolute;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  border: 1px solid white;
}

.content {
  width: 65%;
  transform: skew(-60deg);
  position: relative;
  left: 20px;
}

.inner {
  rotate: 196deg;
  bottom: 8px;
  position: relative;
  display: flex;
  align-items: center;
  transform-origin: 35%;
}
.title {
  pointer-events: none;
  font-size: 14px;
  text-align: right;
  text-transform: uppercase;
}
.q-img {
  position: absolute;
  width: 30px;
  height: auto;
}
.wof-center {
  width: 100px;
  height: 100px;
  color: #fff;
  background-color: #000;
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: contain;
  border-radius: 50%;
  transition: 0.4s;
  position: relative;
  transition: 300ms all;
  box-shadow: 0 0 0 4px #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}

.wof-center:hover {
  box-shadow: 0 0 0 4px #fff, 0 0px 15px 5px rgba(255, 255, 255, 0.6);
  cursor: pointer;
}
.wof-center::after {
  content: '';
  position: absolute;
  top: -13px;
  border: 10px solid transparent;
  border-bottom-color: #fff;
  border-top: none;
  left: 50%;
  margin-left: -10px;
}
</style>

I tried to rotate using css approach but I’m not sure if it’s a good idea.
I have no idea either how to stop the wheel at specific sector.

Stripe.js Error – Invalid value for createPaymentMethod: card was `payment` Element, which cannot be used to create card PaymentMethods

I am receiving this error in my JS console when I click the submit button in my form, which is using a Stripe Payment Element:

[Error] Unhandled Promise Rejection: IntegrationError: Invalid value for createPaymentMethod: card was 'payment' Element, which cannot be used to create card PaymentMethods. (anonymous function) (checkout2.js:44)

The error is not accompanied by any stacktraces, and the error only occurs in the console, with no errors in the server terminal.

Here is the file with the error, checkout2.js:

// Set your publishable key: remember to change this to your live publishable key in production
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = Stripe('publishable key goes here (removed for the sake of the StackOverflow question)');

const appearance = {
  theme: 'night',

  variables: {
    colorPrimary: 'rgb(75, 67, 188)',
    fontFamily: 'Ideal Sans, system-ui, sans-serif',
    borderRadius: '5px',
  }
};

const options = {
  layout: {
    type: 'tabs',
    defaultCollapsed: false,
  }
};
let clientSecret; // declare clientSecret outside the fetch callback
let elements; // declare elements outside the fetch callback

fetch('/secret')
  .then(response => response.json())
  .then(data => {
    clientSecret = data.client_secret;
    elements = stripe.elements({ clientSecret, appearance });
    const paymentElement = elements.create('payment', options);
    paymentElement.mount('#payment-element');
  });

// Handle form submission
const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {
  event.preventDefault();
  if (!clientSecret || !elements) {
    console.error('Client secret or elements not loaded yet');
    return;
  }
  // Get the payment element
  const paymentElement = elements.getElement('payment');
  // Create a PaymentMethod
  const { paymentMethod, error } = await stripe.createPaymentMethod({
    type: 'card',
    card: paymentElement,
  });
  if (error) {
    // Handle error
    console.log(error);
  } else {
    const result = await stripe.confirmCardPayment(clientSecret, {
      payment_method: paymentMethod.id,
    });
    if (result.error) {
      // Handle error
      document.getElementById('error-message').innerText = result.error.message;
    } else {
      // Handle successful payment
      console.log('Payment successful!');
    }
  }
});

Here’s my server.js file that’s running being run by Node:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);

// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
const express = require('express');
const app = express();

const stripe = require('stripe')('secret key would be here, but removed for StackOverflow');

app.use(express.static('public'));

app.get('/secret', async (req, res) => {
  const paymentIntent = await stripe.paymentIntents.create({
    amount: 1099,
    currency: 'usd',
    automatic_payment_methods: {
      enabled: true,
    },
  });
  res.json({ client_secret: paymentIntent.client_secret });
});

app.listen(3000, () => {
  console.log('Server started on port 3000. Open http://localhost:3000 in your browser to view the public directory.');
});

Finally, my index.html file:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Stripe Payment</title>
  <script src="https://js.stripe.com/v3/"></script>
  <style>
    body {
      background-color: #000000;
    }

    #payment-form {
      margin-left: 100px;
      margin-right: 100px;
    }

    #submit {
      margin-top: 30px;
      height: 40px;
      width: 175px;
      font-size: 20px;
      background-color: rgb(55, 48, 163);
      color: #ffffff;
      border: 0px;
      border-radius: 5px;
      cursor: pointer;
    }

    #submit:hover {
      background-color: rgb(75, 67, 188);
    }
  </style>
</head>
<body>
  <form id="payment-form">
    <div id="payment-element">
      <!-- Elements will create form elements here -->
    </div>
    <button id="submit">Submit</button>
    <div id="error-message">
      <!-- Display error message to your customers here -->
    </div>
  </form>
  <script src="../js/checkout2.js"></script>
</body>
</html>

For those wondering, this is running on a Node.js server.

The error occurs in my JS console when I click ‘Submit’ on my HTML page. Because this error occurs, it makes it so the form completely fails. No POST request is sent to Stripe, at all, and the error will continue occurring as you press the ‘Submit’ button over and over again.

Why don’t Copilot actions trigger with my self-hosted server using LangChain adapter and GEMINI_API_KEY, but work with public API key?

I’m building a React.js app using CopilotKit to create a todo app with features like responding to messages, reading data, and performing actions (e.g., adding tasks).

What I’ve tried:

Initially, I used the public Copilot Cloud API key, and everything worked fine (responses, data reading, and actions).
After the free trial ended, I switched to a self-hosted server setup using the LangChain adapter and GEMINI_API_KEY.

What I want:
I need the useCopilotAction functionality (e.g., adding tasks) to work with my self-hosted server, just as it did with the public Copilot Cloud API key.

Details:
I’m using the gemini-1.5-flash model with a custom server setup in Node.js and implementing Copilot actions through the LangChain adapter. The issue I’m facing is that while message responses and readables work fine with my own server setup using my Gemini API key, Copilot actions don’t trigger. When using the public Copilot Cloud API key, everything works, including Copilot actions, but I can’t seem to get them to trigger on my custom server.

Custom server setup using gemini-1.5-flash model with my own Gemini API key.
Messages and responses are successfully processed, and readables work fine.
Copilot actions fail to trigger in my custom server setup.
Copilot actions work as expected when using the public Copilot Cloud API key.
Using LangChain adapter and CopilotKit runtime to manage interactions.

import express from "express";
import {
  CopilotRuntime,
  LangChainAdapter,
  copilotRuntimeNodeHttpEndpoint,
} from "@copilotkit/runtime";
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
import dotenv from "dotenv";

dotenv.config();

const app = express();
const model = new ChatGoogleGenerativeAI({
  model: "gemini-1.5-flash",
  apiKey: process.env.GEMINI_API_KEY,
  region: "us-central1",
});

const serviceAdapter = new LangChainAdapter({
  chainFn: async ({ messages, tools }) => {
    return model.bindTools(tools).stream(messages);
  },
});

app.use("/copilotkit", (req, res, next) => {
  const runtime = new CopilotRuntime();
  const handler = copilotRuntimeNodeHttpEndpoint({
    endpoint: "/copilotkit",
    runtime,
    serviceAdapter,
  });

  return handler(req, res, next);
});

app.listen(4000, () => {
  console.log("Listening at http://localhost:4000/copilotkit");
});

Everything works perfectly when I use the copilot-cloud-public-api-key. Features like messages, useCopilotReadable, and useCopilotAction function as expected. However, when switching to self-hosting with the LangChain adapter and GEMINI_API_KEY, only messages and useCopilotReadable work correctly. While the AI can respond based on the readable data, useCopilotAction doesn’t trigger at all.

HTML a href onlick and parameter substitution without JQuery

I have the following HTML:

<a href="https://datasite.com/data/?search=Datapoints+3-4%3B+Datapoints+4-5&version="
  onclick="location.href=this.href + selectedVersion; return false;">Datapoints 3-4; Datapoints 4-5</a>

A <select> tag returns a string for “selectedVersion”.

This is working. I need to add another OPTIONAL parameter to the url when a CheckBox is checked.

I added an <input type=”checkbox” onclick=”printClick()”> which returns a string for “printableVersion”

  var printableVersion;
  function printClick() {
    var checkBox = document.getElementById("printCheckbox");
    if (checkBox.checked == true){
      printableVersion = "&interface=print";
    } else {
      printableVersion = "";
    }
  }
</script>

I modified the href as follows:

<a href="https://datasite.com/data/?search=Datapoints+3-4%3B+Datapoints+4-5"
  onclick="location.href=this.href + printableVersion + "&version=" + selectedVersion; return false;">Datapoints 3-4; Datapoints 4-5</a>

But neither parameter are added. On this site, I can only use Javascript, not JQuery, ajax, etc.

JavaScript variable calculation not working

I’m new to javascript. I want to perform an arithmetic calculation between two javascript values as follows.
In here “issues” and “re” contains numeric values. Then I want to deduct “re” from “issues” and assign the outed value to “#bal”.

Tried

$('#bal').text(jData.data.issues - jData.data.re);

Output

outs ‘0’

What may be going wrong with me ? Ca anyone help me ?

Chrome Extension with proxy, onAuthRequired never being triggered

I try to make a proxy in the Chrome extension, proxy is working connecting and all is good. But I need to manually enter auth credentials for proxy connection.

I’m trying to use webRequest and webRequestAuthProvider to automatically apply proxy auth credentials when it is required

let authListener = function(details, callbackFn) {
    console.log('Auth required for', details.url);
    callbackFn({
        authCredentials: {
            username: 'username',
            password: 'pass',
        }
    });
}

chrome.webRequest.onAuthRequired.addListener(
    authListener,
    { urls: ["<all_urls>"] }
    ['asyncBlocking']
);

When proxy auth block popups in the browser, chrome.webRequest.onAuthRequired never being triggered, but, for example, chrome.webRequest.onBeforeRequest or chrome.webRequest.onCompleted are triggered correctly

"permissions": ["storage", "alarms", "tabs", "proxy", "webRequest", "webRequestAuthProvider"],
export function proxyConnect(proxy, scheme = 'http') {
    chrome.proxy.settings.set(
        {
            value: {
                mode: "fixed_servers",
                rules: {
                    singleProxy: {
                        scheme,
                        host: proxy.host,
                        port: proxy.port
                    },
                    bypassList: ['https://2ip.io'] // "<all_urls>"
                }
            },
            scope: 'regular'
        },
    );
}