React: Reading map from local storage returns null values

I am making a small game website where users choose between “easy, medium, and hard” difficulties and I am using a hook of type map to keep track of the guess count for each difficulty. I got it to work normally, but the problem is I want to save user’s guesses so if they come back the website will remember where they were at in the game similar to games like Wordle. However, the code below returns undefined if localstorage is empty when it should be returning 6 as shown below.

const Demo = () =>
{
    const [guessCount, setGuessCount] = useState(new Map()); // Key: [difficulty, count]

    const updateGuessCount = (key: string, value: any) =>
    {
        setGuessCount(map => new Map(map.set(key, value)));
    }

    useEffect(() => 
    {
        updateGuessCount("easy",  localStorage.getItem("easyGuessCount") || 6);
        updateGuessCount("medium", localStorage.getItem("mediumGuessCount") || 6);
        updateGuessCount("hard", localStorage.getItem("hardGuessCount") || 6);

    }, []);

    useEffect(() => 
    {
        localStorage.setItem("easyGuessCount", guessCount.get("easy"));
        localStorage.setItem("mediumGuessCount", guessCount.get("medium"));
        localStorage.setItem("hardGuessCount", guessCount.get("hard"));

    }, [guessCount]);
}

I expected for all the values to be 6 if there is localstorage is empty, but it instead returns undefined. The asynchronous behavior of useEffect() has been making this difficult to debug.

How to activate first menu item on dropdown click in Bootstrap 5

Bootstrap 5 dropdown is defined as

<div class="btn-group">
  <button type="button" class="btn btn-danger dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
    Action
  </button>
  <ul class="dropdown-menu">
    <li><a class="dropdown-item" href="#"><u>A</u>ction</a></li>
    <li><a class="dropdown-item" href="#">A<u>n</u>other action</a></li>
    <li><a class="dropdown-item" href="#"><u>S</u>omething else here</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item" href="#">S<u>e</u>parated link</a></li>
  </ul>
</div>

https://jsfiddle.net/b6or2s5e/

If clicked in Action button, first menu item Action is not active (highlighted):

enter image description here

Pressing down arrow is required to activate it:

enter image description here

How to fix it so that opening dropdown highlights first item like in normal windows desktop application menus?

Iframe Youtube API doesn’t work in android webview

I have custom JS player based on IFrame Youtube API. And this player works everywhere except of WebView on Android.
For debugging I connected Android Smartphone to laptop and checked console in Chrome on this page: chrome://inspect/#devices.

In console I see these errors:

Uncaught TypeError: s.playVideo is not a function
at HTMLDivElement. (player.js:1:3594)

Uncaught ReferenceError: _yt_player is not defined
at embed.js:292:104

Uncaught ReferenceError: await is not defined
at :1:13

Uncaught TypeError: p.playVideo is not a function
at HTMLButtonElement.

Looks like API doesn’t init.
My script player.js connected to the page as file. Also tried to connect iframe api as file before my file but situation is the same.

What can be wrong? Part of my player.js file below:

