Error on trying to use jsPDF in tampermonkey. Saying jsPDF object is undefined

Ive been writing a tampermonkey userscript to convert an ebook to a pdf in google play books. However, whenever i try to use the jsPDF object, it throws an error. This is my the part of the code that is throwing an error:

// ==UserScript==
// @name         tampermonkey userscript
// @namespace    http://tampermonkey.net/
// @version      2025-05-26
// @description  try to take over the world!
// @author       You
// @match        https://play.google.com/books/*
// @match        *://*.googleusercontent.com/*
// @match        *://books.google.com/ebooks/reader*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @require      https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
// @grant        none
// @run-at       document-idle
// ==/UserScript==
/* global jsPDF */

(function() {
    'use strict';

    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();
    doc.save("example.pdf");
})();

Frankly, I don’t even know if i am supposed to do it like this as i just asked chatgpt for this part.
I am getting this error message in my console:
Console Error Message

And right after that this:
Console Error Message

So, from the console messages, as well from the tampermonkey extension ui, I can see that my script is also being executed twice for some reason? Is jsPDF causing this?

As per chatGPT’s instructions, ive tried injecting the script tag directly into the HTML as well, tried to use just jspdf.min.js instead of jspdf.umd.min.js in my code and ignored the const { jsPDF } = window.jspdf part, tried making a global alias by window.jsPDF = window.jspdf.jsPDF. But all of them say that either jsPDF is an undefined object or that cannot destructure property jsPDF as window.jspdf is undefined.

Can someone point out the mistake im making?

Windshaft-cartodb error while retrieve svg from millstone cache on kubernates

I am running windshaft-cartodb with redis inside Kubernates. windshaft runs with four replicas (pods), however we have been having problems with the millstone.js library for a long time, in particular when restarting kubernates during the first calls to windshaft an error is always returned:

“ENOENT: No such file or directory, rename ‘/tmp/millstone/cache/41fca2a8-072-myimage.svg.download’ -> ‘/tmp/millstone/cache/41fca2a8-072-myimage.svg'”

The error occurs 4 times each time.

I have tried several times to debug and log internally but I can’t find the source of the error.

I have also tried to run windhshaft on a single pod but nothing has changed and I still have the error.

JS Canvas: How to draw lines of different hardness?

I want to create a brush with a hardness option like in PhotoShop.

I tried to use ctx.createRadialGradient to create a radial transparent circle, but the result was not satisfactory.

function createBrush(size, hardness) {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  [canvas.width, canvas.height] = [size, size];

  const outerRadius = size / 2;
  const innerRadius = outerRadius * (1 - hardness); // how to apply the hardness option?
  const x = size / 2;
  const y = size / 2;
  const gradient = ctx.createRadialGradient(x, y, innerRadius, x, y, outerRadius);
  gradient.addColorStop(0, "rgba(0, 0, 0, 1)");
  gradient.addColorStop(1, "rgba(0, 0, 0, 0)");

  ctx.fillStyle = gradient;
  ctx.clearRect(0, 0, size, size);
  ctx.beginPath();
  ctx.arc(x, y, outerRadius, 0, 2 * Math.PI);
  ctx.fill();

  return canvas;
}

bursh with hardness

drawing

My question is how to create a hardness effect similar to the brush in PhotoShop?

PS: photopea and onemotion implement similar brush hardness, but they are not open source, so I don’t know how they are made.

My example:

function createBrush(size, hardness) {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  [canvas.width, canvas.height] = [size, size];

  const outerRadius = size / 2;
  const innerRadius = outerRadius * (1 - hardness); // how to apply the hardness option?
  const x = size / 2;
  const y = size / 2;
  const gradient = ctx.createRadialGradient(x, y, innerRadius, x, y, outerRadius);
  gradient.addColorStop(0, "rgba(0, 0, 0, 1)");
  gradient.addColorStop(1, "rgba(0, 0, 0, 0)");

  ctx.fillStyle = gradient;
  ctx.clearRect(0, 0, size, size);
  ctx.beginPath();
  ctx.arc(x, y, outerRadius, 0, 2 * Math.PI);
  ctx.fill();

  return canvas;
}

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

let brush, isDrawing, lastPoint;

function drawBrush(x, y) {
  ctx.drawImage(brush, x - brush.width / 2, y - brush.height / 2);
}

canvas.onmousedown = function (e) {
  brush = createBrush(50, 1);
  isDrawing = true;
  lastPoint = { x: e.offsetX, y: e.offsetY };
  drawBrush(lastPoint.x, lastPoint.y);
};

