How to reproduce potential race condition?

I have a crawler which calls an http endpoint every 5s, The endpoint does the code below:

const result = Array.from(this.registry)
     .map(([, metric]) => metric.format())
     .join('n');
this.registry = new Map();
return result;

And somewhere else in my app, I’m adding to the map. I think between reading and mapping from the Map, Items can be added to map so after doing new Map() those items will be gone forever!
I’m trying to write a code that reproduces this problem (Without touching the controller of course).

I’ve tried setting an interval for every 1ms which adds to map, Also with another app call the API every 5s. No matter what I do, I can’t reproduce this.

How can I dynamically calculate golf handicap in JavaScript for a WordPress plugin?

I’m building a front-end golf handicap calculator for my WordPress site using JavaScript. The goal is to let users input their scores, course rating, and slope rating, and then calculate their handicap index based on the USGA formula.

I understand the basic formula for handicap differential:

Handicap Differential = (Adjusted Gross Score – Course Rating) × 113 / Slope Rating

I’ve written this basic function in JavaScript to calculate the differentials:

function calculateHandicap(scores) {
    const differentials = scores.map(score => {
        return ((score.gross - score.rating) * 113) / score.slope;
    });
    // Not sure how to select the best N differentials
}

What I’m struggling with:

  • How to correctly sort the differentials and pick the lowest N values (e.g., lowest 8 out of 20)?

  • Should each differential be rounded to one decimal before or after averaging?

  • Is there a clean way to implement this in vanilla JS that would work well with a WordPress shortcode or embedded form?

I expected to get a working handicap index displayed after the user submits the form, but I’m unsure about the data processing logic and best practices for client-side integration. Any help with the calculation logic or WordPress integration is appreciated!

Typescript error because nested value might be null even after I check it’s not null

I am having a problem with Drizzle response and typescript.
Drizzle joins return an object with nested object | null, and I couldn’t find a “typescript” only way to resolve it without doing extra unnecessary steps that change the code just to make typescript happy.

The following code simulate the type issue:

interface Author {
    id: string;
}

interface Post {
    id: string;
    author: Author;
}

interface PostWithNull {
    id: string;
    author: Author | null;
}

const mixedData = [
    {
        id: '123',
        author: null,
    },
    {
        id: '234',
        author: {
            id: '1'
        },
    }
];

function getPostById(id: string): Post | null {
    // Simulate Drizzle response type -> DO NOT CHANGE
    const res = mixedData.find((record) => record.id === id) as PostWithNull;
    if (!res) {
        return null;
    }

    // The problematic part
    if (res.author) {
        return res;
        // The code below will work.
        // return {
        //     ...res,
        //     author: res.author
        // }
    }


    return null;
}

Removing the “as” will resolve the issue, but that’s not the point, as this is just to simulate the response I am getting, I have no control over it.
I can copy the object like I did there, but it would be an extra step that I am doing only for Typescript compiler, and I’d rather avoid.

I am looking for a Typescript solution to this problem.

Speech to text not working in ios devices

I don’t have that much experience working with javascript.
I have to do a task in which I have to perform both STT and TTS. I’m using javascript library speech syenthesis uterence, this library works well while testing with android device but speech to text conversion fails at the time of using it with ios device.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Voice Command</title>
    <style>
        .chat-container {
            max-width: 400px;
            margin: 20px auto;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            font-family: Arial, sans-serif;
        }
        .user-message {
            background-color: #f0f0f0;
            border-radius: 5px;
            padding: 5px 10px;
            margin: 5px 0;
            text-align: right;
        }
        .bot-message {
            background-color: #d3e9ff;
            border-radius: 5px;
            padding: 5px 10px;
            margin: 5px 0;
        }
        #languageSelector {
            width: 100%;
            margin-top: 10px;
            padding: 5px;
            border-radius: 5px;
            border: 1px solid #ccc;
        }
        #status {
            color: grey;
            font-weight: 600;
            margin-top: 10px;
            text-align: center;
        }
        #permissionModal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }
        #permissionModal div {
            background: white;
            padding: 20px;
            border-radius: 5px;
            text-align: center;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
        }
        #permissionModal button {
            margin: 10px;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            background: #007bff;
            color: white;
            cursor: pointer;
        }
        #permissionModal button:hover {
            background: #0056b3;
        }
        #testSpeakerButton {
            display: block;
            margin: 10px auto;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            background: #28a745;
            color: white;
            cursor: pointer;
            font-family: Arial, sans-serif;
            font-weight: 600;
        }
        #testSpeakerButton:hover {
            background: #218838;
        }
    </style>