document.addEventListener('DOMContentLoaded', function() {
    var players = [];

    var tag = document.createElement('script');

    tag.src = "https://www.youtube.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    // This function is called when the YouTube IFrame API is ready
    function onYouTubeIframeAPIReady() {
        document.querySelectorAll('.player__container').forEach((container, index) => {
            var videoId = container.dataset.id;
            var playerElement = container.querySelector('.player');
            var coverElement = container.querySelector('.player__cover');

            // Set cover image from YouTube thumbnail
            coverElement.style.backgroundImage = `url(https://img.youtube.com/vi/${videoId}/maxresdefault.jpg)`;

            // Initialize the YouTube player
            var player = new YT.Player(playerElement, {
                width: "590",
                height: "640",
                videoId: videoId,
                playerVars: {
                    controls: 0,
                    disablekb: 0,
                    modestbranding: 1,
                    rel: 0,
                    autohide: 1,
                    showinfo: 0,
                    playsinline: 1
                },
                events: {
                    'onReady': (event) => {
                        onPlayerReady(event, container, player, videoId);
                    },
                    'onStateChange': onPlayerStateChange
                }
            });

            // Store the player instance
            players.push(player);
        });
    }

    // This function is called when the player is ready
    function onPlayerReady(event, container, player, videoId) {
        // Setup controls and cover only after player is ready
        setupControls(container, player);
        setupCover(container.querySelector('.player__cover'), player);
    }

    // Handle player state changes (currently empty)
    function onPlayerStateChange(event) {
    }

    // Setup controls for play, pause, stop, volume, etc.
    function setupControls(container, player) {
        var playButton = container.querySelector('.player__play');
        var coverElement = container.querySelector('.player__cover');
        // Another controls...

        // Play button event
        playButton.addEventListener('click', () => {
            player.playVideo();
            coverElement.classList.add('hidden');
        });

        // Another button events...
    }

    // Setup cover click event to play video
    function setupCover(coverElement, player) {
        coverElement.addEventListener('click', () => {
            coverElement.classList.add('hidden');
            player.playVideo();
        });
    }

    // Assign the onYouTubeIframeAPIReady function to the global window object
    window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;
});

ERR_REQUIRE_ESM on node.js app – only on web host and not on local server

I’m trying to implement this Google Wallet pass converter (https://github.com/google-wallet/pass-converter) on my website as a node.js app. I have it working locally on my computer running a local WordPress installation with npm version 10.3.0, node.js 20.11.0, PHP 7.4.30, and an Apache web server.

When I install the app through cPanel on my host using the node.js web app installation, after running npm install and trying node app.js demo I receive the following error:

.../public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js:17
const stripJsonComments = require('strip-json-comments');
                          ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/node_modules/strip-json-comments/index.js from /public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js not supported.
Instead change the require of index.js in /public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js:17:27) {
  code: 'ERR_REQUIRE_ESM'
}

Node.js v20.14.0

When I run node app.js demo locally it comes back with Listening on http://127.0.0.1:3000 — which is the intended response I’m looking for.

My config.js file is

const stripJsonComments = require('strip-json-comments');
const stripJsonTrailingCommas = require('strip-json-trailing-commas').default;
const fs = require('fs');
const path = require('path');

// The Proxy wrapper ensures config is lazily loaded, so we can redefine
// PASS_CONVERTER_CONFIG_PATH at runtime, which we do in the tests.
module.exports = new Proxy(
  {},
  {
    get(target, prop, receiver) {
      if (this._config === undefined) {
        const configPath = process.env.PASS_CONVERTER_CONFIG_PATH || path.resolve(__dirname, 'config.json');
        this._config = JSON.parse(stripJsonTrailingCommas(stripJsonComments(fs.readFileSync(configPath, 'utf8'))));
        // Most of the entries default to empty strings, but code may expect them to be
        // undefined since they were originally env vars, so filter these out to retain the behavior.
        this._config = Object.fromEntries(Object.entries(this._config).filter(([key, value]) => value !== ''));
      }
      return this._config[prop];
    },
  },
);

I am aware this is related to the way node.js handles module imports (‘require’ instead of ‘import’), but I’m not comfortable rewriting everything. I have tried creating a loader script to dynamically import app.js (Node JS (cpanel) Error: I’m getting an error [ERR_REQUIRE_ESM]: Must use import to load ES Module), I have tried using “jsonc-parser” instead of “strip-json-comments” since it is a CommonJS compatible library but that didn’t work (my JS programming skills are lacking, I probably did it wrong), and I have tried a bunch of different versions of node.js.

I am baffled because I had this error come up 6 months ago when I first tried to implement this on my website, yet somehow I was able to fix it (and of course didn’t write down what I did). I only recently noticed that it stopped working again and can’t figure it out anymore. My web host is running npm 10.7.0, PHP 8.0 (could this be the problem?), and I have it configured to be node.js 20.14.0 (and tried it with 18.20.3 and 16.20.2).

Any advice anyone has is appreciated. The fact that it works locally and not on my web host is the most frustrating!

Try to get value from URL in NextJS

I trying to put value in url and trying to extract value in search.js with router, but I’m getting this error:

TypeError: Cannot read properties of undefined (reading ‘q’)

  <form onSubmit={handleSubmit}>
    <input
      type="text"
      placeholder="Search..."
      value={searchValue}
      onChange={(e) => setSearchValue(e.target.value)}
      class="w-full px-4 py-2 rounded-md text-gray-900"
    />
    <button type="submit">Submit</button>
  </form>
</div>
const handleSubmit = (event) => {
  event.preventDefault(); // Prevent the default form submission
  router.push(`../search?q=${encodeURIComponent(searchValue)}`);
};

Search.js:

const Search = () => {
  const router = useRouter();
  const [searchQuery, setSearchQuery] = useState('');

  useEffect(() => {
    if (router.isReady) {
      setSearchQuery(router.query.q || '');
    }
  }, [router.isReady, router.query.q]);

  if (!router.isReady) {
    return <div>Loading...</div>; // Or some loading indicator
  }

  return (
    <div>
      <p>Search Query: {searchQuery}</p>
    </div>
  );
};

export default Search;

How do I reference js and css files from local library for IntroJs

I have a python 2.7 project that uses IntroJs 7. IntroJs just upgraded to a version 8 and it broke, with no warning, the functionality. I need to access 2 files from version 7, Intro.js and Introjs.css. I used to access them externally with this code on a webpage:

<link rel="stylesheet" href="https://unpkg.com/intro.js/introjs.css"/>
    <script src="https://unpkg.com/intro.js/intro.js"></script>

They changed those public access files from version 7 to 8 so those links cannot be used. To deal with it I imported the provided downloadable library from IntroJs. There are many files in it, including theme css options. However the key files intro.js and introjs.css do not exist in that library. Does anyone have experience using IntroJs from a local library and, if so, how do you call the intro.js and introjs.css files if they don’t exist in that library? I’ve downloaded the library from multiple places and those 2 files are never there.

I should add that the support for IntroJs is very vague about using the downloadable library and says nothing about calling intro.js and introjs.css locally. I’ve emailed them and they have been vague and unhelpful. Any help would be greatly appreciated.

image of introjs local library and how to call css and js files

Two paypal buttons [closed]

Is there an easy way to debug the paypal button? I recently made some javascript changes to a site and there’s an impact to the paypal button which may be related which caused there to be two paypal buttons on the checkout page. There are errors in the dev tools console of the browser but they are not super helpful. It has been many years since I have had to do anything serious with the paypal button, honestly it’s one of the more stable payment plugins to use.

loading html from another file gets blocked by oauth2 verification

Using .jsp to create a simple login functionality with oauth 2.0

I’m trying to load a navbar from another file into my login page, using jsp files and a javascript function:

<script>
        $(document).ready(function () {
            $("#navbar").load("navbar.jsp");
            console.log("testing testing");
        });
</script>

This creates the typical “Login with OAuth 2.0” in my navbar. I’ve changed my Antmatchers to accept ‘navbar.jsp’ as well.

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                    .disable()
                .antMatcher("/**")
                .authorizeRequests()    //problem in antmatchers whenever it sends me to sign in w google randomly       //added after example:
                .antMatchers("/", "views/navbar","/Login", "/Register", "/resources/", "/login/database", "/example/**","/public/**", "/resources/**","/resources/static/**")
                    .permitAll()
                .antMatchers("/**.js").permitAll()  //added this for navbar, not sure if works yet
                .anyRequest()
                    .authenticated()
                    .and()
                    .oauth2Login()  
                .and()
                    .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl("/");
    }
}

I’ve been researching for a while and cannot seem to find what I’m missing. Anything helps, thanks!

Javascript add event listner on Input if value change by other button [duplicate]

input event listener fires only when we type something in input, want to fire the event on click of button when values changes from outside

 const currentValue = document.querySelector('#currentValue');
        currentValue.addEventListener('input', function () {
          // This one fires only when we type something in input, want to fire this on click of button when values changes from outside
            console.log("Input alue changed!!");
        });

