How to declare in a *.d.ts file an Iterable of two different types? [duplicate]

This is the javascript function I’m unsuccessfully trying to make vscode show autocomplete suggestions for the returned object:

const profile = (form, validation) =>
  Object.defineProperties(
    { form, validation },
    {
      0: { value: form },
      1: { value: validation },
      length: { value: 2 },
      [Symbol.iterator]: { value: Array.prototype[Symbol.iterator] },
      [Symbol.toStringTag]: { value: 'ValidationProfile' },
    },
  );

This is the *d.ts file for the returned object’s type I was experimenting with. It’s definitely wrong.:

import { Validation } from './validation';

export type ValidationProfile = typeof ValidationProfileAPI;

// !!! the returned object is not an array, just tried to make it work somehow
const ValidationProfileAPI: [HTMLFormElement, Validation];

declare namespace ValidationProfileAPI {
    let form: HTMLFormElement;
    let validation: Validation;
    interface iterator implements Iterable<HTMLFormElement|Validation> {}
}

Usage:

// shows available property propA for a and propB for b
const {a, b} = profile({propA: 'a'}, {propB: 'b'}); 

// doesn't show available properties for a and for b
const [a, b] = profile({propA: 'a'}, {propB: 'b'}); 

I managed to find a similar problem here but I can’t figure out how to adapt it for my case.
I will be grateful for any suggestions.

How to drag and drop in material UI collapsible table in react

I am using matirial UI collapsible table. And for adding the drag-and-Drop feature, I am using react-beautiful-dnd library. Its working properly when all the rows are in collapsed state, but the issue arrises when one of the rows are in expanded mode. please refer the below image (this is working case as all the rows are collapsed)

Dragon drop image when all the rows are in collapsed state

Below is the image of expanded row, which is not being directed and drop
enter image description here
Below is the image when drag and drop is done of a row, which is in expanded state (both the parts are not getting dragged together)
enter image description here

I want that both tables get dragged together because, currently in an expanded state, only one row is getting dragged.
It seems like there is some issue in the code. Please look the structure of my code below.

<Table stickyHeader>
    <TableHead>
        <StyledTableRow sx={{ zIndex: 20 }}>
            {/* Headers: Not providing this code because it's unrelated and will make the question longer */}
        </StyledTableRow>
    </TableHead>
    <DragDropContext
        onDragEnd={handleOnDragEnd}
        onDragStart={handleOnDragStart}
    >
        <Droppable droppableId="job-table-body">
            {(providedTable) => (
                <TableBody
                    ref={providedTable.innerRef}
                    {...providedTable.droppableProps}
                >
                    {props.rows.map((row, idx) => {
                        let backgroundColor = draggingElementIdx === idx ? DRAGGING_ELEMENT_COLOR : (idx % 2 === 0 ? STRIP_COLOR : '');
                        const rowSelected = openedChildIndexes.has(idx);
                        return (
                            <Draggable key={row.id} draggableId={row.id} index={idx}>
                                {(provided) => (
                                    //********************* Please read the below, comment */
                                    // React.Fragment If I use div here My issue will get resolved, 
                                    // as I will move following props to the div(ref={provided.innerRef} & {...provided.draggableProps})
                                    // but the problem is after using div The styling of whole table gets distorted
                                    <React.Fragment key={row.id + idx} >
                                        <StyledTableRow
                                            sx={{
                                                backgroundColor: backgroundColor,
                                                cursor: 'pointer'
                                            }}
                                            onClick={() => rowSelected ? closeChildIndex(idx) : openChildIndex(idx, true)}
                                            ref={provided.innerRef}
                                            {...provided.draggableProps}
                                        >
                                            <StyledTableCell
                                                {...provided.dragHandleProps}
                                                sx={{
                                                    ...rowSelected ? { borderTop: BORDER_STYLE, zIndex: 10 } : {}
                                                }}>
                                                <span className='mr-2'>{'::'}</span>
                                            </StyledTableCell>
                                            {props.columns.map((column, idx) => {
                                                const value = row[column.id];
                                                return (
                                                    <StyledTableCell
                                                        key={row.id + column.id + idx}
                                                        align={column.align}
                                                        sx={{
                                                            ...rowSelected ? { borderTop: BORDER_STYLE, zIndex: 10 } : {}
                                                        }}
                                                    >
                                                        {column.format
                                                            ? column.format(value, row, rowSelected)
                                                            : value}
                                                    </StyledTableCell>
                                                );
                                            })}
                                        </StyledTableRow>
                                        <StyledTableRow sx={{
                                            backgroundColor: backgroundColor,
                                        }}>
                                            <StyledTableCell sx={{
                                                paddingBottom: 0,
                                                paddingTop: 0,
                                                ...rowSelected ? { borderBottom: BORDER_STYLE, zIndex: 10 } : {}
                                            }}></StyledTableCell>
                                            <StyledTableCell sx={{
                                                paddingBottom: 0,
                                                paddingTop: 0,
                                                ...rowSelected ? { borderBottom: BORDER_STYLE, zIndex: 10 } : {}
                                            }} colSpan={props.columns.length}>
                                                <Collapse in={rowSelected} timeout="auto" unmountOnExit>
                                                    {row.additionalInfoComponent}
                                                </Collapse>
                                            </StyledTableCell>
                                        </StyledTableRow>
                                    </React.Fragment>
                                )}
                            </Draggable>
                        );
                    })}
                    {providedTable.placeholder}
                </TableBody>
            )}
        </Droppable>
    </DragDropContext>
