Why does my postgres 16 after setting up a remote connection?

ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:5432
0|index    |     at Client._connectionCallback (/home/root/"Mydatabase"/node_modules/sequelize/lib/dialects/postgres/connection-manager.js:131:24)
0|index    |     at Client._handleErrorWhileConnecting (/home/root/"Mydatabase"/node_modules/pg/lib/client.js:327:19)
0|index    |     at Client._handleErrorEvent (/home/root/"Mydatabase"/node_modules/pg/lib/client.js:337:19)
0|index    |     at Connection.emit (node:events:517:28)
0|index    |     at Socket.reportStreamError (/home/root/"Mydatabase"/node_modules/pg/lib/connection.js:58:12)
0|index    |     at Socket.emit (node:events:517:28)
0|index    |     at emitErrorNT (node:internal/streams/destroy:151:8)
0|index    |     at emitErrorCloseNT (node:internal/streams/destroy:116:3)
0|index    |     at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
0|index    |   parent: Error: connect ECONNREFUSED 127.0.0.1:5432
0|index    |       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1549:16) {
0|index    |     errno: -111,
0|index    |     code: 'ECONNREFUSED',
0|index    |     syscall: 'connect',
0|index    |     address: '127.0.0.1',
0|index    |     port: 5432
0|index    |   },
0|index    |   original: Error: connect ECONNREFUSED 127.0.0.1:5432
0|index    |       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1549:16) {
0|index    |     errno: -111,
0|index    |     code: 'ECONNREFUSED',
0|index    |     syscall: 'connect',
0|index    |     address: '127.0.0.1',
0|index    |     port: 5432
0|index    |   }
0|index    | }

local all all peer

host all all 127.0.0.1/32 ident

host all all ::1/128 ident

local replication all peer

host replication all 127.0.0.1/32 ident

host replication all ::1/128 ident

listen_addresses = ‘*’

deckOfCards API wont choose card from the deck with the specific deck ID

I have been stuck on this for so long and the answer is probably so simple but i cant figure it out at all, basically everytime i click the button to draw a card its giving me a brand new deck and not using the deck with the same ID as the one i am trying to draw from. I am new if it isnt obvios, thank you.

let deckOfCardsApi = 'https://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=1'
const button = document.querySelector('#giveCardButton');

const drawCard = async () => {
    try {
        const response = await axios.get(deckOfCardsApi);
        let deckId = response.data.deck_id;
        const drawCard = await axios.get(`https://deckofcardsapi.com/api/deck/${deckId}/draw/?count=1`)
        console.log(deckId);
    } catch (error) {
        console.error('Error fetching data:', error);
    }
};
button.addEventListener('click', drawCard);

I tried making two seperate async functions, one to summon the new deck and one to pull from the deck with and that didnt work. also kept looking at the api website to see if im typing any of this wrong and it doesnt seem like it.

Detect current date change in JavaScript

I’m writing a calendar Web application and I’m highlighting current date on the calendar. I want to automatically update which date is highlighted when the actual date changes.

So basically I need a way to have a callback called on midnight. How is it possible? I can imagine naive solution which calculates milliseconds before midnight and calls setTimeout, but I’m not sure how reliable this solution is:

  1. What will happen if browser will put my tab into power-save mode? Will timeout be called after unfreezing the tab given the fact that it will happen after midnight and timeout will miss it’s original time?

  2. How to handle timezone/daylight saving changes?

I also can imagine another naive solution which just uses setInterval to have a callback called every second and continuously check current system date. I don’t like this approach, because it is power consuming and may make not happy mobile users.

Coordinate system in JavaScript