function myFunction() {
  console.log("Button Clicked..");
  currentValue.value = 3;
}
<input type="text" id="currentValue" value="1"/>
<button onclick="myFunction()">Test</button>

HTML Canvas, pulse animation from center position

I have created pulse animation using html canvas. There is two rectangles. Rectangle’s positions is updated dynamically. The smaller rectangle has pulse animation. I have problem calculate it’s center position value.
Without scaling I get correct position. But when scaling position is incorrect. How to calculate scaled X and Y?

HTML

<div class="wrap"></div>

JS

const canvas = document.createElement("canvas");
canvas.setAttribute("width", "500px");
canvas.setAttribute("height", "500px");
const ctx = canvas.getContext("2d");
const wrapper = document.getElementsByClassName("wrap")[0];
wrapper.appendChild(canvas);
let scale = 1;
let angle = 0;
const blockSize = 45; // Rectangle size
const pos = {x: 2, y: 1}; // Rectangle position

function anim(){
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.setTransform(1, 0, 0, 1, 0, 0);
   draw(ctx, pos)
   update();
   requestAnimationFrame(anim);
}
anim();

function draw(ctx, position){
    ctx.fillStyle = "#000";
  ctx.fillRect((position.x * blockSize - blockSize), (position.y * blockSize - blockSize), blockSize, blockSize);
  
  // Smaller rectangle with pulse
  ctx.fillStyle = "red";
  const centerX = (position.x * blockSize - blockSize) / 2;
  const centerY = (position.y * blockSize - blockSize) / 2;
  const scaledX = centerX - (centerX * scale); 
  const scaledY = centerY - (centerY * scale);
  ctx.setTransform(scale, 0, 0, scale, centerX, scaledY);
  const recSize = 30;
  const x = (position.x * blockSize - blockSize) + ((blockSize - recSize) / 2);
  const y = (position.y * blockSize - blockSize) + ((blockSize - recSize) / 2);
  ctx.fillRect(x, y, recSize, recSize);
  ctx.setTransform(1, 0, 0, 1, 0, 0);
}

function update(){
    angle += Math.PI / 140;
  scale = 0.5 + Math.abs(Math.cos(angle));
}

const canvas = document.createElement("canvas");
canvas.setAttribute("width", "500px");
canvas.setAttribute("height", "500px");
const ctx = canvas.getContext("2d");
const wrapper = document.getElementsByClassName("wrap")[0];
wrapper.appendChild(canvas);
let scale = 1;
let angle = 0;
const blockSize = 45; // Rectangle size
const pos = {x: 2, y: 1}; // Rectangle position


function anim(){
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.setTransform(1, 0, 0, 1, 0, 0);
   draw(ctx, pos)
   update();
   requestAnimationFrame(anim);
}
anim();

function draw(ctx, position){
    ctx.fillStyle = "#000";
  ctx.fillRect((position.x * blockSize - blockSize), (position.y * blockSize - blockSize), blockSize, blockSize);

  // Smaller rectangle with pulse
  ctx.fillStyle = "red";
  const centerX = (position.x * blockSize - blockSize) / 2;
  const centerY = (position.y * blockSize - blockSize) / 2;
  const scaledX = centerX - (centerX * scale); 
  const scaledY = centerY - (centerY * scale);
  ctx.setTransform(scale, 0, 0, scale, centerX, scaledY);
  const recSize = 30;
  const x = (position.x * blockSize - blockSize) + ((blockSize - recSize) / 2);
  const y = (position.y * blockSize - blockSize) + ((blockSize - recSize) / 2);
  ctx.fillRect(x, y, recSize, recSize);
  ctx.setTransform(1, 0, 0, 1, 0, 0);
}

function update(){
    angle += Math.PI / 140;
  scale = 0.5 + Math.abs(Math.cos(angle));
}
<div class="wrap">

</div>

Cant autofill the last 2 digits of card year in MUI React

I am trying to fix the autofill on my expiry input. It should autofill the last 2 digits of YYYY. Just YY.

I feel like I’m doing this right, but when I autofill it uses the first 2 digits, not the last 2.

Where am I going wrong?

