My link button is not shown selected (lacking border)

I have a link button as shown in the code below:

<div class="col-2">
      <a type="button" routerLink="auto-generate-schedules/generate" class="btn btn-primary mb-2">Generate Schedules
      </a>
            </div>

… which when I click on it, it does not display any border indicating it is selected. But the few bootstrap buttons below it, display that border. What do I need to do to have border around my link button.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>

    <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
    <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
    
<div class="col-2">
  <a type="button" routerLink="auto-generate-schedules/generate" class="btn btn-primary mb-2">Generate Schedules
  </a>
        </div>    
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
<button type="button" class="btn btn-outline-success">Success</button>
<button type="button" class="btn btn-outline-danger">Danger</button>
<button type="button" class="btn btn-outline-warning">Warning</button>
<button type="button" class="btn btn-outline-info">Info</button>
<button type="button" class="btn btn-outline-light">Light</button>
<button type="button" class="btn btn-outline-dark">Dark</button>

package react horizontal scrolling menu scrollnext and scrollprev doesn’t work

i’m using package react horizontal scrolling, but arrowback and arrowforward for scrollnext and scrollprev doesn’t work. i’m confused because it doesnt show any error on the console. i’m using “react-horizontal-scrolling-menu”: “^5.0.1”.

here’s my code below v

import { Box } from "@mui/material";
import React from "react";
import BodyPart from "./BodyPart";
import { ScrollMenu, VisibilityContext } from "react-horizontal-scrolling-menu";
import "react-horizontal-scrolling-menu/dist/styles.css";
import { ArrowBack, ArrowForward } from "@mui/icons-material";
import "../../src/App.css";
import ExerciseCard from "./ExerciseCard";

const HorizontalScrollBar = ({ data, bodyPart, setBodyPart, isBodyParts }) => {
  function LeftArrow() {
    const { scrollPrev } = React.useContext(VisibilityContext);

    return (
      <ArrowBack onClick={() => scrollPrev()} cursor="pointer" sx={{ color: "#ff2625", position: "absolute", top: "30%", left: "0" }}>
        Left
      </ArrowBack>
    );
  }

  function RightArrow() {
    const { scrollNext } = React.useContext(VisibilityContext);

    return (
      <ArrowForward onClick={() => scrollNext()} cursor="pointer" sx={{ color: "#ff2625", position: "absolute", top: "30%", right: "0" }}>
        Right
      </ArrowForward>
    );
  }
  return (
    <ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
      {data.map((item) => (
        <Box key={item.id || item} m={"0 40px"}>
          {isBodyParts ? <BodyPart item={item} bodyPart={bodyPart} setBodyPart={setBodyPart} /> : <ExerciseCard exercise={item} />}
        </Box>
      ))}
    </ScrollMenu>
  );
};

export default HorizontalScrollBar;

Google Drive not retrieving folders

I have this code:

const { google } = require('googleapis');
const fs = require('fs');

// Create an OAuth2 client with the given credentials
const auth = new google.auth.GoogleAuth({
  keyFile: './credentials.json',
  scopes: ['https://www.googleapis.com/auth/drive']
});

// Create a new instance of the Drive API
const drive = google.drive({ version: 'v3', auth });

async function listFolders() {
  try {
    const response = await drive.files.list({
      q: "mimeType='application/vnd.google-apps.folder' and trashed=false",
      fields: 'files(id, name)',
      orderBy: 'name'
    });

    const folders = response.data.files;
    if (folders.length) {
      console.log('Folders:');
      folders.forEach(folder => {
        console.log(`${folder.name} (${folder.id})`);
      });
    } else {
      console.log('No folders found.');
    }
  } catch (error) {
    console.error('Error listing folders:', error.message);
  }
}

listFolders();

which obviously is going to fetch the folders that exists in “My Drive” but even if the folders existed, the logs says otherwise: “No folders found.”

Any thoughts?

I use service account for this one but still i can’t make it work and yes the credentials are there in my .json file

How to querry on multiple tables with join and condition

I haven’t sleep for almost 2 days just trying to come out for query syntax that’s works.

Let me explain.
I have 4 tables with details like the following :

Table 1 – “Voting Place Table” :

