How do I gain access to the array in a method? (P5.JS)

I want my program to print out (“character has died”) when the ball has gone. Problem is I don’t know how to do it properly.

let balls = []; 
let numBalls = 20;
let ballTextures = [];

let subaruImg, emiliaImg, remImg;

//------- Variables initialsed above ---------- //

function preload(){
  subaruImg = loadImage('assets/subaru_chibi.jpg');
  emiliaImg = loadImage('assets/emilaia_chibi.jpg');
  remImg = loadImage('assets/rem_chibi.jpg');

  ballTextures = [subaruImg, emiliaImg, remImg]; // Store my GOAT subaru and his friends in the array
}

// Preload is for images and textures

function setup() {
  createCanvas(600, 600, WEBGL);
  angleMode(DEGREES);

  for (let i = 0; i < numBalls; i++) {
    let pos = createVector(
      random(-width / 2 + 20, width / 2 - 20),
      random(-height / 2 + 20, height / 2 - 20),
      random(-200, 200)
    );
    let vel = p5.Vector.random3D().mult(random(1, 2));
    let r = random(20, 30);
    
    // Let 
    let tex = random(ballTextures); //allows the t
    
    balls.push(new Ball(pos, vel, r, tex));
  }

  frameRate(60);
}

function draw() {
  background(20);
  orbitControl(); // makes me be able to have 3d movementt on the canvas

  //different lights 
  ambientLight(60, 60, 60);

  
  directionalLight(255, 255, 255, -0.5, -1, -0.5);

  // Moving point light (dynamic, cool effect)
  let lightX = sin(frameCount * 0.01) * 300;
  let lightY = cos(frameCount * 0.01) * 300;
  let lightZ = sin(frameCount * 0.005) * 300;
  pointLight(255, 255, 200, lightX, lightY, lightZ);

  // Optional: visualize the light source
  push();
  translate(lightX, lightY, lightZ);
  noStroke();
  emissiveMaterial(255, 255, 200);
  sphere(5); // glowing light orb
  pop();

  for (let i = 0; i < balls.length; i++) {
    balls[i].move();
    balls[i].edgeCheck();
    balls[i].drawBall();

    for (let j = i + 1; j < balls.length; j++) {
      balls[i].checkCollision(balls[j]);
    }
  }
}

class Ball {
  constructor(pos, vel, r, tex) {
    this.pos = pos;
    this.vel = vel;
    this.r = r;
    this.tex = tex;
    this.life = 3; // start with 3 lives
    this.alive = true;
  }

  drawBall() {
    if (!this.alive) return; // don't draw if dead

    push();
    translate(this.pos.x, this.pos.y, this.pos.z);
    texture(this.tex);
    noStroke();
    sphere(this.r);
    pop();
  }

  move() {
    if (!this.alive) return;
    this.pos.add(this.vel);
  }

  edgeCheck() {
    if (!this.alive) return;
    if (this.pos.x + this.r > width / 2 || this.pos.x - this.r < -width / 2) {
      this.vel.x *= -1;
    }
    if (this.pos.y + this.r > height / 2 || this.pos.y - this.r < -height / 2) {
      this.vel.y *= -1;
    }
    if (this.pos.z + this.r > 300 || this.pos.z - this.r < -300) {
      this.vel.z *= -1;
    }
  }

  checkCollision(other) {
    if (!this.alive || !other.alive) return;

    let d = p5.Vector.dist(this.pos, other.pos);
    if (d < this.r + other.r) {
      // Swap velocities
      let temp = this.vel.copy();
      this.vel = other.vel.copy();
      other.vel = temp;

      // Separate overlapping balls
      let overlap = (this.r + other.r - d) / 2;
      let direction = p5.Vector.sub(this.pos, other.pos).normalize();
      this.pos.add(direction.mult(overlap));
      other.pos.sub(direction.mult(overlap));

      // Decrease life
      this.lifeCounter();
      other.lifeCounter();
    }
  }