</head>
<body>
    <div id="permissionModal" style="display: none;">
        <div>
            <p>This site requires microphone and speaker permissions to enable voice input and output.</p>
            <button id="grantPermissions">Grant Permissions</button>
        </div>
    </div>
    <button id="testSpeakerButton">Speaker test</button>
    <div class="chat-container">
        <div id="chat-box"></div>
        <select id="languageSelector">
            <option value="English (US)">English (US)</option>
            <option value="Hindi (India)">Hindi (India)</option>
            <option value="Spanish (Spain)">Spanish (Spain)</option>
            <option value="French (France)">French (France)</option>
            <option value="German (Germany)">German (Germany)</option>
            <option value="Arabic (Saudi Arabia)">Arabic (Saudi Arabia)</option>
        </select>
        <div class="speaker" style="display: flex; justify-content: space-between; width: 100%; box-shadow: 0 0 13px #0000003d; border-radius: 5px; margin-top: 10px;">
            <p id="action" style="color: grey; font-weight: 800; padding: 0; padding-left: 2rem;"></p>
            <button id="speech" style="border: transparent; padding: 0 0.5rem;">
                Tap to Speak
            </button>
        </div>
        <p id="status"></p>
    </div>

    <script>
        // Browser detection
        function detectBrowser() {
            const ua = navigator.userAgent.toLowerCase();
            if (ua.includes('safari') && !ua.includes('chrome')) return 'Safari';
            if (ua.includes('firefox')) return 'Firefox';
            if (ua.includes('edg')) return 'Edge';
            if (ua.includes('chrome')) return 'Chrome';
            return 'Unknown';
        }

        const browser = detectBrowser();
        const statusBar = document.getElementById('status');
        const permissionModal = document.getElementById('permissionModal');
        const grantPermissionsButton = document.getElementById('grantPermissions');
        const testSpeakerButton = document.getElementById('testSpeakerButton');

        // Language mapping
        const speechLangMap = {
            'English (US)': 'en-US',
            'Hindi (India)': 'hi-IN',
            'Spanish (Spain)': 'es-ES',
            'French (France)': 'fr-FR',
            'German (Germany)': 'de-DE',
            'Arabic (Saudi Arabia)': 'ar-SA'
        };

        // Initialize speech synthesis
        const synth = window.speechSynthesis || null;
        let voices = [];

        // Load voices asynchronously
        function loadVoices() {
            return new Promise((resolve) => {
                if (!synth) {
                    statusBar.textContent = 'Text-to-speech not supported in this browser.';
                    resolve([]);
                    return;
                }
                voices = synth.getVoices();
                if (voices.length > 0) {
                    resolve(voices);
                } else {
                    synth.addEventListener('voiceschanged', () => {
                        voices = synth.getVoices();
                        resolve(voices);
                    }, { once: true });
                }
            });
        }

        // Speak text with fallback
        async function speakResponse(text, language) {
            if (!synth) {
                statusBar.textContent = 'Text-to-speech is unavailable. Displaying text only.';
                showBotMessage(text);
                return;
            }

            const langCode = speechLangMap[language] || 'en-US';
            await loadVoices();

            const utterance = new SpeechSynthesisUtterance(text);
            let selectedVoice = voices.find(voice => voice.lang === langCode);
            if (!selectedVoice) {
                console.warn(`No voice for ${langCode}. Falling back to English.`);
                selectedVoice = voices.find(voice => voice.lang.startsWith('en')) || voices[0];
                statusBar.textContent = `Voice for ${language} unavailable. Using English voice.`;
            }

            if (selectedVoice) {
                utterance.voice = selectedVoice;
                utterance.lang = selectedVoice.lang;
            } else {
                statusBar.textContent = 'No voices available for text-to-speech.';
                showBotMessage(text);
                return;
            }

            utterance.volume = 1.0;
            utterance.rate = 1.0;
            utterance.pitch = 1.0;
            utterance.onerror = (event) => {
                console.error('TTS error:', event.error);
                statusBar.textContent = 'Error in text-to-speech. Displaying text only.';
                showBotMessage(text);
            };

            utterance.onend = () => {
                console.log('TTS finished.');
                statusBar.textContent = '';
            };

            if (synth.speaking || synth.paused) {
                synth.cancel();
            }

            try {
                synth.speak(utterance);
            } catch (error) {
                console.error('TTS failed:', error);
                statusBar.textContent = 'Failed to play speech. Displaying text only.';
                showBotMessage(text);
            }

            document.getElementById('speech').addEventListener('click', () => {
                if (synth.speaking) synth.cancel();
            }, { once: true });
        }

        // Initialize TTS and test speaker
        async function testSpeaker() {
            if (!synth) {
                statusBar.textContent = 'Text-to-speech not supported in this browser.';
                return false;
            }

            try {
                await loadVoices();
                // Silent utterance to unlock audio in Safari
                const silentUtterance = new SpeechSynthesisUtterance('');
                silentUtterance.volume = 0;
                silentUtterance.onend = () => synth.cancel();
                silentUtterance.onerror = (event) => {
                    console.error('Silent TTS error:', event.error);
                    synth.cancel();
                };
                synth.speak(silentUtterance);
                await new Promise(resolve => setTimeout(resolve, 100));
                synth.cancel();

                // Test utterance
                const selectedLang = document.getElementById('languageSelector').value;
                const langCode = speechLangMap[selectedLang] || 'en-US';
                const utterance = new SpeechSynthesisUtterance('Speaker works fine');
                let selectedVoice = voices.find(voice => voice.lang === langCode);
                if (!selectedVoice) {
                    selectedVoice = voices.find(voice => voice.lang.startsWith('en')) || voices[0];
                    statusBar.textContent = `Voice for ${selectedLang} unavailable. Using English voice.`;
                }

                if (selectedVoice) {
                    utterance.voice = selectedVoice;
                    utterance.lang = selectedVoice.lang;
                } else {
                    statusBar.textContent = 'No voices available for text-to-speech.';
                    return false;
                }

                utterance.volume = 1.0;
                utterance.rate = 1.0;
                utterance.pitch = 1.0;
                utterance.onerror = (event) => {
                    console.error('Test TTS error:', event.error);
                    statusBar.textContent = 'Error testing speaker.';
                };
                utterance.onend = () => {
                    console.log('Test TTS finished.');
                    statusBar.textContent = 'Speaker test successful.';
                };

                synth.speak(utterance);
                return true;
            } catch (error) {
                console.error('TTS test failed:', error);
                statusBar.textContent = 'Failed to test speaker.';
                return false;
            }
        }

        // Request microphone permission
        async function requestMicPermission() {
            try {
                const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                stream.getTracks().forEach(track => track.stop());
                return true;
            } catch (error) {
                console.error('Microphone permission error:', error);
                statusBar.textContent = 'Microphone access denied. Voice input unavailable.';
                return false;
            }
        }

        // Check and request all permissions
        async function checkAndRequestPermissions() {
            if (browser !== 'Safari') return true;

            try {
                const permissionStatus = await navigator.permissions.query({ name: 'microphone' });
                if (permissionStatus.state === 'granted') {
                    return await testSpeaker(); // Test speaker if mic is granted
                }
            } catch (error) {
                console.warn('Permission query not supported:', error);
            }

            permissionModal.style.display = 'flex';
            return new Promise((resolve) => {
                grantPermissionsButton.onclick = async () => {
                    permissionModal.style.display = 'none';
                    const micGranted = await requestMicPermission();
                    const ttsReady = micGranted ? await testSpeaker() : false;
                    if (!micGranted || !ttsReady) {
                        statusBar.textContent = 'Some permissions were not granted. Features may be limited.';
                    }
                    resolve(micGranted && ttsReady);
                };
            });
        }

        // Speech recognition
        function runSpeechRecog() {
            const selectedLang = document.getElementById('languageSelector').value;
            const action = document.getElementById('action');

            if (!window.SpeechRecognition && !window.webkitSpeechRecognition) {
                statusBar.textContent = 'Speech recognition not supported in this browser.';
                return;
            }

            const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
            recognition.lang = speechLangMap[selectedLang] || 'en-US';
            recognition.interimResults = false;
            recognition.continuous = false;

            recognition.onstart = () => {
                action.textContent = 'Listening...';
                statusBar.textContent = '';
            };

            recognition.onresult = (event) => {
                const transcript = event.results[0][0].transcript;
                action.textContent = '';
                sendMessage(transcript, selectedLang);
            };

            recognition.onerror = (event) => {
                action.textContent = '';
                statusBar.textContent = `Speech recognition error: ${event.error}`;
            };

            recognition.onend = () => {
                action.textContent = '';
            };

            try {
                recognition.start();
            } catch (error) {
                statusBar.textContent = 'Failed to start speech recognition.';
                console.error('STT error:', error);
            }
        }

        // Send message to Flask API
        async function sendMessage(message, language) {
            showUserMessage(message);
            try {
                const response = await fetch('/api/process_text', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ text: message, language })
                });
                const data = await response.json();
                console.log('Response from Flask API:', data);
                handleResponse(data);
            } catch (error) {
                console.error('Error sending data to Flask API:', error);
                statusBar.textContent = 'Error: Unable to process request';
                showBotMessage('Error: Unable to process request');
            }
        }

        // Handle API response
        function handleResponse(data) {
            if (data.error) {
                statusBar.textContent = data.error;
                showBotMessage(data.error);
                return;
            }
            showBotMessage(data.response);
            speakResponse(data.response, data.language);
        }

        // Show user message
        function showUserMessage(message) {
            const chatBox = document.getElementById('chat-box');
            chatBox.innerHTML += `<div class="user-message">${message}</div>`;
            chatBox.scrollTop = chatBox.scrollHeight;
        }

        // Show bot message
        function showBotMessage(message) {
            const chatBox = document.getElementById('chat-box');
            chatBox.innerHTML += `<div class="bot-message">${message}</div>`;
            chatBox.scrollTop = chatBox.scrollHeight;
        }

        // Initialize
        window.addEventListener('load', async () => {
            await loadVoices();
            if (browser === 'Safari') {
                statusBar.textContent = 'Safari detected. Please grant microphone and speaker permissions.';
                const permissionsGranted = await checkAndRequestPermissions();
                if (!permissionsGranted) {
                    statusBar.textContent = 'Permissions denied. Some features may not work.';
                }
            }
            document.getElementById('speech').addEventListener('click', runSpeechRecog);
            testSpeakerButton.addEventListener('click', testSpeaker);
        });

        // Clean up on unload
        window.addEventListener('beforeunload', () => {
            if (synth && synth.speaking) synth.cancel();
        });
    </script>
