Applying currency change from currency dropdown menu to the rest of my budgeting app

I am working on a JS project for an online course where I am creating a budgeting app

I have the following components as part of my app

  1. Budget
  2. Remaining
  3. Spent so far
  4. Allocated Budget
  5. Change Allocation

I was tasked with creating a 6th component for the app “CurrencyDropdown” to house the different currency options to choose from. I have done this.

// CurrencyDropdown.js


import React, { useState } from 'react';
 
const CurrencyDropdown = () => {
const [selectedCurrency, setSelectedCurrency] = useState('$'); // Default currency

const handleCurrencyChange = (event) => {
setSelectedCurrency(event.target.value);
};
return (
<div className='alert alert-primary'>
<label htmlFor="currency">Currency:</label>
<select id="currency" value={selectedCurrency} onChange={handleCurrencyChange}>
<option value="$">$ Dollar</option>
<option value="£">£ Pound</option>
<option value="€">€ Euro</option>
<option value="₹">₹ Rupee</option> 
{/* Add more currency options as needed */}
</select>
</div>
);
};
export default CurrencyDropdown;

The next task is to add code to the project so that when you change the currency from the CurrencyDropdown, the currency displayed on all the other components across the app change to match the selected currency. That is where I got stuck.

I tried to create a new JS component CurrencyContext:

// CurrencyContext.js

import React, { createContext, useContext, useState } from 'react';

const CurrencyContext = createContext();

export const CurrencyProvider = ({ children }) => {
const [selectedCurrency, setSelectedCurrency] = useState('USD');

const changeCurrency = (currency) => {
setSelectedCurrency(currency);
};

return (
<CurrencyContext.Provider value={{ selectedCurrency, changeCurrency }}>
      {children}
</CurrencyContext.Provider>
);
};

export const useCurrency = () => {
return useContext(CurrencyContext);
};

I do not know how or where to apply this component to effect the change to the rest of my app.

How to add global variable if not defined

To avoid rewriting a lot of d3 code in a project, I’m trying to use an older version of d3 (3.5.5). I get this error in the console, which I assume has to do with javascript module system changing over the years. Is there a way to still use an older version of d3 by defining global somewhere in a react project?

index.js:4  Uncaught ReferenceError: global is not defined
    at node_modules/d3/index.js (index.js:4:13)
    at __require (chunk-LNEMQRCO.js?v=b28db8c8:9:50)
    at index.js:9:65

This is what it says it node_modules/d3/index.js (index.js:4:13)

var globals = {};

// Stash old global.
if ("d3" in global) globals.d3 = global.d3;

module.exports = require("./d3");

// Restore old global.
if ("d3" in globals) global.d3 = globals.d3; else delete global.d3;

Web Worker Initialisation Crash without Error

When I create a faulty web worker, it immediately terminates. However, the browser console does not show any error messages, which is strange.

This seems to be reproducible both in Firefox and Chrome.

let code = `
import { crash } from "./nowhere.js"; 
console.log("hi"); // Never gets executed
`;

let alternateCode = `
console.log("hi");
throw new Error("normal errors do show up in the browser console");
`;

let blob = new Blob([code]);

let blobURL = window.URL.createObjectURL(blob);
let worker = new Worker(blobURL);
worker.onmessage = (data) => {
    console.log(data);
};
worker.postMessage("start");

// And check out the browser console

How do we fix the no-unsafe-optional-chaining eslint error

The below line keeps giving me the eslint error

router ? (Object.entries(router.query).length !== 0 ? router.query : state?.query) : {}

I tried

router ? (Object.entries(router.query).length !== 0 ? router.query : (state?.query && state.query)) : {}

I also tried