  lifeCounter() {
    this.life -= 1;
    if (this.life <= 0) {
      this.alive = false && new Ball(pos, vel, r, tex.subaruImg);
      console.log("subaru has died");
    }
    if(this.life <=0) {
      this.alive = false && new Ball(pos, vel, r, tex.emiliaImg);
      console.log("emilia has died")
    }
    if(this.life <= 0){
      this.alive = false && new Ball(pos, vel, r, tex.remImg);
      console.log("Rem has died")
    }
  }


}
html, body {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
    <script src="sketch.js"></script>
  </body>
</html>

[It works perfectly seen here] [1]: https://i.sstatic.net/gJXn19Iz.png

However in the console log it does this [It shows 3 of them when the ball diseapears][2]
[2]: https://i.sstatic.net/lG4c5f09.png

The section I’m having trouble with is this method in the “ball” class at the end of the code

[life Counter method][3] [3]: https://i.sstatic.net/62zAcGBM.png

Download files from OPFS

let’s say I have code that writes some stuff to a file in OPFS. What’s the best way to let the user download that file to their Downloads folder?

I’m aware that I can create a blob and attach it to the href attribute of an a tag. I just wonder if that’s the only/best option, especially if the file is rather big, say, a couple of gigabytes.

Thanks.

Fetch from SSO-protected resource

I need to fetch data using an API. I’ve been pulling the data manually using cURL, and type my password repeatedly.

I need to move this whole process to a web page that will sit on people’s C: drive.

I can fetch stuff just fine in Javascript when there’s no authentication. I expect I could make basic auth work, too. However, my user base is used to SSO via Microsoft, not typing in a password.

My searches aren’t helping. So far, everything tells me how to set up my app to authenticate it’s users, totally useless.

If SSO is feasible, is there sample code?

Would I be better off simply storing a user’s password, and how would I do that safely?

How can I make the image.png texture be the ground

I have code for a super basic driving game, but i tried setting a grass texture for a field. The texture is downloaded to the same file as the game file but its not working. If anyone has any idea of why this could be, I’d really appreciate it.

// Global variables
let scene, mainCamera, renderer, car;
let keys = {};
let speed = 0;
const maxSpeed = 0.3,
  acceleration = 0.001,
  deceleration = 0.001,
  turnSpeed = 0.03;

// Terrain generation parameters
const chunkSize = 5000;
const chunkSegments = 200;
const terrainRange = 2;
const terrainChunks = {};
const noise = new SimplexNoise();

// Infinite Road parameters
let roadPoints = [];
let roadMesh;
const roadSegmentLength = 500;
const roadTubeRadius = 100;
const roadUpdateDistance = 10000;

// Global texture variable.
let grassTexture;

// Start initialization (animation will start after texture loads)
init();

// Returns terrain height (y) for world coordinates (x,z)
function getTerrainHeight(x, z) {
  return noise.noise2D(x / 500, z / 500) * 50;
}

// Create a terrain chunk at grid (cx, cz)
function createTerrainChunk(cx, cz) {
  const geometry = new THREE.PlaneGeometry(chunkSize, chunkSize, chunkSegments, chunkSegments);
  geometry.rotateX(-Math.PI / 2);

  const positions = geometry.attributes.position;
  for (let i = 0; i < positions.count; i++) {
    let x = positions.getX(i) + cx * chunkSize;
    let z = positions.getZ(i) + cz * chunkSize;
    let h = getTerrainHeight(x, z);
    positions.setY(i, h);
  }
  positions.needsUpdate = true;
  geometry.computeVertexNormals();

  // Create the material using the loaded texture.
  const material = new THREE.MeshLambertMaterial({
    map: grassTexture,
    color: 0xffffff
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.set(cx * chunkSize, 0, cz * chunkSize);
  return mesh;
}

// Update terrain: generate chunks around the car and remove distant ones.
function updateTerrain() {
  const carPos = car.position;
  const carChunkX = Math.floor(carPos.x / chunkSize);
  const carChunkZ = Math.floor(carPos.z / chunkSize);
  const needed = {};
  for (let dx = -terrainRange; dx <= terrainRange; dx++) {
    for (let dz = -terrainRange; dz <= terrainRange; dz++) {
      let cx = carChunkX + dx;
      let cz = carChunkZ + dz;
      needed[`${cx},${cz}`] = true;
      if (!terrainChunks[`${cx},${cz}`]) {
        let chunk = createTerrainChunk(cx, cz);
        terrainChunks[`${cx},${cz}`] = chunk;
        scene.add(chunk);
      }
    }
  }
  for (let key in terrainChunks) {
    if (!needed[key]) {
      scene.remove(terrainChunks[key]);
      delete terrainChunks[key];
    }
  }
}

// Extend the road by adding one more segment.
function extendRoad() {
  let lastPoint = roadPoints[roadPoints.length - 1];
  let newAngle;
  if (roadPoints.length < 2) {
    newAngle = 0;
  } else {
    let prev = roadPoints[roadPoints.length - 2];
    newAngle = Math.atan2(lastPoint.z - prev.z, lastPoint.x - prev.x);
  }
  newAngle += (Math.random() - 0.5) * 0.4;
  const newX = lastPoint.x + Math.cos(newAngle) * roadSegmentLength;
  const newZ = lastPoint.z + Math.sin(newAngle) * roadSegmentLength;
  const newY = getTerrainHeight(newX, newZ) + 2;
  roadPoints.push(new THREE.Vector3(newX, newY, newZ));
  rebuildRoadMesh();
}

// Rebuild the road mesh from current roadPoints.
function rebuildRoadMesh() {
  if (roadMesh) {
    scene.remove(roadMesh);
  }
  const curve = new THREE.CatmullRomCurve3(roadPoints);
  const geometry = new THREE.TubeGeometry(curve, Math.max(100, roadPoints.length * 10), roadTubeRadius, 8, false);
  const material = new THREE.MeshLambertMaterial({
    color: 0x000000
  });
  roadMesh = new THREE.Mesh(geometry, material);
  scene.add(roadMesh);
}

function init() {
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x87ceeb);
  mainCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
  mainCamera.position.set(0, 150, -300);
  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  // Increase overall brightness with multiple lights.
  const ambientLight = new THREE.AmbientLight(0xffffff, 5.0); // Ambient light with increased intensity.
  scene.add(ambientLight);

  const directionalLight = new THREE.DirectionalLight(0xffffff, 5.0); // Bright directional light.
  directionalLight.position.set(100, 500, 100);
  scene.add(directionalLight);

  const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0); // Additional fill light.
  hemisphereLight.position.set(0, 500, 0);
  scene.add(hemisphereLight);

  // Load the local grass texture (image.png).
  grassTexture = new THREE.TextureLoader().load(
    'https://i.sstatic.net/gwCGUO2I.png', // image.png
    function(texture) {
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      texture.repeat.set(8, 8);
      texture.needsUpdate = true;
      // Once the texture loads, update the terrain and start the animation loop.
      updateTerrain();
      animate();
    },
    undefined,
    function(error) {
      console.error('Error loading texture:', error);
      animate();
    }
  );

  const carGeometry = new THREE.BoxGeometry(40, 20, 80);
  const carMaterial = new THREE.MeshStandardMaterial({
    color: 0xff0000
  });
  car = new THREE.Mesh(carGeometry, carMaterial);
  car.position.set(0, getTerrainHeight(0, 0) + 10, 0);
  scene.add(car);

  roadPoints.push(new THREE.Vector3(0, getTerrainHeight(0, 0) + 2, 0));
  roadPoints.push(new THREE.Vector3(roadSegmentLength, getTerrainHeight(roadSegmentLength, 0) + 2, 0));
  rebuildRoadMesh();

  window.addEventListener("keydown", (event) => {
    keys[event.code] = true;
  });
  window.addEventListener("keyup", (event) => {
    keys[event.code] = false;
  });
  window.addEventListener("resize", onWindowResize, false);
}

function onWindowResize() {
  mainCamera.aspect = window.innerWidth / window.innerHeight;
  mainCamera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);
  updateCar();
  updateTerrain();
  updateRoadIfNeeded();
  updateCamera();
  renderer.render(scene, mainCamera);
}