</body>
</html>

localStorage dissappears after refresh. The array resets [duplicate]

I was following along a React project tutorial and writing the exact same code to the last bit but noticed that although the favorited movies would be saved to localStorage, upon refresh the array would reset. Then I noticed an error ‘MovieContext.jsx (the file with localStorage code) is not being reloaded’ just before the logs of favorited movies saved to localStorage before a refresh.

import { createContext, useState, useContext, useEffect } from "react";

const MovieContext = createContext()

export const useMovieContext = () => useContext(MovieContext);

export const MovieProvider = ({children}) => {
  const [favorites, setFavorites] = useState([]);

  useEffect(() => {
    console.log('useEffect on mount runs');
    const storedFavs = localStorage.getItem("favorites");
    console.log('storedFavs', storedFavs);

    if (storedFavs) {
      try {
        setFavorites(JSON.parse(storedFavs));
      } catch (err) {
        console.error('Failed to load from localStorage...', err);
      } 
      }
  }, []);

  useEffect(() => {
    try {
      localStorage.setItem("favorites", JSON.stringify(favorites));
      console.log('Saving to localStorage', favorites);
    } catch (error) {
      console.error('Failed to save to localStorage', error);
      
    }
  }, [favorites]);

  const addToFavorites = (movie) => {
    setFavorites(prev => [...prev, movie]);
  }

  const removeFromFavorites = (movieId) => {
    setFavorites(prev => prev.filter(movie => movie.id !== movieId));
  }

  const isFavorite = (movieId) => {
    return favorites.some(movie => movie.id === movieId);
  }

  const value = {
    favorites,
    addToFavorites,
    removeFromFavorites,
    isFavorite
  }

  return <MovieContext.Provider value={value}>
    {children}
  </MovieContext.Provider>
}