</Table>

StyledTableRow and StyledTableColumn are nothing but MUI table and column component, I’ve just added some style to it.
Please inform me if any more information is needed.

How to run an onEdit command only if one of several checkboxes is selected

I have a Google Sheets onEdit function powered by a checkbox in Column A of a spreadsheet tab (I’ll call this the RUN checkbox). When the user selects the RUN checkbox, the function runs, queries the user to confirm their choice, then copies information to another tab.

Goal: I now want to make running the onEdit script dependent on the user having selected another checkbox in one of four columns (I’ll call this the WHY checkbox). I don’t care which box they select — the boxes represent reason codes, and we just need to track which reason code applies to the record they flagged. However, I want the record copy operation to stop if they don’t provide a reason code by checking one of the WHY checkboxes.

If they do have a WHY checkbox selected, then I want the onEdit function to run, but only if the RUN checkbox and WHY checkbox are in the same row.

Then, I want to copy the reason code, along with the other data that the onEdit function is already capturing. I would be fine with copying all of the WHY checkboxes for that record, showing which box was selected. I would also be fine copying just the column header for the checkbox they selected. For example, rather than copying the four WHY checkboxes (three of which would be blank), it just copies the text “Test Makeup” from the WHY checkbox column they picked. Finally, I want to erase all selected from the checkboxes on that tab, so that the system is reset for their next lookup.

The desired page layout:
Screenshot of request page

One problem I foresee is that the copying part of the script will now have to copy three columns, skip Column E (Already Requested by), and then copy the WHY checkboxes or WHY checkbox column header.