function updateRoadIfNeeded() {
  const lastPoint = roadPoints[roadPoints.length - 1];
  const dist = car.position.distanceTo(lastPoint);
  if (dist < roadUpdateDistance) {
    for (let i = 0; i < 5; i++) {
      extendRoad();
    }
  }
}

function updateCar() {
  if (keys["KeyS"]) {
    speed = Math.min(speed + acceleration, maxSpeed);
  } else if (keys["KeyW"]) {
    speed = Math.max(speed - acceleration, -maxSpeed / 2);
  } else {
    if (speed > 0) speed = Math.max(speed - deceleration, 0);
    else if (speed < 0) speed = Math.min(speed + deceleration, 0);
  }
  if (keys["KeyA"]) {
    car.rotation.y += turnSpeed * (Math.abs(speed) / maxSpeed);
  }
  if (keys["KeyD"]) {
    car.rotation.y -= turnSpeed * (Math.abs(speed) / maxSpeed);
  }
  car.position.x -= Math.sin(car.rotation.y) * speed * 30;
  car.position.z -= Math.cos(car.rotation.y) * speed * 30;
  car.position.y = getTerrainHeight(car.position.x, car.position.z) + 10;
}

function updateCamera() {
  const followDistance = 300;
  const heightOffset = 150;
  mainCamera.position.x = car.position.x - Math.sin(car.rotation.y) * followDistance;
  mainCamera.position.z = car.position.z - Math.cos(car.rotation.y) * followDistance;
  mainCamera.position.y = car.position.y + heightOffset;
  mainCamera.lookAt(car.position);
}
body {
  margin: 0;
  overflow: hidden;
}