How I can create a rectangular coordinate system like this on JavaScript?(https://i.sstatic.net/65KljdyB.png)
I tried to use charts, but it can create only this:
(https://i.sstatic.net/JfzdT082.png)
I need some coordinate system with zero at the middle and axes with normal numeration (-0.3 -0.2, -0.1 0 0.1 0.2 0.3) like this. I think Plotly can help me, but I really don`t understand how to use it. Also, I write my project on Vue.js, but I can write all at python with FLask, if it will be easier to do this on Python. If there some answer on Python, I will use it.

I have coordinates(https://i.sstatic.net/ymabMe0w.png) and need to draw a graph (https://i.sstatic.net/M6jJoNIp.png)
Main problem of Charts is only one labels. I can draw only y axis like normal, but x axiss numbers are my coordinates.(https://i.sstatic.net/9MxOIJKN.png) Thats why I can`t draw a circle, only some line.

What do I do if my Apps Script didn’t save?

I was working on an apps script with a personal account. I clearly remember saving it, however when I looked back the next day, all the progress I made was gone. I deployed it once around 30 min in and that deployment’s code is still there in the version history. After that, I just used test deployments to test all changes, and none of the changes were saved. I lost about 3 hours of javascript and would prefer to not have to rewrite it. Is there a way to get back the lost code? This happened around 3 days ago.

I was expecting for my code to save, but instead it didn’t.

Thunderbird AddOn for text replacement debugging

this is my first TB addOn development and I need a hint for debugging. The addOn is a kind of auto correction or auto text replacement. This means, you can save a shortcut like ‘br’ and it will replaced with ‘Br, John Doe’. This works automaticly and to this point everythings works fine. But I would like to offer in setup the function to replace the shortcut if Enter-Key is pressed only. And here I have a problem, the cursor position, if enterReplace is active, aint get catched correctly and I don’t found the bug. I tried a lot, to asked ChatGPT was aint helpful as well.

This is the Code:

window.addEventListener("keydown", async (event) => {
    // Retrieve settings from local storage
    let setting_enter = await browser.storage.local.get({ enterReplace: false });

    // Get the current cursor position node
    let selection = window.getSelection();
    let range = selection.getRangeAt(0);
    let node = range.startContainer;

    // Only handle text nodes if Enter was not pressed
    if (node.nodeType !== Node.TEXT_NODE && event.code !== 'Enter') {
        return;
    }

    // Function for text replacement and HTML insertion
    const replaceText = async () => {
        console.log("Node text content:", node.textContent); // Debugging
        console.log("Cursor position (offset):", range.startOffset); // Debugging

        // Get text up to the cursor position in the current node
        let textBeforeCursor = node.textContent.slice(0, range.startOffset);
        console.log("Text before cursor:", textBeforeCursor); // Debugging

        // Capture the last word before the cursor
        let words = textBeforeCursor.trim().split(/s+/); // Split the text into words
        let wordToReplace = words[words.length - 1]; // The last word is what we want to replace

        console.log("Word to replace:", wordToReplace); // Debugging

        // Retrieve replacements from storage
        let data = await browser.storage.local.get({ replacements: [] });
        let replacements = data.replacements;

        // Check if the last word is a shortcut and should be replaced
        let shortcutFound = false; // Variable to determine if a shortcut was found
        for (let item of replacements) {
            console.log("Checking shortcut:", item.shortcut); // Debugging
            if (wordToReplace === item.shortcut) {
                shortcutFound = true; // Shortcut found
                // Replace line breaks with <br> for HTML context
                let replacementText = item.replacement.replace(/n/g, '<br>');

                // Replace text in the range
                let newText = textBeforeCursor.slice(0, -wordToReplace.length);

                // Remove old text up to the shortcut
                range.setStart(node, newText.length);
                range.setEnd(node, textBeforeCursor.length);
                range.deleteContents();

                // Insert HTML by creating a new Range object
                let fragment = document.createRange().createContextualFragment(replacementText);
                range.insertNode(fragment);

                // After inserting, set the cursor to the end of the inserted HTML
                range.collapse(false);
                selection.removeAllRanges();
                selection.addRange(range);
                break; // Break the loop after replacing the shortcut
            }
        }

        // If no shortcut was found, we can log a message here
        if (!shortcutFound) {
            console.log("No matching shortcut found for:", wordToReplace);
        }
    };

    // If 'enterReplace' is active and Enter is pressed
    if (setting_enter.enterReplace && event.code === 'Enter') {
        event.preventDefault(); // Prevent the default Enter key effect

        // Handle replacement and cursor position in one step
        await replaceText();

        // Optionally: add a new line break after the replacement is done
        let brNode = document.createElement("br");
        range.insertNode(brNode);
        range.collapse(false);  // Set the cursor to the end
        selection.removeAllRanges();
        selection.addRange(range);
    } else if (!setting_enter.enterReplace) {
        // Apply delay only if 'enterReplace' is not active
        setTimeout(async () => {
            // Recheck the current selection
            selection = window.getSelection();
            range = selection.getRangeAt(0);
            node = range.startContainer;

            await replaceText();
        }, 700);
    }
}); 

Where is the bug?

Thx!

autoReplace Setup

Absolute id of fractal cells

I want to create a function to get subobject absolute id of fractal object by layer/row and column id. In an fractal object there are repeating subobjects, you can split them into layers. Object with identifier W1 contains 7x G’s, each of G’s again contain 7x N’s etc.

if layer is ...
...3 (rowId=2) then only strings with "N"...
...2 (rowId=1) then only strings with "G"...
...
are counted.

The raw code:

const rawData = [["W1","W2","W3","W4","W5","W6","W7"],
  ["G1","G2","G3","G4","G5","G6","G7"],
  ["N1","N2","N3","N4","N5","N6","N7"],
  ["T1","T2","T3","T4","T5","T6","T7"]]
  
const selIds=[0,1,2,4] // selected indices of W1 G2 N3 T5 (range per array element: [0-6])

// to calculate absolute fractal "cell" counter
rowId=1 // row index (range: [0-6])
colId=2 // col index (range: [0-6])

I think result can be calculated this way?

result=((7^1*selIds[0])+selIds[1]*7^0)*7^(rowId+1)+3=(0+1)*49+3=52

On click the selIds change with given rowId & colIds to selIds=[0,2,2,4]; letters of rawData are just arbitrary, because in reality they are like identifiers of planets, solar systems, galaxies and so on

My functions so far:

const getFractalIdByRow = function(rowIndex) {
    let result = 0
    let factor = 0
    let j = 0
    for(let i = rowIndex; i >= 0; i--) {
        factor += (selIds[j]) * Math.pow(7, i)
        j++
    }
    result = factor*Math.pow(7, rowIndex+1)
    return result
}

const getCurrentIndex = function(colIndex, rowIndex) {
    let currentIndex = 0
    currentIndex += getFractalIdByRow(rowIndex);
    currentIndex += colIndex
    currentIndex += 1
    return currentIndex
}

Examples (layer/row & element/col = absolute id):

W1:G1:N1:T1 = 1
W1:G1:N1 = 1
W4:G5:N6 = 3*7*7 + 4*7 + 6 = 181
W2:G2:N3 = 1*7*7 + 1*7 + 3 = 59
W3:G4:N3 = 2*7*7 + 3*7 + 3 = 122
W2:G2:N3:T4 = 1*7*7*7 + 1*7*7 + 2*7 + 4 = 410

Column id is the number of the last string element split by :.

Conditional dropdowns in React JS

I’m building a Dnd Character Sheet builder. I need 6 dropdowns for each of the 6 main stats. I want them all to have access to an array of the values [8,10,12,13,14,15], but if one dropdown selects a number, I need that number to be unavailable in the dropdowns. So if the user chooses 15 for the strength score, the other dropdowns would no longer have the option to choose 15.

This is where I build the dropdowns.

    <div>
      {standardArray.map((stat, index) => {
        return (
          <div key={index}>
            <Text marginLeft={5}> {stat.name[index]}</Text>
            <Select
              placeholder={stat.name[index]}
              width="90%"
              marginLeft={3}
              marginBottom={3}
              onChange={handleChange}
              name={"playerStat" + [index]}
            >
              Name: {stat.name}
              {stat.value.map((value, index) => {
                return (
                  <option key={index} value={value}>
                    {value}
                  </option>
                );
              })}
            </Select>
          </div>
        );
      })}
    </div>

and these are the arrays and the value assignments

function App() {
  const [count, setCount] = useState(0);
  const statArray = [8, 10, 12, 13, 14, 15];
  const statTitles = ["STR", "CON", "DEX", "INT", "WIS", "CHA"];
  const standardArray = [
    { id: 1, name: statTitles, value: statArray },
    { id: 2, name: statTitles, value: statArray },
    { id: 3, name: statTitles, value: statArray },
    { id: 4, name: statTitles, value: statArray },
    { id: 5, name: statTitles, value: statArray },
    { id: 6, name: statTitles, value: statArray },
  ];

  const [state, setState] = useState({
    playerName: "Test",
    playerSpecies: "",
    playerClass: "",
    playerSubclass: "",
    playerStat0: 15,
    playerStat1: 14,
    playerStat2: 13,
    playerStat3: 10,
    playerStat4: 8,
    playerStat5: 12,
    playerLevel: 1,
    strModifier: 0,
    conModifier: 0,
    dexModifier: 0,
    intModifier: 0,
    wisModifier: 0,
    chaModifier: 0,
    playerHp: 24,
    proficiencyBonus: 2,
    speciesBonus: 0,
  });

Primefaces TextEditor component Remaining character count

I am trying to get the custom implementation of Remaining character count using javascript. As Primefaces texteditor doesn’t have any KeyUp event, the editor values are not picking into the JS var items,

any other way we can implement to get the remaining characters count using javascript here? pls suggest.

Visual Studio 2022 Go to Definition not Working With JavaScript

Good Day!

I have very bad experience with Visual Studio 2022, Finally after I decide to move from 2015 to the newest version 2022 with the latest version of Devsense PHP Tools, A lot of bad situations start happening, begin with destroy all opened documents ordered over three monitors, some error messages while Go to Definition with PHP functions and classes and finally the worst at all, I can’t use Go to Definition or F12 with JavaScript code and really don’t know how to continue work with this, I have a huge JS files under namespaces and hundreds of functions.

I googled it and tried this solution “Tools > Options > Text Editor > JavaScript/TypeScript > Language Service > (CHECK) Disable dedicated syntax process (restart required)” but still can’t use F12.

I tried to remove the “ASP.NET and Web Development” from Visual Studio Installer and re-install it but doesn’t work.

I saw an article on Visual Studio Developers Community forum (here) and (here) and it seems like it has been fixed a long time ago.

Can anyone help?

Moving map to the center after folding the sidebar

I was wondering how to make my leaflet map displayed slightly to right with using css, so I won’t have to set setview or center values for that. After I fold the sidebar I want the map to come back to center of the site. I tried something with add left:10% to leaflet.css but it messes with the coords popup.

function setupMap() {
let mapData; // Zmienna do przechowywania danych mapy

// Pobranie bieżącej ścieżki URL
const currentPath = window.location.pathname;

// Sprawdzenie ścieżki i ustawienie odpowiednich wartości
if (currentPath.includes('/white_orchard/')) {
    mapData = mapdata_wo; // Użyj danych z mapdata_wo
} else if (currentPath.includes('/velen_novigrad/')) {
    mapData = mapdata_vn; // Użyj danych z mapdata_vn
} else {
    console.error('Nieznana ścieżka mapy');
    return;
}

var bounds = L.latLngBounds(mapData.sWest, mapData.nEast);
var map = L.map('mapid', {
    zoomControl: false,
    center: mapData.map_center, // Ustawienie poprawnych współrzędnych (lat, lng)
    zoom: mapData.map_zoom,
    maxZoom: mapData.max_zoom,
    minZoom: mapData.min_zoom,
    attributionControl: false,
    zoomSnap: 0.5,  // Umożliwia zoom co 0.5
    zoomDelta: 0.5,
    maxBounds: bounds,
    maxBoundsViscosity: 0,
    fullscreenControl: true
}); 

function addBoundaryLine() {
    var corners = [
        [mapData.sWest.lat, mapData.sWest.lng],  // Dolny lewy róg
        [mapData.nEast.lat, mapData.sWest.lng],  // Górny lewy róg
        [mapData.nEast.lat, mapData.nEast.lng],  // Górny prawy róg
        [mapData.sWest.lat, mapData.nEast.lng],  // Dolny prawy róg
        [mapData.sWest.lat, mapData.sWest.lng]   // Zamknięcie obwodu (powrót do dolnego lewego rogu)
    ];

    // Dodanie polilinii (linii wielokątnej) z czerwoną linią
    var boundaryLine = L.polyline(corners, {
        color: 'red',   // Kolor linii
        weight: 2,      // Grubość linii
        opacity: 1      // Przezroczystość
    }).addTo(map);
}

// Wywołanie funkcji po załadowaniu mapy
addBoundaryLine();

// Dodanie kontrolek zoomu
L.control.zoom({
    position: 'bottomright',
    zoomInTitle: 'Przybliż',
    zoomOutTitle: 'Oddal'
}).addTo(map);

// Okienko z koordynatami
map.on('click', function (e) {
    var coords = e.latlng;
    var lat = coords.lat.toFixed(5);
    var lng = coords.lng.toFixed(5);
    console.log('Map clicked at:', lat, lng);
    L.popup()
        .setLatLng(coords)
        .setContent("Koordynaty: " + lat + ", " + lng)
        .openOn(map);
});

// Dodanie warstwy kafelków z opcją TMS
L.tileLayer(mapData.map_path + '.jpg', {
    tms: true, // Ustawienie odwrotnej numeracji kafelków
    noWrap: true,
    bounds: bounds,
    maxZoom: mapData.max_zoom,
    minZoom: mapData.min_zoom,
    continousWorld: true,
}).addTo(map);
}


// Wywołanie funkcji po załadowaniu DOM
document.addEventListener('DOMContentLoaded', function() {
   setupMap();
});


document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('container');
const button = document.getElementById('toggleButton');
const image = document.getElementById('toggleImage');
const hideableDiv = document.getElementById('hideableDiv');
var mapElement = document.getElementById('mapid');

button.addEventListener('click', () => {
    const isHidden = hideableDiv.style.display === 'none';
    if (isHidden) {
        hideableDiv.style.display = 'block'; // Pokazuje div
        image.src = '/resources/images/cc_greaterthan-left.png'; // Zmienia obrazek
    } else {
        hideableDiv.style.display = 'none'; // Ukrywa div
        image.src = '/resources/images/cc_greaterthan-right.png';
    }
    // if (mapElement.classList.contains('map-move-left')) {
    //     mapElement.classList.remove('map-move-left');
    // } else {
    //     mapElement.classList.add('map-move-left');
    // }
});

});

function showCategory(category) {
    document.querySelectorAll('.text-box').forEach((cat) => {
        cat.style.display = (category === 'all' || cat.id === category) ? 'block' : 'none';
    });
 }

document.addEventListener('DOMContentLoaded', () => {
    const rightToggleButton = document.getElementById('rightToggleButton');
    const rightContent = document.getElementById('rightContent');
    const secondRightToggleButton = document.getElementById('secondRightToggleButton');
    const secondRightContent = document.getElementById('secondRightContent');

    rightToggleButton.addEventListener('click', () => {
        const buttonRect = rightToggleButton.getBoundingClientRect();
        rightContent.style.top = (buttonRect.top - 10) + 'px';
        rightContent.style.display = rightContent.style.display === 'none' ? 'block' : 'none';
        secondRightContent.style.display = 'none'; // Ukryj drugie okienko
    });

    secondRightToggleButton.addEventListener('click', () => {
        const buttonRect = secondRightToggleButton.getBoundingClientRect();
        secondRightContent.style.top = (buttonRect.top - 10) + 'px';
        secondRightContent.style.display = secondRightContent.style.display === 'none' ? 'block' : 'none';
        rightContent.style.display = 'none'; // Ukryj pierwsze okienko
    });
});

ERR_UNSUPPORTED_DIR_IMPORT when importing my own package

I created an ESM-only package that expose all the files instead of defining exports in package.json

{
  "name": "@org/runtime",
  "version": "0.0.0-development",
  "description": "Runtime library",
  "module": "index.js",
  "type": "module",
  "scripts": {
    "b": "pnpm build",
    "prebuild": "rm -rf dist",
    "build": "tsc --project tsconfig.build.json && pnpm build:copy-dts && tsc-alias && cp package.json dist/",
    "build:copy-dts": "copyfiles -V -u 1 src/**/*.d.ts src/*.d.ts dist",
    "lint": "eslint .",
    "test": "vitest",
    "test:ci": "vitest --coverage",
    "release": "semantic-release"
  },
  "devDependencies": {
    "tsc-alias": "^1.8.10",
    "typescript": "^5.5.3",
  },
  "dependencies": {
  },
  "engines": {
    "node": ">=22"
  }
}

I get a file structure like this:

├── background-job
│   ├── index.d.ts
│   └── index.js
├── logger
│   ├── formatter
│   │   ├── console-formatter.d.ts
│   │   ├── console-formatter.js
│   │   ├── formatter.d.ts
│   │   ├── formatter.js
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   ├── json-formatter.d.ts
│   │   └── json-formatter.js
│   ├── index.d.ts
│   ├── index.js
│   ├── shared.d.ts
│   └── shared.js
├── package.json
├── request-context
│   ├── fastify.d.ts
│   ├── fastify.js
│   ├── index.d.ts
│   ├── index.js
│   ├── plugin.d.ts
│   └── plugin.js
├── result.d.ts
├── result.js
├── tests
│   ├── setup.d.ts
│   └── setup.js
├── types.d.ts
├── validations
│   ├── is-truthy.d.ts
│   └── is-truthy.js
└── validator
    ├── index.d.ts
    ├── index.js
    ├── schema-extensions.d.ts
    ├── schema-extensions.js
    └── yup.d.ts

In my main project I have this tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2023",
    "module": "NodeNext",
    "esModuleInterop": true,
    "moduleResolution": "NodeNext",
    "lib": [
      "ESNext"
    ],
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "outDir": "dist",
    "rootDir": "src",
    "baseUrl": ".",
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "node"
    ],
    "declaration": false,
    "sourceMap": false,
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "include": [
    "src/**/*.ts",
    "node_modules/@types/node/globals.d.ts",
    "node_modules/vitest/globals.d.ts",
    "node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vitest/globals.d.ts"
  ],
  "exclude": [
    "node_modules",
    "dist"
  ],
  "tsc-alias": {
    "resolveFullPaths": true,
    "verbose": true
  }
}