canvas.onmousemove = function (e) {
  if (!isDrawing) return;

  const currentPoint = { x: e.offsetX, y: e.offsetY };
  const dist = distanceBetween(lastPoint, currentPoint);
  const angle = angleBetween(lastPoint, currentPoint);

  for (let i = 0; i < dist; i++) {
    const x = lastPoint.x + Math.sin(angle) * i;
    const y = lastPoint.y + Math.cos(angle) * i;
    drawBrush(x, y);
  }

  lastPoint = currentPoint;
};

canvas.onmouseup = function () {
  isDrawing = false;
};

function distanceBetween(point1, point2) {
  return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
}
function angleBetween(point1, point2) {
  return Math.atan2(point2.x - point1.x, point2.y - point1.y);
}
canvas {
  border: #000 solid 1px;
}
<canvas id="canvas" width="400" height="300"></canvas>

Webcam video blinks or desyncs during export in browser-based screen recorder (Next.js + MediaRecorder)

I’m building a browser-based screen recorder using Next.js. It records the screen and webcam simultaneously. I use canvas.captureStream() for rendering and MediaRecorder to export the video. Audio from both the screen and background music is added using captureStream().

In the preview, everything works as expected — both screen and webcam play smoothly. But during export, the webcam video either blinks, goes black, or desyncs.

What I’ve tried so far:

  • Using MediaRecorder on a canvas that renders screen + webcam
  • Syncing webcamVideo.currentTime with video.currentTime
  • Using waitForSeek() and calling play() on the webcam element
  • Rendering frame-by-frame using requestAnimationFrame
  • A frame-by-frame processing approach (also failed)

Here’s a simplified version of my export code:
https://onecompiler.com/typescript/43k4htgng

What could be causing the webcam stream to behave like this only during export?
Are there known limitations with MediaRecorder or captureStream() when combining multiple media sources?

Looking for insights from anyone who has handled browser-based video compositing or webcam stream export.

Why is my registration still failed after Operation `users.insertOne()` buffering timed out after 10000ms?

enter image description here

authController.js under backend> controllers file 

const User = require('../models/User');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

exports.register = async (req,res) => {
  try {
    const {username, email, mobile, password, role} = req.body;

    // Hash password
    const salt = await bcrypt.genSalt(10);
    const hashed = await bcrypt.hash(password, salt);
    
    // Save user
    const user = new User({username, email, mobile, password: hashed, role});
    await user.save();

    res.status(201).json({message: "User registered"});
  } catch (err) {
    res.status(500).json({error:err.message});
  }
};

exports.login = async (req, res) => {
  try {
    const {email, password} = req.body;
    const user = await User.findOne({ email });
    if (!user) return res.status(404).json({ message: "User not found" });

    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) return res.status(401).json({ message: "Wrong password" });

    const token = jwt.sign({id: user._id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '2d'});
    res.status(200).json({token, user: { id: user._id, username: user.username, role: user.role } });
  } catch (err) {
    res.status(500).json({ rror:err.message});
  }
};

pls help with my auth controller code if possible and a suggested frontend code site for my register.jsx using react.js cause i have real issues man and i only learnt the basics of react only

Selenium Click Intercepted by ui-widget-overlay Despite Removing Overlay and Modal

I’m automating a shipping form using Selenium and running into an issue where clicking a button fails because of a persistent overlay. The application uses jQuery UI for modals and overlays.

The error I’m getting is:

Message: element click intercepted: Element <a class="..."> is not clickable at point (...). Other element would receive the click: <div class="ui-widget-overlay ui-front"></div>

Despite trying to remove this overlay and dialog using JavaScript, the click is still blocked or doesn’t perform the desired action. Sometimes it looks like the page resets or the browser quits. Other times, I get a JavaScript error like:

javascript error: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions...

Or:

Message: element not interactable

Here’s what I tried:

# 1. Using Selenium's click directly
try:
    driver.find_element(By.ID, 'ctl00_CPPC_ConfirmMessage_OSNR_btnOk').click()
except Exception as e:
    print(f"❌ Failed: {e}")

Fails with element click intercepted.

# 2. Removing overlay and modal manually
try:
    driver.execute_script("""
        let overlay = document.querySelector('.ui-widget-overlay');
        let dialog = document.querySelector('.ui-dialog');
        if (overlay) overlay.remove();
        if (dialog) dialog.remove();
    """)
    time.sleep(1)
except Exception as e:
    print(f"❌ Overlay remove failed: {e}")