canvas {
  display: block;
}
<!-- Include Three.js and SimplexNoise -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>

It shoulda set the field to image.png, but it just shows black for me. This is image.png for me. Image

Loading OpenCascade.js causes a crash in my webapp

I’m trying to use opencascade.js to host a CAD kernel in my react+vite webapp that i’m using google chrome to view. The kernel loads for a short amount of time, then crashes the chrome tab with error code 5. I’m using both a CDN and a local package for opencascade, because vite won’t work with just the local package when trying to initialize opencascade. What is going on? I’m just trying to render a simple shape – am I getting an OOM error? How can I reduce memory footprint? Should I be hosting opencascade.js on a seperate server or something?

I have the following code

initOCC.ts

// Improved initialization with memory configuration
export async function initOcc() {
  // Import the module with a more explicit path
  const openCascadeJsUrl = "https://cdn.jsdelivr.net/npm/[email protected]/dist/opencascade.full.js";
  const openCascadeWasmUrl = "https://cdn.jsdelivr.net/npm/[email protected]/dist/opencascade.full.wasm";
  
  try {
    const openCascadeModule = await import(/* @vite-ignore */ openCascadeJsUrl);
    const openCascade = openCascadeModule.default;
    
    // Initialize with memory configuration
    return await openCascade({
      locateFile: () => openCascadeWasmUrl,
      // Increase memory limits
      // TOTAL_MEMORY: 256 * 1024 * 1024, // 256MB
      ALLOW_MEMORY_GROWTH: true,
    });
  } catch (error) {
    console.error("Failed to initialize OpenCascade:", error);
    throw error;
  }
}

shapetourl:

import { OpenCascadeInstance, TopoDS_Shape } from "opencascade.js";

// Takes a TopoDS_Shape, creates a GLB file from it and returns a ObjectURL
export default function shapeToUrl(
  oc: OpenCascadeInstance,
  shape: TopoDS_Shape,
) {
  // Create a document and add our shape
  const docHandle = new oc.Handle_TDocStd_Document_2(
    new oc.TDocStd_Document(new oc.TCollection_ExtendedString_1()),
  );
  const shapeTool = oc.XCAFDoc_DocumentTool.ShapeTool(docHandle.get().Main())
    .get();
  shapeTool.SetShape(shapeTool.NewShape(), shape);

  // Tell OpenCascade that we want our shape to get meshed
  new oc.BRepMesh_IncrementalMesh_2(shape, 0.1, false, 0.1, false);

  // Export a GLB file (this will also perform the meshing)
  const cafWriter = new oc.RWGltf_CafWriter(
    new oc.TCollection_AsciiString_2("./file.glb"),
    true,
  );
  cafWriter.Perform_2(
    docHandle,
    new oc.TColStd_IndexedDataMapOfStringString_1(),
    new oc.Message_ProgressRange_1(),
  );

  // Read the GLB file from the virtual file system
  const glbFile = oc.FS.readFile("./file.glb", { encoding: "binary" });

  return URL.createObjectURL(
    new Blob([glbFile.buffer], { type: "model/gltf-binary" }),
  );
}

Component:

import React, { useState, useEffect } from 'react';
import { Box, Flex, Text, Progress } from '@chakra-ui/react';
import { initOcc } from '../../../helpers/initOcc';
import shapeToUrl from '../../../helpers/shapeToUrl';
import "@google/model-viewer";