After installing my package, I try to import it like this:

import { Logger } from '@org/runtime/logger';

ESlint, my IDE and tsc work without any warning/error on that import statement. I can lint and build with no issues. Then, when I run the transpiled code I get the error

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/my-project/node_modules/@org/runtime/logger' is not supported resolving ES modules imported from /my-project/index.js
Did you mean to import "@org/runtime/logger/index.js"?

If I add index.js to my import statement, I can run the project without issues. How can I make TSC catch these issues during build-time? Or how can I make the IDE aware of this issue?

I would prefer to avoid depending on eslint, so I can catch this when I build the project.

PDF blank in ngx-extended-pdf-viewer for Japanese

My application uses ngx-extended-pdf-viewer to display PDFs. It works fine for all other languages but if I upload a PDF with Japanese characters, it loads a blank page.

pdfviewer.component.html

<ngx-extended-pdf-viewer #pdfViewer [zoom] = "'page-width'" [height]="'100%'" [src]="pdfSrc" 
[showPrintButton]="false" 
[customToolbar]="additionalButtons" 
[enablePinchOnMobile]="true" 
[showBookmarkButton]="false" 
[showOpenFileButton]="false" 
[showFindButton]="false" 
[showBorders]="false" 
[showScrollingButton]="false"
[showSpreadButton]="false" 
[page]="page" (pagesLoaded)="pagesLoaded($event)" [handTool]="false" theme="dark" useBrowserLocale="true" height="85vh" ></ngx-extended-pdf-viewer>

