isObject error in react-phone-number-input with all versions

I am getting below error for using react-phone-number-input. I tried different versions package and also different version of libphonenumber-js. But still getting same error every time. I want to know what is causing it.

Below is the error:

ERROR
isObject is not defined
ReferenceError: isObject is not defined
    at normalizeArguments (http://localhost:3001/static/js/bundle.js:206497:8)
    at parsePhoneNumber (http://localhost:3001/static/js/bundle.js:206993:95)
    at parsePhoneNumber (http://localhost:3001/static/js/bundle.js:286499:76)
    at new PhoneNumberInput_ (http://localhost:3001/static/js/bundle.js:285033:102)
    at constructClassInstance (http://localhost:3001/static/js/bundle.js:269211:13)
    at updateClassComponent (http://localhost:3001/static/js/bundle.js:273260:9)
    at beginWork (http://localhost:3001/static/js/bundle.js:274655:20)
    at HTMLUnknownElement.callCallback (http://localhost:3001/static/js/bundle.js:261677:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3001/static/js/bundle.js:261721:20)
    at invokeGuardedCallback (http://localhost:3001/static/js/bundle.js:261776:35)

and this is code snippet for the component:

import React from 'react';
import { Typography } from '@mui/material';
import PhoneInput from 'react-phone-number-input';
import 'react-phone-number-input/style.css'

const CustomPhoneInput = ({
  error,
  label,
  id,
  name,
  onChange,
  value,
  errorText,
  className,
  disabled,
  defaultCountry,
}) => {
  return (
    <>
      <div
        className={`input-phone-num-wrapper ${error ? 'has-error' : ''} ${className ? className : ''} ${
          disabled ? 'input-disabled' : ''
        }`}
      >
        <p>{label}</p>
        <PhoneInput
          initialValueFormat="national"
          countryCallingCodeEditable={false}
          defaultCountry={defaultCountry}
          placeholder="Enter phone number"
          value={value}
          onChange={(val) => {
            onChange(val);
          }}
          disabled={disabled}
        />
      </div>
      <Typography variant="caption" className={error ? 'error-text' : 'text-gray'}>
        {errorText}
      </Typography>
    </>
  );
};

export default CustomPhoneInput;



Current version : "react-phone-number-input": "^3.4.3"

Style a set of GeoJSON features with Google Maps JS API?

I am working on a map that will show about 90 different hiking trails in a specific area. I have GeoJSON for each trail, however each trail’s GeoJSON is broken up into multiple “features.”

I am finding it particulary difficult to target a specific trail rather than just one segment (or feature) of a trail. For example when I hover over a trail the hover is only detected on each individual feature.

What I want to have happen is that anywhere I hover on each trail I want the stroke color to change.

Is there a way to group a bunch of features together and target them together so I can change their stroke colors all at the same time?

The code below works but only on the specific feature that I hover on. I want the stroke color to change on all features of a trail.

map.data.addListener("mouseover", (event) => {
    map.data.revertStyle();
    map.data.overrideStyle(event.feature, { strokeWeight: 4 });
});

I want to create form items with right to left text using google apps script [duplicate]

I have a google spreadsheet with questions for a quiz and I want to extract the cells and create a google form from that spreadsheet, So I can then use it in google classroom. Gemini has written a nice code that uses google scripts, working on the spreadsheet:

function createQuizFromSheet() {
  // Get the active spreadsheet and the sheet containing the questions
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();

  // Get the data from the sheet (assuming header row)
  var data = sheet.getDataRange().getValues();

  // Get the header row to find column indices
  var headers = data[0];
  var typeIndex = headers.indexOf("Type"); // Added 'Type'
  var titleIndex = headers.indexOf("Title");
  var helpIndex = headers.indexOf("Help"); // Added 'Help'
  var requiredIndex = headers.indexOf("Required"); // Added 'Required'
  var optionsIndex = headers.indexOf("Options"); // Added 'Options'
  var correctIndex = headers.indexOf("Correct");
  var pointIndex = headers.indexOf("Point"); // Added 'Point'
  var feedbackIndex = headers.indexOf("Feedback"); // Added 'Feedback'
  var incorrectFeedbackIndex = headers.indexOf("IncorrectFeedback"); // Added 'IncorrectFeedback'

  // Check if all necessary headers are found
  if (titleIndex === -1 || correctIndex === -1) { //   الأساسية
    Logger.log("Missing required headers in the sheet.");
    return;
  }

  // Create a new Google Form (or use an existing one)
  var form = FormApp.create("Geometry Quiz"); // Create a new form.  To use an existing form, replace with FormApp.openById("FORM_ID");

  // Loop through the data and create questions
  for (var i = 1; i < data.length; i++) {
    var row = data[i];
    var type = row[typeIndex];
    var title = row[titleIndex];
    var options = row[optionsIndex] ? row[optionsIndex].split(',') : []; // Split options if they exist
    var correct = row[correctIndex];
    var help = row[helpIndex];

    // Create question based on type
    if (type === "MULTIPLE_CHOICE") {
      var item = form.addMultipleChoiceItem();
      item.setTitle(title)
          .setHelpText(help)
          .setRequired(row[requiredIndex] === "TRUE")
          .setChoices(options.map(function(option) {
            return item.createChoice(option.trim(), option.trim() === correct.trim()); // Trim options
          }));


    } else if (type === "TEXT") {
         var item = form.addTextItem();
         item.setTitle(title)
             .setHelpText(help)
             .setRequired(row[requiredIndex] === "TRUE");
    }
     // You can add more question types here (e.g., CHECKBOXES, DROPDOWN)

  }

  Logger.log("Quiz created: " + form.getEditUrl());
}

The code works just fine, but I am writing in Hebrew and I need that all the form items will be written from right to left. I could not find anywhere a method that does that (The bots have invented a setDirection method that does not exist)

Does anyone know how to program a google form to write its content from right to left?

Images stored on NodeJs server are not not displaying in ReactJs front-end

I am creating a website in node-js as back-end and react-js as front-end. Node js is running on server
http://localhost:4100/
and react is running on
http://localhost:5173/

My images are stored on node js server at folder http://localhost:4100/api/uploads/
How ever in front-end react images are not showing and giving the “blocked:NotSameOrigin” error. I have enabled he cors at node and when i run image url in browser it is showing but in the “img” tag in the react website it is not showing.

enter image description here

how to relize this block js php

как мне реализовать данный блок, в плане php и js
как мне реализовать данный блок, в плане php и js
только начинаю изчение js php и вообще без понятие как реализовать или как прогуглить реализацию данного блока.

  1. как сделать слайдер переключения панели (Редактирование услуг, добавление услуги, удаление услуг)
  2. как через php реализовать слева переключение между услугами, и их редактирование

Landtrendr on GEE spectral indices

I am working with Landtrendr Algorithm in GEE. I want to use the Pixel Time Series plotter for my own ImageCollection based on Landsat 4-9. When I am applying the Landtrendr using my own NDVI function, the result looks quite good. But when I am applying the exact same code but with the NDVI provided by the Landtrendr API, it doesn’t seems like that the Algotithm is identifying the right breaking points. I have no idea how to fix and change this, because I need to use the NDVI provided by the API, otherwise the getChangeMap wont work. I am very thankful for any advise or tips.

```
// LANDTRENDR LANDSAT TIME SERIES ANALYSIS
// Define coordinates for the Time Series Plot
var long = 55.40631284191384
var lat = -4.6561753011485605
var coordinates = ee.Geometry.Point(long, lat);

// Define AOI to download Landsat scenes for //
var my_aoi = geometry;
// add to map
Map.addLayer(my_aoi, {}, 'aoi');
// Zoom to aoi
Map.centerObject(my_aoi, 15);

// Define Time Range for your Time Series Analysis
var startYear = 1990    // what year do you want to start the time series, Note: no 
images before 1990
var endYear   = 2024;    // what year do you want to end the time series
var startDay  = '01-01'; // what is the beginning of date filter | month-day
var endDay    = '12-31'; // what is the end of date filter | month-day

// Defne LandtrendR parameters
var run_params = { 
maxSegments:            6,
spikeThreshold:         0.9,
vertexCountOvershoot:   3,
preventOneYearRecovery: true,
recoveryThreshold:      0.25,
pvalThreshold:          0.05,
bestModelProportion:    0.75,
minObservationsNeeded:  6
};
// define the sign of spectral delta for vegetation loss for the segmentation index - 
var distDir = -1; 

// define index for the Time Series Analysis //

// NDVI
var NDVI = function(img) {
    var index = img.normalizedDifference(['NIR', 'R'])                      // 
calculate normalized difference of band 4 and band 7 (B4-B7)/(B4+B7)
               .multiply(1000)                                          // ...scale 
results by 1000 so we can convert to int and retain some precision
               .select([0], ['NDVI'])                                    
               .set('system:time_start', 
img.get('system:time_start'));
    return index ;
};


//
///// ----------------------- \\
/// Prepare Landsat Collections \
///// ----------------------- \\

// Scaling factor is needed for Landsat
function applyScaleFactors(image) {
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);
  return image.addBands(opticalBands, null, true)
              .addBands(thermalBands, null, true);
}

//  functions to select and rename bands for Landsat-4/5/7
function renameBandsTM_ETM(image) {
    var bands = ['SR_B1', 'SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B7'];
    var new_bands = ['B', 'G', 'R', 'NIR', 'SWIR1', 'SWIR2'];
    return image.select(bands).rename(new_bands);
}

//  functions to select and rename bands for Landsat-8
function renameBandsOLI(image) {
    var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'];
    var new_bands = ['B', 'G', 'R', 'NIR', 'SWIR1', 'SWIR2'];
    return image.select(bands).rename(new_bands);
}

// Mask clouds, snow and cloud shadows based on the pixel_qa band
var cloudMask = function (image) {
  // Get the pixel QA band.
  var qa = image.select('QA_PIXEL');
  // Bits 3 and 5 are cloud shadow and cloud, respectively.
 // Use LeftShift-Operators to define Bit values
  var CloudShadowBitValue = (1 << 3);
  var CloudBitValue = (1 << 4);
  // Create masks
  var shadow_mask = qa.bitwiseAnd(CloudShadowBitValue).eq(0);
  var cloud_mask = qa.bitwiseAnd(CloudBitValue).eq(0);
  // Given bit values should be set to zero for masking.
  var final_mask = shadow_mask.and(cloud_mask);
  return image.updateMask(final_mask);
};

 // Function to get Landsat SR collection
// Function to get an SR collection for a given Landsat sensor
var getSRcollection = function(year, startDay, endDay, sensor, aoi) {
  var srCollection = ee.ImageCollection('LANDSAT/' + sensor + '/C02/T1_L2')
.filterBounds(aoi)
.filterDate(year + '-' + startDay, year + '-' + endDay)
.map(cloudMask) // Apply your cloud mask function
.map(applyScaleFactors) // Apply scale factors
.map(function(image) {
  // Apply appropriate renaming function
  var renamed = ee.Algorithms.If(
    sensor === 'LC08'|| sensor === 'LC09', 
    renameBandsOLI(image), // Landsat 8,9
    renameBandsTM_ETM(image)   // Landsat 4, 5, 7
  );
  return ee.Image(renamed).set('system:time_start', image.get('system:time_start'));
})
.map(function(image) { return image.clip(aoi); });

return srCollection;
};

// Function to merge collections from different Landsat sensors
var getCombinedSRcollection = function(year, startDay, endDay, aoi) {
var lt4 = getSRcollection(year, startDay, endDay, 'LT04', aoi);
var lt5 = getSRcollection(year, startDay, endDay, 'LT05', aoi);
var le7 = getSRcollection(year, startDay, endDay, 'LE07', aoi);
var lc8 = getSRcollection(year, startDay, endDay, 'LC08', aoi);
var lc9 = getSRcollection(year, startDay, endDay, 'LC09', aoi)
return ee.ImageCollection(lt4.merge(lt5).merge(le7).merge(lc8).merge(lc9));
};

//CREATE ANNUAL MOSAIC COLLECTION
// Function to create a Medoid Composite
var medoidMosaic = function(inCollection, dummyCollection) {
var imageCount = inCollection.toList(1).length();
var finalCollection = ee.ImageCollection(ee.Algorithms.If(imageCount.gt(0), 
inCollection, dummyCollection));

var median = finalCollection.median();
var difFromMedian = finalCollection.map(function(img) {
var diff = ee.Image(img).subtract(median).pow(ee.Image.constant(2));
return diff.reduce('sum').addBands(img);
});

return 
ee.ImageCollection(difFromMedian).reduce(ee.Reducer.min(7)).select([1,2,3,4,5,6], 
['B','G','R','NIR','SWIR1','SWIR2']);
};
// Function to build a yearly mosaic
var buildMosaic = function(year, startDay, endDay, aoi, dummyCollection) {                                                                      
// create a temp variable to hold the upcoming annual mosiac
var collection = getCombinedSRcollection(year, startDay, endDay, aoi);  // get the SR 
collection
var img = medoidMosaic(collection, dummyCollection)                     // apply the 
medoidMosaic function to reduce the collection to single image per year by medoid 
          .set('system:time_start', (new Date(year,8,1)).valueOf());  
return ee.Image(img);                                                   
};

// Function to build an annual mosaic collection
var buildMosaicCollection = function(startYear, endYear, startDay, endDay, aoi, 
dummyCollection) {
  var imgs = [];                                                                    
 for (var i = startYear; i <= endYear; i++) {                                      
   var tmp = buildMosaic(i, startDay, endDay, aoi, dummyCollection);               
   imgs = imgs.concat(tmp.set('system:time_start', (new Date(i,8,1)).valueOf()));
}
return ee.ImageCollection(imgs);                                                  
};
print(buildMosaicCollection, 'buildMosaicCollection')

// empty dummy collection
var dummyCollection = ee.ImageCollection([ee.Image([0,0,0,0,0,0]).mask(ee.Image(0))]); 
// make an image collection from an image with 6 bands all set to 0 and then make them 
masked values

// build annual image collection
var annualMosaicCollection = buildMosaicCollection(startYear, endYear, startDay, 
endDay, my_aoi, dummyCollection);
print(annualMosaicCollection, 'annualMosaicCollection')




// ----- FUNCTION TO GET LT DATA FOR A PIXEL -----
var getPoint = function(img, geom, z) {
  return img.reduceRegion({
   reducer: 'first',
   geometry: geom,
   scale: z
  }).getInfo();
};


// ----- FUNCTION TO CHART THE SOURCE AND FITTED TIME SERIES FOR A POINT -----
var chartPoint = function(lt, pt, distDir) {
  Map.centerObject(pt, 14);
  Map.addLayer(pt, {color: "FF0000"});
  var point = getPoint(lt, pt, 10);
  var data = [['x', 'y-original', 'y-fitted']];
  for (var i = 0; i <= (endYear-startYear); i++) {
    data = data.concat([[point.LandTrendr[0][i], point.LandTrendr[1][i]*distDir, 
point.LandTrendr[2][i]*distDir]]);
  }
  print(ui.Chart(data, 'LineChart',
            {
              'hAxis': 
                {
                  'format':'####'
                },
              'vAxis':
                {
                  'maxValue': 1000,
                 'minValue': -1000   
               }
           },
            {'columns': [0, 1, 2]}
          )
        );
};

//----- BUILD LT COLLECTION -----

var annualSRcollection = buildMosaicCollection(startYear, endYear, startDay, endDay, 
coordinates, dummyCollection); // put together the cloud-free medoid surface 
 reflectance annual time series collection
print(annualSRcollection, 'annualSRcollection')
// apply the function to calculate the segmentation index and adjust the values by the 
var ltCollection = annualSRcollection.map(NDVI)                                             
// map the function over every image in the collection - returns a 1-band annual image 
collection of the spectral index
                                          .map(function(img) {return 
img.multiply(distDir)           // ...multiply the segmentation index by the distDir to ensure that vegetation loss is associated with a positive spectral delta
                                          .set('system:time_start', 
img.get('system:time_start'))}); // ...set the output system:time_start metadata to the 
input image time_start otherwise it is null
print(ltCollection, 'ltCollection')
//----- RUN LANDTRENDR -----
run_params.timeSeries = ltCollection;              
var lt = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LandTrendr 
spectral temporal segmentation algorithm

//----- PLOT THE SOURCE AND FITTED TIME SERIES FOR THE GIVEN POINT -----
chartPoint(lt, coordinates, distDir); // plot the x-y time series for the given point

print(lt, 'lt');


And here is the version with the NDVI provided by the Landtrendr API, everything stays the same except that i am not usinf distDir and changed this part: 

var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); 
// Transform collection and include at least two indices/bands, otherwise shit wont 
work
var ltCollection_transformed = ltgee.transformSRcollection(annualSRcollection, 
['NDVI']);
print(ltCollection_transformed, 'ltCollection_transformed')

//----- RUN LANDTRENDR -----
run_params.timeSeries = ltCollection_transformed;              
var lt = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); //

//----- PLOT THE SOURCE AND FITTED TIME SERIES FOR THE GIVEN POINT -----
chartPoint(lt, coordinates); // plot the x-y time series for the given point

print(lt, 'lt');

Many thanks in advance!

Im trying to make my scrolling smooth but its jerky – React horizontal scroll carousel by dragging the mouse

I am making a horizontal scroll slider and it almost works except for some reason its jerky. I think it has something to do with re-enabling snap-x which causes it to jerk back. Ive tried not putting it on but scrolling with the mouse does nothing except jerk back when you fire the onmouseup event. It does work when actually using the scroll bar, which i have no idea how i can control scrolling by dragging the mouse to move the carousel (its like doing it on a touch device). The first direction bit is using 2 buttons to move it left or right, along with a formula for getting the first item in the centre. Dragging sets to true when pressing down, which sets the x position, and the scroll position. when you drag it, it will update every time the mouse moves and calculates the distance from the point of your mouse minus the starting position, which it then scrolls left by getting the start of the scroll and minusing the distance.

import {useEffect, useRef, useState, MouseEvent } from "react";
    import { Link } from "react-router-dom";
    
    export default function Basics() {
      //Todo: put this logic into its own useHook
      const scrollRef = useRef<HTMLDivElement>(null);
    
      const [currentSlide, setCurrentSlide] = useState(0);
    
    
      const scroll = (direction: string) => {
        if (scrollRef.current) {
          if (direction == "Left" && currentSlide > 0) {
            scrollRef.current.scrollBy({ left: -1000, behavior: "smooth" });
    
            setCurrentSlide((prev) => prev - 1);
          } else if (direction == "Right" && currentSlide <= 1) {
            setCurrentSlide((prev) => prev + 1);
    
            scrollRef.current.scrollBy({ left: 1000, behavior: "smooth" });
    
          }
        }
      };
      
      //Resizing
    
      const [windowWidth, setWindowWidth] = useState<number>(window.innerWidth);
      
      const handleResize = () => {
        setWindowWidth(window.innerWidth);
      };
      
      useEffect(() => {
        console.log(windowWidth);
        
        window.addEventListener("resize", handleResize);
    
    
        return () => {
          window.removeEventListener("resize", handleResize);
        };
      }, [windowWidth]);
    
      //Dragging
      
      const [startX, setStartX] = useState(0);
      const [isDragging, setIsDragging] = useState(false);
      const [scrollStart, setScrollStart] = useState(0);
    
      const handleDragStart = (e: MouseEvent) => {
        e.preventDefault();
        if (scrollRef.current) {
          setIsDragging(true);
          setStartX(e.pageX);
          setScrollStart(scrollRef.current.scrollLeft);
        }
      };
    
      const handleDragMove = (e: MouseEvent) => {
        if (!isDragging || !scrollRef.current) {
          return;
        }
        e.preventDefault();
    
        const distance = e.pageX - startX; 
        scrollRef.current.scrollLeft = scrollStart - distance; 
      };
    
      const handleDragEnd = () => {
    
        setIsDragging(false);
      };
    
      return (
        <>
          <div className="flex items-center relative">
            <div
              ref={scrollRef}
              onMouseDown={handleDragStart}
              onMouseMove={handleDragMove}
              onMouseUp={handleDragEnd}
              onMouseLeave={handleDragEnd}
              className={`relative flex gap-6 w-full ${isDragging ? '' : 'snap-x snap-center snap-mandatory'} overflow-x-auto h-calc justify-items-center items-center`}>
              <div
                className="shrink-0 snap-center relative"
                style={{
                  paddingLeft: `${windowWidth / 2 - 506}px`,
                }}>
                <Link
                  to="Introduction"
                  draggable={false}
                  className="bg-custom bg-cover w-250 h-150 flex items-center justify-center select-none">
                  Test
                </Link>
              </div>

YouTube subtitles download script returns empty .txt file and “no text nodes in XML” message

I’m working on a userscript that adds a download button to YouTube videos to export English subtitles as a .txt file. The idea is to fetch the subtitle track in XML format and extract the nodes.

However, although the request to the subtitles URL succeeds, the resulting XML doesn’t contain any elements, and the downloaded .txt file is empty. The console logs:
No nodes found in subtitles XML.

Here’s the relevant part of the code:

    async function exportSubtitlesToTxt() {
  const videoId = new URLSearchParams(window.location.search).get("v");
  const subtitleTrack = await getFirstEnglishTrack(videoId);
  if (!subtitleTrack) {
    alert("No subtitles found.");
    return;
  }

  const { lang_code, name, kind } = subtitleTrack;
  const encodedName = encodeURIComponent(name || '');
  const kindParam = kind ? `&kind=${kind}` : '';
  const subtitleUrl = `https://www.youtube.com/api/timedtext?lang=${lang_code}&v=${videoId}&name=${encodedName}${kindParam}`;

  const res = await fetch(subtitleUrl);
  const xml = await res.text();

  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(xml, "text/xml");
  const texts = Array.from(xmlDoc.getElementsByTagName("text"));

  if (texts.length === 0) {
    console.log("No <text> nodes found in subtitles XML.");
  }

  const subtitles = texts.map(node => decodeHTMLEntities(node.textContent));
  const fullText = subtitles.join("n");

  saveTextToFile(fullText, `subtitles-${videoId}.txt`);
}

Example video where this happens:
https://www.youtube.com/watch?v=dQw4w9WgXcQ

Any idea why the nodes might be missing even though the XML loads successfully? Could YouTube be doing something differently with subtitle tracks now?

GPT interprets date input incorrectly [closed]

im sending a Usermessage to gpt-3.5-turbo via Axios like:

const prompt = [
    {
      role: "system",
      content: 
      `
       Your task: ONLY use the information provided. Never 
       invent anything!
      `
    },
    {
      role: "user",
      content: `Here is the information to be used:

      ${JSON.stringify(data)}

      Now please answer this question based on the information above:

      "${userMessage}"
      `
    }
      ];

    try {
        const gpt = await axios.post(
          "https://api.openai.com/v1/chat/completions",
          {
            model: "gpt-3.5-turbo",
            messages: prompt,
            temperature: 0.2,
            max_tokens: 700
          },
          {
            headers: {
              Authorization: `Bearer ${openaiKey}`,
              "Content-Type": "application/json"
            }
          }
        );

my data looks like:

{
  "events": [
    {
      "date": "Monday, 07.04.2025",
      "title": "Event1",
      "body": "xxx2"
    },
    ...
}

If i send this for example this prompt:

Which event is on 07.04?

or

Which event is on 7. April?

often i get a completely different Event with a completely different Date?

Why does AI confuse such simple data sets?

How to implement a location-based game flow in React: OpenStreetMap map click to native route + in-app QR code validation?

I’m developing an educational web application for kids using React and JavaScript. The goal is to teach them about decision trees through a game format focused on environmental projects in my city (Oldenburg, Germany).

The core gameplay loop involves these steps:

Question & Location: The user answers a question related to an environmental topic.
Map Display: Based on the answer, a new geographic location is determined and displayed as a marker on an OpenStreetMap (OSM) map embedded in the web app (e.g., using a library like react-leaflet).
Native Navigation Trigger: The user should be able to click the marker on the OSM map. This action should trigger the native maps/navigation app on their smartphone (like Google Maps or Apple Maps) to provide directions to that specific location.
Arrival & QR Code: Once the user physically arrives at the location, they will find a physical QR code.
In-App QR Scanning: Back in the web app, the user clicks a “Scan QR Code” button. This should activate the device’s camera from within the web app to scan the QR code.
Validation: The scanned QR code’s data needs to be validated against the expected value for the current step in the decision tree/game sequence.
Loop: If the QR code is correct, the user proceeds to the next question/location step. This continues until they reach an end point of the decision tree.
(Optional Bonus): At the end, visualize the decision tree, highlighting the path taken.
My specific challenges / questions:

OSM Marker to Native Navigation: How can I make an OSM map marker (specifically within a React component, possibly using react-leaflet) clickable such that it opens the user’s native mobile navigation app with the coordinates of the marker pre-filled as the destination? What’s the best approach or URL scheme to achieve this reliably across different devices (iOS/Android)?
In-App QR Code Scanning & Validation: How can I implement QR code scanning directly within my React web application? Which JavaScript libraries or browser APIs (like the MediaDevices API) are suitable for accessing the camera and decoding QR codes? Crucially, how do I then take the scanned data and validate it against the expected data associated with the current game state?
I’m looking for guidance on the best practices, recommended libraries, or specific APIs to implement features #3 and #5/#6 within a React web app context. Any pointers on managing the game state (current location, expected QR code) effectively would also be helpful.

Technologies: React, JavaScript, OpenStreetMap (potentially react-leaflet).

Thanks in advance for your help!

Here’s my GitHub Project atm:
https://github.com/FoiFoi13/EntBaumIDX

Angular EventEmitter does not work when I try to refresh a page after doing a put

I’m having trouble with Angular’s EventEmitter.

I don’t know why, but when I create an element, the EventEmitter works correctly, but when I try to update an element, it doesn’t works.

I have declared the eventemitter such that:

@Output() public updatedIngredient = new EventEmitter<boolean>();

The function to create an element is as follows:

public async createIngredient(): Promise<void> {
    try {
      if (this.ingredientForm.valid) {
        const ingredient: Ingredient = {
          name: this.ingredientForm.get('ingredientName')?.value,
          description: this.ingredientForm.get('ingredientDesc')?.value,
          type: this.ingredientForm.get('ingredientType')?.value,
        };

        await this.ingredientService.createIngredient(ingredient);

        this.closeIngredientModal(true);
      }
    } catch (error: any) {
      if (error.error.code === 'DUPLICATE_KEY') {
        this.ingredientNameError = this.translateService.instant(
          'APPS.YOUR_CHEF.INGREDIENT.error_existing_ingredient'
        );
      }
      throw error;
    }
}

The function to update an element is as follows:

public async updateIngredient(): Promise<void> {
    try {
      if (this.ingredientForm.valid) {
        const ingredientData: Partial<Ingredient> = {
          name: this.ingredientForm.get('ingredientName')?.value,
          description: this.ingredientForm.get('ingredientDesc')?.value,
          type: this.ingredientForm.get('ingredientType')?.value,
        };

        await this.ingredientService.updateIngredientById(
          this.ingredient?._id || '',
          ingredientData
        );
        this.closeIngredientModal(true);
      }
    } catch (error) {
      throw error;
    }
}

Both functions go through closeIngredientModal, which is responsible for both closing the creation/update modal of the element, and emitting an event indicating whether the element has been created or updated.
This is the implementation of closeIngredientModal

public closeIngredientModal(createdOrUpdated: boolean) {
    this.openedCreateModal = false;
    this.ingredientNameError = '';

    if (this.ingredient) this.initializeUpdateForm();
    else this.initializeCreateForm();

    this.updatedIngredient.emit(createdOrUpdated);
}

As you can see in this function, an event is emitted to the parent when an element has been created or updated, but I don’t know why, when I update an element, this event is not emitted.

I have verified that createdOrUpdated is pulled both when the item is created and when it is updated and in both cases it is true. That’s why I don’t undertand why it doesn’t work in EventEmitter when I update an element.

Does anyone know why the event emitter doesn’t work in the case I mentioned?

algorithm to detect the edge in a grid [closed]

I have this grid:

stored in a 2d array. And I want to find the blue edge tiles marked with the outline. The end goal is to move the left side, if there is at least one tile wide continuous path from top to bottom.

like this

But figured the code needs to find the edges to move first.

so, it have to:

  • Check if it connects top to bottom.
  • skip internal islands
  • stick to the left side

Methods I’ve tried:
A star path finding: Needs too many corrections to stick to the left, also finding the start and end position is challenging.

detecting neighbors in several ways: Either internal islands or U shapes cause unclear edge cases.

The code is written in JavaScript so some internal array function might help, not sure.
Any help with an algorithm accomplishing the above goal is appreciated.

filter nested tree object by id

I searched all over Google, but I still haven’t found a working solution on how to display a tree with only the necessary ids. Given:

 items = [
      {
        name: "a1.1",
        id: 1,
        children: [
          {
            name: "a1.2",
            id: 2,
            children: [
              { name: "a1.3", id: 3 },
              { name: "a1.4", id: 4 },
            ],
          },
        ],
      },
      {
        name: "a2.1",
        id: 5,
        children: [
          {
            name: "a2.2",
            id: 6,
            children: [
              { name: "a2.3", id: 7 },
              { name: "a2.4", id: 8 },
            ],
          },
        ],
      },
      {
        name: "a3.1",
        id: 12,
      },
    ];

Function call: filterTree(items, [3, 4, 8])

As a result, only the items with the specified identifiers should remain with name “a1.1”, “a1.2”, “a1.3”, “a1.4”, “a2.1”, “a2.2”, “a2.4”:

 [
      {
        name: "a1.1",
        id: 1,
        children: [
          {
            name: "a1.2",
            id: 2,
            children: [
              { name: "a1.3", id: 3 },
              { name: "a1.4", id: 4 },
            ],
          },
        ],
      },
      {
        name: "a2.1",
        id: 5,
        children: [
          {
            name: "a2.2",
            id: 6,
            children: [
              { name: "a2.4", id: 8 },
            ],
          },
        ],
      }
    ];

How to implement point cloud elevation coloring (material.pointColorType) in potree-core?

I’m working on a project that integrates potree-core and i need to color point clouds by elevation. This functionality is available in the original Potree viewer using:

material.pointColorType = PointColorType.HEIGHT;

However, this feature doesn’t seem to be implemented in potree-core. I found a related issue in the GitHub repo that discusses this exact need, but unfortunately it was closed without a solution:

https://github.com/tentone/potree-core/issues/25

Has anyone faced and solved this issue? Any tips or suggestions on how to implement elevation-based coloring in potree-core would be greatly appreciated!