The page code as-is:

    function checkbox1(e) {
    if (e.range.columnStart != 1) return;
    if (e.value != 'TRUE') return;
    var sheet = SpreadsheetApp.getActive();
    if (e.range.getSheet().getName() != "Student search page") {return}
    const value = e.value
    const range = e.range
    const setsheet = range.getSheet();
    const refrow = range.getRow();
    const refcolumn = range.getColumn();
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const checkValue = setsheet.getRange(refrow, 5).getValue(); // Column E value
    var row_index = e.range.rowStart;
    var row = sheet.getRange('B' + row_index + ':D' + row_index).getDisplayValues().flat();
    if (row[1] == '') return; 
    var result = SpreadsheetApp.getUi()
    .alert("Do you wish to request this student?", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
    if (result != SpreadsheetApp.getUi().Button.OK) {
    sheet.toast("Request canceled.");
    sheet.getActiveCell().setValue(false);
    sheet.getRange('B3').activate();
    return;}
    sheet.toast("Request initiated.");
    sheet.getActiveCell().setValue(false);
    sheet.getRange('B3').clearContent();
    sheet.getSheetByName('Dumbledore requests page').appendRow(row);
    sheet.getSheetByName('Student search page').setActiveCell('B3');}

In terms of what I want, the only part I can pretty much figure out is the code for the error message if they click the RUN checkbox without selecting a WHY checkbox:

    var result = SpreadsheetApp.getUi()
    .alert("You must provide a reason before requesting this student.", SpreadsheetApp.getUi().ButtonSet.OK);
  if (result = SpreadsheetApp.getUi().Button.OK) {
    sheet.toast("No reason provided. Request denied. 
    sheet.getActiveCell().setValue(false);
    sheet.getRange('B3').activate();
    return;};

I’ve searched for similar problems, but couldn’t find a like case. Any help would be immensely appreciated! Thank you.

expo push notifications not working on real devices

I’m using ‘native-notify’ in my React native expo app and notifications work on my virtual device but not on my real device. expoPushTokens can be used on the virtual device but not on the real device. Notification permission etc. everything is completed. There is no problem when you start the project by writing “npx expo start”, but when you create an apk with “eas build -p android –profile preview” it does not work. I even wanted to use notify because I had the same problem in FCM V1, but there is the same problem here too. I have seen FCM causing an issue with Firebase, maybe it’s the same issue, I don’t know

I tried the development versions but it doesn’t work. Notifications work only when you open Expo Go by writing “npx expo start”.

Also when i send a message from real device to emulator it sent but from emulator to real device is not.

import registerNNPushToken from 'native-notify';
import { registerIndieID } from 'native-notify';

const Login = ({navigation}) => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [isEyeEnabled, setIsEyeEnabled] = useState(false);
    const [loading, setLoading] = useState(false);
    const [hack, setHack] = useState(0);
    const [rememberMe, setRememberMe] = useState(false);
    const [isCredentialsLoaded, setIsCredentialsLoaded] = useState(false);

    registerNNPushToken(xxxxx, 'xxxxxxxxxxxxxxxxxx');
.
.
.

const handleLogin = async () => {
        setLoading(true);
        try {
          const userCredentials = await auth.signInWithEmailAndPassword(email, password);
          const user = userCredentials.user;
          if (user.emailVerified) {
              if (rememberMe) {
                await SecureStore.setItemAsync('email', email);
                await SecureStore.setItemAsync('password', password);
                await SecureStore.setItemAsync('rememberMe', "true");
              } else {
                await SecureStore.deleteItemAsync('email');
                await SecureStore.deleteItemAsync('password');
                await SecureStore.deleteItemAsync('rememberMe');
              }
              registerIndieID(user.uid, xxxx, 'xxxxxxxxxxxxxxxx');
              navigation.navigate('Dashboard');
              setEmail("");
              setPassword("");
          } else {
            alert('Please check email');
            await user.sendEmailVerification();
          }
        } catch (error) {
          alert(error.message);
        } finally {
          setLoading(false);
        }
      };

channel.createWebhook causes ‘no such file or directory’ error

I am creating a bot in Discord.JS v14, I am trying to make a simple modmail bot, but when attempting to create the webhook, I get a very strange error which doesn’t look like it has any connection with creating a webhook, but when I remove the function, it works completely fine.

I have tried every combination of this function, as it is the only way to create webhooks

const webhook = await channel.createWebhook({
    name: `${message.author.name} (${message.author.id})`,
    avatar: `${message.author.avatar}`,
});

And the error I always recieve is:

Error: ENOENT: no such file or directory, stat 'C:UsersrileyDocumentsGitHubadvanced-modmailc43c7fdd43c8315ddf7a816a1f25a85c'
Emitted 'error' event on Client instance at:
    at emitUnhandledRejectionOrErr (node:events:397:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:84:21) {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'stat',
  path: 'C:\Users\riley\Documents\GitHub\advanced-modmail\c43c7fdd43c8315ddf7a816a1f25a85c'
}

the ending random gibberish changes each time

How does the time complexity of different sorting algorithms compare? [closed]

I’m trying to understand the time complexity of various sorting algorithms like Bubble Sort, Merge Sort, Quick Sort, and Insertion Sort. Could someone please explain how these algorithms differ in terms of their best, average, and worst-case time complexities? Additionally, under what scenarios would one algorithm be preferred over another?

Thank you !

i need a simple explanation

I need to make cards shake in game (typescript / pixi / gsap)

So im making SolitaireGame and now i wanted to add functionality, that if card doesnt have any place to be moved into it should shake.
for now i have this shakeCard.ts file:

import { Sprite } from 'pixi.js';
import gsap from 'gsap';

export function shakeCard(card: Sprite) {
    const shakeIntensity = 1; // Intensywność drgań
    const shakeTime = 0.5; // Całkowity czas trwania drgań

    const initialX = card.x;
    const initialY = card.y;

    console.log(`Initial position: x=${initialX}, y=${initialY}`);

    // Animacja drgań w poziomie
    gsap.to(card, {
        x: initialX + shakeIntensity,
        duration: shakeTime / 2,
        ease: 'power1.inOut',
        repeat: 5, // Powtarzaj nieskończoność
        yoyo: true, // Wróć do początkowej pozycji po każdym cyklu
    });
}

Which i use in SolitaireGame class (i do import { shakeCard } from ‘./shakeCard’; and then in dropCard() method i call it like this (in a place when move isnt avaliable):

this.moveGroup.forEach((card) => {
                shakeCard(card.container);
            });

The problem is that it isnt shaking- it looks like it shakes once and then it makes bigger move to left and back to starting position.
Iv tried different approaches but then it didnt even came back to its original place.
Could anyone help me out? Thanks !

Also here is my dropCard() method:

dropCard() {
        //@TODO create events file
        const diff = new Point(
            Math.abs(this.lastPointerPosition.x - this.firstPointerPosition.x),
            Math.abs(this.lastPointerPosition.y - this.firstPointerPosition.y)
        );
        const isClick = Math.pow(diff.x, 2) + Math.pow(diff.y, 2) < 850;
        removeEventListener('pointermove', this.dragCard);
        removeEventListener('pointerup', this.dropCard);
        const firstCard = this.moveGroup[0];

        const place = isClick ? this.getClickPlace(this.moveGroup) : this.getDropPlace();
        let dropOnCard = null as null | Card;
        let validMove = false;
        let revealedCard = false;
        if (place) {
            switch (place.place) {
                case CardPlace.TABLEAU:
                    dropOnCard = this.getColumnLastCard(place.dropColumnIndex);
                    if (!dropOnCard && firstCard.value === KING_VALUE) {
                        validMove = !(
                            firstCard.place.cardPlace === CardPlace.TABLEAU &&
                            firstCard.place.value === place.dropColumnIndex
                        );
                    } else if (dropOnCard && dropOnCard.canDropInColumn(firstCard)) validMove = true;
                    if (
                        firstCard.place.cardPlace === CardPlace.TABLEAU &&
                        firstCard.place.value === place.dropColumnIndex
                    )
                        validMove = false;
                    else if (validMove) {
                        // Track if card is revealed
                        const originalColumn = this.tableau[firstCard.place.value];
                        if (
                            originalColumn &&
                            originalColumn.length > 0 &&
                            !originalColumn[originalColumn.length - 1].visible
                        ) {
                            revealedCard = true;
                        }
                    }
                    break;
                case CardPlace.FOUNDATION:
                    dropOnCard = this.getAceLastCard(place.dropColumnIndex);
                    if (!dropOnCard && firstCard.value === ACES_VALUE) {
                        validMove = !(
                            firstCard.place.cardPlace === CardPlace.FOUNDATION &&
                            firstCard.place.value === place.dropColumnIndex
                        );
                    } else if (dropOnCard && dropOnCard.canDropOnAce(firstCard)) {
                        validMove = true;
                    }

                    // Track if we reveal a card when moving to foundation
                    if (validMove && firstCard.place.cardPlace === CardPlace.TABLEAU) {
                        const originalColumn = this.tableau[firstCard.place.value];
                        if (
                            originalColumn &&
                            originalColumn.length > 0 &&
                            !originalColumn[originalColumn.length - 1].visible
                        ) {
                            revealedCard = true;
                        }
                    }
                    break;
            }
        }
        let targetPosition = new Point();
        if (validMove && place) {
            const newZIndex = dropOnCard ? dropOnCard.place.zIndex : COLUMN_Z_INDEX;
            if (place.place === CardPlace.TABLEAU) {
                const posY = this.getColumnNextCardPosition(place.dropColumnIndex);

                targetPosition = new Point(this.getColumnPosition(place.dropColumnIndex), posY);
            } else {
                targetPosition = new Point(this.getFoundationPosition(place.dropColumnIndex), foundationPosition.y);
            }

            this.addMove(this.moveGroup, place.place, this.cardToActivate);

            this.foundationStreakManager.foundationSoundStreak(place);
            //if (place.place === CardPlace.FOUNDATION && firstCard.value === KING_VALUE) SoundManager.play('cardPutSFX');
            //else SoundManager.play('cardRewardSFX');

            this.moveGroup.forEach((card, index) => {
                card.setPlace({
                    cardPlace: place.place,
                    value: place.dropColumnIndex,
                    zIndex: newZIndex + index,
                    position: new Point(
                        targetPosition.x,

                        place.place === CardPlace.TABLEAU
                            ? this.getColumnNextCardPosition(place.dropColumnIndex, index)
                            : targetPosition.y
                    ),
                });
            });
            if (this.cardToActivate) {
                this.cardToActivate.setActive(true);
                this.cardToActivate.setVisible(true);
                if (this.cardToActivate.place.cardPlace === CardPlace.WASTE_PILE) this.refreshWastePile();
            }
        } else {
            let putOnEmpty = true;
            [...this.tableau, ...this.foundation].forEach((t) => {
                if (t.length) {
                    const lastCard = t[t.length - 1];
                    if (areBoxesCollide(lastCard.container, this.moveGroup[0].container)) {
                        putOnEmpty = false;
                    }
                }
            });

            // Animate all cards in move group
            this.moveGroup.forEach((card) => {
                shakeCard(card.container);
            });

            SoundManager.play(putOnEmpty ? 'cardPutEmptySFX' : 'missCardSFX');
        }
        this.placeMoveGroup();
    }

here is link to the video with the problem im talking about:
https://streamable.com/y5casd

Earlier it was making the same mistake, but the card wasnt even going to its original place- https://streamable.com/a7cntf – now it is moving back, but still something is wrong with the way they are moved…
im pretty newbie in these topics, so id apreciate someone to explain it to me

Dark Theme Toggle Button Code Not Working?

My code, shown below, for a dark theme toggle button isn’t working; Visual Studio Code isn’t telling me I have any errors. Can someone help me figure out what the issue is?

My HTML:

<!DOCTYPE html>
<html>
    <head>
        <!--CSS link-->
        <link rel="stylesheet" href="styles2.css">
        <!--Tab label-->
        <title>Site Test</title>
</head>
<body>
    <h1>Basic Website</h1> <!-- Site text content --> 
    <hr>
    <h2>Welcome to my basic webpage.</h2>
    <p>This isn't my first time coding, but it's been so long that it might as well be.</p>
    
    <img src="treehouse.jpg" alt="An elaborate treehouse."> <!-- Image -->
    <hr>

    <button id="themeButton">Change Theme Color</button> <!-- Theme button -->
    
    <script>
        document.getElementById('themeButton').addEventListener('click'), function() { /* Theme button script */
            document.body.classList.toggle('dark-theme');
        }
    </script>
</body>
</html>

My CSS:

body{
    
    background-color: rgb(246, 246, 246);
    color: black;
    

    h1 {
        color: rgb(63, 66, 145); /* Header 1 features */
        font-size: 50px;
        padding-bottom: 8px;
        margin: 10px;
        
    }

    h2 {
       font-family: Arial, Helvetica, sans-serif; /* Header 2 features */
       margin: 10px;
    }

    p {
        font-family: Arial, Helvetica, sans-serif; /* Paragraph features */
        font-size: 20px;
        padding-bottom: 10px;
        margin: 10px;
    }
 
    /* Dark theme styles */
    .dark-theme {
        background-color: #A9a9a9; /* Dark gray background */
        color:#F5F5F5 /* Light gray body text */
    }
    .dark-theme h1 {
        color:rgb(170, 172, 244) /* Light blue text for header 1 */
    }

}

The button should change the background to a dark gray, and the text should become light gray, but the button changes nothing when clicked.

Patch method gives back “acknowledged”: false in postman

I want to update a product in my PATCH request. I get back “acknowledged”: false on my request in postman.

I get back status code 200

Here is my model and patch request:

const mongoose = require("mongoose");

const productSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: String,
    price: Number
});

module.exports = mongoose.model("product", productSchema);
router.patch("/:productId", (request, response, next) => {
    const id = request.params.productId;
    const updateOps = {};
    for (const ops of request.body) {
        updateOps[ops.propName] = ops.value;
    }
    Product.updateOne({ _id: id }, { $push: { updateOps } })
        .exec()
        .then((result) => {
            console.log(result);
            response.status(200).json(result);
        })
        .catch((err) => {
            console.log(err);
            response.status(500).json({
                error: err,
            });
        });
});

I was expecting my product to be updated

how to handle RESOURCE_EXHAUSTED exception in zeebe

I am using the following library https://github.com/camunda-community-hub/zeebe-client-node-js

I am having issues handling RESOURCE_EXHAUSTED exceptions I tried all the configurations that the library suggests.

I want to achieve the following : try to activate the job 5 times and after that I want to quit

class MyCamunda {
    constructor() {
        this.zbClient = new ZBClient({
            onReady: () => console.log("broker connected")
        })

        this.pollUserTask();

    }

    userTask() {
        this.zbClient.createWorker({
            taskType: 'io.camunda.zeebe:userTask',
            taskHandler: async () => {
                // handle the task
            },
            onReady: () => console.log("worker ready"),
            onConnectionError: () => console.log("worker error")
        })
    }

    async pollUserTask() {
        try {
            const response = await this.zbClient.activateJobs({
                type: 'io.camunda.zeebe:userTask',
                maxJobsToActivate:20,
                timeout: 60 * 1000,
                worker: 'test',
                requestTimeout: 5000
            })

            // handle the task
        } catch (error) {
            console.log("error",error)
        } finally {
            setTimeout(() => this.pollUserTask(),5000);
        }
    }

}

I tried to poll the userTasks from the broker but when calling the activateJobs method the application gets stuck it will not resume the execution flow. (seen in the pollUserTask method)

I would expect to get all the userTasks 0..n and I would expect that I would be able to handle the exceptions when they are thrown.

Web worker creation from a different origin?

I’m using a npm package which internally create web workers. I need to send the base URL to the library config, and it uses that URL to fetch the worker files. In our case, it’s a CDN path.

As it’s a different origin from the hosted application, the worker creation is failing with the following error.

Uncaught DOMException: Failed to construct ‘Worker’: Script at
‘cdn.com/worker.js’ cannot be accessed from origin ‘example.com’

I already saw some solutions which suggest to reference a Blob URL while creating a worker.

Something like this: new Worker(blobUrl);

As the worker creation is within the dependency library, we can’t change the way the worker is being initialised. I wanted to know if there’s a way to make it work with a different origin.

Does anyone already recognise this problem?

Thanks!

Event Listeners for Ellipsis Navigation in Image Slideshow Not Working

I am working on a webpage where I’m loading several slides, including 14 images in total. The page displays ellipses after every 5 slides to indicate that there are additional slides available. When the user clicks on the right ellipsis, it should navigate to the next set of slides. Similarly, clicking the left ellipsis should take the user to the previous set. I’ve implemented event listeners for the ellipses, but they aren’t functioning as expected. I’m unsure what’s causing the issue. Here is my code.

// Initialization
let slideIndex = 1;
const dotsPerPage = 5; // Number of dots to show per page
showSlides(slideIndex);

function plusSlides(n) {
    showSlides(slideIndex += n);
}

function currentSlide(n) {
    showSlides(slideIndex = n);
}

function showSlides(n) {
    let slides = document.getElementsByClassName("mySlides");
    let dotsWrapper = document.querySelector(".dots-wrapper");
    let totalSlides = slides.length;

    let ellipsisLeft = document.querySelector(".ellipsis-left");
    let ellipsisRight = document.querySelector(".ellipsis-right");

    if (n > totalSlides) { slideIndex = 1; }
    if (n < 1) { slideIndex = totalSlides; }

    // Show or hide slides
    for (let i = 0; i < totalSlides; i++) {
        slides[i].style.display = "none";
    }
    slides[slideIndex - 1].style.display = "block";

    // Clear existing dots
    dotsWrapper.innerHTML = '';

    // Determine the range of dots to show
    let start = Math.floor((slideIndex - 1) / dotsPerPage) * dotsPerPage;
    let end = Math.min(start + dotsPerPage, totalSlides);

    // Show or hide ellipses based on total slides
    ellipsisLeft.style.display = (start > 0 && totalSlides > dotsPerPage) ? "inline" : "none";
    ellipsisRight.style.display = (end < totalSlides && totalSlides > dotsPerPage) ? "inline" : "none";

    // Generate dots dynamically
    for (let i = start; i < end; i++) {
        let dot = document.createElement("span");
        dot.className = "dot";
        dot.setAttribute("tabindex", "0");
        dot.setAttribute("aria-label", `Go to slide ${i + 1}`);
        dot.setAttribute("role", "button");
        dot.setAttribute("onclick", `currentSlide(${i + 1})`);
        if (i === slideIndex - 1) {
            dot.className += " active";
        }
        dotsWrapper.appendChild(dot);
    }

    // Handle arrow visibility
    document.querySelector(".prev").classList.toggle("disabled", slideIndex === 1);
    document.querySelector(".next").classList.toggle("disabled", slideIndex === totalSlides);
}

// Add event listeners for ellipsis after DOM content has loaded
document.addEventListener('DOMContentLoaded', function() {
    document.querySelector('.ellipsis-left').addEventListener('click', function() {
        let start = Math.floor((slideIndex - 1) / dotsPerPage) * dotsPerPage;
        let newSlideIndex = Math.max(1, start); // Go to the first slide of the previous set
        showSlides(newSlideIndex);
    });

    document.querySelector('.ellipsis-right').addEventListener('click', function() {
        let start = Math.floor((slideIndex - 1) / dotsPerPage) * dotsPerPage;
        let newSlideIndex = Math.min(start + dotsPerPage + 1, document.getElementsByClassName("mySlides").length); // Go to the first slide of the next set
        showSlides(newSlideIndex);
    });
});
<style>
.rbs-slideshow .slideshow {
    position: relative;
    padding: 32px;
    padding-top: 16px;
    border: 1px solid lightgray;
   
}

.rbs-slideshow .mySlides {
    position: relative;
    display: none;
}

.rbs-slideshow .slideshow img {
    cursor: pointer;
}

.rbs-slideshow .slideshow img {
    vertical-align: middle;
}

.rbs-slideshow .caption {
    background-color: #185A95;
    padding: 20px;
}

.h2-text {
    color: #ffffff;
}

.block-text {
    color: #ffffff;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
    height:50px;
}

/* Target .usa-button inside .rbs-slideshow .slideshow */
.rbs-slideshow .slideshow .usa-button, 
.rbs-slideshow .slideshow a.usa-button {
    background-color: #fff;
    color: #026fc2;
    box-shadow: inset 0 0 0 1px #026fc2;
    }

/* Target a.usa-button:hover inside .rbs-slideshow .slideshow */
.rbs-slideshow .slideshow a.usa-button:hover {
    color: #fff;
    background-color: #105183    
}

.rbs-slideshow .fade {
    -webkit-animation-name: fade;
    -webkit-animation-duration: 1.5s;
    animation-name: fade;
    animation-duration: 1.5s;
}

@-webkit-keyframes fade {
    from {opacity: .4}
    to {opacity: 1}
}

@keyframes fade {
    from {opacity: .4}
    to {opacity: 1}
}

.rbs-slideshow .prev, .rbs-slideshow .next {
    cursor: pointer;
    color: #185A95;
    font-size: 50px;
    transition: 0.6s ease;
    user-select: none;
    text-decoration: none;
    vertical-align: middle;
}

.rbs-slideshow .prev {
    margin-right: 5px;
}

.rbs-slideshow .next {
    margin-left: 5px;
}

.rbs-slideshow .prev:hover, .rbs-slideshow .next:hover {
    text-decoration: none;
    color: #185A95;
}

.rbs-slideshow .dot {
        cursor: pointer;
    height: 16px;
    width: 16px;
    margin: 0 2px;
    background-color: lightgray;
    border-radius: 50%;
    display: inline-block;
    transition: background-color 0.6s ease;
    vertical-align: middle;
}

.rbs-slideshow .active {
    background-color: #185A95 !important;
    font-weight: bold;
    background: none;
}

.rbs-slideshow .disabled {
    pointer-events: none;
    color: #bbb;
}



/* Responsive layout - makes the text and buttons adapt to screen size */
@media screen and (max-width: 768px) {
    .rbs-slideshow .caption-container {
        padding: 10px;
    }
}

@media screen and (max-width: 30em) {
    .rbs-slideshow .caption h2 {
        font-size: 14px;
    }
    .rbs-slideshow .caption p {
        font-size: 10px;
    }
}

@media screen and (max-width: 30em) {
    .rbs-slideshow .usa-button {
        width: auto;
        font-size: 1.06rem;
    }
}

/* Lightbox */
.lightbox {
    display: none;
    position: fixed;
    z-index: 1000;
    padding-top: 60px;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0, 0, 0, 0.6); /* Light gray background */
}