<ng-template #additionalButtons>
    <div id="toolbarViewer">
      <div id="toolbarViewerLeft">
        <pdf-paging-area *ngIf ="!mobileView"></pdf-paging-area>
        <pdf-page-number *ngIf ="mobileView" id="pageNumber"  ></pdf-page-number>
      </div>
      <pdf-zoom-toolbar *ngIf ="!mobileView"></pdf-zoom-toolbar>
      <div *ngIf ="mobileView" id="toolbarViewerMiddle">
            
            <pdf-zoom-out id="zoomOut"></pdf-zoom-out>
            <pdf-zoom-in id="zoomIn"></pdf-zoom-in>
      </div>
      <div id="toolbarViewerRight">
        <pdf-download id="download"> </pdf-download>
        <pdf-toggle-secondary-toolbar>
                <div class="secondaryToolbar hidden doorHangerRight" id="secondaryToolbar"  >
                                <button title="Download" id="secondaryDownload"  ></button>
                                <button title="Go to First Page" id="firstPage"  ></button>
                                <button title="Go to Last Page" id="lastPage"  ></button>
                                <button title="Rotate Clockwise" id="pageRotateCw"  ></button>
                                <button title="Rotate Counterclockwise" id="pageRotateCcw"  ></button>
                                <button title="Document Properties…" id="documentProperties"  ></button>
                </div>   
        </pdf-toggle-secondary-toolbar>
      </div>
     </div>

  </ng-template>