id (Auto Increment) place_number area zone_id
1 1 Area 1 3
2 2 Area 2 4

Table 2 – “Zone Table” :

id (Auto Increment) zone_name area_coverage (Varchar)
3 Zone 1 Area 1, Area 2
4 Zone 2 Area 3, Area 4

Table 3 – “Candidates Table” :

id (Auto Increment) serial_number name
1 1 Candidate 1
2 2 Candidate 2

Table 4 – “Result Table” :

id (Auto Increment) voting_place_id candidate_id zone_id total_vote
1 1 1 3 120
2 2 2 4 240

I’m trying to call the result like this :

Area Candidate 1 Candidate 2
Area 1 (Zone 1, Zone 2) (Total Vote of Candidate 1 from Area 1) (Total Vote of Candidate 2 from Area 1)
Area 2 (Zone 3, Zone 4) (Total Vote of Candidate 1 from Area 2) (Total Vote of Candidate 2 from Area 2)

The main framework i’m using is a Codeigniter 3 based on PHP 7.
I’m using ajax to call the data and put it into the result table but didn’t know how to.

I have tried calling the candidate list first, foreach them and based on the data i’ve tried to call the voting result and order it based on Zone Name. Here’s my latest querry on the SQL :

SELECT SUM(r.vote) as total
FROM tbl_result AS r
LEFT JOIN tbl_voting_place AS v ON r.voting_place_id = v.id
LEFT JOIN tbl_candidates AS c ON r.candidate_id = c.id
WHERE v.area = 'Area 1'
GROUP BY c.serial_number
ORDER BY (c.serial_number+0) ASC

It does give the result, but if there’s no vote in the area, it doesn’t return anything and if (let’s say) candidate 2 is the only candidate that gets vote in the zone, how do i foreach them inside the table?

Page reload in IOS devices using javascript in

The screens in my IOS device doesn’t reload after clicking the back button. It works using PC and android devices. Is there specific reload code for IOS device?

here is my code

```
<script>
  document.addEventListener("DOMContentLoaded", function() {
    var goBackButton = document.getElementById("goBackButton");

    if (goBackButton) {
      goBackButton.addEventListener("click", function() {
        window.location.reload();
        window.history.back();
     });

      goBackButton.addEventListener("touchstart", function() {
        window.location.href = window.location.href
        window.history.back();
      });
    }
  });
</script>
```

I was expecting it to reload the screen so it updates the newly fetched data after clicking the back button.

Implement sqlite3.wasm Web Assembly in my Older AngularJS Solution

I need to implement a persistent Sqlite3 database in my older AngularJS solution. So far, I’ve managed to implement a transient Sqlite3 database, but have not successfully implemented the persistent database.

I have been successful at implementing a transient database by using this page: A Database in your Browser in sqlite3 Steps

I have followed the instructions at this page: SQLite Wasm in the browser backed by the Origin Private File System and get hung up with the import statement. I just get a Javascript console error that indicates it no longer recognizes the page. In lieu of the import statement, I have tried the following that I found at Loading and running WebAssembly code

    WebAssembly.instantiateStreaming(fetch("/js/lib/sqlite3/sqlite3.wasm"), someKindOfObject).then(
        (results) => {
            alert("Here we are");
            // Do something with the results!
        }
    );

However, I have no idea what I should use for someKindOfObject in the above snippet.

How do I correctly import/instantiate sqlite3.wasm in my AngularJS application so I can access a persistent database?

Passing Methods vs Generic Objects vs Event Specific Objects

I often reach a crossroad in my code when it comes to passing methods vs generic objects vs specialised objects. Let me explain.

I am using the mediator pattern. I have DAO’s which have generic methods based on a specific entity of the database it’s targeting.If a method is targeting that specific entity I am putting it in that class. Sometimes the entity targeted is a table, other times it’s a column within a table depending on whether this DAO class starts to be complex or not and needs breaking down. Then I have service type classes where it receives the DAO as the dependancy. This is an additional layer but it prevents me from passing my DAO classes directly into a mediator. This is so that I can unit test each class outside of the main meditator and call methods from each service class inside the mediator. This also allows me to potentially pick service objects which mediate together and pass that mediator into the main mediator if my dependancies start to grow.