Still gets intercepted. Sometimes the browser shuts down instantly.

# 3. Clicking via JavaScript after removal
try:
    driver.execute_script("""
        const btn = document.getElementById('ctl00_CPPC_ConfirmMessage_OSNR_btnOk');
        if (btn) btn.click();
    """)
except Exception as e:
    print(f"❌ JavaScript click failed: {e}")

Sometimes this throws Cannot read properties of null (reading 'click').

# 4. Forcing the postback directly
try:
    driver.execute_script("DoButtonPostBack('ctl00$CPPC$btnShip');")
except Exception as e:
    print(f"❌ Postback failed: {e}")

This can reload or completely close the page.

# 5. Disabling jQuery dialog itself
try:
    driver.execute_script("""
        if (window.jQuery) {
            jQuery.fn.dialog = function() { return this; };
        }
    """)
except Exception as e:
    print(f"❌ jQuery disable failed: {e}")

Still no effect. Overlay blocks action.

Debug Insight:

I logged success messages after each script like this:

print("✅ Removed overlay")
print("✅ Clicked OK button")

But sometimes it prints these and still does nothing visible, or instantly quits. I even tried combinations of waiting and interacting. Example:

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'ctl00_CPPC_ConfirmMessage_OSNR_btnOk'))).click()

Still failed.

My environment:

Chrome: 136.0.7103.114
Selenium: 4.x
Python: 3.11+
chromedriver used

What I need help with:

  1. A reliable way to remove the overlay and modal dialog completely.

  2. A working method to click the OK and Ship buttons afterward.

  3. Prevent the browser from closing or resetting after running the script.

Any help would be appreciated. I’ve exhausted all reasonable ways I know. If you’ve dealt with persistent overlays or jQuery dialogs, your suggestions are welcome!

Note: English is not my first language, so some parts of this post were helped by AI to better explain my issue. I’ve done my best to make everything clear.

Intl.DisplayNames with type: “language” can’t recognize certain languages on mobile

Intl.DisplayNames can’t recognize certain languages when running on mobile.

Running the following code:

const displayNames=new Intl.DisplayNames(["en-US"], {type:"language"})
console.log(displayNames.of("bs-BA"))
console.log(displayNames.of("ps-AF"))

I see that it works properly on desktop but not on mobile. On mobile, it outputs “bs (Bosnia & Herzegovina)” instead of “Bosnian (Bosnia & Herzegovina)”.

I used Chrome to run both snippets.
My desktop Chrome version is 136.0.7103.114.
My mobile Chrome version is 136.0.7103.127.

how to use prettier recommended rules with eslint’s defineConfig API?

I have a folder with this structure:

root
|- folderA
|- folderB
|- folderC

I want to apply two sets of rules to eslint to each folderA and folderB and completely skip folderC. so I have this:


export default defineConfig([
    {
        files: ["folderA/**/*.{vue,ts}", "folderB/**/*.{vue,ts}"],
        ignore: ["folderC"],
    },
    eslintPluginPrettierRecommended,
    {
        files: ["folderA/**/*.{vue,ts}"],
        settings: {
            "vue/setup-compiler-macros": true,
            "import/parsers": {
                "@typescript-eslint/parser": [".ts", ".tsx"],
            },
        },
        plugins: {
            vue: fixupPluginRules(vuePlugin),
            "@typescript-eslint": fixupPluginRules(typescriptEslint),
        },
        languageOptions: {
            globals: {
                ...globals.browser,
            },
            parser: vueParser,
            parserOptions: {
                ecmaVersion: "latest",
                extraFileExtensions: [".vue"],
                parser: tsParser,
                sourceType: "module",
                ecmaFeatures: {
                    jsx: true,
                },
            },
        },
        extends: ["plugin:prettier/recommended"],
        rules: {
            "prettier/prettier": [
                "error",
                {
                    tabWidth: 2,
                },
            ],
            eqeqeq: "error",
        },
    },
    {
        files: ["folderB/**/*.{vue,ts,tsx}"],
        extends: ["plugin:prettier/recommended"],
        settings: {
            "vue/setup-compiler-macros": true,
            "import/parsers": {
                "@typescript-eslint/parser": [".ts", ".tsx"],
            },
        },
        plugins: {
            vue: fixupPluginRules(vuePlugin),
            "@typescript-eslint": fixupPluginRules(typescriptEslint),
        },
        languageOptions: {
            globals: {
                ...globals.browser,
            },
            parser: vueParser,
            parserOptions: {
                ecmaVersion: "latest",
                extraFileExtensions: [".vue"],
                parser: tsParser,
                sourceType: "module",
                ecmaFeatures: {
                    jsx: true,
                },
            },
        },
        rules: {
            "prettier/prettier": [
                "error",
                {
                    tabWidth: 4,
                },
            ],
        },
    },
]);

