How to successfuly use Essentia.js library in the context of web extension

I’m trying to create a web extension using Web Audio API and Essentia.js.
Basically, the process I’m currently focused on is:

  1. User inputs an audio file from device;
  2. File is converted to the Uint8Array (I can’t send it as an ArrayBuffer using runtime message) and sent to the offscreen document with its metadata;
  3. Offscreen creates two AudioContexts: one for playback and one for analysis, after which it converts the contents to the ArrayBuffer and decodes it to create an AudioBuffer (both contexts decode it separately, basically copying);
  4. Analysis context buffer is converted – its channels’ data (Float32Array) is pushed to an array (using getChannelData), after that it’s sent to the processing Worker opened just before that;
  5. Worker converts the received data to mono and analyses it using the Essentia.js library, specifically RhythmExtractor2013;
  6. Worker sents the results of analysis back.

I’m using Worker for the processing task because the lib uses eval and/or new Function the use of which is forbidden – 'unsafe-eval' directive is strictly prohibited in the manifest.json. But I’ve found that this problem can be avoided using Web Workers.

I’m making the extension for Google Chrome and Manifest V3, so I don’t rule out that it’s just impossible to do on Chrome right now.

Initially, I wanted to make the extension for the Mozilla Firefox, but when I found out, that audio capturing using getDisplayMedia is NOT supported in Firefox I moved to Chrome. Currently, I don’t mind moving back, because the deadlines are pressing very hard and I’m not going to implement this functionality anyway. :)

Manifest:

{
    "manifest_version": 3,
    "default_locale": "en",

    "name": "TimeKeeper", // also – MetroGnome
    "version": "1.0",
    "description": "Provides real-time beat detection and metronome from a playing audio.",

    "action": {
        "default_popup": "popup/popup.html#popup?=true"
        //  cool hack! to check if the script was opened by an extension popup,
        //  set "default_popup": "popup.html#popup", and then check with location.hash == "popup"
        //  (if string has a word "popup" in it – it will determine whether it is a popup
        //      (no one will open this page in such a way anyway))
    },
    
    "background": {
        "service_worker": "background/background.js", // Google Chrome
        // "scripts": ["background/background.js"],   // Mozilla Firefox
        "type": "module"
    },

    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["unsorted/content.js"]
    }],

    "content_security_policy": {
        "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' 'wasm-unsafe-eval'"
    },

    "permissions": [
        "tabs",
        "activeTab",
        "offscreen",
        "tabCapture",
        "storage"
    ],

    "host_permissions": [
        "<all_urls>"
    ],

    "web_accessible_resources": [
        {
            "resources": [
                "lib/essentia/*",
                "file-mode/*"   
            ],
            "matches": ["<all_urls>"]
        }
    ]
}

Offscreen document:

if (typeof browser === "undefined") 
    var browser = chrome;

// ...

/*
    There are 2 audio contexts: playback and analysis.
    
    Playback context is responsible for:
    - playing the audio;
    - generating click-track;
    - volume control.

    Analysis context is responsible for:
    - analysing different parts of the loaded song;
    - giving the necessary data for the playback context.
*/
/** All parts of the playback audio context (nodes and clicker) */
let playback = {
    /** @type {AudioContext} */
    context: null,
    
    /** @type {AudioBuffer} */
    buffer: null,
    
    /** @type {AudioBufferSourceNode} */
    audioSource: null,

    /** @type {IntervalClicker} */
    clickSource: null,

    /** @type {GainNode} */
    audioGain: null,

    /** @type {GainNode} */
    clickGain: null
};

/** All parts of the analysis audio context (nodes) */
let analysis = {
    /** @type {AudioContext} */
    context: null,

    /** @type {AudioBuffer} */
    buffer: null,

    /** @type {AudioBufferSourceNode} */
    source: null,

    /** @type {Worker} */
    detector: null,

    result: null
};

// ...