The App.jsx had the MovieProvider wrapper:

import "./css/App.css";
import Favorites from "./pages/Favorites";
import Home from "./pages/Home";
import { Routes, Route } from "react-router-dom";
import { MovieProvider } from "./contexts/MovieContext";
import NavBar from "./components/NavBar";

function App() {
  return (
    <MovieProvider>
      <NavBar />
      <main className="main-content">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/favorites" element={<Favorites />} />
        </Routes>
      </main>
    </MovieProvider>
  );
}

export default App;

Next.js App Crashes with SIGINT Error Using Turbopack and PNPM

When developing a Next.js application with GraphQL using Turbopack on an M4 MacBook (24GB RAM), the application starts correctly but exhibits the following behavior:

  1. After 15-20 minutes of runtime

  2. Subsequent page loads fail to complete

  3. Network requests (particularly .json requests) remain pending indefinitely

  4. Server eventually exits with SIGINT

http server closed - sigintnetwork log

I tried increasing the allocated TypeScript memory to 7 GB, but it still didn’t work.

How to extract OTP codes from temporary emails automatically for testing purposes?

I’m writing automated tests for registration forms that require email-based OTP verification.

Using real mailboxes (like Gmail or Outlook) is slow, hard to reset, and sometimes blocked. I need a way to receive one-time codes quickly and programmatically, without having to scrape full emails or deal with login processes.