.lightbox-content {
    position: relative;
    margin: auto;
    max-width: 80%;
}

.lightbox-slide {
    display: none;
    text-align: center;
}

.lightbox img {
        margin: auto;
    border: 10px solid white;
    box-shadow: 0 0 20px #fff;
    height: auto;
    max-height: 100%;
    max-width: 100%;
    vertical-align: middle;
    width: auto;
}

.lightbox .close {
    position: absolute;
    top: 20px;
    right: 35px;
    color: #fff;
    font-size: 40px;
    cursor: pointer;
    background-color: transparent;
    border: 0px;
}

.lightbox .prev, .lightbox .next {
    cursor: pointer;
    position: fixed;
    top: 50%;
    width: auto;
    padding: 16px;
    margin-top: -50px;
    color: white;
    font-weight: bold;
    font-size: 30px;
    transition: 0.6s ease;
    user-select: none;
}

.lightbox .prev {
    left: 0;
    text-decoration: none;
        font-size: 50px;
}

.lightbox .next {
    right: 0;
    text-decoration: none;
        font-size: 50px;
}

.lightbox .prev:hover, .lightbox .next:hover {
    background-color: rgba(0,0,0,0.8);
}

.lightbox-caption {
    color: #f2f2f2;
    font-size: 16px;
    padding: 16px 24px;
    position: absolute;
    bottom: 24px;
    left: 0;
    width: 80%;
    text-align: center;
    background-color: rgba(0, 0, 0, 0.8);
    border-radius: 5px;
    margin: 0 0 0 130px;
    line-height: 24px;
}