However I often struggle when deciding upon the next step. Do I

  1. pass the whole service object to the mediator giving it access to things it never intends to use. Ive read this goes against the Least Privilidge principle. Like this

    const turn = new ServerTurnMediator(
     new DiceService(DiceDAO),
     new PlayerMoneyService(PlayerMoneyDAO)
    )
    
  2. Pass only methods from the specific service class to the mediator using and bind the methods I am passing in to the instance of the service object like this :

     const playerMoneyService = new PlayerMoneyService(PlayerMoneyDAO);
     const methodFromPlayerMoneyService = playerMoneyService.addMoneyToPlayer.bind(playerMoneyService);
    
     const turn = new ServerTurnMediator(
      new DiceService(DiceDAO),
      methodFromPlayerMoneyService
     )
    

here I pass methodFromPlayerMoneyService into the mediator class that requires it. If the mediator then needs 3 other methods from this service objects shall I repeat this binding process for each method?When is this too much ?

  1. Start to create more event specific service objects that take in the DAO but rename the service objects around what they are trying to achieve and then pass the service object in full into the mediator. The methods are cohesive and are all referenced and possibly used in specific situations within the mediator class and there are no derelict methods within the class for the given mediator its passed into. If I did this I could use either inheritance or composition to extend each event specific class so that I prevent repeating methods in different event specific classes.

    const turn = new ServerTurnMediator(
     new DiceService(DiceDAO),
     new PlayerMoneyIncreaserService(PlayerMoneyDAO)
    )
    

This also feels like I am adhering to SRP more, but suddenly I will need a lot more classes specific to each event that occurs rather a single service object.

  1. I could do the same as 3 but also create the same inheritance hierarchy or composition within my DAO classes so that the correct service object receives the DAO that has access to the functionality the service object is trying to achieve.

I am using interfaces where appropriate and my service classes often receive different DAO implementations with the same named methods or abstract methods.

Is there a right or wrong answer here or any specific moments that scream out for refactoring ? If so then why ?

Passing a Blazor object reference to a Telerik Chat control

I’ve read Microsoft’s documentation for calling JavaScript from Blazor. I’ve been on the Telerik site and searched through their documentation and forums. I’ve done many search engine queries. I’ve searched SO and found similar issues that don’t quite answer my problem.

Specifically, I want JavaScript code that is a property of an object passed to kendo.Class.extend to be able to call a Blazor component instance method.

What I’m not trying to do is call a static method – I can get that to work and it isn’t what I want. I don’t want to call an arbitrary method in a script tag because I have a specific scenario for using the Telerik Chat control with specific syntax.

Again, if you refer me to another question or show me a link, please ensure it’s specific to my situation.

The context of this approach is that Telerik doesn’t have a Blazor chat control. Therefore, by Telerik’s recommendation, I needed to communicate between the Blazor component and the Kendo jQuery Chat widget.

Here’s the code that’s similar to Telerik examples of how to write the jQuery portion:

// MyChatComponent.razor.js

var chat = $("#chat").kendoChat({
    post: function (args) {
        agent.postMessage(args);
    }
}).data("kendoChat");

window.ChatAgent = kendo.Class.extend({
    init: function (chat, dotnet) {
        this.chat = chat;
        this.dotnet = dotnet;

        console.log('dotneti', dotnet);
    },
    postMessage: function (args) {
        var chat = this.chat;

        this.dotnet.invokeMethodAsync('MyChatComponent', 'AskAsync', args.text)
            .then(data => {
                chat.renderMessage({
                    type: "text",
                    text: data,
                    timestamp: new Date()
                }, {
                    name: "Generellem"
                });
            });
    }
});

var agent = new ChatAgent(chat);

agent.chat.renderMessage({
    type: "text",
    text: "Hi, How can I help today?",
    timestamp: new Date()
}, {
    name: "Generellem"
});

The modification that I made was to add the dotnet parameter to the init function in the kendo.Class.extend object. Further down, in the postMessage function, I use that dotnet instance variable to call invokeMethodAsync. This doesn’t work – the console.log in the init function prints out that dotnet is undefined.

One of the problems is that I don’t know where to put dotnet so that it will have the proper instance reference. That brings me to the component, which is the instance I want the code above to receive:

// MyChatComponent.razor

@page "/chat"
@rendermode InteractiveServer

@inject IJSRuntime JS

<h3>Chat</h3>

<div id="chat"></div>

@code {
    CancellationTokenSource cancelTokenSource = new();
    DotNetObjectReference<Chat>? objRef;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);

            await JS.InvokeAsync<IJSObjectReference>(
            "import", "./Components/Pages/Chat.razor.js", objRef);
        }
    }

    [JSInvokable]
    public async Task<string> AskAsync(string message)
    {
        return await Task.FromResult(message);
    }
}

There are a couple of items here that are interesting. The first is in OnAfterRenderAsync where I call DotNetObjectReference.Create(this) to get an instance of the current object, as objRef. I want to pass objRef to the JavaScript code so that I can call the AskAsync instance method.

Inside of AskAsync, I added objRef as the 3rd argument to InvokeAsync. I don’t know if that’s the right thing to do, but I tried it.

To summarize, I want to pass objRef from the C# code to the JavaScript code so that the JavaScript code has a reference to the component instance when it calls AskAsync.

how to handle error handling with iFrame?

In the iFrame documentation on mdn here it states that the error event wont be fired off. Was wondering, how would one go about handling errors that might occur during the rendering of an iFrame, if something like onError isnt supported by some browsers anymore?

Android Data Storage and run corresponding javascript

everyone. I am a new beginner to Android. I design an app mainly driven by javascript by following this youtube video.

My asset folder

I put my css, html and js and image folder together in the asset folder and everything runs fine. Now I want to go one step further that I want my app can:

1.) check if there is any file in the app that had stored data. If no, create a new file and input default data (simply string and number). If yes, check the data in the file and run javascript according to the data stored. For example, if “1” is stored, run frunjavascript “first.js” and javascript “second.js” if “2” is stored.

2.) store some simple data(not a not, simply string and number) when I use my app automatically WITHOUT clickng any button. That means I don’t want to click a “save” button when storing data. The app stores data itself when I use it.

3.) replace all the data with default data (that means return back to initial state) when I click a button designed in HTML.

Can I perform it purely by Javascript? Or I shall cooperate javascript with Android?

I searched in google and what I found is simply driven Android. My problem is as my app is mainly javascript, what shall I do when dealing with data (It is impossible to rewrite the whole app mainly driven by Android for me as the whole javascript is very complicated)? If possible, I wish the 3 steps I listed above can be done by purely javascript.

Is there a performant method of checking if a word exists in a massive dictionary? [closed]

I am creating a game using Node.js where I need to validate that a string the user inputs is a real English word. I have thought of three ways to do this:

  1. Use a Dictionary API, like this.
  2. Store every valid word in a massive text file, and check that the string exists in that.
  3. Store every valid word in a database table, and check that the string exists in that.

I am wondering which of these would be the most performant. I want control over the word list if possible, so the first option seems less appealing to me.