async function audioContextsSetup(file) {
    if (playback.context || analysis.context)
        throw new Error("Previous context wasn't closed");

    audioContextsClose();

    playback.context = new AudioContext();  
    analysis.context = new AudioContext();

    try {
        // Because they're different context's, the buffer have to be decoded twice...
        playback.buffer = await playback.context.decodeAudioData(file.buffer.slice(0));
        analysis.buffer = await analysis.context.decodeAudioData(file.buffer.slice(0));
        file.meta.duration = playback.buffer.duration;
    }
    catch (error) {
        return Result.failure({
            description: "Failed decoding audio: " + error
        })
    }

    playback.clickSource = new IntervalClicker(playback.context);
    playback.audioGain = new GainNode(playback.context, { gain: state.songVolume});
    playback.clickGain = new GainNode(playback.context, { gain: state.clickVolume});

    analysis.detector = new Worker("processor.js", { type: "module" });
    analysis.detector.onmessage = (e) => {
        const msg = e.data;
        switch (msg.type) {
            case "message-error":
                console.error("Message error occured: " + msg.description);
                break;

            case "analysis-log":
                console.log("Analysis:", msg.description);
                break;
            case "analysis-result":
                analysis.result = msg.result;
                playbackStartClickerFrom(playback.context.currentTime);
                break;
            case "analysis-error":
                console.error("Analysis error occured: " + msg.description);
                break;
        }
    };
    analysis.detector.onerror = (e) => {
        console.error("Worker error occured:", e);
    }

    if (analysis.buffer.numberOfChannels > 2) {
        return Result.failure({
            description: "Audio data has more than 2 channels"
        });
    }

    let channels = [];
    for (let c = 0; c < analysis.buffer.numberOfChannels; c++) {
        channels.push(analysis.buffer.getChannelData(c).buffer);
    }

    analysis.detector.postMessage({
        type: "analysis-start",
        audio: {
            channels
        }
    }, [...channels]);

    playback.audioGain.connect(playback.context.destination);
    playback.clickSource.connect(playback.clickGain);
    playback.clickGain.connect(playback.context.destination);

    state.currentFile = file.meta;
    state.songTimeLast = 0.;

    console.log("Current file is:", state.currentFile);

    return Result.success({ description: "Audio contexts setup successfully" });
}

Worker:

import Essentia from "../lib/essentia/essentia.js-core.es.js";
import { EssentiaWASM } from "../lib/essentia/essentia-wasm.web.js";

const essentia = new Essentia(EssentiaWASM);

let audio;
let result;

const messageHandlers = {
    "analysis-start": (message) => {
        if (message?.audio === undefined)
            postMessage({
                type: "analysis-fail",
                description: "Can't analyse audio since no audio passed"
            });

        audio = message.audio;

        postMessage({
            type: "analysis-log",
            description: "Audio acquired, starting analysis.."
        });

        try { analyse(); }
        catch(error) {
            postMessage({
                type: "analysis-error",
                description: error
            });
        }

        postMessage({
            type: "analysis-result",
            result: {
                bpm: result.bpm,
                beats: result.beats
            }
        });
    }
};

onmessage = (e) => {
    const message = e.data;

    console.log(message);

    const handle = messageHandlers[message.type];
    if (handle === undefined) {
        postMessage({
            type: "message-error",
            description: "Unknown message type"
        });
    }
    else handle(message);
};

function analyse() {
    if (audio?.audioBuffer) analyseAudioBuffer();
    else if (audio?.channels) analyseChannels();
    else postMessage({
        type: "analysis-error",
        description: "Unknown structure of received audio data"
    });
}

function analyseAudioBuffer() {
    let signal;

    signal = essentia.audioBufferToMonoSignal(audio.audioBuffer);

    result = essentia.RhythmExtractor2013(signal);
}

function analyseChannels() {
    let signal;

    switch (audio.channels.length) {
        case 1:
            signal = essentia.arrayToVector(audio.channels[0]);
            break;
        case 2:
            signal = essentia.MonoMixer(audio.channels[0], audio.channels[1]);
            break;

        default:
            throw new Error("Analysis is supported only for 1 or 2 (mixed to mono) channel audio");
    }
    
    result = essentia.RhythmExtractor2013(signal);
}