@media only screen and (max-width: 760px) {
.lightbox-caption {
        margin: auto;
            }
}

@media screen and (max-width: 1000px) {
 .rbs-slideshow .slideshow  a {
         font-size: 50px !important;
    }
}

@media screen and (max-width: 1000px) {
    .lightbox .prev, 
    .lightbox .next {
        font-size: 50px !important;
    }
}

</style>    

<style>
.dots-container {
    text-align: center;
    margin-top: 20px;
}

.dots-wrapper {
    display: inline-block;
}


.ellipsis-left, .ellipsis-right {
    display: inline-block;
    
        border-radius: 50%;
      font-weight: bold;
    font-size: 20px;       }
</style>                 
<div class="rbs-slideshow" style=" margin-top: 20px;">
<div class="slideshow" style=" width: 656px;">
<p style=" color: black; font-weight: 700;">Click on the image to view higher resolution pictures</p>



<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(2)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(2); }" style=" width: 656px; height: 451px;" />
<div class="caption" tabindex="0"><span class="block-text">1983</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(3)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(3); }" style=" width: 656px; height: 451px;" />
<div class="caption" tabindex="0"><span class="block-text">1983</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(4)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(4); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">1988</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(5)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(5); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">1992</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(6)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(6); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">1993</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(7)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(7); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2016</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(8)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(8); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2017</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(9)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(9); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2018</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(10)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(10); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2018</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(11)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(11); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2018</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(12)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(12); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2019</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(13)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(13); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2023</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(14)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(14); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2023</span></div>
</div>

