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?

Prisma database setup for Cal.com

I am trying to setup a database for calcom locally on my System, so that I can contribute open-source code.

I have already seeded the database by running this syntax, yarn workspace @calcom/prisma prisma migrate dev

and when I try to generate the prisma client, run yarn workspace @calcom/prisma prisma generate

and yet, I keep getting this error message.

PrismaClientKnownRequestError: 


Invalid `prisma.user.count()` invocation:

The table `public.users` does not exist in the current database.

Angular – non-existing circular dependency detected (!)

I’m getting the message in console:

Circular dependency detected for MyService. Source: Environment

…however, that service is being injected in only one component, and obviously – that component isn’t injected in service.

This message is listed in console few times, but stack-trace says nothing. Any ideas?

Angular version: 20.x, Vite

stack trace

Set a Viewport to have a margin (or padding) on the right-hand side?

I have a FileMaker file, which uses a web-viewer as a Rich Text Editor. I also have a ‘Slide Control’ which slides a layout object in from one side. When this happens, I run a Function in the RTE which resizes it by adding Padding to one side. I’d like to do the same thing, for a web-viewer that’s being used for browsing the internet.

So essentially, I’m trying to have a clear space to one side of any given web page.

Is this possible to achieve with a Viewport???

This is what I use to resize my RTE:

function changeStyle(PadLeft, PadRight){
var element = document.getElementById('defaultRTE');
element.style.paddingLeft = (PadLeft);
element.style.paddingRight = (PadRight);
}

(NB.. I’m an amateur)

Why does npm run dev fail with “vite is not recognized as an internal or external command” in Laravel 10?

I recently installed a fresh Laravel 10 project with Vite as the frontend build tool. After running composer install and npm install, I tried to start the development server with:

npm run dev

But I get this error on Windows:

'vite' is not recognized as an internal or external command,
operable program or batch file.

I have:

  • Deleted node_modules and re-run npm install.

  • Ensured that vite is listed in devDependencies inside package.json.

  • Tried running npx vite directly, but it shows the same error.

  • Cleared cache with npm cache clean --force.

Expected result: running npm run dev should start the Laravel Vite dev server and compile my assets.

Actual result: it throws the “vite is not recognized” error and does not run.

What is the correct way to fix this issue and ensure npm run dev works properly with Laravel 10 and Vite?

Preflight Request Failure Handling Axios

error image

when i put rate limiting on my server , and when rate exceeds the preflight request fails so code execution stops and interceptor error is also not shown is there any way to handle it in axios , in axios interceptor

 api.interceptors.response.use(
  res => res,
  err => {
    }
  }
);

Different code update with No replies from Gemini

I’ve tested and uploaded my code to the link https://github.com/Dio-Damar-Danendra-Portofolio/Chatbot-Dio-Damar-Danendra (I recently updated on 9:24 A.M in Western Indonesian Time). I have tested with different usernames and I test the messages but it come with the same error message (No reply from Gemini). Please check and revise the errors. (Note: I already set the API key from the https://aistudio.google.com/app/apikey)

I have tested with different usernames and I test the messages but it come with the same error message (No reply from Gemini). I expected to be functional as any other chatbots, but in reality it comes with that Error message from invalid authentication credentials until the reply reads “Error: No reply from Gemini”. I have tried so many solutions.

Make array with osclass custom category while loop

How can i make an array of veriables using a while loop

I am using osclass for a uni project and i find no way whatsoever to make a variable for the custom catagory fields.

I have made Identifiers for the custom catagories and have tried many different approaches to grab and echo the custom catagory value elsewhere on the page other than in the current catagory.

I cannot isolate the custom catagory values by any means.

My only option i am thinking is making or buying a plugin , OR using a PHP veriable array

Below is the code used to display the custom catagory values on my osclass page

<?php if( osc_count_item_meta() >= 1 ) { ?> 
   
          <?php while ( osc_has_item_meta() ) { ?>
          
                    <?php if(osc_item_meta_value()!='') { ?> 
                   
                   
                    // I WOULD LIKE TO MAKE MAKE AN ARRAY OF VERIABLES SO I CAN USE THE CUSTOM CATAGORY DATA 
                    // TRIED SO FAR if(osc_item_meta_name()!='') {  $caughtcountry = osc_item_meta_value('country'); } 
                    // BUT THIS APPROACH DOES NOT WORK 

                    <?php } ?>
            
          <?php } ?>
          
          
      
    <?php } ?>`
    

I have tried using the identifiers that i added to the catagory in Admin panel

I have also tried using the Current PHP but cannot grab the values of specific custom catagories

Below is an example of one of my attempts to grab a custom catagory value but it only shows the 1st value within the values instead of cataching the ‘age’ value using the ‘age’ identifier i used.

 <?php if( osc_count_item_meta() >0 ) {  // The If osc_count_item_meta() >=1 
      if(osc_item_meta_value('age')!='') {  $caughtage = osc_item_meta_value('age'); }  else { $caughtage=''; }
                
    }   else { $caughtage=''; }
     ?>