I’ve now tried to test just the loading and found out that only essentia.js-core.es.*.js doesn’t fire a Worker error.
The WASM backends on the other hand ALL fire errors but ONLY the essentia-wasm.es.js fires an informative event. All other don’t have any description.

essentia-wasm.es.js error: Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*".

Please help!

How to change a background color of a button after pressing it using JavaScript?

A button inside a form.

<form asp-area="Sets" asp-controller="Home" asp-action="Favorite" asp-route-id="@Model.CurrentWord.Id" method="post" class="col-2 text-white">
    <button id="BtnFav" type="submit" class="btn sound-fav-btn" title="Favorite"><i class="bi bi-star-fill"></i></button>
</form>

After I submit the form, I want this button’s background to change its color.

I tried to put inside a button’s style Razor syntax using ternary (e.g. background-color: @(if statement ? “yellow” : “transparent”)), but it works ONLY if I leave the page and then come back even though submitting the form means rerendering the entire page, but for some reason the background stays the same.

Also tried JavaScript. The same result. Works only if the page is left and then opened again.

<script type="text/javascript">
    const BtnFav = document.getElementById('BtnFav');
    if ("@{@Model.CurrentWord.IsFavorite}" == "True") {;
        BtnFav.style.backgroundColor = "yellow";
    }
    else {
        BtnFav.style.backgroundColor = "transparent";
    }
</script>

I need it to work right after I press the button. How can this be done?

How to link nginx and php-fpm with docker compose?

I’m learning docker compose and trying to run the project provided from some Docker course.
There is the project to link nginx:latest and php:8.2-fpm containers to display message from index.php. But I cannot reproduce the results. It’s supposed to display “Hello from PHP!” message, when I go to localhost, but I’ve got this message instead:


    Welcome to nginx!
    If you see this page, the nginx web server is successfully installed and working.
    Further configuration is required.
    
    For online documentation and support please refer to nginx.org.
    Commercial support is available at nginx.com.
    
    Thank you for using nginx.

As I understand nginx container is ok, and the problem is with linking nginx and php.

Explain how to solve this issue, please.

Project structure:

    project/
    ├── docker-compose.yml
    ├── nginx/
    │   ├── default.conf
    │   ├── html/
    │   └── Dockerfile
    ├── php/
    │   ├── index.php
    │   └── Dockerfile

Here is docker-compose.yml:


    version: '3.8'
    services:
      nginx:
        build: ./nginx
        image: nginx:latest
        container_name: nginx
        ports:
          - "80:80"
        volumes:
          - ./nginx/html:/var/www/html
        depends_on:
          - php
        networks:
          - app_network
    
      php:
        build: ./php
        image: php:8.2-fpm
        container_name: php
        volumes:
          - ./php:/var/www/html
        networks:
          - app_network
    
    networks:
      app_network:
        driver: bridge