<InputField
    id={id}
    name={'YY'}
    label={'YY'}
    placeholder='YY'
    maxlength="2"
    pattern="d{2}" 
    autoComplete='cc-exp-year'
/>

Vue breaks upon Object modification

If I do this:

Object.prototype.breakVue=true;

Vue will break.

How to avoid it?

More details (only if you want more context/details, first section is enough to reproduce the problem):

I wrote an Object plugin which injects many methods I wrote into every object by adding them into Object‘s prototype.
This works fine with plain JavaScript applications, but if I use Vue, it breaks it.
I use those handy methods in my code.
For example, if I want to make my class final, I do:

export default class FinalClass {}
FinalClass.makeFinal();

which is a handy shortcut for what I would usually have to type:

export default class FinalClass {}
Object.freeze(FinalClass);

and is made possible by injection of the makeFinal method into Object:

Object.prototype.makeFinal=function() { Object.freeze(this); }

I do have my own utility class:

export default class OBJECT { static makeFinal() { Object.freeze(this); } }

which I can use like this:

export default class FinalClass extends OBJECT {}
FinalClass.makeFinal();

but the downside is that all classes in which I want to use this have to extend from OBJECT, plus this does not work for objects which are not created by me. I want to be able to call my method on any object, so I want {}.makeFinal(); to be a valid syntax. Or "text".makeFinal(); and so on. So, I want all built in objects to have my extension methods injected.
Plus it is not just one extension function I wrote for Object. I have tens of them.

This works with plain JavaScript application. But now I want my extensions to be used with Web application which uses Vue. However, this does not work.

I have injected methods into many other JavaScript built in objects, such as Date and Vue worked without problems.

Do you know how to fix Vue? How to allow Vue to work, while allowing, for example, true.and(true); or 5.isGreaterThen(6); or {}.equals({}) to be a valid syntax in my code?

How to create better chunks to send openai

i have been creating a application which is connected to the drive from there they fetch the .docx file then i have converted the docx file into the html format so that LLM easily understand where is heading in the document but the problem i am facing is chunk creating

i tried to create chunk on the basis of bold formatting tags in the html file
for example such type of tag i consider for making chunks
strong html tag Buyer Management Procedure /strong

but the problem i faced is that when i got improved chunks from openai llm they gave me repeated content which i dont want

i tried everything but nothing works now i am clueless how to solve this probelm

CODE FOR CRREATING CHUNK