Currently, my plan is to use Node’s fs module to read this file in as a Buffer, then convert the user’s input string to a Buffer and add two 0a bytes to the front and back (because that file is new line separated, and I need to match a line exactly, not just an occurrence of the string anywhere in the file, which is what differentiates this question from the other ‘find string in file’ questions I’ve seen here), then check if the file’s Buffer contains the string’s modified Buffer. However, I’m worried that reading the entire file in every time will be slow and reading it in once and storing the Buffer in a constant or something would be memory intensive. Are these even valid concerns? If not, how would I implement that in Node.js, seeing as fs.readFileSync('./data/words_dict.txt', 'utf-8);` returns a string, not a Buffer.

Problem with two differents solution of fetch (async/await and then)

First of all, sorry for my bad english and my messy code (I’m still learning), and thanks beforehand of your help.
It’s my first post, and I don’t know very well how to organize the content, or in which text box each content goes, so if the order it’s wrong, I’ll be happy to edit it in the proper way

I’m trying to manage this petition:

function login(event) {
    event.preventDefault();

    const newUser = {
        email: emailInput.value,
        password: passwordInput.value,
    };

    const config = {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(newUser),
    };

    fetch(LOGIN_URL, config)
        .then((response) => {
            if (!response.ok) {
                throw new Error(
                    "Network not working OK. Status: " + response.status
                );
            } else {
                return response.json();
            }
        })
        .then((data) => {
            if (data.error) {
                alert(data.error);
            } else {
                fetchAllUsersV2();
            }
        })
        .catch((error) => console.log(error.message));
},

to the API ReqRes, just to practice; but while the asyncronous function works perfectly (call the API, take the data, and fill an unordered list in my index.html):

async function fetchAllUsers() {
    let response = await fetch(USERS_URL);
    let data = await response.json();
    let users = [];
    for (let page = 1; page <= data.total_pages; page++) {
        response = await fetch(`${USERS_URL}?page=${page}`);
        let newData = await response.json();
        users = users.concat(newData.data); //users = [...users, ...newData.data]
    }
    usersList.innerHTML = "";
    console.log(users);
    users.forEach((user) => {
        const createLi = document.createElement("li");
        createLi.textContent = `${user.last_name}, ${user.first_name}. Correo: ${user.email}`;
        usersList.appendChild(createLi);
    });
}

but with the recursive function I can´t manage the response, it calls an error “Error fetching or parsing data: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data”:

let users = [];
function fetchAllUsersV2(USERS_URL) {
    fetch(USERS_URL)
        .then((response) => response.json())
        .then((newData) => {
            users = users.concat(newData.data);

            if (newData.page < newData.total_pages) {
                fetchAllUsersV2(`${USERS_URL}?page=${newData.page + 1}`);
            } else {
                usersList.innerHTML = "";
                users.forEach(
                    (user) => (usersList.innerHTML += `<li>${user.email}</li>`)
                );
            }
        })
        .catch((error) => {
            console.error("Error fetching or parsing data:", error);
        });
},

I don’t know form where the parsing of the JSON is failing, or how make it work.
This is just to practice, in a real enviroment if I have to choose knowing the difficulty of both, I will take the async function.
How I said, it’s just to know how to do it the both ways.

//Primera parte

const LOGIN_URL = "https://reqres.in/api/login";
const USERS_URL = "https://reqres.in/api/users";

const emailInput = document.querySelectorAll("input")[0];
const passwordInput = document.querySelectorAll("input")[1];

const loginButton = document.querySelector("#loginButton");
loginButton.addEventListener("click", login);
const usersList = document.querySelector("#usersList");

//Te vale cualquier email de la API siempre que este en la BD, cambia del token el ultimo numero (ID)

function login(event) {
    event.preventDefault(); //OJO

    const newUser = {
        email: emailInput.value,
        password: passwordInput.value,
    };

    const config = {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(newUser),
    };

    fetch(LOGIN_URL, config)
        .then((response) => {
            if (!response.ok) {
                throw new Error(
                    "Network not working OK. Status: " + response.status
                );
            } else {
                return response.json();
            }
        })
        .then((data) => {
            if (data.error) {
                alert(data.error);
            } else {
                fetchAllUsersV2();
            }
        })
        .catch((error) => console.log(error.message));
}

//mas sencillo con async/await
//Util independientemente de las paginas

async function fetchAllUsers() {
    //primera peticion para saber nº de paginas
    let response = await fetch(USERS_URL);
    let data = await response.json();

    //con await se puede hacer paso a paso, al contrario que .then.then
    //con el for, una peticion por cada pagina que tenga
    let users = [];
    for (let page = 1; page <= data.total_pages; page++) {
        response = await fetch(`${USERS_URL}?page=${page}`);
        let newData = await response.json();
        users = users.concat(newData.data); //users = [...users, ...newData.data]
    }
    usersList.innerHTML = "";
    console.log(users);
    users.forEach((user) => {
        const createLi = document.createElement("li");
        createLi.textContent = `${user.last_name}, ${user.first_name}. Correo: ${user.email}`;
        usersList.appendChild(createLi);
    });
}

//alternativa para recuperar paginas de api usando .then() => RECURSION
let users = [];
function fetchAllUsersV2(USERS_URL) {
    fetch(USERS_URL)
        .then((response) => response.json())
        .then((newData) => {
            console.log(newData);
            users = users.concat(newData.data);

            if (newData.page < newData.total_pages) {
                fetchAllUsersV2(`${USERS_URL}?page=${newData.page + 1}`);
            } else {
                usersList.innerHTML = "";
                users.forEach(
                    (user) => (usersList.innerHTML += `<li>${user.email}</li>`)
                );
            }
        })
        .catch((error) => {
            console.error("Error fetching or parsing data:", error);
        });
}

Here it’s the full main.js.
The expected behaviour:
This is how works with the async function, and I want to make the same with the .then() function.

create a logic is message from admin

import { Message } from ‘whatsapp-web.js’;

const messageListener = async (message: Message) => {

let chat = await message.getChat();

// Chat from group
if (chat.isGroup) {


} else {
    console.log("Heello");
}

};

export default messageListener;

please help me to create logic is sender message is admin on // Chat from group

create a logic is message from admin

Jetpack compose webview calculation of measured height

val calculatedHeight = contentHeight * scale - viewHeight

contentHeight: document.body.scrollHeight

scale: displayMetrics.density

viewHeight: webview.measuredHeight

I am using the above formula to calculate my scrollable height of my webview. Is there a way to use injected javascript into my webview to calculate webview.measuredHeight instead?

Check background image is visible on the page using JavsScript

Please note that I don’t want only to check whether the image loaded in the browser. I want to check whether the image is visible on the page.

Problem Background:
I’m using the chrome-php library to take screenshots of HTML using a headless Chrome browser by first loading HTML in Chrome and then taking screenshot. The code was working fine until I started using HD images in the HTML then that screenshot service is still working but sometimes it takes the screenshot however background image of the overlay element is not visible in the screenshot.

The most important piece here to consider is the JS piece that has the logic to check image is loaded + the overlay element is visible but still, I don’t have a code to verify image is actually visible. I’m also using a loop to continuously check whether the global js variables went true or not.

        $page = $browser->createPage();
        $page->setViewport($width, $height)->await(); // wait for the operation to complete
        $page->setHtml($html, 5000);

        //we are going to check if the image is being loaded
        // Execute JavaScript code to set up the variable isBackgroundImageLoaded and check overlay visibility
        $jsInitialization = <<<JS
        // Set boolean variables to track whether the background image and overlay div are loaded and visible
        let isBackgroundImageLoaded = false;
        let isOverlayVisible = false;

        // Function to check if the background image is loaded
        function checkBackgroundImageLoaded() {
            // Select the overlay div
            const overlay = document.getElementById('overlay');

            // Create an image element to load the background image
            const img = new Image();
            img.src = getComputedStyle(overlay).backgroundImage.replace(/url(['"]?(.*?)['"]?)/i, "$1");

            // Check if the image has loaded
            img.onload = function() {
                // Set the boolean variable to true when the image has loaded
                isBackgroundImageLoaded = true;

                // Check if the overlay div is visible within the viewport and has non-zero dimensions
                const rect = overlay.getBoundingClientRect();
                const isVisible = (
                    rect.width > 0 &&
                    rect.height > 0 &&
                    rect.top >= 0 &&
                    rect.left >= 0 &&
                    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
                );
                
                // Set the boolean variable to true if both conditions are met
                isOverlayVisible = isVisible;
            };
        }

        // Call the function to check if the background image is loaded and overlay div is visible
        checkBackgroundImageLoaded();
        JS;


        // Execute the JavaScript code in the client's browser
        $page->evaluate($jsInitialization);

        // Polling loop to wait for the background image to be loaded
        $timeout = 9000; // Timeout in milliseconds
        $startTime = microtime(true);

        while (microtime(true) - $startTime < $timeout) {
            // Evaluate the JavaScript variable in the browser
            $evaluation = $page->evaluate("isBackgroundImageLoaded;");
            $isImageLoaded = $evaluation->getReturnValue();

            $evaluationOverlay = $page->evaluate("isOverlayVisible;");
            $isOverlayVisible = $evaluationOverlay->getReturnValue();

            // If the background image is loaded, break out of the loop
            if ($isImageLoaded && $isOverlayVisible) {
                break;
            }

            // Sleep for one second before polling again
            usleep(1000000); // 1000 milliseconds
        }

        // Take a screenshot
        $screenshot = $page->screenshot();