I went through the details of this package on npmjs website but couldn’t find anything related to my issue. The PDF is not corrupted as it opens fine in the browser. The application uses Angular 8 and latest version of ngx-extended-pdf-viewer.

How to get seamless display in javascript slideshow

I’ve written a basic slideshow with javascript. It downloads a randomly-chosen JPEG from a CGI script, scales it down if necessary, deletes the previously-displayed slide and displays the new one on the page, repeating this every two seconds.

The problem is that some of the JPEGs are very large (from 3MB to 20MB). The downloading (and, I presume, the scaling) take so long that sometimes, when the previous slide is deleted, several seconds elapse before the next one appears.

I’m sure this is because of the asynchronous nature of the processing, but I don’t know how to control it. What I’d like is for each slide to appear for a minimum of two seconds or long enough that the next slide will appear without any delay.

(I’m using a placeholder image generator in this demo, so I don’t know how well it will illustrate the delay problem.)

    function showSlides() {
        const my_img = document.createElement('img');
        fetch('https://picsum.photos/2000/600')
            .then(my_response => my_response.blob())
            .then(my_blob => {
                const my_url = URL.createObjectURL(my_blob);
                my_img.setAttribute('src', my_url);
                my_img.setAttribute('class', 'picture-div-img');
            })
            .catch(my_error => console.error('Error: ', my_error));

        /* NOTE: would like to wait until new slide is completely downloaded
           and rendered offscreen before deleting current slide and displaying
           new one */

        /* Delete current slide */
        const my_parent = document.querySelector('#slide-div');
        while (my_parent.firstChild) {
            my_parent.removeChild(my_parent.firstChild);
        }
        /* Insert new slide */
        my_parent.appendChild(my_img);
        setTimeout(showSlides, 2000); /* Change image every 2 seconds */
    }
    html {
        height: 100%;
        width: 100%;
    }

    body {
        /* prevent body from displacing */
        margin: 0;
        /* body should perfectly superimpose the html */
        height: 100%;
        width: 100%;
    }

    .outer-div {
        display: flex;
        flex-flow: column;
        height: 100%;
        /* Now create left/right margins */
        margin: 0 0.5em;
    }

    .inner-fixed-div {
        margin-top: 0.5em;
    }

    .inner-remaining-div {
        margin-bottom: 1em;
        flex-grow: 1;
        /* hints the contents to not overflow */
        overflow: hidden;
    }

    .picture-div {
        /* force the div to fill the available space */
        width: 100%;
        height: 100%;
    }

    .picture-div-img {
        /* force the image to stay true to its proportions */
        width: 100%;
        height: 100%;
        /* and force it to behave like needed */
        object-fit: scale-down;
        object-position: center;
    }
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body onload="showSlides();">
  <div class="outer-div">
    <div class="inner-fixed-div">
      <h1>Lorem Ipsum</h1>
    </div>
    <div class="inner-remaining-div">
      <!-- This div will hold the <img> -->
      <div id="slide-div" class="picture-div">
      </div>
    </div> <!-- end of inner-remaining-div -->
  </div> <!-- end of outer-div -->