nginx/default.conf:


    server {
        listen 80;
        server_name localhost;
    
        root /var/www/html;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        location ~ .php$ {
            fastcgi_pass php:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }

nginx/Dockerfile:


    FROM nginx:latest
    COPY default.conf /etc/nginx/conf.d/
    COPY ./html /usr/share/nginx/html

Docker Desktop logs:

  • php:

    NOTICE: fpm is running, pid 1
    NOTICE: ready to handle connections

  • nginx:

    /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
    /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
    10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
    10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
    /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
    /docker-entrypoint.sh: Configuration complete; ready for start up
    2025/05/25 08:03:14 [notice] 1#1: using the "epoll" event method
    2025/05/25 08:03:14 [notice] 1#1: nginx/1.27.5
    2025/05/25 08:03:14 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 
    2025/05/25 08:03:14 [notice] 1#1: OS: Linux 5.15.167.4-microsoft-standard-WSL2
    2025/05/25 08:03:14 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
    2025/05/25 08:03:14 [notice] 1#1: start worker processes
    2025/05/25 08:03:14 [notice] 1#1: start worker process 29
    2025/05/25 08:03:14 [notice] 1#1: start worker process 30
    2025/05/25 08:03:14 [notice] 1#1: start worker process 31
    2025/05/25 08:03:14 [notice] 1#1: start worker process 32
    2025/05/25 08:03:14 [notice] 1#1: start worker process 33
    2025/05/25 08:03:14 [notice] 1#1: start worker process 34
    2025/05/25 08:03:14 [notice] 1#1: start worker process 35
    2025/05/25 08:03:14 [notice] 1#1: start worker process 36
    2025/05/25 08:03:14 [notice] 1#1: start worker process 37

Sorry about such amount of text.

Mariadb time data corrupted after server crash

I have a problem when the server is down and when it is finished processing, the old data in the database is time-shifted.

column information: created_at - timestamp

i use Laravel 11 + mariadb, php8.4,

in Laravel i have set Timezone of our country

i am very sure about the time because before that i still check database daily and keep the record data with the time of the timezone i set

For example, the record is at 12 noon but it is recorded as 18:00 pm.

i tried to set timezone in mariadb and reformat with laravel for timezone +7 but the time is completely wrong

===
update: i double checked my old data before down is not affected, but the new records after server up are wrong

Server side timer to execute PHP code upon expiration? [closed]

I’m looking for a server side timer that would execute a PHP file at expiration. The timer should be controlled by another PHP file to start, stop and reset the timer.

The PHP module EvTimer would work great in this situation, but it is not available on the Bluehost shared servers I’m using.
Cron jobs? Hmmm, could those be activated when the command is received, canceled when successful?
Other options?

JavaScript Async/Await knowledge

Q. What is the correct order of output for this JavaScript async/await and setTimeout example?

I’m trying to understand how JavaScript handles async/await together with setTimeout() in the context of the event loop, macrotasks, and microtasks.

I wrote the following code and I’m confused about what the correct output order should be:

async function example() {

 console.log("Before await");
 
 
  await new Promise((res,rej)=>{
   setTimeout(()=>{
     res();
     console.log("Hi there !");
     
   },1000)
 })

 await new Promise(resolve =>{
 setTimeout(resolve, 1000)}
 );
 
  console.log("After 2 awaits");
 


}

console.log("Start");


setTimeout(() => {
 console.log("Start again1");
}, 1000);


setTimeout(() => {
 console.log("Start again22");
}, 1000);


setTimeout(() => {
 console.log("Start again32");
}, 1000);

example();


setTimeout(() => {
 console.log("Start again2");
}, 1000);


console.log("End");

I expected the logs to show up in a specific order based on the setTimeout and async/await behavior. But I’m confused about the timing of “Hi there!”, “After 2 awaits”, and the setTimeout outputs.
Can someone please explain the correct output order and what happens behind the scenes with the event loop and task queues?

Inconsistent Object/Mesh Rotations in ThreeJS

I am encountering rotation issues in THREEJS where my object (From blender, gltf.scene) totations are extremely unpredictable and inconsistent. I want my object to spin like a ballerina when the mouse moves (depending on the x coordinates of the mouse, the object will spin: anticlockwise when the mouse moves to the right and clockwise when the mouse moves to the left).

There are two points in my code where I rotated my object 1) initially when I imported my model and 2) in the tick function (so it moves like a ballerina accordingly to the position of the mouse).

This is the main part of my issue: Sometimes when I load my page it does exactly what I want. However, sometimes when I reload the page the object might not even rotate, and I can reload the page and my object will be fine again. I searched online for similar issues already and I believe it is due to Gimbal Lock. I am unsure how to fix my code so my rotations are not inconsistent. I also have a imageMesh object created in THREEJS that will spin in the same manner as my object imported from blender and this object never has the rotation issue present in gltf.scene object.

Code From Initially Loading The Object