Ideally, the service should support receiving verification codes from real platforms like Telegram, Discord, or visa appointment systems.

I tried using some common disposable email services like 10minutemail and TempMail, but most of them either:

  • Don’t offer an API,
  • Or return full HTML that I have to parse manually,
  • Or are blocked by many platforms.

I’m looking for a solution where I can just fetch the OTP or verification link in plain JSON via API, ideally filtered out from the message body.

Expected result:

json
{ “otp”: “123456” }

Disable and enable button in oracle apex

I have a button which uses DA and executes the server side code… when there is a low network user clicks the button multiple times which cause duplicate entry… I want to disable when user clicks the button and enable after completing the process… I have achieved this but when PLSQL raises the raise_application_error the disabled button is not enabled.. Tried this.. Let me know how to achieve this

Event: Click
Selection Type: Button
Button: ADD

True Action: Execute JavaScript Code
$(this.triggeringElement).prop('disabled', true);
$(this.triggeringElement).addClass('is-disabled');

True Action: Execute server side Code (which raises the error)

For this created another DA

Event: Custom
Custom Event: apexerror
Selection Type: JavaScript Expression

JavaScript Expression:
$('button.is-disabled').prop('disabled', false).removeClass('is-disabled');

enter image description here

How to make the gap not covered by the gradient. Or maybe there are some other ways to achieve this result?

