Razorpay UI not opening on iOS device

I’m integrating Razorpay in my React Native project using:

react-native-razorpay: ^2.3.0

CocoaPods versions tried: 1.4.0, 1.4.3, 1.4.5

The issue is:

On Android, the Razorpay checkout UI (payment webview) opens and works correctly.

On iOS, the payment UI does not open at all.

Steps I already tried:

Verified that all Razorpay credentials (key ID, order ID, amount, etc.) are correct.

Passed the required options object correctly to the RazorpayCheckout.open(options) function.

Re-installed pods and cleaned the iOS build (pod install, pod update, npx pod-install, xcode clean build).

Tested on both simulator and real device (same issue).

Here’s a sample of the code I am using:

import RazorpayCheckout from ‘react-native-razorpay’;

const openRazorpay = () => {
const options = {
description: ‘Test Payment’,
image: ‘https://your-logo-url.png’,
currency: ‘INR’,
key: ‘my key’,
amount: ‘5000’, // 50 INR
name: ‘Test Merchant’,
order_id: ‘my order id’, // generated from backend
prefill: {
email: ‘[email protected]’,
contact: ‘9999999999’,
name: ‘Test User’,
},
theme: {color: ‘#53a20e’},
};

RazorpayCheckout.open(options)
.then(data => {
    console.log('Payment success:', data);
})
.catch(error => {
    console.log('Payment failed:', error);
});

};

Since the same code works fine on Android, I believe the issue is iOS-specific.

Question:
Has anyone faced this issue where the Razorpay checkout UI does not open on iOS? Do I need any additional setup or configuration in Xcode / Info.plist for iOS?

Performance drop drawing hundreds of shapes at once

I am creating a visualizer for a project. I extended the konva.group class and created whst i call a “location”.
Each location consists on 2 concentric circles and a lable and I need it to be clickable.
Locations are created from an array of objects each containing parameters that defines it like: internal diameter, external diameter, internal color, external color and idx(label).
For reference drawing 400 locations takes around 3 seconds.
After the initial draw I only create “new” locations if the array increases and update existing shapes lowering unpdates to milliseconds.
Any suggestions on ways of improving performance?

I tryed caching but without mutch luck, possibly due to me not implementing it correctly.

PWA para controle de estoque e vendas [closed]

desenvolvi um app para controlar o estoque e as vendas de uma adega ou varias, iniciei o codigo em html/css e javascript, dei continuidade com o gpt e agora não consigo continuar e o gpt so piora o que tento consertar, alguem pode me ajudar com os codigos ?

tentei ajuda com o gpt mais sem sucesso e so frustração

How to add a second CSS property (color change) to a transform animation using classList.toggle?

I’m working on a simple project where I want to animate a div element. I’m trying to make a white box both move to the right and change color when it’s clicked. I’m using a JavaScript click event to toggle a CSS class.

The problem is that my code only makes the box move, but it does not change its color. I have a transition: all property on the box, so I expected it to animate both properties.

Here is my code:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Animation Problem</title>
    <style>
        body {
            display: flex;
            justify-content: center;
        }
        #container {
            height: 130px;
            width: 350px;
            background: linear-gradient(to right, red, blue);
            display: flex;
            align-items: center;
            border-radius: 100px;
        }
        #box {
            height: 100px;
            width: 100px;
            background-color: #edeaea;
            margin-left: 15px;
            cursor: pointer;
            border-radius: 50%;
            transition: all 1s ease-in-out;
        }
        .clicked-box {
            transform: translateX(220px);
        }
    </style>
</head>
<body>
    <div id="container">
        <div id="box"></div>
    </div>
    <script>
        let box = document.querySelector("#box");
        box.addEventListener("click", function(){
            box.classList.toggle('clicked-box');
        });
    </script>