// Load GLTF Model
    gltfLoader.load(
        '/Trial8.glb',
        (gltf) => {
            modelRef.current = gltf.scene;
            gltf.scene.traverse((child) => {
                if (child.isMesh) {
                    child.geometry.center(); // Centers the geometry relative to its local origin
                    child.material = bakedMaterial;
                    child.castShadow = true;
                    console.log('Model material:', child.material.constructor.name);
                }
            });
            gltf.scene.position.set(1.5, -7.54, 3);

            // Set initial rotation using Quaternion to avoid Euler issues
            const initialQuaternion = new THREE.Quaternion();
            initialQuaternion.setFromEuler(new THREE.Euler(0, -Math.PI / 2, Math.PI / 2, 'XYZ'));
            gltf.scene.quaternion.copy(initialQuaternion);
            gltf.scene.scale.set(0.5, 0.5, 0.5);
            scene.add(gltf.scene);

            // Add AxesHelper to visualize origin
            const axesHelper = new THREE.AxesHelper(1); // 1 unit long, scaled with model (0.5)
            gltf.scene.add(axesHelper);
            

            const originMarker = new THREE.Mesh(
                new THREE.SphereGeometry(0.1),
                new THREE.MeshBasicMaterial({ color: 0xff0000 })
            );
            originMarker.position.set(0, 0, 0);
            modelRef.current.add(originMarker);
        },
        (progress) => {
            console.log(`Loading: ${(progress.loaded / progress.total * 100).toFixed(2)}%`);
        },
        (error) => {
            console.error('Error loading GLTF:', error);
        }
    );

Code in Tick Function

// Animation loop
    const clock = new THREE.Clock();
    const tick = () => {
        const elapsedTime = clock.getElapsedTime();

        if (cameraRef.current) {
            const targetX = mouse.x * moveRange;
            const targetZ = -mouse.y;
            cameraRef.current.position.x = THREE.MathUtils.lerp(
                cameraRef.current.position.x,
                targetX,
                dampingFactor
            );
            cameraRef.current.position.z = THREE.MathUtils.lerp(
                cameraRef.current.position.z,
                targetZ,
                dampingFactor
            );
            cameraRef.current.lookAt(
                cameraRef.current.position.x,
                0,
                cameraRef.current.position.z
            );
        }

        // Add rotation for models based on mouse X
        const targetRotationZ = mouse.x * Math.PI; // Adjust rotation range as needed
        if (modelRef.current) {
            // Define target rotation based on mouse.x
            const targetRotationZ = mouse.x * Math.PI; // Same rotation range as before
            const targetQuaternion = new THREE.Quaternion();
            // Combine initial rotation with mouse-driven Y-axis rotation
            targetQuaternion.setFromEuler(
                new THREE.Euler(0, -Math.PI / 2 + targetRotationZ, Math.PI / 2, 'XYZ')
            );
            // Interpolate current quaternion to target quaternion
            modelRef.current.quaternion.slerp(targetQuaternion, dampingFactor);
        }
        imageMesh.rotation.z = THREE.MathUtils.lerp(
            imageMesh.rotation.z,
            targetRotationZ,
            dampingFactor
        );

        // Update directional light's x-position based on mouse.x
        const lightTargetX = initialLightX + mouse.x * lightMoveRange;
        directionalLight.position.x = THREE.MathUtils.lerp(
            directionalLight.position.x,
            lightTargetX,
            dampingFactor
        );

        renderer.render(scene, camera);
        requestAnimationFrame(tick);
    };
    tick();

What is the difference between ‘const dotenv = require(‘dotenv’);’ and ‘require(‘dotenv’).config();’ in Node.js?

I’m learning how to use the dotenv package in my Node.js project to manage environment variables. I’ve seen two common ways to include it in the code:

const dotenv = require('dotenv');

and

require('dotenv').config();

What exactly is the difference between these two statements? Are they both importing the module? Do they both load the environment variables from the .env file? When should I use one over the other?

And should I use dotenv.load(); in both after exporting the module? Or what is the usage of this method?

Also, does either of these export anything, or are they just importing the module? I want to understand the best practice to use dotenv in my application.