I’m trying to apply a single background gradient to a grid of cards (statistic blocks) in React using Tailwind CSS. The goal is to have the gradient visible only on the cards, while the gaps between them remain transparent.

What I need:
enter image description here

What I have:
enter image description here

My code

<section className="container-base m-section">
      <Title title="By the numbers" />
      <div className="relative grid grid-cols-5 grid-rows-2 gap-4 h-[500px] mt-8 bg:[#181413] before:absolute before:inset-0 before:bg-gradient-to-b before:bg-[linear-gradient(135deg,_#ffdd55,_#ff55cc,_#88f,_#55ffff)] before:rounded-xl">
        {statisticData.map((item, index) => (
          <StatisticBlock
            className="z-10 "
            key={index}
            title={item.title}
            subtitle={item.subtitle}
            col={item.col}
            row={item.row}
          />
        ))}
      </div>
    </section>

StatisticBlock:

<div
      className={clsx(
        className,
        "flex flex-col items-center justify-center p-4 rounded-xl text-black text-center",
        col === 2 && "col-span-2",
        col === 3 && "col-span-3",
        row === 2 && "row-span-2",
        row === 3 && "row-span-3"
      )}
    >
      <div className="text-6xl leading-20 font-bold">{title}</div>
      <p className="text-2xl leading-6 font-bold">{subtitle}</p>
    </div>

WebGL “Framebuffer is incomplete: Attachment has zero size” when displaying 3Dmol.js model loaded from raw PDB text in React (Chrome & Firefox)

Symptoms:

  • Model renders once, then the next frame throws the error.
  • On route change or Collapse/Tab hide, the error repeats.
  • Adding viewer.clear() in cleanup removes the message but stops
    rendering completely.

Component code:

import React, { useRef, useEffect } from "react";
import * as $3Dmol from "3dmol";

export default function Protein3DMol({ pdbText }) {
  const divRef = useRef(null);

  useEffect(() => {
    if (!divRef.current || !pdbText) return;

    const viewer = $3Dmol.createViewer(divRef.current, { backgroundColor: "white" });

    viewer.addModel(pdbText, "pdb");
    viewer.setStyle({}, { cartoon: { color: "spectrum" } });
    viewer.zoomTo();
    viewer.render();

    return () => {
      viewer.clear();
      const canvas = divRef.current.querySelector("canvas");
      const gl = canvas?.getContext("webgl") || canvas?.getContext("experimental-webgl");
      gl?.getExtension("WEBGL_lose_context")?.loseContext();
    };
  }, [pdbText]);

  return <div ref={divRef} style={{ width: "100%", height: "100%", minHeight: 300 }} />;
}

Fetch Logic:

fetch("https://two4-cp-backend.onrender.com/filtered_pdbs/{pdb}")
  .then(res => res.text())
  .then(setPdbText);

What I’ve tried:

  • Wait for div.clientWidth && clientHeight before calling
    createViewer.
  • Set minHeight: 300 on the container.
  • Attach WEBGL_lose_context in cleanup.
  • Disable GPU hardware acceleration.
    (Error disappears, but 3D is of course disabled.)

How can I safely render a PDB string using 3Dmol.js without triggering GL_INVALID_FRAMEBUFFER_OPERATION in Brave and Firefox? I want to keep the rendering live and interactive, not just a static snapshot.

Global CSS styles from component library not loading in Next.js

I have few global styles in my component library, which I am trying to use in a Next.js project. They only get applied as soon as I add the console.log in following snippet.