router ? (Object.entries(router.query).length !== 0 ? router.query : (state !== 'undefined && state.query)) : {}

None of the above seem to fix it

Why doesn’t manual “reset” event bubble to a form tag?

Why does the following not trigger the alert?

document.addEventListener('reset', function(event) {
  alert('Reset clicked!');
});
  
document.querySelector('button').addEventListener('click', () => {
  document.querySelector('span').dispatchEvent(new Event('reset', { bubbles: true }));
});
<form>
  <span>
    <button>Reset</button>
  </span>
</form>

However, if I change the form tag to a div, it works as expected:

document.addEventListener('reset', function(event) {
  alert('Reset clicked!');
});
  
document.querySelector('button').addEventListener('click', () => {
  document.querySelector('span').dispatchEvent(new Event('reset', { bubbles: true }));
});
<div>
  <span>
    <button>Reset</button>
  </span>
</div>

I’ve also tried changing the event name to something other than “reset” and again it works as expected.

Background images for sveltekit routes don’t fill the whole background on routing. When I reload the pages it works perfect

I have a sveltekit application with different routes. Each route has a custom background image. My problem is, that while routing in the Navbar between the subpages the right background picture is displayed, but it doesn’t fill the whole background of the body. There is a small padding where the background picture of the first loaded page is visible. When I reload the subpage, the padding is gone and everything works perfectly fine, until I navigate to another sub page. I think it has something to do with, which body is loaded first and there is a problem with “overwriting” the loaded body background image. Shouldn’t it be standard to have different background images for routes? Does anyone know the problem and could help me out?

Below is an example how. I set my background image in my routes. Each Route looks linke this.

My Routes:

<script>

    (...My Script)

</script>


<body>

   (...My Route Content...)

</body>


<style>

    body{
        background-image: url('my/path/to/image');
        background-size: cover; 
        background-repeat:repeat-y;
    }

    (...More Styles...)

</style>

Polygons not animating CSS & JS(GSAP)

I want to create a entry transition to my website but the polygons are not rendering like they should. The polygons animate on entry from right to left like window bind. It was working before with 10 Masks but I thought 20 would look better.

I tried adding ‘%’ to 0s but no luck

The polygon values sometimes change style sometime not
Like this

Codepen

Image 1
Image 2

Here is the Code

<a href="" id="project-link" draggable="false">
        <div class="hero-img">
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
            <div class="mask"></div>
        </div>
    </a>

CSS

.hero-img{
    position: absolute;
    right: 3.9464882943144%;
    top: 37.68538874%;
    width: 51vw;
    height: 28.95vh;
}

.mask{
    position: absolute;
    width: 51vw;
    height: 28.95vh;
    background: url(assets/images/image.avif);
    background-size: cover;
}

.mask:nth-child(1){
    clip-path: polygon(0% 0%, 5% 0%, 5% 100%, 0% 100%);
}

.mask:nth-child(2) {
    clip-path: polygon(5% 0, 10% 0, 10% 100%, 5% 100%);
}

.mask:nth-child(3) {
    clip-path: polygon(10% 0, 15% 0, 15% 100%, 10% 100%);
}

.mask:nth-child(4) {
    clip-path: polygon(15% 0, 20% 0, 20% 100%, 15% 100%);
}
    
.mask:nth-child(5) {
    clip-path: polygon(20% 0, 25% 0, 25% 100%, 20% 100%);
}

.mask:nth-child(6) {
    clip-path: polygon(25% 0, 30% 0, 30% 100%, 25% 100%);
}
    
.mask:nth-child(7) {
    clip-path: polygon(30% 0, 35% 0, 35% 100%, 30% 100%);
}

.mask:nth-child(8) {
    clip-path: polygon(35% 0, 40% 0, 40% 100%, 35% 100%);
}

.mask:nth-child(9) {
    clip-path: polygon(40% 0, 45% 0, 45% 100%, 40% 100%);
}

.mask:nth-child(10) {
    clip-path: polygon(45% 0, 50% 0, 50% 100%, 45% 100%);
}

.mask:nth-child(11) {
    clip-path: polygon(50% 0, 55% 0, 55% 100%, 50% 100%);
}

.mask:nth-child(12) {
    clip-path: polygon(55% 0, 60% 0, 60% 100%, 55% 100%);
}

.mask:nth-child(13) {
    clip-path: polygon(60% 0, 65% 0, 65% 100%, 60% 100%);
}

.mask:nth-child(14) {
    clip-path: polygon(65% 0, 70% 0, 70% 100%, 65% 100%);
}

.mask:nth-child(15) {
    clip-path: polygon(70% 0, 75% 0, 75% 100%, 70% 100%);
}

.mask:nth-child(16) {
    clip-path: polygon(75% 0, 80% 0, 80% 100%, 75% 100%);
}

.mask:nth-child(17) {
    clip-path: polygon(80% 0, 85% 0, 85% 100%, 80% 100%);
}

.mask:nth-child(18) {
    clip-path: polygon(85% 0, 90% 0, 90% 100%, 85% 100%);
}

.mask:nth-child(19) {
    clip-path: polygon(90% 0%, 95% 0%, 95% 100%, 90% 100%);
}

.mask:nth-child(20) {
    clip-path: polygon(95% 0, 100% 0, 100% 100%, 95% 100%);
}

JavaScript

    const counter = document.querySelector(".counter");
    const loader = document.querySelector(".loader");
    const elementsToAnimate = document.querySelectorAll(
      "p:not(.intro), .logo h1"
    );
    const introTag  = document.querySelector(".intro");
    let animationIntialized = false;
  
    function shuffleText(finalText, duration, callback){
      let i = 0;
      const shuffleInterval = setInterval(() => {
        if(i < duration){
          counter.innerHTML = Math.random().toString(36).substring(2,8);
          i++;
        }
        else{
          clearInterval(shuffleInterval);
          counter.innerHTML = finalText;
          if(callback) callback();
        }
      }, 100)
    }
  
  
  function removeLetters(){
    let text = counter.innerHTML;
    const removeInterval = setInterval(()=>{
      if(text.length > 0){
        text = text.substring(0, text.length - 1);
        counter.innerHTML = text;
      }
      else{
        clearInterval(removeInterval);
        
        if(!animationIntialized){
          animateElements();
          animateIntroTag();
        }
        fadeOutLoader();
      }
    }, 100);
  }
  
  function animateElements(){
    if(animationIntialized) return;
    animationIntialized = true;
  
    elementsToAnimate.forEach((element) =>{
      let originalText = element.textContent;
      let index = 0;
  
      const shuffleElement = setInterval(() => {
        if (index < originalText.length){
          let shuffledText = "";
          for(let i = 0; i<=index; i++){
            shuffledText +=
            i < index ? originalText[i] : Math.random().toString(36)[2];
          }
          element.textContent = 
            shuffledText + originalText.substring(index + 1);
          index++;
        }
        else{
          clearInterval(shuffleElement);
          element.textContent = originalText;
        }
      }, 100);
    } );
  }
  
  function animateIntroTag(){
    let originalText = introTag.textContent;
    let currentText = "";
    let index = 0;
  
    const revealText = setInterval(()=> {
      if(index < originalText.length){
        currentText += originalText[index];
        introTag.textContent = currentText;
        index++;
      }
      else {
        clearInterval(revealText);
      }
    }, 25);
  }
  
  function animateMasks() {
    const masks = document.querySelectorAll(".hero-img .mask");
    const clipPathValues = [
        "clip-path: polygon(0% 0%, 5% 0%, 5% 100%, 0% 100%)",
        "clip-path: polygon(5% 0%, 10% 0%, 10% 100%, 5% 100%)",
        "clip-path: polygon(10% 0%, 15% 0%, 15% 100%, 10% 100%)",
        "clip-path: polygon(15% 0%, 20% 0%, 20% 100%, 15% 100%)",
        "clip-path: polygon(20% 0%, 25% 0%, 25% 100%, 20% 100%)",
        "clip-path: polygon(25% 0%, 30% 0%, 30% 100%, 25% 100%)",
        "clip-path: polygon(30% 0%, 35% 0%, 35% 100%, 30% 100%)",
        "clip-path: polygon(35% 0%, 40% 0%, 40% 100%, 35% 100%)",
        "clip-path: polygon(40% 0%, 45% 0%, 45% 100%, 40% 100%)",
        "clip-path: polygon(45% 0%, 50% 0%, 50% 100%, 45% 100%)",
        "clip-path: polygon(50% 0%, 55% 0%, 55% 100%, 50% 100%)",
        "clip-path: polygon(55% 0%, 60% 0%, 60% 100%, 55% 100%)",
        "clip-path: polygon(60% 0%, 65% 0%, 65% 100%, 60% 100%)",
        "clip-path: polygon(65% 0%, 70% 0%, 70% 100%, 65% 100%)",
        "clip-path: polygon(70% 0%, 75% 0%, 75% 100%, 70% 100%)",
        "clip-path: polygon(75% 0%, 80% 0%, 80% 100%, 75% 100%)",
        "clip-path: polygon(80% 0%, 85% 0%, 85% 100%, 80% 100%)",
        "clip-path: polygon(85% 0%, 90% 0%, 90% 100%, 85% 100%)",
        "clip-path: polygon(90% 0%, 95% 0%, 95% 100%, 90% 100%)",
        "clip-path: polygon(95% 0%, 100% 0%, 100% 100%, 95% 100%)",    
    ];
  
    setTimeout(()=> {
      masks.forEach((mask,index) => {
        gsap.to(mask, {
          clipPath: clipPathValues[index % clipPathValues.length],
          duration: 1,
          delay: index * 0.1,
        });
      });
    });
  }
  
  gsap.to(counter, {
    innerHTML: 100 +"%",
    duration: 2.5,
    snap: "innerHTML",
    ease: "none",
    onComplete: () => {
      setTimeout(
        () =>
          shuffleText("ISAN/24", 5, () =>{
            setTimeout(removeLetters, 800);
          }),
          800
      );
    },
  });
  
  function fadeOutLoader () {
    gsap.to(loader, {
      opacity: 0,
      pointerEvents: "none",
      duration: 1,
      onComplete: () => {
        animateMasks();
      },
    });
  }
  });