What AI tool can actually write code for me in May 2025 [closed]

TL;DR: What AI tool(s) can actually write code (i.e. not just code complete or assist) for an experienced, but not professional (i.e. hobbyist) developer working on an online game in late May 2025, who has an existing codebase but has never used AI?

I’m posting this question on Sunday, 25th May 2025. The date is important because the industry is moving so fast that if I link to any research I’ve done I think it will be out of date by the time I review any answers!

For some context, I’m an indie dev who has written the codebase for a multi-player online real time strategy game (MMORTS) myself. I’m self-taught, and not a “professional” dev. I have in the past used freelance developers to help me, some sourced from this very site, other times using freelancer.com, and one great dev in India who I use to do the time-consuming, fiddly stuff I just don’t have time to do. In these scenarios, I architect the solution and tell them what I need done. I’ve almost never handed over the reigns to someone and said “develop this feature” or “make this script run faster” or “fix this bug” without me knowing the optimal solution to begin with.

The game has been in development for a few years, and has a small player base. I would still call it “early alpha” because I’m not confident enough to put it out there until I’m satisfied with the content, replayability and stability of the game.

I use the LAMP stack and have no intention of changing this – it’s what I know and my game runs well using it. It’s hosted on a VPS with a small amount of CPU, RAM etc. I use raw HTML5/CSS3/JS on the front end, with PHP 8.3 and MariaDB 10.11.13 on the back end.

My codebase is about 100k LoC, and there are less than 10 front-end files with ~60 PHP scripts. I use very few libraries included as files (a CSS animation library, marker clusterer library and two geometry libraries, turf.js on the front-end and GeoPHP on the back end) and only one real-time API (google maps JavaScript version).

Now here’s my problem: I’ve never used any AI at all. However, I want to use it to work through my backlog and just develop faster. I’d like to start with minor features and bug fixing. If it works well, I’d move on to major features and code optimisation.

I am happy to pay a small amount per month on a subscription basis that I can cancel if it doesn’t meet my needs, but I would prefer to stick to one tool if possible.

As an additional question: I am happy to supply the tool with my entire codebase (*.html, *.css, *.js, *.php files), but how would any tool read my database? Do I just export the schema as an *.sql file? Or the actual data as well (which is massive)?

method getElementsByClassName issue

Facing a problem in moving the card
im use this function to scroll the card item by two button next and prev
it work with me but when i duplicate card item under the first one it does not work with the second card list ,can any one help me
how can i use this function with many card list
here is my full code

let left_btn=document.getElementsByClassName('bi-chevron-left')[0];
let right_btn=document.getElementsByClassName('bi-chevron-right')[0];
let cards=document.getElementsByClassName('cards')[0];




left_btn.addEventListener('click',()=>{

    cards.scrollLeft -=140;
})

right_btn.addEventListener('click',()=>{

    cards.scrollLeft +=140;
})
section{


    position: relative;
    width: 100%;
    height: auto;
    padding: 0px 30px;
    bottom: 10px;
    color: white;
    margin-bottom: 40px;
    
    
}

section .movie-list-title{

    
    margin-top: 10px;
}

section .cards{


   position: relative;
   
   width: 100%;
   height: 350px;
   /* border: 1px solid white; */
   
   display: flex;
   align-items: center;
   overflow-x: auto;
   scroll-behavior:smooth ;

   

}

section .cards .card{


    position: relative;
    min-width: 200px;
    height: 280px;
    /* border: 1px solid white; */
    border-radius: 10px;
    margin-right: 30px;
    background: transparent;
    transition: .3s linear ;
     

 }

section .bi-chevron-left , .bi-chevron-right{

    position: absolute;
    top: 50%;
    left: 3%;
    width: 25px;
    height: 25px;
    background: gray;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: 12px;
    cursor: pointer;
    transition: .3s linear;
    z-index: 999999999;
    opacity: 0;
    
}


section .bi-chevron-right{

   left: unset;
   right: 3%;
}

section:hover .bi-chevron-left{

    opacity: 1;
 }

 section:hover .bi-chevron-right{

    opacity: 1;
 }