However when I execute the above, things in folderC still get executed. My theory is eslintPluginPrettierRecommended is not bound with the files and ignore defined right before it.

The question is how can I achieve my goal to have different rules for folderA and folderB while completely ignore folderC?

Is “data-val-required” supposed to display message when required validation fails?

The cshtml for my modal dialog has two input forms. When I click on “Submit” the required attributes for the input forms are working since the ajax call is not invoked unless both inputs have a string value. That works great.

The only minor issue is that nothing’s being displayed when the required attribute fails. Isn’t data-val-required supposed to show the message? If not, how can I display an error message?

<div id="modal_dialog" style="display: none">
    <form id="myForm">
        <input type="text" name="fullname" id="fullname" required data-val="true" data-val-required="Name is required" />
        <input type="text" name="email" id="email" required data-val="true" data-val-required="email is required" />
        <button type="submit">Submit</button>
    </form>
</div>

My javascript looks like this:

<script>
    $(document).ready(function () {
        $("#myForm").validate();
        $("#myForm").submit(function (event) {
            event.preventDefault(); 

            if ($("#myForm").valid()) {
                alert("valid");
                $.ajax({
                    type: "POST",
                    url: "/Index?handler=Send",
                    data: $("#myForm").serialize(),
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("XSRF-TOKEN",
                        $('input:hidden[name="__RequestVerificationToken"]').val());
                    }
                });
            }
        });

    });
</script>

overiding the mvw using server.use(…) fails


describe("render Context data", () => {
  it("render correct email", async () => {
    render(<App usersData={[]} />);
    server.use(
      http.get("https://jsonplaceholder.typicode.com/users/*", (resolve) => {
        return Response.json({
          id: 333,
          name: "Ifeoluwa",
          username: "ifeoluwa",
          email: "[email protected]",
        });
      })
    );

    await waitFor(async () => {
      expect(
        await screen.findByText("Email: [email protected]")
      ).toBeInTheDocument();
    });
  });
});

the test still passes…
but why? I expected it to fail

I mocked the MVW requests expecting it to use the data i passed from in the server.use(...) it doesn’t. it even passed with a wrong Email in the test assertion.

Translate permutation algorithm by Sedgewick from Pseudocode into JavaScript

In his classical paper [Permutation Generation Methods, Computing Surveys 1977][https://www.princeton.edu/~rblee/ELE572Papers/p137-sedgewick.pdf] Robert Sedgewick presents his “Algorithm 1” on page 140 like this:

procedure permutations(N);
    begin
        c:= 1;
        loop:
            if N > 2 then permutations(N - 1) 
            endif;
        while c < N:
            P[B[N, c]] :=: P[N];
            c:= c + 1;
        repeat
    end;

This is neither Algol60 nor Algol68, but Pseudocode. His :=: operator is the swap operator for array elements. The loop-while-repeat construct is taken from D. E. Knuth, Sorting and Searching, The Art of Computer Programming 3.

Please, can anyone help me to translate the algorithm into JavaScript.

Also: that procedure is supposed to generate all permutations of N different elements. Where does Sedgewick intend to yield or output each new permutation to the caller?

JavaScript return last then as a promise

I wrote the following code to resize an image:

Main().then(function(x){console.log(x)});

Main=function(){
Base64() 
.then(function(i){ImageObject(i)}) 
.then(function(i){x=Resize(i);NOW RETURN 'x' AS A PROMISE}) //***
});
}

function Base64(i){  //Generate base64 of the image
let reader=new FileReader();
reader.readAsDataURL(imaginary.file());
return new Promise((resolve,reject)=>{reader.onload=()=>{resolve(reader.result)}});
}

function ImageObject(i){ //Load the image
let img=new Image(0,0);
img.src=i;
return new Promise((resolve,reject)=>{img.onload=()=>{resolve(img)}});
}

function Resize(i){ //Resize image and return base64
let canvas=document.createElement('canvas');
let canvasContext=canvas.getContext('2d');
canvas.width=300;
canvas.height=200;
canvasContext.drawImage(i,0,0,canvas.width,canvas.height);
return canvas.toDataURL();  //Return the resized base64
}

In the line with the ***, I need to return x as a promise to allow Main to be ‘thenable’.