<div class="mySlides fade" style=" display: block;"><img alt="" src="" aria-label="click to enlarge" tabindex="0" onclick="openLightbox(); currentImage(15)" onkeydown="if(event.key === 'Enter'){ openLightbox(); currentImage(15); }" style=" width: 656px; height: 451px;" />
<div class="caption"><span class="block-text" tabindex="0">2024</span></div>
</div>

<!-- The dots/circles and navigation arrows 
<div style=" text-align: center; margin-top: 20px;"><a class="prev disabled" onclick="plusSlides(-1)">❮</a> <span class="dot active" tabindex="0" aria-label="Go to slide 1 to view CARE Leaders photo from 2024 NOLA All-staff meeting" role="button" onclick="currentSlide(1)">&#160;</span> <span class="dot" tabindex="0" aria-label="Go to slide 2 to view CARE group Photo 2 from 2024 NOLA All-staff meeting" role="button" onclick="currentSlide(2)">&#160;</span> <span class="dot" tabindex="0" aria-label="Go to slide 3 CARE group Photo 2 from 2024 NOLA All-staff meeting" role="button" onclick="currentSlide(3)">&#160;</span> <span class="dot" tabindex="0" aria-label="Go to slide  4 to view CARE group Photo 3 from NOLA All-staff meeting" role="button" onclick="currentSlide(4)">&#160;</span> <span class="dot" tabindex="0" aria-label="Go to slide 5 to view CARE group Photo 4 from NOLA All-staff meeting" role="button" onclick="currentSlide(5)">&#160;</span> <a class="next" onclick="plusSlides(1)">❯</a></div>
</div>-->
<div style=" text-align: center; margin-top: 20px;"><a class="prev disabled" onclick="plusSlides(-1)">❮</a> <span class="ellipsis ellipsis-left" style=" display: none; cursor: pointer;">…</span>
<div class="dots-wrapper"><!-- Dots will be generated dynamically here --></div>