"use client";

import * as components from 'component-library';
import { FloButton } from 'component-library';

export default function Home() {
  console.log(components); // <--
  return (
    <>
      <FloButton click={() => console.log('clicked')}>Button</FloButton>
    </>
  );
}

What’s my best bet here?

The package.json of the component library:

{
  "name": "component-library",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "main": "dist/main.js",
  "types": "dist/main.d.ts",
  "files": [
    "dist"
  ],
  "sideEffects": [
    "**/*.css",
    "**/*.scss"
  ],
  "exports": {
    ".": {
      "import": "./dist/main.js",
      "types": "./dist/main.d.ts"
    },
    "./icon/*": {
      "import": "./dist/components/FloIcon/*.js",
      "types": "./dist/components/FloIcon/*.d.ts"
    },
    "./webcomponents": {
      "import": "./dist/webcomponents.js",
      "types": "./dist/webcomponents.d.ts"
    }
  },
  "scripts": {
    "dev": "vite",
    "build": "rm -rf dist && vite build",
    "lint": "eslint .",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "peerDependencies": {
    "@floating-ui/react": "^0.27.12",
    "@r2wc/react-to-web-component": "^2.0.4",
    "@types/classnames": "^2.3.4",
    "classnames": "^2.5.1",
    "react-dom": "^19.1.0",
    "react": "^19.1.0"
  },
  "devDependencies": {
    "@eslint/js": "^9.25.0",
    "@storybook/react-vite": "^9.0.12",
    "@types/lodash.kebabcase": "^4.1.9",
    "@types/node": "^24.0.3",
    "@types/react": "^19.1.2",
    "@types/react-dom": "^19.1.2",
    "@vitejs/plugin-react": "^4.4.1",
    "eslint": "^9.25.0",
    "eslint-plugin-react-hooks": "^5.2.0",
    "eslint-plugin-react-refresh": "^0.4.19",
    "eslint-plugin-storybook": "^9.0.12",
    "glob": "^10.4.5",
    "lodash.kebabcase": "^4.1.1",
    "prettier": "^3.6.0",
    "sass-embedded": "^1.89.2",
    "storybook": "^9.0.12",
    "ts-morph": "^26.0.0",
    "typescript": "~5.8.3",
    "typescript-eslint": "^8.30.1",
    "vite": "^6.3.5",
    "vite-plugin-css-injected-by-js": "^3.5.2",
    "vite-plugin-dts": "^4.5.4",
    "vite-plugin-lib-inject-css": "^2.2.2"
  }
}

Thanks!

JQuery Calendar Date Picker – Show Calendar without Clicking

enter image description here

On our website we currently have the Jquery date picker implemented, but my boss would like it if the calendar could just be active the whole time without the user needing to click on it to get the calendar to pop up. I know I can hide the textbox with the hidden feature, so it will still pass the information the information along. I just can’t figure out how to get it to display just the calendar itself all the time without the textbox being present or needing to toggle something since the code itself never seems to trigger a click event and must be in the base JS of the Jquery calendar.

Our current code:

    {{ '//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css' | stylesheet_tag }}
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js" defer="defer"></script>
<p></p><div style="display: flex; margin-left:auto !important;">
  <div style="width:400px; clear:both; float:right; margin-left:auto !important;">
  
  <p style="float:right;">
    
    <label style="float:right;font-size: 30px;font-weight: bold; position:relative; left: -25px;" for="date">Select Future Delivery Date:</label>
    <input style="float:right; position:relative; left: -35px; width: 365px" id="date" type="text" name="attributes[date]" value="{{ line_item.attributes.date }}" />
    <span class="instructions"> </span>
  </p>
</div>
</div>
<script>
  window.onload = function() {
    if (!window.jQuery) return;
    let $ = window.jQuery;
    
    // 1) List your blocked dates here (in YYYY-MM-DD format)
    const blocked = ["2025-05-26","2025-07-04"];
    
    // 2) Function to calculate dynamic minDate based on current day/time
    function calculateMinDate() {
      const now = new Date();
      
      // Convert to Eastern Time
      const easternTime = new Date(now.toLocaleString("en-US", {timeZone: "America/New_York"}));
      const currentDay = easternTime.getDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday
      const currentHour = easternTime.getHours();
      
      let minDate;
      
      if (currentDay >= 1 && currentDay <= 3) { // Monday (1) through Wednesday (3)
        if (currentHour >= 14) { // 2pm (14:00) or later
          minDate = 3;
        } else { // Before 2pm
          minDate = 2;
        }
      } else if (currentDay === 4) { // Thursday
        if (currentHour >= 14) { // 2pm or later on Thursday
          // Next Tuesday is 5 days from Thursday (Thu->Fri->Sat->Sun->Mon->Tue)
          minDate = 5;
        } else { // Before 2pm on Thursday
          // Next Monday is 4 days from Thursday (Thu->Fri->Sat->Sun->Mon)
          minDate = 4;
        }
      } else if (currentDay === 5) { // Friday
        // Next Tuesday is 4 days from Friday (Fri->Sat->Sun->Mon->Tue)
        minDate = 4;
      } else if (currentDay === 6) { // Saturday
        // Next Tuesday is 3 days from Saturday (Sat->Sun->Mon->Tue)
        minDate = 3;
      } else { // Sunday (0)
        // Next Tuesday is 2 days from Sunday (Sun->Mon->Tue)
        minDate = 2;
      }
      
      return minDate;
    }
    
    // 3) Build a beforeShowDay function
    function customDay(date) {
      // format the date as "YYYY-MM-DD"
      const y = date.getFullYear();
      const m = ("0" + (date.getMonth() + 1)).slice(-2);
      const d = ("0" + date.getDate()).slice(-2);
      const str = `${y}-${m}-${d}`;
      
      // a) block weekends:
      const weekendResult = $.datepicker.noWeekends(date);
      if (!weekendResult[0]) {
        // [false] → disabled weekend
        return weekendResult;
      }
      
      // b) block any dates in your list:
      if (blocked.indexOf(str) !== -1) {
        return [false, "", "Unavailable"];
      }
      
      // otherwise enable
      return [true, ""];
    }
    
    // 4) Initialize datepicker with dynamic minDate
    $(function() {
      const initialMinDate = calculateMinDate();
      
      $("#date").datepicker({
        minDate: initialMinDate,
        maxDate: "+12M",
        beforeShowDay: customDay
      });
      
      // Update minDate every minute to handle time changes
      setInterval(function() {
        const newMinDate = calculateMinDate();
        const currentMinDate = $("#date").datepicker("option", "minDate");
        if (newMinDate !== currentMinDate) {
          $("#date").datepicker("option", "minDate", newMinDate);
        }
      }, 60000); // Check every minute
    });
  };
</script>

How to unit test a function that returns AsyncIterable

const plans = client.listPlans({
  params: { limit: 200 },
});
for await (const plan of plans.each()) {
  planList.push(plan);
}

I have code that looks like this, the return type of listPlans is a class that looks like

    export declare class Pager<T> {
     count(): Promise<number>;
     first(): Promise<T>;
     each(): AsyncIterable<T>;
     eachPage(): AsyncIterable<T[]>;
   }

I am trying to mock the function listPlans, ultimately to mock the each() function.

How to use a key event without pressing a key every time?

I am building a simple game where the ground moves when a user pressed a space bar once. My problem is that the ground does not move if I do not press a space bar.

My code:

class Ground {
    constructor(position) {
        this.position = position;
    }

    move() {
        this.position.x--;
    }
}

const ground = new Ground({
    position: {
        y: 135
    }
})


window.addEventListener("keydown", (event) => {
    switch(event.key) {
        case " ": {
            ground.move();
            break;
        };
    };
});