</body>
</html>```




I have tried adding background-color: blue; to the .clicked-box class, but it still doesn't seem to work, and I'm not sure if I'm missing a property or using the transition incorrectly.

How can I get the box to both move and change color smoothly when it's clicked?

`your text`

Babel plugin to add function keyword [closed]

Is there a Babel plugin or equivalent that could re-add the function keyword in front of a prototype function declaration, while still generating ES5?

Input:

myObject.prototype = { myMethod() { console.log("whatever"); } };

Into:

myObject.prototype = { myMethod: function() { console.log("whatever");} };

why the log on the post shows, tried to fix but no success

I am trying to deploy a project on Vercel and the error on the log shows, can anyone assist me?

2025-09-15T12:51:38.681Z [error] Error: ENOENT: no such file or directory, mkdir '/var/task/uploads'

at Object.mkdirSync (node:fs:1364:26)
at Object.<anonymous> (/var/task/server.js:46:6)
at Module.<anonymous> (/opt/rust/bytecode.js:2:1435)
at A.l._compile (/opt/rust/bytecode.js:2:3160)
at Object..js (node:internal/modules/cjs/loader:1895:10)
at Module.load (node:internal/modules/cjs/loader:1465:32)
at Function.<anonymous> (node:internal/modules/cjs/loader:1282:12)
at /opt/rust/nodejs.js:2:13528
at Function.Br (/opt/rust/nodejs.js:2:13906)
at Le.e.<computed>.De._load (/opt/rust/nodejs.js:2:13498) {
errno: -2,
code: 'ENOENT',
syscall: 'mkdir',
path: '/var/task/uploads'
}
Node.js process exited with exit status: 1. 

Multi EVM Gateway [closed]

I have 3 EVM Nodes, Eth Main, Base, and Arbitrum, my goal is to connect them all to one gateway and have API’s and Websockets be able to pull information from all 3 through 1 endpoint. will the different costs in gas fees be the downfall of this? Most likely it is my lack of foundational understanding that is causing this issue. I have the nodes, I have the gateway built I just can’t get all the information through a single point it is still connecting to each individual node.

I am using Google Cloud with VM instances and Compute engine with Ethereum nodes for the setup and coding with js. I have also been told this is an ambitious project for a beginner but I am mostly setup and getting information from each node it is just connecting them together and getting the information for all 3 through 1 endpoint that I am struggling with.

Detect if “message” event ran inside iframe came from my Chrome extension or from a page script (and block the latter)

I’m building an extension whose content script injects an iframe with my content into a page, extending its functionality, while not being interfered by a page.

The content script needs to send some data it extracts on the page to the iframe.
I want to use postMessage and onmessage for this, like so:

Content script:

let div = document.createElement('div');
let iframe = document.createElement('iframe');
iframe.src = chrome.runtime.getURL("page.html");
div.appendChild(iframe);
document.getElementById("main").appendChild(div);
iframe.onload = function(){
    iframe.contentWindow.postMessage(itemList, "*"); 
}

Script inside page.html, the injected iframe:

let list;
window.addEventListener('message', function(event) {
    list = event.data;
}

This setup works, but the problem is that the callback for the “message” event runs more than once, and I only call postMessage once in my content script. This leads me to believe, that my iframe detects postMessage sent from the page scripts.

I tried looking at event.origin but it is the same as the document host (example.org), so that can’t be detected.

A workaround to detect which is which would be sending my data in a more specific format as currently I send an just array (adding some from: myAwesomeExtension property), but I would prefer filtering the “noise” altogether, as this has the risk of forgery and a potential security issue as well.

Another, more common approach is sending the data from the content script to the iframe through the background script (content -> background -> iframe) with browser extension APIs, but that feels clumsy.

I’m interested in cross browser support, so Chrome as well as Firefox.

Cannot export function from plain js module without export default

I am trying to export like this :

export function play(a){
  console.log(a)
}

And importing like this :

import { play } from "../../audio.js";

In browser console getting this error :

Uncaught SyntaxError: The requested module ‘http://localhost:5173/audio.js?t=1757949216309’ doesn’t provide an export named: ‘default’

But when I export default like this :

export default function play(a){
  console.log(a)
}

import

import play  from "../../audio.js";

it works fine.
How can I export without default?

Module.findExportByName doesn’t compile [duplicate]

I installed Frida 17.2.17:

python -m pip install frida-tools

and to hook setsockopt Win API function I generated the following script with AI:

function readOptVal(optvalPtr, optlen) {
    return "<not implemented>";
}

var fn = Module.findExportByName("ws2_32.dll", "setsockopt");

if (!fn)
{
    console.log("setsockopt not found!");
}
else
{
    Interceptor.attach(fn, {
        onEnter: function(args) {
            var sock = args[0].toInt32();
            var level = args[1].toInt32();
            var optname = args[2].toInt32();
            var optval = args[3];
            var optlen = args[4];

            var val = readOptVal(optval, optlen);

            console.log("[setsockopt] called");
            console.log("  Socket:", sock);
            console.log("  Level :", level);
            console.log("  Opt   :", optname);
            console.log("  Val   :", val);
            console.log("  Len   :", optlen.toInt32());
        },
        onLeave: function(retval) {
            console.log("  Return:", retval.toInt32());
            console.log("------------------------------------");
        }
    });
}

and tried the following command:

frida -p 351768 -l hook_setsockopt.js

but got the following error:

TypeError: not a function
    at <eval> (C:devworkhook_setsockopt.js:5)

line 5 is:

var fn = Module.findExportByName("ws2_32.dll", "setsockopt");   

what is wrong with it?

How to add a custom search/filter function for DataTables’ searchList using Vue templates?

I am trying to create a Vue DataTable component so I can make several tables without having to worry about their overall set-up (since it will be done in this main table component).

One of the features I want is for the columns that use searchList (similar to the MultiSelect column in Notion) to recognize cells that have a list of values (here described as “tags”). I need the search function to recognize that, if the cell content is a list, then each individual item in that list may be searched and accounted for when it comes to filtering.

For that, I believe I need to modify the columns.search API so that, for each column it applies to, it:

  1. Parses each cell into a list
  2. Tries to match the items in the list of point #1 to the selected tags in the column’s searchList.
  3. Returns true if a single item matches

However, I am using Vue and not the “default” DataTables; and I am using Vue as a child component, not as the parent one. The reference documentation says I need to use the dt() method to access the API that should allow me to modify columns.search(). I have seen the example of how to do so for a predefined column with a predefined search query (here, with numbers), but I am stuck on how to do so for a general case scenario (again, the Vue component is meant as a template for any table I may want to add).

How do I obtain the searchlist selected items when I don’t know what information each column will contain yet? How do I do the same for each cell?

So far, I’ve managed to parse each item for display, but not for filtering.
Sample code and result below

Step 1: Display with no filtering yet
Tag selection - default

Step 2: Display with Tag A selected (Tag A Tag B and Tag C count as a single value to searchList – Not intended)
Tag selection - Tag A selected, Tag A Tag B and Tag C count as a single value

Step 3: with Tag A selected, the item with tags A B and C does not appear
Tag selection - Tag A selected, item with tags A B and C does not appear

Code on main.js:

import './assets/css/main.css'

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

import '@fortawesome/fontawesome-free/js/all'

const app = createApp(App)

app.use(router)

app.mount('#app')

Code on App.vue:

<script setup>
import { RouterView } from 'vue-router'

import Sidebar from './components/sidebar/Sidebar.vue';
import {sidebarWidth} from './components/sidebar/sidebar-state.js';
</script>

<template>
  <Sidebar />
  <div :style="{'margin-left': sidebarWidth}">
    <RouterView />
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

Code on Table.vue:

<script setup>
import jquery from 'jquery';
import DataTable from 'datatables.net-vue3';
import DataTablesLib from 'datatables.net-dt';
import 'datatables.net-colreorder-dt';
import 'datatables.net-columncontrol-dt';
import 'datatables.net-fixedheader-dt';
import 'datatables.net-fixedcolumns-dt';
import 'datatables.net-responsive-dt';
import 'datatables.net-searchpanes-dt';
 
DataTable.use(DataTablesLib);

const props = defineProps({
  columns: {
    default: [
      {data: 'id', title: 'PersonId',},
      {data: 'name', title: 'PersonName',},
    ]
  },
  options: {
    default: {
      responsive: true,
      scrollX: true,
      fixedHeader: true,
      fixedColums: true,
      colReorder: true,
      paging: false,
      scrollY: 300,
      scrollCollapse: true,
      columnControl: ['order', ['searchList']],
      ordering: {
        indicators: false
      }
    }
  },
  data: {
    default: [
      {name:'RowItem1ValueA', id:'RowItem1ValueB'},
      {name:'RowItem2ValueA', id:'RowItem2ValueB'},
    ]
  }
})

</script>

<template>
  <DataTable :columns="props.columns" :options="props.options" :data="props.data" 
  class="display compact">
  </DataTable>
</template>

<style>
@import 'datatables.net-dt';
@import 'datatables.net-responsive-dt';
@import 'datatables.net-fixedheader-dt';
@import 'datatables.net-fixedcolumns-dt';
@import 'datatables.net-colreorder-dt';
@import 'datatables.net-columncontrol-dt';
@import 'datatables.net-searchpanes-dt';
</style>

<style scoped>
th, td { white-space: nowrap; }

td.multiples{
  white-space: pre-wrap;  
}

div.dataTables_wrapper {
    margin: 0 auto;
}

div.container {
    width: 80%;
}
</style>

Code on OrganizationView.vue (view where I’m trying to use the default table as a template for “random” data):

<script setup>
import Table from '../components/table/Table.vue'

const tableInfoPeople = {
  'Columns': [
    {data: 'dtPerson', title: 'Person',},
    {
      data: 'dtTags', 
      title: 'MultiTags', 
      render: {
          _: '[, ].id',
          sp: '[].id'
      }
    },
  ],
  'Data': [
    { dtPerson: 'Name01',
      dtTags: [
        {'id': 'TagA'}
      ],
    },
    { dtPerson: 'Name02',
      dtTags: [
        {'id': 'TagA'}, {'id': 'TagB'}, {'id': 'TagC'}
      ],
    },
    {
      dtPerson: 'Name03',
      dtTags: [{'id': 'TagD'}],
    },
    
  ] 
}
</script>

<template>
  <Table :columns="tableInfoPeople.Columns" :data="tableInfoPeople.Data">
  </Table>
</template>

I appreciate any help you might give me.

Note: I know the css doesn’t look great, I wanted to change it after fixing the functionality.

addEventListener applies to all buttons

In my HTML, there are 7 buttons. I have created the following JavaScript with the intent that each time a button is pressed, the alert is called. However, how it actually operates is that once the first button is pressed the alert appears 7 times, each alert appearing once the previous has been dismissed. I was expecting this function to apply the EventListener to each button separately.

let buttons = document.querySelectorAll("button");

buttons.forEach(myFunction);

function myFunction(){
    addEventListener("click", function() {
        alert("I got clicked!");
    });
};

How do SPAs implement JS scripts?

I have a simple routing script which does the work for my SPA however, when it comes to implementing JS scripts for each page, it fails.

I am using simply using ‘fetch()’ to acquire the HTML and then ‘.innerHTML’. However, this does not execute JS scripts as we know and if I do make JS scripts execute and then navigate to another page and back, it fails because the specific variables are already allocated memory in the Virtual DOM leading to an error. How do I execute JS scripts with my simple JS routing?

Here is my router.js,

const mainEl = document.getElementsByTagName("main")[0];
let loc =
  window.location.search.replace("?loc=", "") !== ""
    ? window.location.search.replace("?loc=", "").split(".html")[0] + ".html"
    : "home.html";

function route(routeLoc) {
  if (routeLoc !== loc) {
    history.pushState({}, "", "?loc=" + routeLoc);
    render();
  }
}

async function render() {
  loc = window.location.search.replace("?loc=", "");
  const response = await fetch(loc);
  mainEl.innerHTML = await response.text();
}

window.pushstate = render;
window.onpopstate = render;
history.replaceState({}, "", "?loc=" + loc);
render();

raster layers “freeze” at the zoom they were first added and only refresh after I zoom

Problem:
I’m using Leaflet with georaster + georaster-layer-for-leaflet to toggle multiple single-band GeoTIFF rasters (only one visible at a time). When I switch which raster is visible, the previously added raster visually “sticks” at the zoom level where it was first rendered. The new raster doesn’t appear until I perform any zoom action; after a zoom, the correct raster shows up. In other words, the canvas seems frozen until a zoom* event fires.
All rasters are fetched over HTTPS from Firebase Storage (Cloud Storage for Firebase). Files are publicly readable through firebasestorage.googleapis.com. CORS is enabled on the bucket and allows GET/HEAD with Content-Type response header.

Example of what happened

The code:

(function (app) {
  'use strict';

  // -------------------------------------------------
  // Helpers
  // -------------------------------------------------
  function computeLegendRange(legend) {
    if (!legend || !Array.isArray(legend.classes) || legend.classes.length === 0) {
      return { min: 0, max: 1 };
    }
    const bounds = legend.classes
      .map(c => (typeof c.upper_bound === 'number' ? c.upper_bound : null))
      .filter(v => v !== null && isFinite(v));
    if (bounds.length === 0) {
      return { min: 0, max: 1 };
    }
    return { min: Math.min(...bounds), max: Math.max(...bounds) };
  }

  function createGeoRasterLayer(layerState) {
    const georaster = layerState.georaster;
    const config = layerState.config;
    const colorClasses = (config.legend && config.legend.classes) ? config.legend.classes : [];

    return new GeoRasterLayer({
      georaster: georaster,
      pane: layerState.paneId,
      opacity: 0.7,
      bounds: layerState.bounds,
      resolution: 256,
      updateWhenZooming: true,
      updateWhenIdle: true,
      updateInterval: 0,
      keepBuffer: 0,
      pixelValuesToColorFn: values => {
        const value = values[0];
        if (value === null || value === undefined || isNaN(value) || value === 0 || value === georaster.noDataValue) {
          return null;
        }
        const [minFilter, maxFilter] = layerState.filterRange;
        if (value < minFilter || value > maxFilter) {
          return null;
        }
        for (let i = 0; i < colorClasses.length; i++) {
          const cls = colorClasses[i];
          if (typeof cls.upper_bound === 'number' && value <= cls.upper_bound) {
            return cls.color || '#000';
          }
        }
        if (colorClasses.length) return colorClasses[colorClasses.length - 1].color || '#000';
        return '#000';
      }
    });
  }

  // -------------------------------------------------
  // Cleaning management
  // -------------------------------------------------
  function forceCleanupRasterLayer(layerId) {
    const layerState = app.activeRasterLayers[layerId];
    if (!layerState || !layerState.layer) return;

    if (app.map.hasLayer(layerState.layer)) {
      app.map.removeLayer(layerState.layer);
    }
    const pane = app.map.getPane(layerState.paneId);
    if (pane) pane.innerHTML = '';
    layerState.layer = null;
  }

  // -------------------------------------------------
  // UI Controls (Filter and Opacity)
  // -------------------------------------------------
  function applyRasterFilter(layerId) {
    const layerState = app.activeRasterLayers[layerId];
    if (layerState && layerState.layer) {
      forceCleanupRasterLayer(layerId);
      if (layerState.visible) {
        showRasterLayer(layerId);
        if (layerState.layer?.redraw) layerState.layer.redraw();
      }
    }
  }

  function createRangeFilterControl(layerId) {
    const layerState = app.activeRasterLayers[layerId];
    const { min, max } = layerState.legendRange;
    const [currentMin, currentMax] = layerState.filterRange;
    const container = document.createElement('div');
    container.className = 'range-filter-container';
    container.innerHTML = `
      <div class="range-labels">
        <span id="label-min-${layerId}">${currentMin.toFixed(1)}</span>
        <span id="label-max-${layerId}">${currentMax.toFixed(1)}</span>
      </div>
      <div class="range-slider">
        <div class="range-track"></div>
        <div class="range-selection" id="selection-${layerId}"></div>
        <input class="range-handle" id="slider-min-${layerId}" type="range" min="${min}" max="${max}" step="0.1" value="${currentMin}">
        <input class="range-handle" id="slider-max-${layerId}" type="range" min="${min}" max="${max}" step="0.1" value="${currentMax}">
      </div>`;

    const minSlider = container.querySelector(`#slider-min-${layerId}`);
    const maxSlider = container.querySelector(`#slider-max-${layerId}`);
    const minLabel = container.querySelector(`#label-min-${layerId}`);
    const maxLabel = container.querySelector(`#label-max-${layerId}`);
    const selection = container.querySelector(`#selection-${layerId}`);

    function updateSliderVisuals() {
      const minVal = parseFloat(minSlider.value);
      const maxVal = parseFloat(maxSlider.value);
      minLabel.textContent = minVal.toFixed(1);
      maxLabel.textContent = maxVal.toFixed(1);
      const range = max - min;
      if (range > 0) {
        const from = ((minVal - min) / range) * 100;
        const to = ((maxVal - min) / range) * 100;
        selection.style.left = `${from}%`;
        selection.style.right = `${100 - to}%`;
      }
    }

    function updateStateFromSliders() {
      let minVal = parseFloat(minSlider.value);
      let maxVal = parseFloat(maxSlider.value);
      if (minVal > maxVal) {
        [minVal, maxVal] = [maxVal, minVal];
        minSlider.value = minVal;
        maxSlider.value = maxVal;
      }
      layerState.filterRange = [minVal, maxVal];
      updateSliderVisuals();
    }
    minSlider.addEventListener('input', updateStateFromSliders);
    maxSlider.addEventListener('input', updateStateFromSliders);
    minSlider.addEventListener('change', () => applyRasterFilter(layerId));
    maxSlider.addEventListener('change', () => applyRasterFilter(layerId));
    updateSliderVisuals();
    return container;
  }

  function createOpacitySlider(layerId) {
    const layerState = app.activeRasterLayers[layerId];
    const controlContainer = document.createElement('div');
    controlContainer.className = 'opacity-control-container';
    const initialOpacity = layerState.layer ? layerState.layer.options.opacity : 0.7;
    controlContainer.innerHTML = `
      <i class="fas fa-eye"></i>
      <input type="range" min="0" max="1" step="0.05" value="${initialOpacity}" class="opacity-slider">
      <span>${Math.round(initialOpacity * 100)}%</span>`;
    controlContainer.querySelector('input').addEventListener('input', (e) => {
      const opacity = parseFloat(e.target.value);
      if (layerState.layer) layerState.layer.setOpacity(opacity);
      controlContainer.querySelector('span').textContent = `${Math.round(opacity * 100)}%`;
    });
    return controlContainer;
  }

  function toggleExtraControl(type, button, layerId, container) {
    const wasActive = button.classList.contains('active');
    document.querySelectorAll(`#wrapper_controls_${layerId} .opacity-tool-btn, #wrapper_controls_${layerId} .filter-tool-btn`).forEach(btn => btn.classList.remove('active'));
    container.innerHTML = '';
    container.style.display = 'none';
    if (!wasActive) {
      button.classList.add('active');
      const newControl = (type === 'opacity') ? createOpacitySlider(layerId) : createRangeFilterControl(layerId);
      container.appendChild(newControl);
      container.style.display = 'block';
    }
  }

  // -------------------------------------------------
  // Point analysis (value at the clicked point)
  // -------------------------------------------------
  function toggleInfoTool(button, layerId) {
    const layerState = app.activeRasterLayers[layerId];
    if (!layerState || !layerState.isLoaded) {
      alert('Por favor, carregue a camada primeiro.');
      return;
    }
    layerState.infoToolActive = !layerState.infoToolActive;
    button.classList.toggle('active', layerState.infoToolActive);
    const anyToolActive = Object.values(app.activeRasterLayers).some(state => state.infoToolActive);
    if (anyToolActive) {
      app.map.on('click', updatePixelValueOnClick);
    } else {
      app.map.off('click', updatePixelValueOnClick);
      const pixelValuePanel = document.getElementById('pixelValuePanel');
      if (pixelValuePanel) pixelValuePanel.style.display = 'none';
      if (app.clickPin) app.map.removeLayer(app.clickPin);
    }
  }

  function updatePixelValueOnClick(e) {
    const { lat, lng } = e.latlng;
    const panel = document.getElementById('pixelValuePanel');
    const content = document.getElementById('pixelValueContent');
    let htmlContent = `<b>Latitude:</b> ${lat.toFixed(4)}<br><b>Longitude:</b> ${lng.toFixed(4)}<hr style="margin: 5px 0;">`;
    for (const layerId in app.activeRasterLayers) {
      const layerState = app.activeRasterLayers[layerId];
      if (layerState.visible && layerState.infoToolActive && layerState.georaster) {
        const georaster = layerState.georaster;
        let valueText = 'Fora da área de dados';
        if (lng >= georaster.xmin && lng <= georaster.xmax && lat >= georaster.ymin && lat <= georaster.ymax) {
          try {
            const x = Math.floor((lng - georaster.xmin) / georaster.pixelWidth);
            const y = Math.floor((georaster.ymax - lat) / georaster.pixelHeight);
            const pixelValue = georaster.values[0][y][x];
            if (pixelValue !== georaster.noDataValue && !isNaN(pixelValue) && pixelValue !== 0) {
              const unit = layerState.config.unit || '';
              valueText = `${pixelValue.toFixed(2)} ${unit}`;
            }
          } catch (err) { }
        }
        htmlContent += `<b>${layerState.config.name}:</b> ${valueText}<br>`;
      }
    }
    content.innerHTML = htmlContent;
    panel.style.display = 'block';
    if (app.clickPin) app.map.removeLayer(app.clickPin);
    app.clickPin = L.marker(e.latlng).addTo(app.map);
    const removePinBtn = document.getElementById('removeAnalysisPinBtn');
    if (removePinBtn) removePinBtn.style.display = 'block';
  }

  function createOperationalControls(layerId, controlsWrapper, controlsContainer) {
    controlsWrapper.innerHTML = '';
    const infoBtn = document.createElement('i');
    infoBtn.className = 'fas fa-info-circle layer-action-icon info-tool-btn';
    infoBtn.title = 'Análise de Ponto';
    infoBtn.dataset.layerId = layerId;
    controlsWrapper.appendChild(infoBtn);
    const opacityBtn = document.createElement('i');
    opacityBtn.className = 'fas fa-eye layer-action-icon opacity-tool-btn';
    opacityBtn.title = 'Ajustar opacidade';
    controlsWrapper.appendChild(opacityBtn);
    const filterBtn = document.createElement('i');
    filterBtn.className = 'fas fa-sliders-h layer-action-icon filter-tool-btn';
    filterBtn.title = 'Filtrar valores de pixel';
    controlsWrapper.appendChild(filterBtn);
    infoBtn.addEventListener('click', () => toggleInfoTool(infoBtn, layerId));
    opacityBtn.addEventListener('click', () => toggleExtraControl('opacity', opacityBtn, layerId, controlsContainer));
    filterBtn.addEventListener('click', () => toggleExtraControl('filter', filterBtn, layerId, controlsContainer));
  }

  // -------------------------------------------------
  // Layer Visibility
  // -------------------------------------------------
  function hideRasterLayer(id) {
    const st = app.activeRasterLayers[id];
    if (!st) return;

    forceCleanupRasterLayer(id);
    st.visible = false;

    if (st.infoToolActive) {
      const infoBtn = document.querySelector(`.info-tool-btn[data-layer-id="${id}"]`);
      if (infoBtn) infoBtn.classList.remove('active');
      st.infoToolActive = false;
      const anyToolActive = Object.values(app.activeRasterLayers).some(state => state.infoToolActive);
      if (!anyToolActive) {
        app.map.off('click', updatePixelValueOnClick);
        const panel = document.getElementById('pixelValuePanel');
        if (panel) panel.style.display = 'none';
        if (app.clickPin) app.map.removeLayer(app.clickPin);
      }
    }
  }

  function showRasterLayer(id) {
    const st = app.activeRasterLayers[id];
    if (!st || !st.georaster) return;

    st.paneId = `raster-${id}`;
    if (!app.map.getPane(st.paneId)) {
      app.map.createPane(st.paneId);
      // app.__rZ = (app.__rZ || 1050) + 1;
      app.map.getPane(st.paneId).style.zIndex = app.__rZ;
    }
    if (st.layer) {
      forceCleanupRasterLayer(id);
    }
    st.layer = createGeoRasterLayer(st);
    st.visible = true;
    st.layer.addTo(app.map);
    if (typeof st.layer.redraw === 'function') {
      st.layer.redraw();
    }
    app.map.once('idle', () => { if (st.visible && st.layer?.redraw) st.layer.redraw(); });
    app.map.once('zoomend', () => { if (st.visible && st.layer?.redraw) st.layer.redraw(); });
  }

  // -------------------------------------------------
  // Raster loading
  // -------------------------------------------------
  async function loadRasterLayer(layerId) {
    const layerState = app.activeRasterLayers[layerId];
    const config = layerState.config;
    const icon = document.getElementById(`icon_${layerId}`);
    icon.className = 'fas fa-spinner fa-spin layer-action-icon';

    try {
      const response = await fetch(config.path, { mode: 'cors' });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const arrayBuffer = await response.arrayBuffer();
      const georaster = await parseGeoraster(arrayBuffer);

      layerState.georaster = georaster;
      layerState.bounds = L.latLngBounds([
        [georaster.ymin, georaster.xmin],
        [georaster.ymax, georaster.xmax]
      ]);
      layerState.legendRange = computeLegendRange(config.legend);
      layerState.filterRange = [layerState.legendRange.min, layerState.legendRange.max];
      layerState.isLoaded = true;

      const checkbox = document.getElementById(`cb_${layerId}`);
      checkbox.disabled = false;
      checkbox.checked = true;
      checkbox.dispatchEvent(new Event('change', { bubbles: true }));

      const controlsWrapper = document.getElementById(`wrapper_controls_${layerId}`);
      const controlsContainer = document.getElementById(`controls_${layerId}`);
      createOperationalControls(layerId, controlsWrapper, controlsContainer);
      icon.className = 'fas fa-check layer-action-icon';
      setTimeout(() => { icon.className = 'fas fa-download layer-action-icon'; }, 1200);
    } catch (error) {
      console.error(`Falha ao carregar camada raster ${layerId}:`, error);
      icon.className = 'fas fa-download layer-action-icon';
      alert(`Não foi possível carregar a camada ${config.name}.`);
    }
  }

  // -------------------------------------------------
  // Initialization
  // -------------------------------------------------
  function init() {
    // Point Analysis Panel Configuration
    const panelHeader = document.querySelector('#pixelValuePanel .popup-header h4');
    if (panelHeader) panelHeader.innerHTML = `<i class="fas fa-chart-area"></i> Análise de Ponto`;
    const panelContent = document.getElementById('pixelValueContent');
    if (panelContent) {
      const removePinBtn = document.createElement('button');
      removePinBtn.id = 'removeAnalysisPinBtn';
      removePinBtn.className = 'panel-action-button danger';
      removePinBtn.innerHTML = '<i class="fas fa-times-circle"></i> Remover Marcador';
      removePinBtn.style.cssText = 'display: none; width: 100%; margin-top: 10px;';
      panelContent.after(removePinBtn);
      removePinBtn.addEventListener('click', () => {
        if (app.clickPin) {
          app.map.removeLayer(app.clickPin);
          app.clickPin = null;
          removePinBtn.style.display = 'none';
        }
      });
    }
    const closeBtn = document.getElementById('closePixelValuePanel');
    if (closeBtn) {
      closeBtn.addEventListener('click', () => {
        Object.keys(app.activeRasterLayers).forEach(layerId => {
          const layerState = app.activeRasterLayers[layerId];
          if (layerState.infoToolActive) {
            layerState.infoToolActive = false;
            const infoBtn = document.querySelector(`.info-tool-btn[data-layer-id="${layerId}"]`);
            if (infoBtn) infoBtn.classList.remove('active');
          }
        });
        app.map.off('click', updatePixelValueOnClick);
        const pixelValuePanel = document.getElementById('pixelValuePanel');
        if (pixelValuePanel) pixelValuePanel.style.display = 'none';
        if (app.clickPin) app.map.removeLayer(app.clickPin);
      });
    }

    // Building the Layer UI
    const rasterList = app.config.rasterLayers;
    if (!Array.isArray(rasterList) || rasterList.length === 0) return;
    app.activeRasterLayers = app.activeRasterLayers || {};
    rasterList.forEach(rasterConfig => {
      const groupContainer = document.getElementById(`group-content-${rasterConfig.group}`);
      if (!groupContainer) return;

      const layerId = rasterConfig.id;
      app.activeRasterLayers[layerId] = {
        layer: null, config: rasterConfig, georaster: null,
        visible: false, isLoaded: false, filterRange: null,
        bounds: null, legendRange: computeLegendRange(rasterConfig.legend),
        infoToolActive: false, paneId: null,
        legend: { type: 'raster', title: rasterConfig.name, ...(rasterConfig.legend || {}) }
      };
      const listItem = document.createElement('div');
      listItem.className = 'layer-group-item';
      listItem.innerHTML = `
        <div class="layer-item" data-layer-id="${layerId}">
          <i class="fas fa-grip-vertical layer-drag-handle"></i>
          <input type="checkbox" id="cb_${layerId}" disabled>
          <label for="cb_${layerId}">${rasterConfig.name}</label>
          <div class="layer-controls-wrapper" id="wrapper_controls_${layerId}">
            <i class="fas fa-download layer-action-icon" id="icon_${layerId}" title="Carregar camada"></i>
          </div>
        </div>
        <div class="raster-controls" id="controls_${layerId}" style="display: none;"></div>`;
      groupContainer.appendChild(listItem);
      document.getElementById(`icon_${layerId}`).addEventListener('click', () => loadRasterLayer(layerId));

      const checkbox = document.getElementById(`cb_${layerId}`);
      checkbox.addEventListener('change', (e) => {
        const isChecked = e.target.checked;
        if (!app.activeRasterLayers[layerId].isLoaded) { e.target.checked = false; return; }

        if (isChecked) {
          Object.keys(app.activeRasterLayers).forEach(otherId => {
            if (otherId !== layerId && app.activeRasterLayers[otherId]?.visible) {
              const cb = document.getElementById(`cb_${otherId}`);
              if (cb) cb.checked = false;
              hideRasterLayer(otherId);
            }
          });
          showRasterLayer(layerId);
        } else {
          hideRasterLayer(layerId);
        }
        if (app.legend && app.legend.update) {
          app.legend.update();
        }
      });
    });
  }

  // -------------------------------------------------
  // Public API
  // -------------------------------------------------
  app.raster = {
    init,
    loadRasterLayer,
    showRasterLayer,
    hideRasterLayer,
    toggleInfoTool,
    updatePixelValueOnClick
  };
  app.initRasterLayers = init;

})(window.app = window.app || {});