</body>
</html>

Getting wrong offsetWidth

Title: Breadcrumbs offsetWidth gives wrong value in JavaScript

I’m trying to collapse a breadcrumbs list when its size is larger than the container it is in. However, when I use offsetWidth to get the size of the .breadcrumbs class, it consistently returns a value smaller than expected. Here’s a simplified version of my code:

setTimeout(() => {
  var breadcrumbSize = document.querySelector(".breadcrumbs").offsetWidth;
  var componentSize = document.querySelector(".components").offsetWidth;
  
  if (breadcrumbSize > componentSize) {
    console.log("It is working!");
    showHideItems(false); // Collapse items
  } else {
    showHideItems(true); // Show all items
  }
}, 3000);

function showHideItems(display) {
  const li = document.querySelectorAll(".breadcrumbs .ellipsis ~ li");
  li.forEach(item => {
    item.setAttribute("aria-hidden", display ? "false" : "true");
  });
}
<ul class="breadcrumbs" style="display: flex; width: fit-content;">
  <li>Home</li>
  <li class="ellipsis">...</li>
  <li>About</li>
  <li>Contact</li>
</ul>

<div class="components">
  <!-- Other content -->
</div>

The problem is that breadcrumbSize returns a value smaller than the actual width of the .breadcrumbs. As a result, the breadcrumbs don’t collapse when they should. I’ve added a delay with setTimeout but still face the issue.