function processDocument(htmlContent) {
  console.log("Starting document processing...");
  const chunks = [];
  let customPrompts = {};

  // Process custom prompts across the entire document
  const processedContent = htmlContent.replace(/(([ws]+))((([ws]+)))/g, (match, text, prompt) => {
    customPrompts[text] = prompt;
    console.log(`Found custom prompt: "${text}" with instruction "${prompt}"`);
    return `(${text})`;
  });

  const dom = new JSDOM(processedContent);
  const document = dom.window.document;

  // Function to check if an element is a bold formatting tag
  function isBoldTag(element) {
    return ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'STRONG', 'B'].includes(element.tagName);
  }

  // Function to get heading level
  function getHeadingLevel(element) {
    if (element.tagName.startsWith('H')) {
      return parseInt(element.tagName.slice(1));
    }
    return 0; // For <strong> and <b> tags
  }

  let currentChunk = [];
  let currentHeading = '';
  let currentLevel = 0;

  function processNode(node) {
    if (node.nodeType === Node.ELEMENT_NODE) {
      if (isBoldTag(node)) {
        // If we have a current chunk, save it
        if (currentChunk.length > 0) {
          chunks.push({
            content: currentChunk.join(''),
            heading: currentHeading,
            level: currentLevel,
            customPrompts: { ...customPrompts }
          });
          currentChunk = [];
        }

        currentHeading = node.textContent;
        currentLevel = getHeadingLevel(node);
        currentChunk.push(node.outerHTML);
      } else {
        // For non-bold tags, just add their HTML to the current chunk
        currentChunk.push(node.outerHTML);
      }

      // Process child nodes
      node.childNodes.forEach(processNode);
    } else if (node.nodeType === Node.TEXT_NODE) {
      // Add text nodes to the current chunk
      currentChunk.push(node.textContent);
    }
  }

  // Start processing from the body
  processNode(document.body);

  // Add the last chunk if there's any content left
  if (currentChunk.length > 0) {
    chunks.push({
      content: currentChunk.join(''),
      heading: currentHeading,
      level: currentLevel,
      customPrompts: { ...customPrompts }
    });
  }

  console.log("Document processing complete.");
  console.log(`Total chunks created: ${chunks.length}`);

  // Log all chunks for visibility
  chunks.forEach((chunk, index) => {
    console.log(`nChunk ${index + 1}:`);
    console.log("Heading:", chunk.heading);
    console.log("Level:", chunk.level);
    console.log("Content:");
    console.log(chunk.content);
    console.log("Custom prompts:", chunk.customPrompts);
    console.log("Word count:", chunk.content.replace(/<[^>]*>/g, '').split(/s+/).filter(Boolean).length);
    console.log("-".repeat(50)); // Separator for readability
  });

  return chunks;
}
// Function to create an OpenAI assistant
async function createAssistant() {
  const assistant = await openai.beta.assistants.create({
    name: "Document Improvement Assistant",
    instructions:
      "You are an AI assistant that helps improve documents. Use the existing knowledge base to improve the content provided. Don't use any content from internet or your own knowledge. Enhance clarity, coherence, and relevance of the text. Use proper formatting and heading and make sure such text is improved. Don't add image placeholders or use links. Use simple text and don't use complex formatting. Use formatting which is good looking and readable, and provide detailed information.",
    model: "gpt-4o-mini",
    tools: [{ type: "file_search" }],
    tool_resources: {
      file_search: {
        vector_store_ids: [VECTOR_STORE_ID],
      },
    },
  });
  console.log(`Assistant created with ID: ${assistant.id}`);
  return assistant;
}

IMPROVMENT CHUNK CODE

async function improveChunk(chunk, fullDocument, assistantId, documentContext, customPromptInstruction, chunkIndex, totalChunks) {
console.log(Processing chunk ${chunkIndex + 1} of ${totalChunks});
const startTime = Date.now();

try {
const { content, customPrompts } = chunk;

let promptContent = `You are tasked with improving a chunk of text from a larger document. You will be provided with the following information:
  1. Document Context:
    ${documentContext}

  2. Custom Prompt Instruction:
    ${customPromptInstruction}

  3. The full document content:
    ${fullDocument}

  4. The current chunk of text to improve (chunk ${chunkIndex + 1} of ${totalChunks}):
    <current_chunk>${content}</current_chunk>

Your task is to improve the current chunk of text while ensuring continuity with the rest of the document and staying within the context. Follow these guidelines:

  1. It is CRUCIAL to avoid ANY repetition of information that exists elsewhere in the document. If you encounter content that appears elsewhere, you MUST either:
    a) Omit it to avoid repeatation
  2. Follow the custom prompt instruction provided above.
  3. If it’s a heading, format it correctly using Markdown syntax (e.g., # for main headings, ## for subheadings).
  4. Use Markdown formatting that is visually appealing and readable.
  5. Ensure smooth transitions with the surrounding content in the full document.
  6. also donot add such line This revision maintains continuity with the rest of the document while enhancing clarity and readability. The content has been organized into relevant categories, emphasizing the importance of buyers without introducing redundant information.
  7. if (#,*,##) any line start with such markdown syntax so elaborate that part

Additionally, there are specific parts of the text that require special attention. For each of these parts, enclosed in parentheses (), apply the corresponding custom prompt:

`;

for (const [text, prompt] of Object.entries(customPrompts)) {
  promptContent += `For the text "${text}": ${prompt}n`;
}

promptContent += `

Please provide the improved version of the current chunk, or indicate if it should be omitted due to redundancy:`;

const thread = await openai.beta.threads.create({
  messages: [{ role: "user", content: promptContent }],
  tool_resources: {
    file_search: { vector_store_ids: [VECTOR_STORE_ID] },
  },
});

const run = await openai.beta.threads.runs.create(thread.id, {
  assistant_id: assistantId,
});

let runStatus;
do {
  runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);
  await new Promise((resolve) => setTimeout(resolve, 1000));
} while (runStatus.status !== "completed");

const messages = await openai.beta.threads.messages.list(thread.id);
const improvedChunk = messages.data[0].content[0].text.value;

if (improvedChunk.toLowerCase().includes("this chunk should be omitted")) {
  console.log(`Chunk ${chunkIndex + 1} suggested for omission due to redundancy.`);
  return null;
}

const endTime = Date.now();
const timeTaken = endTime - startTime;

const processData = new ProcessData({
  iterationNumber: fetchCounter,
  functionType: 'improve',
  chunk: content,
  aiPrompt: promptContent,
  openaiResponse: improvedChunk,
  timeTaken: timeTaken
});
await processData.save();

return improvedChunk;

} catch (error) {
console.error(Error improving chunk:, error);
return chunk.content;
}
}