const OpenCascadeViewer = () => {
  const [modelUrl, setModelUrl] = useState();
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function init() {
      try {
        setLoading(true);
        const oc = await initOcc();
        
        // Create a simpler model first as a test
        const sphere = new oc.BRepPrimAPI_MakeSphere_1(1);
        
        // Release memory after operations
        const cleanup = (shape) => {
          if (!shape) return null;
          // Create a deep copy to detach from the operations
          const result = new oc.TopoDS_Shape();
          result.ShallowCopy(shape);
          return result;
        };
        
        // Simplify boolean operations with garbage collection
        const makeCut = (shape, translation, scale) => {
          try {
            const tf = new oc.gp_Trsf_1();
            tf.SetTranslation_1(
              new oc.gp_Vec_4(translation[0], translation[1], translation[2]),
            );
            tf.SetScaleFactor(scale);
            const loc = new oc.TopLoc_Location_2(tf);
            
            // Create the second shape for the boolean operation
            const secondShape = sphere.Shape().Moved(loc, false);
            
            // Perform the cut
            const cut = new oc.BRepAlgoAPI_Cut_3(
              shape,
              secondShape,
              new oc.Message_ProgressRange_1(),
            );
            
            cut.Build(new oc.Message_ProgressRange_1());
            const result = cleanup(cut.Shape());
            
            // Clean up temporary objects
            cut.delete();
            tf.delete();
            loc.delete();
            
            return result;
          } catch (error) {
            console.error("Error in makeCut:", error);
            return shape; // Return original shape on error
          }
        };
        
        // Perform operations sequentially with cleanup
        let result = sphere.Shape();
        
        // Do one operation at a time with memory cleanup between
        result = makeCut(result, [0, 0, 0.7], 1);
        result = makeCut(result, [0, 0, -0.7], 1);
        
        // Skip some complex operations that might cause memory issues
        // result = makeCut(result, [0, 0.25, 1.75], 1.825);
        // result = makeCut(result, [4.8, 0, 0], 5);
        
        // Convert to URL with simplified options
        const url = await shapeToUrl(oc, result, {
          quality: 0.5, // Lower quality for better performance
          deflection: 0.1, // Increase for fewer triangles
        });
        
        setModelUrl(url);
        setLoading(false);
        
        // Cleanup
        sphere.delete();
      } catch (err) {
        console.error("Error initializing OpenCascade:", err);
        setError(err.message || "Failed to initialize 3D viewer");
        setLoading(false);
      }
    }
    
    init();
  }, []);

  return (
    <Box bg="#0a1929" color="white" p={4} borderRadius="lg" minH="70vh">
      <Box 
        borderRadius="md" 
        overflow="hidden" 
        bg="#051525" 
        position="relative"
        h="70vh"
        borderWidth="1px"
        borderColor="#1e3a5f"
      >
        {error ? (
          <Flex 
            width="100%" 
            height="100%" 
            alignItems="center" 
            justifyContent="center"
            direction="column"
          >
            <Text color="red.400" mb={2}>Error: {error}</Text>
            <Text>Try refreshing the page or using a device with more memory</Text>
          </Flex>
        ) : loading ? (
          <Flex 
            width="100%" 
            height="100%" 
            alignItems="center" 
            justifyContent="center"
            direction="column"
          >
            <Text mb={4}>Loading OpenCascade Geometry...</Text>
            <Progress width="80%" size="sm" isIndeterminate colorScheme="blue" />
          </Flex>
        ) : (
          <model-viewer
            id="model-viewer"
            src={modelUrl}
            camera-controls
            auto-rotate={false}
            shadow-intensity="0"
            environment-image="neutral"
            style={{ width: '100%', height: '100%' }}
          />
        )}
      </Box>
    </Box>
  );
};

export default OpenCascadeViewer;

How would you implement a WebTransport over HTTP/2 server using JavaScript/WebAssembly in the browser?

Originally asked over on superuser.

I’m scraping the surface of implementing WebTransport over HTTP/2 using Direct Sockets TCPServerSocket in an Isolated Web App (IWA) in the browser.

So far I have successfully created an HTTP and WebSocket server using TCPServerSocket, see https://github.com/guest271314/direct-sockets-http-ws-server/blob/main/assets/script.js.

The requirement shoukd be possible per one of the IWA maintainers

There’s nothing stopping you from implementing your own TLS client/server library on top of the Direct Sockets API. The API proposed here makes that easier by allowing you to validate certificates using the browser’s certificate store instead of providing your own.

From my reading of the WICG repository HTTPS is explicitly not allowed https://github.com/WICG/direct-sockets/issues/19.

That issue is obsolete. There is nothing stopping you from implementing a WebTransport server other than building an implementation using JavaScript or WebAssembly.

No, verifying certificates isn’t necessary to implement an HTTP/2 server. You could do that today with TCPServerSocket, or implement a QUIC server with UDPSocket.

This presents some challenges.

  1. WebTransport uses the https URI.
  1. Protocol Overview

    WebTransport servers are identified by an HTTPS URI as defined in
    Section 4.2.2 of [HTTP].

The browser will throw an error when http: protocol is used with WebTransport() constructor.

This means I either have to try to intercept the http: request somehow, or implement https: in the browser. Creating self-signed certificates is not the issue.

  1. It’s not clear to me, yet, how to create HTTP/2 frames. I’ve got some guidance from here https://github.com/molnarg/node-http2, which I have bundled to a standalone script, yet the code was created for general HTTP/2 connections, not WebTransport-specific, e.g.,