<span class="ellipsis ellipsis-right" style=" display: none; cursor: pointer;">…</span> <a class="next" onclick="plusSlides(1)">❯</a></div>

JS/TS: Same class instances over different projects

I’m having issues with instances of the same package over different JavaScript projects and I’d like to know if there is any workaround other than modifying the original package. My project setup is the following:

Project A
In this project there are several classes that are used on other places. This project is uploaded as a package to the npm repository.

Project B
This project has Project A as dependency (via npm) and creates instance generators of the classes provided there. It’s kind of a repository of functions that create Project A instances.

Project C
This project has Project A as dependency (via npm) as well. The project attempts to generate the instances from Project B and check if there are valid Project A instances.


The problem comes when Project C attempts to check the instanceof from Project B generated instances, because it alwais returns false. Instances are being created importing from a project to the other with a require(filepath) the generator function and then executing it.

Maybe it’s easier to understand with an example:

Project A

class A {
   // ...
}

Project B

import { A } from 'npm-package-name';

export const generator = () => new A(); 

Project C

import { A } from 'npm-package-name';

const { generator } = require('...');
const a = generator();

return a instanceof A; // false

I tried to upload de Project A as an npm package because I thought that way the definitions would be somehow shared between projects but clearly it didn’t work.

Issue with dynamically loading React components in a unified mobile and web project: Module parse failed error with expo-barcode-generator on web