section .cards::-webkit-scrollbar{


    display: none;
 }



 section .cards .card:hover .poster{

    transform: scale(1.1);
  
    

   }



 section .cards .card .poster{


  width: 100%;
  height: 100%;
  border-radius: 12px;
  position: relative;
  transition: all .5s ease-in-out;
  /* margin-left: 20px; */

 }
<?php
session_start();
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link
        href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&family=Sen:wght@400;700;800&display=swap"
        rel="stylesheet">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
       
        
     
    
    <link rel="stylesheet" href="styleee.css">

   
    <title> onc</title>
</head>
<body>


<?php

include 'signUp.php';
include 'login.php';

?>

   <div class="navbar">
        <div class="navbar-container">
             <div class="logo-container"><h1 class="logo">ONC</h1></div>   
             <div class="menu-container">
                <ul class="menu-list">

                   
                    <li class="menu-list-item">Home</li>
                    <li class="menu-list-item">Movies</li>
                    <li class="menu-list-item">series</li>
                    <li class="menu-list-item">popular</li>
                    <li class="menu-list-item">trends</li>
                    
                    
                </ul>
             </div> 
             
           
             <div class="profile-container">
                <!-- <img class="profile-picture" src="img/profile.jpg" alt=""> -->
                 
                <div class="profile-text-container">

                  <a class="btnLogin-popup"> Login</a>
                  
                </div>

                <div class="toggle">

                    <i class="fa-solid fa-moon toggle-icon"></i>
                    <i class="fa-solid fa-sun toggle-icon"></i>
                     <div class="toggle-ball"></div>
                </div>
             </div>  
        </div>
   </div>

   


   
   


   <div class="container">    <!--start div container -->

     <div class="content-container">  <!--start div content-container --> 

        <div class="featurd-content">
                
        </div>
 

         <div class="movie-list-container">  <!--start div movie-list-container1 --> 

           <section>

         <h1> Watch Today</h1>
         <i class="bi bi-chevron-left"></i>
         <i class="bi bi-chevron-right"></i>
         
         <div class="cards">

           <?php
            $servername = "localhost";
            $username = "root";
            $password = "";
            $dbname = "login_register";

            // Create connection
            $conn = new mysqli($servername, $username, $password, $dbname);
            // Check connection
            if ($conn->connect_error) {
              die("Connection failed: " . $conn->connect_error);
            }
            $sql = 'SELECT * FROM movies ';
            $result = $conn->query($sql);

            
            if ($result->num_rows > 0) {
              // output data of each row
              while ($row = $result->fetch_assoc()) {

                
                
           ?>
           
            <a href="#" class="card">
            <img src="../image/<?php echo $row['movie_image']; ?>" alt="" class="poster">
            </a>

            <?php }
            } ?>
        
         </div>
         
         </section>

         </div>  <!--end div movie-list-container1 --> 





         <div class="movie-list-container">  <!--start div movie-list-container2 --> 

         <section>

            <h1> Movies Today</h1>
           <i class="bi bi-chevron-left"></i>
         <i class="bi bi-chevron-right"></i>
         

         
         
         <div class="cards">

           <?php
            $servername = "localhost";
            $username = "root";
            $password = "";
            $dbname = "login_register";

            // Create connection
            $conn = new mysqli($servername, $username, $password, $dbname);
            // Check connection
            if ($conn->connect_error) {
              die("Connection failed: " . $conn->connect_error);
            }
            $sql = 'SELECT * FROM movies ';
            $result = $conn->query($sql);

            
            if ($result->num_rows > 0) {
              // output data of each row
              while ($row = $result->fetch_assoc()) {

                
                
           ?>
           

            <a href="#" class="card">
            <img src="../image/<?php echo $row['movie_image']; ?>" alt="" class="poster">
            </a>

            <?php }
            } ?>
        
         </div>


            </section>


            
            

            </div>  <!--end div movie-list-container2 --> 



            

            

         </div>     <!--end div content-container -->         

         </div>  <!--end div container -->