When an HTTP/2 connection is established, the server sends a
SETTINGS_WEBTRANSPORT_MAX_SESSIONS setting with a value greater than
“0” to indicate that it supports WebTransport over HTTP/2.

How would you implement a WebTransport over HTTP/2 server using JavaScript/WebAssembly in the browser?

dexie.js using variable in LIKE operator

im using this code

var db = new Dexie("likeTest");
db.version(1).stores({
friends: "name,age"
});
db.on('populate', function() {
db.friends.add({name: "Foo Barsson", age: 33});
});
db.open();
db.friends.filter (function (friend) { return /Bar/.test(friend.name); })
.toArray()
.then(function(result) {
    alert ("Found " + result.length + " friends containing the word 'Bar' in its name...");
});

I wanted to know how I can use a variable instead of the search?

Ex.

var VarTest = 'Dani';
db.friends.filter (function (friend) { return /VarTest/.test(friend.name); })

Wrong input’s selectionStart value after pressing arrow key

Here is the scenario to reproduce the problem:

  1. Given input element has test string as a content. Focus given input element by clicking at the end of the input element
  2. After focusing, caret is set at the end of input field (after last symbol t)
  3. At this point – input’s element selectionStart property is equal to 4. Which is right
  4. Then press arrow left key on keyboard. After pressing the key, expected
    input’s selectionStart value is 3. But actually selectionStart value equals to 4 again. Which is wrong.

In result, when input’s element caret at the end, selectionStart equals 4,
but, after pressing left arrow key, caret is set to position 3, but selectionStart equals 4.