How can the text be displayed in the toastr alert library based on a text found in a paragraph tag with a specific id?

I use the toastr alert library to display notifications. The library works in principle, but there are some errors associated with its functionality, which are as follows:

First: The alert properties do not work, such as the progress bar, close button, alert position, etc.

Second: The text displayed in the alert should be retrieved from the paragraph tag in the HTML code with the id “toastr text”.

Please correct my code with the appropriate suggestions.

const translations = {

              en: {

                home: "Home",

                about: "About",

                contact: "Contact us",

                selectLanguage: "Select a language",

                english: "English",

                arabic: "Arabic",

              },

              ar: {

                home: "الصفحة الرئيسية",

                about: "من نحن",

                contact: "تواصل معنا",

                selectLanguage: "إختر لغة",

                english: "الانجليزية",

                arabic: "العربية",

              },

            };

     

            const languageSelector = document.querySelector("select");

            languageSelector.addEventListener("change", (event) => {

              setLanguage(event.target.value);

            });

           

            const setLanguage = (language) => {

              const elements = document.querySelectorAll("[data-i18n]");

              elements.forEach((element) => {

                const translationKey = element.getAttribute("data-i18n");

                element.textContent = translations[language][translationKey];

              });

              document.dir = language === "ar" ? "rtl" : "ltr";

            };

            toastr.success('')// display the Toastr text here 

          toastr.options = {

            "closeButton": true,

            "debug": false,

            "newestOnTop": false,

            "progressBar": true,

            "positionClass": "toast-top-center",

            "preventDuplicates": false,

            "onclick": null,

            "showDuration": "300",

            "hideDuration": "1000",

            "timeOut": "5000",

            "extendedTimeOut": "1000",

            "showEasing": "swing",

            "hideEasing": "linear",

            "showMethod": "fadeIn",

            "hideMethod": "fadeOut"

          }
<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link

      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"

      rel="stylesheet"/>

      <link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.1/css/toastr.css" rel="stylesheet"/>

      <title>Multi Language Translation</title>

  </head>

  <body>

    <div class="container">

      <nav class="navbar navbar-expand-lg navbar-light justify-content-center">

        <div>

          <ul class="navbar-nav">

            <li class="nav-item">

              <a class="nav-link" lang="en" data-i18n="home">Home</a>

            </li>

            <li class="nav-item">

              <a class="nav-link" data-i18n="about">About</a>

            </li>

            <li class="nav-item">

              <a class="nav-link" data-i18n="contact">Contact us</a>

            </li>

          </ul>

        </div>

      </nav>

      <h3 class="text-primary" data-i18n="selectLanguage">Select a language</h3>

      <select class="p-1 mt-2">

        <option value="en" data-i18n="english" selected>English</option>

        <option value="ar" data-i18n="arabic">Arabic</option>

      </select>

      <p id="Toastr text">toastr text</p>

    </div>

    <script src="https://code.jquery.com/jquery-3.7.1.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>

    </body>

</html>

Axios Error – HPE_INVALID_CONSTANT error “Error: Parse Error: Expected HTTP/”

curl -v –location ‘http://api.mast.com/webservice/fourthparty/content/apple/fallback?content_id=236&product=EEF’ –header ‘PRODUCT: EEF’ | hexdump -C