How to deallocate WASM heap memory that is exported to Javascript

I was trying to find a way to export vector or other heap alocated data to Javascript. I tried this:

use wasm_bindgen::prelude::*;
use std::alloc::{Layout, dealloc};

#[wasm_bindgen]
pub struct ArrayBuffer {
    ptr: *const u8,
    len: usize,
}

#[wasm_bindgen]
impl ArrayBuffer {
    #[wasm_bindgen(getter)]
    pub fn ptr(&self) -> *const u8 {
        self.ptr
    }

    #[wasm_bindgen(getter)]
    pub fn len(&self) -> usize {
        self.len
    }
}

#[wasm_bindgen]
pub fn get_array() -> ArrayBuffer {
    let data = vec![1, 2, 3, 4, 5];
    let ptr = data.as_ptr();
    let len = data.len();

    std::mem::forget(data);

    ArrayBuffer { ptr, len }
}

#[wasm_bindgen]
pub fn free_array_raw(ptr: *mut u8, len: usize) {
    unsafe {
        let mut v = Vec::from_raw_parts(ptr, len, len);
        v.fill(0); 
        drop(v);  
    }
}

The I compile with wasm-pack targetting nodejs

wasm-pack build --target nodejs

Here is my Javascript code I used to test it

const wasm = require('./pkg/wasm.js');

async function run() {
  const arrayBuffer = wasm.get_array();
  const ptr = arrayBuffer.ptr;
  const len = arrayBuffer.len;

  const memory = wasm.__wasm.memory;

  const uint8Array = new Uint8Array(memory.buffer, ptr, len);

  console.log(uint8Array);

  arrayBuffer.free();
  wasm.free_array_raw(ptr, len);
  
  console.log(uint8Array);
}

run().catch(console.error);

The memory does not get deallocated, I still can access the data

[root@localhost wasm]# node ./main.js
Uint8Array(5) [ 1, 2, 3, 4, 5 ]
Uint8Array(5) [ 1, 2, 3, 4, 5 ]

How is the correct way to deallocate the heap memory?

Parsing text in html document and replacing symbols with open and close html tags

I am trying to parse through an HTML document text and replace certain symbols (### and **) with HTML tags. I’m not sure how to implement open and close tags like <ul><li></li></ul> and <b></b>.

For example:

  • ### should be a bullet.
  • **Requirement Analysis and Planning** should be <b>Requirement Analysis and Planning</b>

Currently using jQuery. Please advise!

  $(document).ready(function() {

    //var balle = '<i class="fas fa-square"></i>';
    var balle = '<ul><li></li></ul>'; //BULLET
    var bold = '<b></b>'; //BOLD TEXT

    $(".chat-box").children().each(function() {
      $(this).html($(this).html().replace(/###/g, balle));
    });

  }); //END JQUERY 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="chat-box">
  <div>
    <pre><code>Implementing and managing an orchestration tool involves several key steps and considerations to ensure that it effectively automates and coordinates various tasks and workflows within an IT environment. Here’s a detailed description of the experience:<br>
<br>
### 1. **Requirement Analysis and Planning**<br>
   - **Understanding Needs:** Begin by understanding the specific needs of your organization. Identify the tasks and workflows that need to be automated.<br>
   - **Tool Selection:** Choose an orchestration tool that fits your requirements. Popular options include Ansible, Puppet, Chef, Kubernetes, and Terraform.<br>
   - **Resource Allocation:** Allocate the necessary resources, including personnel, budget, and infrastructure.<br>
<br>
### 2. **Setup and Configuration**<br>
   - **Installation:** Install the chosen orchestration tool on the appropriate servers or environments.<br>
   - **Configuration:** Configure the tool according to your organization's policies and requirements. This may include setting up authentication, permissions, and network configurations.<br>
   - **Integration:** Integrate the orchestration tool with existing systems, such as CI/CD pipelines, monitoring tools, and cloud services.<br>
<br>
</code></pre>
  </div>
</div>