In result there is a strange thing, if caret at the end (after symbol tselectionStart is 4,
and if caret one position less (after symbol s) caret is again has selectionStart equal to 4

The question is how to get right selectionStart value?
Is it a bug? Why does it happen?

const element = document.getElementById('test');
element.addEventListener('keydown', (event) => {
    console.log(`Keydown. Selection start: ${element.selectionStart}`);
    console.log(`Keydown. Selection end: ${element.selectionEnd}`);
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>

    <meta name="viewport"
          id="viewport-meta-tag"
          content="width=device-width, initial-scale=1.0">
</head>
<body>
    <input id="test"
           type="text"
           value="test">

</body>
</html>

How to correctly display a route on a Google Map instance with 25+ stops

I’m trying to display a map of my local area with a route of stops at specific locations. Previously, the DirectionsService and DirectionsRenderer API were being used, wherein the origin, all of the waypoints, and the destination were being fed to create a polyline to display on the map, connecting all of the markers. That API is no longer available, so I am trying to create a new solution.

Thus far I have tried using https://routes.googleapis.com/directions/v2:computeRoutes to accomplish this, but it has a hard limit of 25 intermediate stops. I’m not only unsure if that is even the correct method to solve my issue, but any attempt I’ve made to chunk a route into segments to stitch back together have failed.

Is there a separate service I should be using instead?

Is the UMD format interchangeable with ESM for Web Components served over CDNs?

The current Lit element starter projects rollup builds publish the bundles in esm format.

I’d like to switch out the rollup build with Vite, and the Vite Library builds output UMD format.

Can we switch out esm format with UMD format?

Is there anything that esm does that we cannot do with UMD?

For example with the current Lit builds we can use a component published to NPM like this via the UNPKG CDN.

<script
      type="module"
      src="https://unpkg.com/example-component"
></script>

Can we do the same thing with UMD?

Are there any differences as far as regular imports go. For example with esm we can do import { ExampleComponent } from "example-component". Is it the same with UMD?

(nextjs) how can i use /app/page.tsx on below group routes as default page?

pic1

as can see, no.1 is app/page.tsx.
and right below of it, there’s 2 group routes and one of them is parellel & intercept routes.

I thought /app/page.tsx is working on those right below routes, but it isn’t :'<

the best way of it is just copy and paste it to /app/(beforeSignup)/default.tsx? or is there any better way?

without copy /app/page.tsx to /app/(beforeSignup)/default.tsx
pic2

after copy
pic3


all codes

/app/pages.tsx

export default function Page() {
    const router = useRouter();

    const modal = () => router.push('/signup');

    //todo 회원 인증후 라우팅

    return (
        <div className={'flex flex-col'}>
            main
            <Button onClick={modal} className={'bg-blue-300/30 hover:cursor-pointer'}>
                modal bttn
            </Button>
        </div>
    );
}

/app/layout.tsx

export const metadata: Metadata = {
    title: 'Hold House!',
    description: 'manage your ledger',
};

type props = { children: React.ReactNode; modal: ReactNode };
export default function RootLayout({ children, modal }: props) {
    return (
        <html lang="en" suppressHydrationWarning={true}>
            <body className={'bg-sky-50 overflow-y-scroll px-6 py-4 max-w-full pt-16'} cz-shortcut-listen="true">
                {children}
                {modal}
            </body>
        </html>
    );
}

/app/(beforeSignup)/layout.tsx

export type HomeLayoutProps = Readonly<
    PropsWithChildren<{
        modal: ReactNode;
    }>
>;

export default function BeforeSignupLayout({ children, modal }: HomeLayoutProps) {
    return (
        <div>
            {children}
            {modal}
        </div>
    );
}

/app/(beforeSignup)/signup.tsx

export default function SignupPage() {
    return <div>no modal</div>;
}

/app/(beforeSignup)/@modal/(.)signup/page.tsx

export default function SignupModal() {
    return (
        <ModalDefault>
            <div className={''}>modaldal</div>
        </ModalDefault>
    );
}

Custom wPDataTables JS – Color text based on cell value from another table

I have multiple cells in a wPDataTable where the text needs to be red if the value in the cell is less than a similar value in a cell on a different table.

For instance – if the callbackRate in cell F2 of Table 1 is less than the callbackRateGoal in cell F2 of Table 2, then the text of callbackRate should be red. If not, the text should of callbackRate should be green.

I am basing everything on the steps followed in this solution – Custom wpDataTables JS – positive and negative

However, my tables are on tab #3 (KTI Performance) of this page – https://rhdev.teamspg.com/kti-leadership-test/

My steps are to:

  1. Use javascript to change/add a class to the required cell (.numdata.float.column-callbackrate). If the cell should be red, the class is “neg”. If the cell should be green, the class is “pos”.
  2. The tables are wpDataTablesID-21 (table 1 on the tab) and wpDataTablesID-31 (table 2 on the tab).
  3. Right now, I have this javascript placed on the page itself.
  4. Then, on the specific tab, I have the CSS.

Here is the javascript I have right now:

<script type="rocketlazyloadscript" data-rocket-type="text/javascript">
  window.addEventListener('DOMContentLoaded', function() {
    jQuery(window).on('load', function() {
      // Update wpDataTables ID for table 1 and table 2
      var table1 = wpDataTablesID_21; // Update table 1 ID
      var table2 = wpDataTablesID_31; // Update table 2 ID

      table1.addOnDrawCallback(function() {
        // Iterate through each row in table 1
        table1.fnGetData().forEach(function(row, index) {
          // Get the callbackrate from table 1 (column index may vary, adjust accordingly)
          var callbackRate = parseFloat(jQuery('#wpDataTablesID_21 tbody tr').eq(index).find('.numdata.float.column-callbackrate').text());

          // Get the callbackrategoal from table 2 (column index may vary, adjust accordingly)
          var callbackRateGoal = parseFloat(jQuery('#wpDataTablesID_31 tbody tr').eq(index).find('.numdata.float.column-callbackrategoal').text());

          // Compare the values
          if (callbackRate < callbackRateGoal) {
            // Add class "neg" if callbackRate is less than callbackRateGoal
            jQuery('#wpDataTablesID_21 tbody tr').eq(index).find('.numdata.float.column-callbackrate').addClass('neg').removeClass('pos');
          } else {
            // Add class "pos" if callbackRate is greater than or equal to callbackRateGoal
            jQuery('#wpDataTablesID_21 tbody tr').eq(index).find('.numdata.float.column-callbackrate').addClass('pos').removeClass('neg');
          }
        });
      });
    });
  });
</script>

Here is the CSS I am using:

.table.wpDataTable.wpDataTableID-21.pos {
    color: green;
}

table.wpDataTable.wpDataTableID-21.neg {
    color: red;
}

Obviously, this is not working for me. Any help would be greatly appreciated.

Nuxt not recognizing directory in interpolated route

I am attempting to create an image link in Nuxt component

 <NuxtLink
            v-if="player?.image_url"
            :to="`/players/${player.slug}`"
            >
          <img
            class="w-16 h-16 rounded-full object-cover border border-rgba-blackLight"
            :src="player?.image_url"
            :alt="player?.fullName"
          />
        </NuxtLink>

the image displays, but the link is undefined.

no error in console. Intellij complains it cannot resolve directory “`” or “players”

The page I am trying to link to is located at pages/players/[:slug]

How to use dayjs duration plugin in a vue app

I have a plain HTML page (made using .NET MVC, not node or anything like that) that uses Vue for client side rendering (among other things).

<script src="~/lib/vue/dist/vue.global.js"></script>
<script type="module">
    const { createApp } = Vue;

    import * as dayjs from '/lib/dayjs/dayjs.min.js';
    import * as dateFormatting from '/js/DateFormatting.js';

    createApp({
        data() {
            return {
                // data
            }
        },
        methods: {
            ...dateFormatting,
            // other methods
        }
    }).mount('#app');
</script>

I also have a javascript module (DateFormatting.js) with some date/time formatting functions that I need to reuse on several different pages.

export function formatDate(d) {
    if (d) {
        return dayjs(d).format('M/D/YYYY');
    }
    return "";
}

// many other functions follow...

Set up this way, I am able to use the formatDate() function in my Vue template.

But now I need to use the dayjs duration plugin in a few of my functions, and I can’t figure out how to do that. Per the documentation and several searches, I tried:

    import * as dayjs from '/lib/dayjs/dayjs.min.js';
    import * as duration from '/lib/dayjs/plugin/duration.js';
    dayjs.extend(duration);

    import * as dateFormatting from '/js/DateFormatting.js';

When I do this I get the following error in the Chrome console:

Uncaught TypeError: dayjs.extend is not a function

I also tried importing dayjs and the duration plugin directly in to DateFormatting.js as opposed to the Vue app (which I would rather do), and I get the same thing.

How do I use the dayjs duration plugin in my use case?

Is it possible to import the dayjs (and duration plugin) in to my DateFormatting.js file directly instead of having to remember to do it in the Vue app?

Svelte 5 Unsafe State Mutation at Tree Component

I need help with Svelte components. I’ve built a tree that should allow users to check nodes and update related nodes. When a node is checked, its parents and children should react accordingly. However, it’s not working as expected, and I consistently receive state_unsafe_mutation warnings, even though I’m not using $derived.

Here is the Code:

    <script>
import { Button } from '$lib/components/ui/button/index.js';
        import Node from './Node.svelte';
        import { createEventDispatcher } from 'svelte';
        import { Checkbox } from '$lib/components/ui/checkbox/index.js';
        import { Label } from '$lib/components/ui/label/index.js';
        import { slide } from 'svelte/transition';
        import { ChevronDown } from 'lucide-svelte';
        // /** @type {{tree: any}} */
    
        let open = $state(false);
    
        let indeterminate = $state(false);
    
        let { checked = $bindable(false), name = 'Unnamed', tree, updateParent } = $props();
    
        function toggleOpen() {
            open = !open;
        }
    
        function toggleIndeterminate() {
            indeterminate = !indeterminate;
            checked = false;
        }
        function onCheckedChange() {
            if (tree) {
                for (var node of tree) {
                    node.checked = checked;
    
                    if (name != 'root') updateParent();
                }
            }
        }
    
        function updateState() {
            console.log(name);
            if (tree) {
                for (var child of tree) {
                    console.log(child.label + child.checked);
                }
                if (tree.every((child) => child.checked === true)) {
                    checked = true;
                    indeterminate = false;
                } else if (tree.every((child) => child.checked === false && child.indeterminate === false)) {
                    checked = false;
                    indeterminate = false;
                } else {
                    indeterminate = true;
                }
                if (name != 'root') updateParent();
            }
        }
    
        
    </script>
    
    <!-- 
     -->
    <div class="w-full">
        <div class="w-[13rem] pt-2">
            <Button
                class="flex w-full items-center justify-between px-4 py-2 text-sm  {checked
                    ? 'checked'
                    : indeterminate
                        ? 'indeterminate'
                        : 'unchecked'}"
            >
                <div class="flex items-center gap-2">
                    <Checkbox {onCheckedChange} class="checkbox" bind:checked bind:indeterminate></Checkbox>
                    <span onclick={updateState}>{name}</span>
                </div>
    
                <!-- Rechte Seite (z. B. Shortcut, Badge oder anderes Icon) -->
                {#if tree}<div class="text-xs" onclick={toggleOpen}>
                        <ChevronDown
                            class={`transition-transform duration-300 ${open ? 'rotate-0' : '-rotate-90'}`}
                        />
                    </div>{/if}
            </Button>
        </div>
        {#if open}
            <div class="pl-8" transition:slide>
                {#each tree as node}
                    <Node
                        updateParent={updateState}
                        bind:checked={node.checked}
                        name={node.label}
                        tree={node.children}
                    ></Node>
                {/each}
                
            </div>
        {/if}
    </div>