How to find non reducible fractions more efficently(code keeps timing out)

I’m trying to find the non-reducible 0-1 fractions for a number passed as an argument in my function.
I was able to do this but my code keeps timing out for large numbers. Please help

function properFractions(n) {
  function gcd(a, b) {
    if (a == 0) return b;
    return gcd(b % a, a);
  }

  let result = 0;

  if (n === 1) {
    return result;
  } else if (n > 1) {
    for (let i = 1; i < n; i++) if (gcd(i, n) === 1) result++;
    return result;
  }
}

How to Ensure Database Update Only After Successful Document Printing in JavaScript?

I’m developing a web application where users can print documents from a browser. I need to ensure that a database update occurs only if the user actually prints the document, and not if they cancel or close the print dialog.

Problem Description
When a user initiates printing, I open a new window with the content to be printed. I want to:

  1. Trigger a database update only when the document is printed.
  2. Ensure that no database updates are made if the user cancels or closes the print dialog.

Current Approach
Here’s the approach I’m currently using:

  1. Open a new window with the document content to be printed.

  2. Attach an onafterprint event handler to this window to detect when the print dialog is
    closed.

  3. Use a timer to assume printing based on the time the print dialog is open.

    const handlePrint = async () => {
    const content = printRef.current.innerHTML;
    const printWindow = window.open(”, ”, ‘width=600,height=400’);
    let isPrintConfirmed = false;

    printWindow.document.write(<html> <head> <title>Print</title> <style> @media print { @page { margin: 0; } body { margin: 0; } .print-container { text-align: center; padding: 20px; } } </style> </head> <body> <div class="print-container"> ${content} </div> </body> </html>);

    printWindow.document.close();
    printWindow.focus();

    const confirmPrint = () => {
    if (!isPrintConfirmed) {
    isPrintConfirmed = true;
    const userConfirmed = window.confirm(“Did you successfully print the document?”);
    if (userConfirmed) {
    fetch(‘/api/updatePrintStatus’, {
    method: ‘POST’,
    body: JSON.stringify({ status: ‘printed’, guestId: guest.id }),
    headers: { ‘Content-Type’: ‘application/json’ },
    }).then(() => alert(“Database updated successfully.”))
    .catch(err => alert(“Error updating database: ” + err.message));
    } else {
    alert(“Print action was canceled or failed.”);
    }
    }
    };

    printWindow.onafterprint = confirmPrint;

    const printCheckTimer = setTimeout(() => {
    if (!isPrintConfirmed) {
    confirmPrint();
    }
    }, 5000);

    printWindow.print();
    printWindow.close();
    };

Issues Encountered

  • False Assumptions: If a user stays on the print dialog but does not actually print, the code might incorrectly assume printing occurred based on the timer.
  • Edge Cases: How can I improve handling to ensure that the database update happens only if the user actually prints?

Desired Solution
I am looking for a reliable way to:

  • Confirm if the user has actually printed the document.
  • Ensure that the database update only occurs if printing is confirmed.

Any advice on improving the current implementation or alternative approaches to achieve this would be greatly appreciated!