Trying to make the same call using POSTMAN and Axios(JS code), they are not able to parse the response when https is used in URL

Error : HPE_INVALID_CONSTANT error "Error: Parse Error: Expected HTTP/"

204 returned by a server
, curl works fine on terminal

hexdump of the response is 0 bytes in both the cases.

Response of the HTTP call on Terminal

< HTTP/1.1 204 No Content
< Cache-Control: max-age=0
< Content-Type: application/json
< Date: Fri, 05 Jan 2024 14:20:52 GMT
< Server: nginx/1.10.3
< Via: 1.1 google
< X-Cache: BYPASS
< x-edgecast-rewrite: /80E/api.mast.com/webservice/fourthparty/content/apple/fallback
< x-edgecast-rules: 0.57K11-v14
< X-Powered-By: PHP/5.4.45
< 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Connection #0 to host api.mast.com left intact

Response of HTTPS call on Terminal

< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
< cache-control: max-age=0
< content-type: application/json
< date: Fri, 05 Jan 2024 14:20:43 GMT
< server: nginx/1.10.3
< via: 1.1 google
< x-cache: BYPASS
< x-edgecast-rewrite: /80E/api.mast.com/webservice/fourthparty/content/apple/fallback
< x-edgecast-rules: 0.57K11-v14
< x-powered-by: PHP/5.4.45
< 
{ [0 bytes data]
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Connection #0 to host api.mast.com left intact

Is the parsing issue due to a different version of HTTP protocol or encoding with HTTPS or some header causing the issue or something else ?

JavaScript arrays processing

I have a countries array and a provider array which has duplictae providers concatinated by contries.
Countries array = [‘CL’,’BR’,’CO’,’MX’,’US’]

providers array [‘MERCADOLIBRE_CL’,’MERCADOLIBRE_BR’,’MERCADOLIBRE_CO’,”MERCADOLIBRE_MX’,’VERIZON’,’VERIZON’]

what i am looking for is finding a array which doses not have duplicate providers if countries existed in the system

final array needed
[‘MERCADOLIBRE’,’VERIZON’,’DGMI_UK]

expecting [‘MERCADOLIBRE’,’VERIZON’,’DGMI_UK]

Flow of Control between Handlers in Promises

I want to know why the following 2 codes are giving different outputs.

Code 1:

const motherPromise = new Promise((resolve, reject) => {
  reject(new Error("Milk has spilled due to overboiling"));
});

motherPromise.catch((rejectValue) => console.log("Hello"));

Output of Code 1:

Hello

Code 2:

const motherPromise = new Promise((resolve, reject) => {
  reject(new Error("Milk has spilled due to overboiling"));
});

motherPromise.then((resolveValue) =>
  console.log(`${resolveValue} and Stove was shut`)
);
motherPromise.catch((rejectValue) => console.log("Hello"));

Output of Code 2:

Hello
Uncaught (in promise) Error: Milk has spilled due to overboiling
    at app.js:2:10
    at new Promise (<anonymous>)
    at app.js:1:23

What is the flow of control in both the codes and why is an extra Error being generated in the console for the second code?

Convert an ECDSA signature in P1363 format to ASN.1 and vice versa in Javascript

I’d like to be able to verify ECDSA signatures across the browser and OpenSSL. While I believed this should be trivial, it turns out both applications use different signature standards; OpenSSL requires signatures to be in ASN.1, while subtle crypto in the browser generates signatures that adher to IEEE P1363.

I have found many questions and discussions on SO regarding this topic, but no good solution so far. They either use various libraries to do the job, or were regarding languages that I can’t use in the browser. So I attempted to write my own implementation in vanilla JS.

There are a few special cases that needed to be handled, such as signatures with large curves, eg. P-521, or calculating the correct length of various components.

I have put together two functions which I believe work well, but I have not tested them thoroughly. They take and return an ArrayBuffer, which I think makes sense for interaction with subtle crypto. Can somebody who knows Javascript and ECDSA tell me if this will work correctly for all cases and signature lengths? (and maybe also if this can be written in a more efficient way)

function p1363_to_asn1 (p1363) {
    const input = new Uint8Array(p1363);

    let asn1; // ASN.1 contents.
    let len = 0; // Length of ASN.1 contents.
    const componentLength = Math.floor(input.byteLength / 2); // Length of each P1363 component.

    // Separate P1363 signature into its two equally sized components.
    const chunks = [];
    chunks.push([...input.slice(0, componentLength)]);
    chunks.push([...input.slice(componentLength)]);

    const prefix = parseInt('02', 16); // 0x02 prefix before each component.

    for (let i=0; i<chunks.length; i++) {
        // remove leading 0x00 bytes in R and S!
        // https://stackoverflow.com/questions/59904522/asn1-encoding-routines-errors-when-verifying-ecdsa-signature-type-with-openssl#comment105937557_59905274
        while (chunks[i][0] === 0) {
            chunks[i].shift();
        }

        // Add 0x00 because first byte of component > 0x7f.
        // Length of component = (componentLength + 1).
        if (chunks[i][0] > parseInt('7f', 16)) {
            chunks[i].unshift(parseInt('00', 16));
        }
    }

    len = 4 + chunks[0].length + chunks[1].length;
    // 4 is the combined length of 2 prefixes and 2 lengths (?)

    let finalLength;
    if (len > parseInt('7f', 16)) {
        // handle large lengths, like P-521
        // https://security.stackexchange.com/a/164906
        finalLength = [parseInt('81', 16), len];
    } else {
        finalLength = [len];
    }

    asn1 = [
        parseInt('30', 16),
        ...finalLength,

        prefix,
        chunks[0].length,
        ...chunks[0],

        prefix,
        chunks[1].length,
        ...chunks[1]
    ];

    return new Uint8Array(asn1).buffer;
}

function asn1_to_p1363 (asn1) {
    // https://stackoverflow.com/a/48727351/3625228
    const input = new Uint8Array(asn1);
    const inputArray = Array.from(input);

    inputArray.shift(1); // remove 0x30 sequence

    let totalLength = inputArray.shift(1);
    if (totalLength == parseInt('81', 16)) {
        // handle large length curves
        totalLength += inputArray.shift(1);
    }

    inputArray.shift(1); // remove 0x02 prefix
    const c1Len = inputArray.shift(1);
    const c1 = inputArray.splice(0, c1Len);

    inputArray.shift(1); // remove 0x02 prefix
    const c2Len = inputArray.shift(1);
    const c2 = inputArray;

    // remove leading 0x00 bytes (??)
    while (c1[0] === 0) {
        c1.shift();
    }
    while (c2[0] === 0) {
        c2.shift();
    }

    return new Uint8Array([...c1, ...c2]).buffer;
}

I have also put up an example on Github, where you can convert between the formats entirely on the client.

(Firebase,js) Problem with creating document that have userID as documentID

So i’m working on registration system using firebase authentication and this is what i want to achieve is:

  1. user registers with name,surname,email and password(for that im using createUserWithEmailAndPassword())
  2. once user registered, system creates document in collection “users”, that documentID matches registered userID.
    3.That newly created document create fields: name and surname based on user input.

I’m currently stuck at the moment of creating document and i don’t know how to make it work properly.

Finally i ended up with this:

signupForm.addEventListener("submit",(e)=>{
  e.preventDefault();
  const name = signupForm.name.value;
  const surname = signupForm.surname.value;
  const email = signupForm.email.value;
  const password = signupForm.password.value;
  
  createUserWithEmailAndPassword(auth, email, password)
    .then(cred => {
      signupForm.reset();
      userId = cred.user.uid;
      
    })
    .catch(err => {
      console.log(err.message);
    });
  
  setUserData(userId,name,surname);
});

function setUserData(userId,name,surname){
  const userRef = doc(db,"users",userId);
  setDoc(userRef,{
    name: name,
    surname: surname
  }).then(() => {
    console.log("Document successfully written!");
  })
  .catch((error) => {
    console.error("Error writing document: ", error);
  });
}

it throws: Uncaught FirebaseError: Invalid document reference. Document references must have an even number of segments, but users has 1.

I tried many solutions from stackoverflow and even chatGPT, nothing works. How can i fix this?

Convert 3D view into 2D

Question:

Hi there, I am trying to build a kitchen planner | room planner. I am working on three.js library and I am trying to replicate this project IKEA Room Planner for experience. The issue is that I don’t know what to use and where. Like in what framework, library or language should the 2D part be made and how to convert it into three.js.

Expectation:

To be clear I don’t want a whole code just an idea or a way of performing the action.

[EDIT] 2D to 3D will also work!

My PDF text field after encryption become not visible in Chrome and Adobe Reader and visible in Mozilla and X-Change Editor

I created a valid pdf with a single blank page and an existing text field, everything is fine:

enter image description here
I can edit the pdf and save it, everything is fine. I tested the pdf with tools for validation, the pdf is valid.
But when I encrypt it, with those permissions:

const securityOptions = {
   ownerPassword: "azer",
   permissions: {
     printing: 'highResolution', //'lowResolution',
     modifying: true,
     copying: true,
     annotating: true,
     fillingForms: true,
     contentAccessibility: true,
     documentAssembly: true
   }
 };

And save it, I have an issue with the text field when I open the pdf:
Text field invisible in:

  • Adobe Reader.
  • Chrome (and all chromium browser), when a do a ctrl+p the text field is visible in the print viewer.

Text field visible with its value in:

  • Mozilla
  • X-Change Editor

I tested the encrypted pdf with tools for validation, the pdf is valid.

This is the encrypted PDF, may be something wrong with the streams or Metadata encryption, I am not sure:

%PDF-1.7
%

1 0 obj
<<
/CreationDate (D:20240103094920-05'00')
/Creator (PDF-XChange Editor 9.3.361)
/ModDate (D:20240105100343Z)
/Producer (pdf-lib (https://github.com/Hopding/pdf-lib))
>>
endobj

2 0 obj
<<
/AcroForm 4 0 R
/Metadata 5 0 R
/Pages 6 0 R
/Type /Catalog
>>
endobj

4 0 obj
<<
/DR <<
/Font <<
/Helv 7 0 R
>>
>>
/Fields [ 8 0 R ]
>>
endobj

5 0 obj
<<
/Length 3008
/Subtype /XML
/Type /Metadata
>>
stream
Kbù9Kw–5×ik¢w)-®•ƉyZˆ³­‚Æ´Î:$zûô7H+x·’À"~˹Xí(t@¦‚eBÌ$îˆë´/øçS0¼~Å.#â™âu8²‡~ÚC)J¬vtä Ž
nôÎŽ¤‹yQlø°·c~£mÛµëè/Çhiì¹ÃgY#WWIZoþG-Þ÷qçz×ê ñ{N»ƒqB:§@Êì±{Õg§ºÅ½2+Fl*Í­ºu Yñ­Â    ÛÂsÎK‰qþÜ$+õЇ¼õF8w¼ïì™?'_åµ0«è‡~X[ý2¶Sî5Ð¥q££R¶G¯¤5 =
BäV:ÁÒŽ>¢«ð¢šw»^,ÂÑÑ¿(UëÕöds‰ŽI‚>Ì,.— dÕÖ!ž”P¹¦ÿkÊ
S´M÷nñqkx¡
WoÄ8ͨȷèQÂ=ýuÏÓyXûô¬#˜×g…¯O—Ž?#9&ãž«…ÍÇ÷ÞØ6)êS©
™¦:à7lYtãOuB˜êΧ‡Hש6]þÍ¢cd2üßúÏ™™-ý,ƈÛçxN·â´ÔŦl¯ h…‘ÕR®Ú6c Y§éYÉ j6bJxá‹^ùo¯d1š63©{‚6ê±uÈk-öã¯*žÆã2ªT7FcqÆÄhĬ;:]m]gŸåö–«q3™ø>ɆƒÛžB@X)?/N"…UJbcÜý²îÓéáRæ³JYè=FÖ;-“,óFeûº&§«Ÿ›ˆDÛ19Í VëقǛߋS_IäO‚xì¬ÆÍaËÇh‡yº{Wúe»'HÑX™ÅQà 7™ýàpû¬yM÷:æv‚¹_@`©†ú/;úî˜Fª}¢y`usxFȪ ø½ 2ä1þNĶø¦m…¡a
Ý×9nYî›° XÞ$òƒ“@¤ ðGK¯màqIà€éNŒÍíË4K¤”8Ã<AŽCµòÕá·ÆFBÓY4d‰™@Z%ä§ßÙ 6@‡"rüúô;~‚çYX™^2ReÞ¹·}úž&3×ebÆ pÿHÛp“‡°$눣ނì[!Pú»P   Ÿóu¦°‡³äL“8]´à؆q¼IÛ
­i¶ê,gÆ;bh.Y
 pÕN9s¥­ôl7lMbŒÒ8oŒçµð´…!ƒÖ^~A|²½e½õ´†ûE(Ø¢ÌÀÀË-SK…¾Òú"xE§;¡A¤=:ßLa‘³,x6=iuçªÔAŸ ¶n.XýZ‚]°€”ìé*ÔŽh¹T’%ìÛ¹î&D2Ïýh1£n»)‹úæƒDî ìòördÂWŸ@yb5¤gn6)ªbaÕHÎJdÝ>N~ù÷þ2Ç€ð¿å?U‚‡‹x•²g::ç3¬-_%> äÐhÒiÌk·v]rC §äe£Ÿpy“s÷ÍÇV÷…üXEw|yÃߟ=iÊú†¡)!eKë,x_uqrKrc8b‡X„)ÙÊ¢íL6A¬Bìê¼ä?%ÜÝÊ9±^HuuÞvI:•Ä‚6-FÃ#.{Ž|æ-¿6H4ŸOžëµý,Hl/5¹ƒ‡^é<³°PæJu
ºi³FPîØu›Ó"Iï>©Ç‹‚ŒÎ*ET´)Kåv+ŒVm? ûÈ9á3·‰Æä¨x(…Ò¦ñDWºZG¡œDÕFÒëG€»­`AÉù¸ù[ò'S"Jߘ§Úƒv‘ÿvÜÄBßE:¸1.VE‰µÞEL´`
)&k2éऋ]E.Ï‘JÄÊ‚½Õ•R­7·0‚:s°˜ü«qéõlϤñ#ËÛ{NЗUì¢&ëWêÏÓú>˜¨Á”ö`4ZŒ.¦£­½ôgÅ6ÃL3³«ZëÜ÷{Zß‘J{7ŠË«M49E¸uuòo6m¸ylä±s.3=¾‚lÂ`½wÖ~šàÌœV*ÆåàCãÚ™~ÏzËPwöNEX&G⻜BGUl¯ÆËT<vüNýC_ÔÍï^.æâ,H ±b€äxö{6þØYÑá¦àõ‡G&””6ɇóXw7TWš^¼<ÜÛÌhâ¥IL€icÌ¡RÎq^ÇpÕœì¼t­Ð÷¾S F“%Ü=ËOβù?¹kóŠYxßk)à
‚¢töZä6ú(cì¬Pb^ŠdÍGÅꬲ*ÌŠ£ÑBuÉ uApº?Ö*¤zf‚Æ+•2“Âó"ûdS;æ°ggÈÐí°{%ú¯GœÐ
±ÜÁ²õb'§ù7òÆœâN=N%¶¾ð>œºOÐï#oø}ăŽrîø6£…LŒœpƒ[ñY³9¸{öçêÚ_3MÑDþ%¸CwäUìw`jÀŽÒaR+}aæ¯@àÙµYÒ†4}4
B¾åëáí„G !tß,Úןωá!ÍF|ê]˜µyç¡ÛæÊ_0RY>s¾|ò°-”J>"ÆC9Ÿì°Æß‘;ö¬^Óu·xª  Ǧ‰Þ–Êár]ad5¬ëzþW@Û¼!+ìï´s6I
lÊI½3ˆM4ÌÞd'.Ê÷þp¡«"¤"
ÙÁj¦šÉj´€E…¯=_y¡lvÕE·!Éê›^é´|Ts„ ãý­&ç Šù#–J3µMÁèÓÌLódK…¾ü,÷QD©`úÊ?ä²[™£ñã…Óc   ²ÅË]•JögÜjZäà$øäÖpü‘{÷ê xt‘˜‰¿Ù÷ÁŠP¦tú«tËW+Òö&«<ã|ë
ÀØî†z­é:‘¢5³ì—³¤·èy*ÊÎML‚Õƒ&@ ®ñ5Ü6ç ôGlhC,°ýQ(H·ò16žz¶Ó_Ëê X)‰á棱i=‰M
eH˜5L
iGÏ. ž?zÐ ¼ä¾…cšô÷µÄù…ÀoOÎûô¯® Ù[ÇA
(MÆÈáö":çhË;°d¨ˆ3Hd}AÐ/££žaXxZÇ¿áóú²Å­5Ãl rŠ`æ?‰hº;Çä3QЫ1Œ/wNU¥™Àé’.K¸¥y
‘ób ŸÕùÅ<“ §èW4 0cIõAšÇoåJö5öƒø„±†YïŒ'¬<DÑ~äçmÕSî³"éžId°+©Âü8®ü„¾´î0£°Qw’Es§:?x!ûf†E0Óž¯¢^—(R=1ï¿^û#:
2kiBxô´ÖŠÜ]ˬ²9p<­É*¿iŒ)ï=ÜÈäùÀSã@“›@jŒu5÷i˜ñÇÂsÖ R<’±‡÷Õ…àØ£š%Ý#½¢Aq4?kxL!¨/Ãñ<eÄÚ¢šÜàÄ„D6!¤¢SúžH&¤êoÔ[,-Gj¿Œ]T—+že3s+‰ù
Õa8!0,¹G;Ýôø±§ší,Ù×$DÕöMõÎ$å3Z…g =?^áúò×Ñ   `¯WjÞw[²[—ÁÌê‡m‰[ÆÆiŸ
W"2åö3>Úö´vAžx
¿¡KÊÏD篴­j—߇«Î/LŸ­/ÝmwÎÙf*o±Éìf"^BØ®#úe =DÅR»Œ7éÜeë0Eb‰ŠAcí±»ømV–l(Ðó¯båaòyÐ"sUÂ$O5Î}.³ð©ŠÄ†6'±]ß ¿pRZG^ÍPâ‡&ä݇âixDÈ›ÁW”}ÃìÑ´…¦;Éaèfª>ÃR¨öMÿæ é¼=îþO_åØôèXÖ0ò/þd ÓM¸ÊÒ­ZÓ§tòS$dAó´L¤-Cû²:Í3^f$UÂl£ób<5óZ|X«YƒvË{HÎ    ¹(‘½Ÿ:q2˜VÝkÈ9ýsw¨  ÒdH8žÐÕç¦ñxÞffSK#’;¨«ÄõÐôÆ
endstream
endobj

6 0 obj
<<
/Count 1
/Kids [ 9 0 R ]
/Type /Pages
>>
endobj

7 0 obj
<<
/BaseFont /Helvetica
/Encoding 10 0 R
/Subtype /Type1
/Type /Font
>>
endobj

8 0 obj
<<
/AP <<
/N 11 0 R
>>
/DA (0 g /Helv 0 Tf)
/DV (I am a default value)
/F 4
/FT /Tx
/MK <<
/BC [ 0 0 0 ]
>>
/P 9 0 R
/Rect [ 32.076511 725.777222 182.076508 747.777222 ]
/Subtype /Widget
/T (Text1)
/Type /Annot
/V (Hello SE)
>>
endobj

9 0 obj
<<
/Annots [ 8 0 R ]
/MediaBox [ 0 0 612 792 ]
/Parent 6 0 R
/Resources <<
>>
/Type /Page
>>
endobj

10 0 obj
<<
/Differences [ 24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde 39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright /minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 160 /Euro 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot /.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine 188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ]
/Type /Encoding
>>
endobj

11 0 obj
<<
/BBox [ 0 0 150 22 ]
/Filter /FlateDecode
/Length 144
/Resources <<
/Font <<
/Helv 7 0 R
>>
>>
/Subtype /Form
/Type /XObject
>>
stream
q'I,][‚ŒÌÀtÙ·rR‹ÇåbVÀŠ  b^ÄQWÖÑÞvûSÌ=rÕ–ïç^ÐðsùV…ž¸ "E+—BªÑ#t©  [4cä¡pûðGÔŽ‹¨€£c5ÿØEx„RBïwUxªðäF>”'<¥œñkþžUU“Š4)
3ÐJÉO%Múÿ°Ü
endstream
endobj

12 0 obj
<<
/ModDate (D:20240105100345Z)
/Producer (pdf-lib (https://github.com/Hopding/pdf-lib))
/Creator (pdf-lib (https://github.com/Hopding/pdf-lib))
/CreationDate (D:20240105100345Z)
>>
endobj

13 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj

14 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica-Bold
/Encoding /WinAnsiEncoding
>>
endobj

15 0 obj
<<
/ModDate (D:20240105100345Z)
>>
endobj

16 0 obj
<<
/Filter /Standard
/V 4
/Length 128
/CF <<
/StdCF <<
/AuthEvent /DocOpen
/CFM /AESV2
/Length 16
>>
>>
/StmF /StdCF
/StrF /StdCF
/R 4
/O <8a93ac1e4c390a3351364adb88835ac7c283cf5a348242ece01d07acf8ba4ec6>
/U <075a3fa40c89c5f57fba188347dd8a8f00000000000000000000000000000000>
/P -4
>>
endobj

xref
0 3
0000000000 65535 f 
0000000016 00000 n 
0000000202 00000 n 
4 13
0000000284 00000 n 
0000000358 00000 n 
0000003449 00000 n 
0000003509 00000 n 
0000003597 00000 n 
0000003841 00000 n 
0000003950 00000 n 
0000005278 00000 n 
0000005588 00000 n 
0000005787 00000 n 
0000005886 00000 n 
0000005990 00000 n 
0000006042 00000 n 

trailer
<<
/Size 17
/Root 2 0 R
/Encrypt 16 0 R
/Info 15 0 R
/ID [ <0e64bebcd34321987c69258cf231ea8c> <0e64bebcd34321987c69258cf231ea8c> ]
>>

startxref
6343
%%EOF

The not encrypted PDF:

%PDF-1.7
%âãÏÓ
2 0 obj
<<
/AcroForm 4 0 R
/Metadata 5 0 R
/Pages 6 0 R
/Type /Catalog
>>
endobj
5 0 obj
<<
/Length 2979
/Subtype /XML
/Type /Metadata
>>
stream
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:Description rdf:about=""
                xmlns:dc="http://purl.org/dc/elements/1.1/"
                xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
                xmlns:xmp="http://ns.adobe.com/xap/1.0/"
                xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
            <dc:format>application/pdf</dc:format>
            <xmpMM:DocumentID>uuid:f0bc7a01-dd93-4c4e-9bec-783a9464b1c0</xmpMM:DocumentID>
            <xmpMM:InstanceID>uuid:6b75ef77-09b1-43ed-8d0b-d5721e91bdea</xmpMM:InstanceID>
            <xmp:CreateDate>2024-01-03T09:49:20-05:00</xmp:CreateDate>
            <xmp:CreatorTool>PDF-XChange Editor 9.3.361</xmp:CreatorTool>
            <xmp:ModifyDate>2024-01-05T04:52:55-05:00</xmp:ModifyDate>
            <pdf:Producer>PDF-XChange Core API SDK (9.3.361)</pdf:Producer>
        </rdf:Description>
    </rdf:RDF>
</x:xmpmeta>
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                                                                                                    
                           
<?xpacket end="w"?>
endstream
endobj
11 0 obj
<<
/BBox [0 0 150 22]
/Filter /FlateDecode
/Length 122
/Resources <<
/Font <<
/Helv 7 0 R
>>
>>
/Subtype /Form
/Type /XObject
>>
stream
xÚÉ1
Â@@Ñ~NñKm63!qM›°˜&…fÀh$(¦0âée›Ïƒ¯(Ê週J¨    5V5”Æ21Já_Ú¡“·†U{JÍçÌSZåŽâ—œSÅÙKÑOó‹¡Áo”T!6q‡_eÓOóübL[Hr9J:ùÇ"š
endstream
endobj
3 0 obj
<<
/Filter /FlateDecode
/First 41
/Length 991
/N 7
/Type /ObjStm
>>
stream
xÚ]UÁnÛ8½ó+æVûÐŒ$Û²½(8¶ƒÝÔFât·›ö@‹#™Mº™÷ë”èHè‰âÌ{og()…„!Íg,‡,³)dyÎf0ÍØ&yÆÒòIÊ>}b¸´Ä4zÅÁ`õG–dã$MFÉ|<Ï’ÉäC’|Fœ±0Ø®n?þ½<p]¬…±ùÕèj”§C†÷Fü&4IÆ“l2é„¶Ö_ÐoJKc  Û;x}ƒ¨øc8d××ÏÕ„åÖh×<|&õ
SHà! ®¯ÞJR¢†çYþ¼ð–Æk)Ã/2$çmwçnyEõyÃkjämr²à׺0Bê
Ò¤©…~ïnPH/BwÑYlƒ_!M/öpµ€AU+
    ìÊ!ÃÕ7Ü?A%÷ÊÁ+Wž†oaÌðv¸{cxÿ¥¼YÂs0‘4gÃ-Ì[GT8xeWÉ4Ÿ¤)L³ÉÕt:ͲÒYMf0OcôgïIQ‘c¸ƒÁŽÞa{ …ÖÆ1üƒÏ¤”Çõû$šT×g¼'!ùykÝåiÓy(²å–´ƒüâ²6ÞT‡³ÿÝÞG,Ë’,é zÎÆ€{K¯Xpk4`!mᥢ7@a/Š ¯+nýQqï Me4½ Ú03tR ‚Ñð—7Žj©+E0Ï+Ë_ Òl¸÷J‘¼ªÈ²¸Š½$¥ä©–5 ¯€¤ÛµTÆJ
XZ^„×°òR5•®·µ²:8À£Ô¾<‘uãk®E4%öjÏkêv-ÿ²‹ôfÛËôÃM™ ÁÐY.èÈí`)ƒKÀ?kÕ8Þ¬c+¿I–šƒýCÂ8Eu-U$¬cö¿vMópí­43,¼
ã:CšçaZæ…ôžÛðéìJætŽ~%¥–š f€ÊT²àJx¥TZªdíÈ’ <ò¢õG•%<)_Ç^ºMíOd¥±€î`‰.[†¼ðŽ ÒÙ¨i»4"˜Vµ !•â€FS§a¬8òºðª±7›5é_ž[G¶y>pUÆR1C:Ï í}ÂE¬»è_ÖEs
.º–,Úû¹X.ß½¬£È:Ьû"ëŽ|qww×ÇÝu¸µ; ~mßÜDÒ¦!1ÜôI›¨#½rò¤Î€›xž¢ÂS,ûÔWxê˜ßc~w06¼d‹½ªy”àÂû<¶‰wR¼m÷6Q¡(B}êÈ2âdÄÉ>Nv8
mÒ±&’Ll“é“ÌÔ‘…|•M(6ÉG¾E}Ÿï;Þ9æ]Û¤ó%óþkºüxÂÇñ&”{(
endstream
endobj
12 0 obj
<<
/DecodeParms <<
/Columns 4
/Predictor 12
>>
/Filter /FlateDecode
/ID [<482C1B0356F27EAD2EB01BDF7B8A9DF9> <482C1B0356F27EAD2EB01BDF7B8A9DF9>]
/Info 1 0 R
/Length 56
/Root 2 0 R
/Size 13
/Type /XRef
/W [1 2 1]
>>
stream
xÚ]DZ
€0 Á÷GéÌrôQ&bF¤Kc”–æ¤(¥…E"ÇÄxïÝ«âO幤>O3    ã
endstream
endobj
startxref
4534
%%EOF

I don’t know what is missing in my encryption