I have a project where both a mobile app and a web app are integrated into the same server and repository. The React components are loaded dynamically based on the environment like this:

import React from "react";
class Sheet extends React.Component {
  constructor(props) {
    super(props);
    this.state = {

      componentLoaded: false,
      Component: null,
    };
  }
  componentDidMount() {

    if (!!process.env.EXPO_PUBLIC_PROJECT_ROOT) {
      this.setState({ Component: require('./mobile').default, componentLoaded: true });
    } else {
      this.setState({ Component: require('./web').default, componentLoaded: true });
    }
  };
  render = () => {
    if (!this.state.componentLoaded) {
      return null; // or a loading indicator, e.g. <div>Loading...</div>
    }
    return React.createElement(this.state.Component, this.props);
  };
}
export default Sheet;

This setup works fine on mobile, but when I run the web application, I encounter the following error related to the expo-barcode-generator library:

: Module parse failed: Unexpected token (44:4)
|
| return (

<Svg
| x={0}
| y={0}

Here are the files that reference the expo-barcode-generator and react-native-view-shot libraries:

import * as Print from 'expo-print';
import * as FileSystem from 'expo-file-system';
import { captureRef } from 'react-native-view-shot';

import ProductionOrderSheet from "../../ProductionOrderSheet"

const printSheet = async (viewRef) => {
    try {
        const uri = await captureRef(viewRef, {
            format: "png",
            quality: 1.0
        })...
};

const Sheet = (props) => {
    const { appContext, type, sheet } = props;
    
    switch (type) {
        case "productionOrderSheet":
            return (
                <ProductionOrderSheet
                    {...sheet}
                    type={"productionOrderSheet"}
                    printSheet={printSheet}
                    appContext={appContext}
                />
            );

        default:
            throw new Error(`(Sheet) the sheet type ${type} not found`);
    }
}

export default Sheet
import Table from "../../Table";
import Button from '../../Button';
import Container from "../../Container"
import TextFormatter from "../../TextFormatter"
import { Barcode } from 'expo-barcode-generator';

const MobileProductionOrderSheet = (props) => {
    ...
    const getHeader = () => {
        return (
                    <Barcode
                        value={productionLot}
                        options={{ format: 'CODE128', background: 'white', height: 70, fontSize: 18 }}
                    />
                </Container>
            </Container>
        )
    }
    ...

package.json:

{
  "name": "@monorepo/appmobile",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "expo start",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@apollo/client": "^3.10.8",
    "@expo/ngrok": "^4.1.3",
    "@fortawesome/fontawesome-svg-core": "^6.5.2",
    "@fortawesome/free-solid-svg-icons": "^6.5.2",
    "@fortawesome/react-native-fontawesome": "^0.3.2",
    "@react-native-community/datetimepicker": "8.0.1",
    "@react-native-picker/picker": "2.7.5",
    "@react-navigation/drawer": "^6.6.15",
    "@react-navigation/material-top-tabs": "^6.6.13",
    "@react-navigation/native": "^6.1.17",
    "@react-navigation/native-stack": "^6.10.0",
    "core-js": "^3.37.1",
    "expo": "~51.0.21",
    "expo-barcode-generator": "^3.0.2",
    "expo-navigation-bar": "^3.0.6",
    "expo-print": "^13.0.1",
    "expo-screen-orientation": "~7.0.5",
    "expo-secure-store": "~13.0.2",
    "expo-status-bar": "~1.12.1",
    "graphql": "^16.9.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.74.3",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-media-query": "^2.0.1",
    "react-native-pager-view": "6.3.0",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "4.10.5",
    "react-native-screens": "3.31.1",
    "react-native-svg": "15.2.0",
    "react-native-tab-view": "^3.5.2",
    "react-native-vector-icons": "^10.1.0",
    "react-native-view-shot": "^3.8.0",
    "react-native-web": "~0.19.10",
    "socket.io-client": "^4.7.5"
  },
  "devDependencies": {
    "@babel/core": "7.19.6",
    "@types/react-native": "^0.73.0"
  },
  "private": true
}

Commenting out the library imports: I commented out the imports for expo-barcode-generator and react-native-view-shot, and the code worked on the web but not on mobile, as the component could not be used.
// import { Barcode } from ‘expo-barcode-generator’;
// import { captureRef } from ‘react-native-view-shot’;

Commenting out the conditional mobile import: I also tried commenting out the conditional import for mobile, which made the web work, but then I couldn’t use the component on mobile.

if (!!process.env.EXPO_PUBLIC_PROJECT_ROOT) {
  // this.setState({ Component: require('./mobile').default, componentLoaded: true });
} else {
  this.setState({ Component: require('./web').default, componentLoaded: true });
}

Finally, I attempted to use dynamic require for the libraries, like this:

if (!!process.env.EXPO_PUBLIC_PROJECT_ROOT) {
    const Barcode = require('expo-barcode-generator');
}

but it not works