Questions:

*- Is there a known issue with GeoRasterLayer (or its L.GridLayer internals) where the canvas doesn’t invalidate until a zoom?

  • Is there a recommended way to fully dispose/destroy a GeoRasterLayer so that switching rasters forces a fresh render without needing a zoom?
  • Is creating a separate pane per raster contributing to the issue (z-index/canvas stacking), and should I reuse a single dedicated pane for all rasters instead?
  • Any hook I should call (e.g., map.invalidateSize() with options, or a different redraw/clear path) to force immediate repaint on toggle?*

What actually happens:
When I toggle visibility (A → B), raster B should render immediately (no zoom/pan required) and the canvas from raster A should be fully cleared. After toggling, the screen still shows raster A at the zoom level where it was first added. Only after a zoom (in or out) does raster B render.

What I’ve tried:

*- Calling layer.redraw() right after addTo(map) and also on map.once(‘idle’) / map.once(‘zoomend’).

  • Using keepBuffer: 0, updateWhenZooming: true, updateWhenIdle: true, updateInterval: 0.
  • Removing the layer and clearing the pane’s DOM (pane.innerHTML = ”) before recreating.
  • Ensuring only one raster layer is visible at a time (checkbox logic toggles A/B).
  • Verifying CORS and fetch; data loads fine and pixels are read correctly.
  • Confirming no leftover global listeners are required; I don’t rely on zoomstart/zoomend to trigger the first render.*

How can I use the code of HTML, CSS and JS consisting of different animations and styles into the WordPress? [closed]

I liked some animations and styles in a website. I have the code (HTML, CSS, JS) where I have a website built with WordPress. Tried to use the code in the page but no use, its not working out.Also the maximum animations and effects are written in JavaScript. So how and where can I find the best animations and effects, any sources?

Tried to import the php file and short code and muchmore. I thought the animations would work. Like they are on hover animations?