Firebase cloud message gettoken not work on Edge newest version

I using firebase cloud message.
It just work perfect on Chrome but not work on Edge with same code.

Here is the code:

import {
    initializeApp
} from 'https://www.gstatic.com/firebasejs/11.10.0/firebase-app.js';
import {
    isSupported,
    getMessaging,
    getToken,
    onMessage,
    deleteToken
} from 'https://www.gstatic.com/firebasejs/11.10.0/firebase-messaging.js';
const firebaseConfig = {
    apiKey: 'apiKey',
    authDomain: 'authDomain',
    projectId: 'projectId',
    storageBucket: 'storageBucket',
    messagingSenderId: 'messagingSenderId',
    appId: 'appId'
};
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
var registration = null;
navigator.serviceWorker.register('/mydomain/service-worker-sw.js').then((reg) => {
    registration = reg;
    console.log('Service Worker registered with scope:', reg.scope);
    return navigator.serviceWorker.ready;
}).then((registration) => {
    if (registration.active) {
        registration.active.postMessage({
            type: 'SET_GLOBAL_VARIABLE',
            value: firebaseConfig
        });
    } else if (navigator.serviceWorker.controller) {
        navigator.serviceWorker.controller.postMessage({
            type: 'SET_GLOBAL_VARIABLE',
            value: firebaseConfig
        });
    }
    return getToken(messaging, {
        vapidKey: 'vapidKey',
        serviceWorkerRegistration: registration
    });
}).then((currentToken) => {
    if (currentToken) {
        console.log('Token - ' + currentToken);
        myFireBaseToken = currentToken;
    } else {
        console.log('No registration token available. Request permission to generate one.');
        requestPermission();
    }
}).catch((err) => {
    console.log('An error occurred while retrieving token. ', err);
});
onMessage(messaging, (payload) => {
    myFireBase = JSON.stringify(payload);
});

function requestPermission() {
    console.log('Requesting permission...');
    Notification.requestPermission().then((permission) => {
        if (permission === 'granted') {
            console.log('Notification permission granted.');
        }
    });
}

Error message:

An error occurred while retrieving token. AbortError: Registration failed – push service error

  • Browser: Edge version 138.0.3351.95
  • Windows 10: 22H2

How can I solve this issue on Edge?

How do i bundle a full stack Next js app with API routes in an electron JS?

for several days I’ve been trying to use my full stack next js app with app route, API route and typescript and bundle it in an Electron JS app. but all my attempts have failed, some only work as dev but not in production. so Here i wanna give you my next js tree and some basic code.

next-app/
├── src/
│   ├── app/
│   │   ├── api/
│   │   │   └── hello/route.ts      # Simple API route (GET)
│   │   ├── layout.tsx              # Root layout (mandatory)
│   │   └── page.tsx                # Home page
│   ├── styles/
│   │   └── globals.css             # Optional global styles
│   └── lib/                        # (Optional) helper functions, utils
├── public/                         # Static files (images, etc.)
├── next.config.js                  # Next.js config
├── tsconfig.json                   # TypeScript config
├── package.json                    # Scripts and dependencies
├── .gitignore
└── README.md

so the page.ts

"use client";

import { useEffect, useState } from "react";

export default function HomePage() {
  const [data, setData] = useState<any>(null);

  useEffect(() => {
    fetch("/api/hello")
      .then((res) => res.json())
      .then(setData)
      .catch(console.error);
  }, []);

  return (
    <main style={{ padding: 40 }}>
      <h1>Welcome to Electron + Next.js</h1>
      <p>This is a fullstack app running inside Electron.</p>

      <h2>API response:</h2>
      {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : <p>Loading...</p>}
    </main>
  );
}

and the route.ts

import { NextResponse } from 'next/server';

export function GET() {
  return NextResponse.json({
    message: 'Hello from API route!',
    time: new Date().toISOString(),
  });
}

so this is a simple next js app. Now Please help me integrate electron to it. I would want to build an installable from it and be able to install on my computer and the full app to work. if you include the steps of what to install and configure it would be amazing.

How do I restrict the results by date range based on which S&F Pro form is used while allowing a date range in the search form?

We are using the Search & Filter Pro plugin on our WordPress site and need to be able to restrict results for two particular categories by preset dates. I am trying to accomplish this without having to manually edit over 1000 posts to change the category or add a category, or require us to tag it a certain way to separate the posts into eras.

My preference is to restrict the dates that can be entered in the form with a min date on some forms and a min and max date on others. In version 2, I don’t see a way to set a min and/or max date on the date range control in the search form and can’t even begin to figure out how to do that in code (PHP or JS). It would greatly improve the user experience if users can’t enter a date outside the range so that the results match the entered dates. I can filter behind the scenes using the below code.

I have managed to find a code snippet, and modified it, for altering the query for specific S&F Pro forms:

function filter_media_release_current_term( $query_args, $sfid ) {

    if($sfid==2530 || $sfid==2488)
    {
        $currentafter = 2025;
        $startyear = '2025';
        $aftermonth = '01';
        $afterday = '01';
        $currentbefore = '2025';
        // edit later to use a full date, not just year
        // if no date query set the after value
        if (!isset($query_args['date_query'])) {
            $query_args['date_query'] = 
                array(
                    'after'     => array (
                        'day'   => $afterday,
                        'month' => $aftermonth,
                        'year'  => $startyear,
                    ),
                    'inclusive' => true,
                );
        } else {
            // One or both dates are entered: see if they entered a 'To:' date and grab those values
            if (isset($query_args['date_query']['before']) && isset($query_args['date_query']['before']['year'])) {
                $currentbefore = $query_args['date_query']['before']['year'];
                $beforeday = $query_args['date_query']['before']['day'];
                $beforemonth = $query_args['date_query']['before']['month'];
                if ($currentbefore < $startyear) {
                    // can't return any results prior to the start date - resets the date query to default
                    print_r("<br/><span style='color: red'>&nbsp;&nbsp;Enter dates starting " . $aftermonth ."/" . $afterday . "/" . $startyear . "</span><br/><br/>");
                    $query_args['date_query'] = 
                    array(
                        'after'     => array (
                            'day'   => $afterday,
                            'month' => $aftermonth,
                            'year'  => $startyear,
                        ),
                        'inclusive' => true,
                    );
                } else {
                    // Before date is valid
                    // Did they enter a 'From:' date?
                    if (isset($query_args['date_query']['after']) && isset($query_args['date_query']['after']['year'])) {
                        $currentafter = $query_args['date_query']['after']['year'];
                        // if before start date - reset it to the start date but keep the before entry
                        if ($currentafter < $startyear) {
                            print_r("<br/><span style='color: red'>&nbsp;&nbsp;Start date out of range!</span><br/><br/>");
                            $query_args['date_query'] = 
                                array(
                                    'after'     => array (
                                        'day'   => $afterday,
                                        'month' => $aftermonth,
                                        'year'  => $startyear,
                                    ),
                                    'before'     => array (
                                        'day'   => $beforeday,
                                        'month' => $beforemonth,
                                        'year'  => $currentbefore,
                                    ),
                                    'inclusive' => true,
                                );
                        } // no else here - do nothing if both dates are in the valid range
                    } else {
                        // no 'From:' date entered - use default from date and the 'To:' date they entered
                        $query_args['date_query'] = 
                            array(
                                'after'     => array (
                                    'day'   => $afterday,
                                    'month' => $aftermonth,
                                    'year'  => $startyear,
                                ),
                                'before'     => array (
                                    'day'   => $beforeday,
                                    'month' => $beforemonth,
                                    'year'  => $currentbefore,
                                ),
                                'inclusive' => true,
                            );
                    }
                }
            } else {
                // they entered only the 'From:' value but make sure it is set to avoid errors
                if (isset($query_args['date_query']['after']) && isset($query_args['date_query']['after']['year'])) {
                    $currentafter = $query_args['date_query']['after']['year'];
                    // if before start date - reset it to the start date but keep the before entry
                    if ($currentafter < $startyear) {
                        print_r("<br/><span style='color: red'>&nbsp;&nbsp;Start date out of range!</span><br/><br/>");
                        $query_args['date_query'] = 
                            array(
                                'after'     => array (
                                    'day'   => $afterday,
                                    'month' => $aftermonth,
                                    'year'  => $startyear,
                                ),
                                'inclusive' => true,
                            );
                   } // no else here - do nothing if the date is in the valid range
                } else {
                    // no year set for some reason
                    $query_args['date_query'] = 
                            array(
                                'after'     => array (
                                    'day'   => $afterday,
                                    'month' => $aftermonth,
                                    'year'  => $startyear,
                                ),
                                'inclusive' => true,
                            );
                }
            }
        }
    }

    return $query_args;
}
add_filter( 'sf_edit_query_args', 'filter_media_release_current_term', 20, 2 );

This successfully filters the results, ensuring no results prior to 1/1/2025 are shown even if they don’t filter by date range. However, I had to turn off ajax results so that the page reloads on each submit instead of without reloading because it didn’t go through this function with ajax updates. Also, I can’t figure out how to update the form or the URL from this function so the page displays “Showing results from [date] to [date]” using the original dates.

How do I apply fix the UI problems?

Thank you for any guidance you can give me.

mPDF adds blank first page when rendering large HTML content with

I’m generating a PDF from HTML using mPDF, and when the document contains a large amount of content, an almost blank first page is added unexpectedly. This only happens with longer documents — shorter ones work fine.

That is function generating PDF:

private function getMPDF($filename = null) {
    $mpdf = $this->mpdfInit();
    $mpdf->charset_in = 'utf-8';
    $mpdf->SetTopMargin(33);

    $mpdf->WriteHTML($this->html);
        
    if ($filename === null) {
        return $mpdf->Output('', "S");
    } else {
        $mpdf->Output($filename, "F");
    }
}

The $this->html contains HTML with multiple nested tags and paragraphs, such as this:

<table style="width: 700px;" border="0">
<tbody>
<tr>
<td style="width: 432px;"> </td>
<td style="width: 225px; padding-top: 8px;">
<p style="font-size: 13px; font-family: Arial;">Pani<br />[IMIĘ I NAZWISKO]<br />[ADRES]<br />[KOD POCZTOWY] [MIASTO]</p>
</td>
<td style="width: 43px;"> </td>
</tr>
</tbody>
</table>
<p> </p>
<table style="text-align: justify; width: 700px;" border="0">
<tbody>
<tr>
<td style="width: 50px;"> </td>
<td style="width: 600px;">
<p style="font-size: 13px; font-family: Arial;">[DATA]</p>
<p> </p>
<p style="font-size: 15px; font-family: Georgia;">Dotyczy zgłoszenia o numerze [NUMER_ZGŁOSZENIA] z dnia [DATA]; przedmiot: [NAZWA_SPRZĘTU]; numer dokumentu: [NUMER_DOKUMENTU].</p>
<p> </p>
<p> </p>
<p style="font-size: 13px; font-family: Arial;">Szanowna Pani,</p>
<p> </p>
<p style="font-size: 13px; font-family: Arial;">Informujemy, że po analizie dostępnych informacji nie stwierdzono przesłanek do pozytywnego rozpatrzenia zgłoszenia.<br /><br />Na podstawie przeprowadzonych czynności ustalono, że nie wystąpiły okoliczności, które uzasadniałyby dalsze działanie.</p>
<br />
<p style="font-size: 13px; font-family: Arial;">Podjęta decyzja wynika z:</p>
<p style="font-size: 13px; font-family: Arial;">- informacji zebranych podczas zgłoszenia<br />- analizy technicznej<br /><br />Zgłoszony opis: brak ładowania, pęknięcie plastiku, brak aktywacji systemu. Wskazana data: [DATA].<br /><br />W wyniku analizy technicznej stwierdzono mechaniczne uszkodzenie elementów:
<br />- bateria cmos<br />- osłona zawiasów<br /><br /><br />Stwierdzono również, że niektóre elementy uległy naturalnemu zużyciu, co nie stanowi podstawy do dalszego działania w tym zakresie.</p>
<p> </p>
<p style="font-size: 13px; font-family: Arial;">W związku z powyższym brak jest podstaw do zmiany stanowiska. </p>
</td>
<td> </td>
</tr>
<tr>
<td style="width: 50px;"> </td>
<td style="width: 600px;">
<p style="font-size: 13px; font-family: Arial;"><br />Informujemy o możliwości przekazania sprawy do niezależnych instytucji oraz skorzystania z dostępnych środków odwoławczych. Sprawa może być również rozpatrzona przez sąd właściwy miejscowo zgodnie z obowiązującymi przepisami.</p>
</td>
<td style="width: 50px;"> </td>
</tr>
<tr>
<td style="width: 50px;"> </td>
<td style="vertical-align: top; text-align: justify; width: 600px;">
<p style="font-size: 13px; font-family: Arial;"><br />Sprawy sporne mogą być również rozpatrywane w drodze pozasądowego postępowania przed wyznaczonymi instytucjami, zgodnie z obowiązującymi przepisami prawa.</p>
</td>
<td style="width: 50px;"> </td>
</tr>
<tr>
<td style="width: 50px;"> </td>
<td style="text-align: justify;">
<p style="font-size: 13px; font-family: Arial;">[NAZWA INSTYTUCJI] jest administratorem danych, które są przetwarzane zgodnie z obowiązującymi przepisami. Kontakt z Inspektorem Ochrony Danych możliwy jest za pośrednictwem formularza na stronie [STRONA], pisemnie lub mailowo: iod@[DOMENA].pl. Szczegóły dostępne są również pod numerem telefonu [NUMER].</p>
<p style="font-size: 13px; font-family: Arial;"><br /><br />Z wyrazami szacunku</p>
<br />
<p style="font-size: 13px; font-family: Arial;">[IMIĘ I NAZWISKO]<br /> <img src="[ZDJĘCIE]" alt="" width="190" /> <br />Główny Specjalista<br />[DZIAŁ]</p>
</td>
<td style="width: 50px;"> </td>
</tr>
</tbody>
</table>

After debugging, I noticed the issue seems to be related to the table element. When I remove the table (or extract all its content before rendering), the blank page disappears — but this breaks other documents, so it’s not a viable solution.

I also tried modifying margins and adding CSS to control page breaks:

table { page-break-inside: auto; }
tr    { page-break-inside: avoid; }
thead { display: table-header-group; }
tbody { display: table-row-group; }

Why is my WordPress plugin shortcode output duplicating every time I refresh the page?

I’m building a simple WordPress plugin that fetches a random quote from an external API and displays it using a shortcode.

The problem is: every time I refresh the page, the quote seems to duplicate — it appears twice (or more) inside the same container. I expected it to show just one quote per page load.

Here’s a simplified version of my code:

function my_quotes_shortcode() {
       $response = wp_remote_get('https://api.quotable.io/random');
       if (is_wp_error($response)) {
               return 'Quote unavailable.';
       }
      
       $data = json_decode(wp_remote_retrieve_body($response));
       $quote = $data->content ?? 'Default quote';
       $author = $data->author ?? 'Unknown';
       return "<div class='quote-box'>"{$quote}" - {$author}</div>";
}

add_shortcode('daily_quote', 'my_quotes_shortcode');

What I Tried

  • Wrapped the return inside ob_start() / ob_get_clean() — no change
  • Ensured add_shortcode() is called only once, outside any hook
  • Cleared browser, site, and server cache
  • Switched to the default Twenty Twenty-Four theme — still duplicates

What I Expected

  • I expected the shortcode to return just one quote inside a each time the page loads. No duplicates.

Notes

  • I’m not enqueueing any custom JavaScript or CSS
  • Using the shortcode inside a basic Page block through the WordPress editor
  • Duplicates happen more often when refreshing quickly

Is this related to how WordPress handles shortcode rendering or something with API timing?
Any help would be appreciated!

htaccess block root folder bit allow access to list of specified sub folders

I am trying to create htaccess rules at the root of a client site to block traffic from a specific subfolder where wordpress is installed.

Here is my structure

site.com
|--blog
   |--.htaccess
   |--wp-files
.htaccess
site-root-files

My root htaccess file look like this:

RewriteEngine On

# Define the list of exception folders
RewriteCond %{REQUEST_URI} ^/blog/([^/]+)/
RewriteCond %{REQUEST_URI} !^/blog/(wp-admin|wp-json)/

# List of exception files
RewriteCond %{REQUEST_URI} ^/blog/wp-login.php$ [NC]
RewriteCond %{REQUEST_URI} !^/blog/wp-login.php$

# Redirect all other requests under /blog/
RewriteCond %{REQUEST_URI} ^/blog/
RewriteRule ^/blog/ / [L]

Redirect 301 /tmp /
ErrorDocument 404 /error/404.html

Nothing seems to work except the last two lines the tmp redirect and the 404 page.

WordPress is installed in the blog folder.

Then it dawned on my that WordPress might have its own htaccess file. It does and it looks like this:


# BEGIN WordPress
# Direktiverne (linjer) mellem 'BEGIN WordPress' og 'END WordPress' er
# dynamisk genereret og bør kun ændres via WordPress-filtre.
# Eventuelle ændringer i direktiverne mellem disse markører vil blive overskrevet.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>

# END WordPress

What have I tried?

Commenting out all of the rules in the blog/.htaccess file
Inverting the functions in the site root .htaccess file.

Nothing seems to work.

My regex knowledge is pretty basic but I can wrap my head around this. !^/blog/(wp-admin|wp-json)/ looks like not/don’t write rewrite rules for blog/wp-admin, or blog/wp-json etc

TL;DR

Block access to

  • site.com/blog

With these exceptions (allow access to)

  • site.com/blog/wp-admin
  • site.com/blog/wp-json
  • site.com/blog/wp-login.php

Can anyone help me?

Is moving inline JavaScript to an external file a valid way to avoid using nonces in CSP for a static site?

I’m building a static site (using Vite + React, hosted on Netlify) and I want to set a strict Content Security Policy (CSP) without using unsafe-inline or nonces.

Since my site is static, managing nonces dynamically via backend is not ideal.

Question:
If I move all my inline JavaScript into external .js files, can I completely avoid using CSP nonces?
In other words, is the following approach valid and secure for modern browsers?

Set CSP to:

Content-Security-Policy: default-src ‘self’; script-src ‘self’; object-src ‘none’; base-uri ‘self’;

Load all scripts only via <script src="..."></script> (no inline JavaScript in HTML).

Optionally add Subresource Integrity (integrity) attributes for extra protection.

Does this fully eliminate the need for nonces, or is there something I’m missing?
Any security implications or browser compatibility issues?

Thanks in advance!

I removed all inline JavaScript from my index.html file and moved it into external .js files.

I then updated my CSP header to only allow script-src ‘self’ without ‘unsafe-inline’ or nonces, expecting everything to work securely.

However, I want to confirm if this setup is valid and secure according to CSP best practices, especially on static sites where managing nonces dynamically is not possible.

Pyppeteer returns None or empty content when scraping Digikala product page

I’m trying to scrape a product page from Digikala using Pyppeteer because the site is heavily JavaScript-rendered.

Here is my render class:

import asyncio
from pyppeteer import launch
from pyppeteer.errors import TimeoutError

class JsRender:
    def __init__(self, chromium_path):
        self.chromium_path = chromium_path

    async def fetch_content(self, url, headers=None):
        try:
            browser = await launch(executablePath=self.chromium_path, headless=True)
            page = await browser.newPage()

            if headers:
                await page.setExtraHTTPHeaders(headers)

            await page.goto(url, {'waitUntil': 'networkidle2', 'timeout': 60000})
            await asyncio.sleep(2)  # Added sleep just in case
            content = await page.content()
            await browser.close()
            return content
        except TimeoutError:
            print(f'Timeout while loading {url}')
            return None

    def get_page_content(self, url, headers=None):
        return asyncio.get_event_loop().run_until_complete(self.fetch_content(url, headers))

And here’s how I call it:

from browser_configure import JsRender
from bs4 import BeautifulSoup
from utility import covert_price

browser = JsRender(r'C:UserssamaAppDataLocalChromiumApplicationchrome.exe')

url = 'https://www.digikala.com/product/dkp-17986495/%DA%AF%D9%88%D8%B4%DB%8C-%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84-%D8%A7%D9%BE%D9%84-%D9%85%D8%AF%D9%84-iphone-16-ch-%D8%AF%D9%88-%D8%B3%DB%8C%D9%85-%DA%A9%D8%A7%D8%B1%D8%AA-%D8%B8%D8%B1%D9%81%DB%8C%D8%AA-128-%DA%AF%DB%8C%DA%AF%D8%A7%D8%A8%D8%A7%DB%8C%D8%AA-%D9%88-%D8%B1%D9%85-8-%DA%AF%DB%8C%DA%AF%D8%A7%D8%A8%D8%A7%DB%8C%D8%AA/'
content = browser.get_page_content(url)

soup = BeautifulSoup(content,'html.parser')

#-------------------------------------------------------------
tilel = soup.select_one('h1.text-h5-180').text
star = soup.select_one('p.text-body1-strong')
star = float(star.text) if star else 0
price = soup.select_one('div.w-full.flex.gap-1.item-center').text
price = covert_price(price)
colors = soup.select('span.text-body-1-180.whitespace-nowrap.text-neutral-650')
colors = [color.text for color in colors if color ]
#-------------------------------------------------------------

detail = soup.select_one('table.border-collapse')
print(detail)

No matter what I try, content is always None.

I’ve tried:

Adding await asyncio.sleep(2)

Using waitUntil: ‘networkidle2’

Making sure Chromium path is valid

Changing selectors

Still, page.content() returns nothing or fails.

The Digikala page works in the browser, but not with Pyppeteer.

How can I properly render and scrape content from Digikala with Pyppeteer?

I tried several approaches to make sure the page content is fully loaded before extracting it:

Added await asyncio.sleep(2) after page.goto to wait extra time for rendering.

Used waitUntil: ‘networkidle2’ in page.goto to wait until network activity calms down.

Tried await page.waitForSelector(‘div#ProductTopFeatures’) to wait for a specific element on the page.

Verified the Chromium executable path is correct.

Checked if the URL is accessible and not blocked.

Used BeautifulSoup to parse the returned HTML content.

I expected to get the full HTML content of the product page with all dynamic elements rendered, so I could scrape the product details successfully.
But instead, the content is always None or empty.

I’m trying to filter an array of objects based on a specific condition, but I’m not getting the expected output [duplicate]

I’m trying to filter an array of objects in JavaScript based on the age field. I expected the result to return objects with age === 25, but the output is an empty array. Here’s my code:

const data = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 25 }
];

const result = data.filter(person => person.age === "25");
console.log(result);

Expected Output:

[
  { name: "Alice", age: 25 },
  { name: "Charlie", age: 25 }
]

Actual Output:

[]

What I Tried:

  • Used == instead of === and it worked.
  • Checked data types using typeof person.age → it’s number.
  • Changed "25" to 25 in filter condition and it worked.

Question:

Is this a data type issue? What’s the best practice in such cases to avoid unexpected empty results?

When specifying the mimeType for a Gremlin connecting, what is the significance of ‘types=false’?

I am connecting to various implementations of Gremlin using the javascript library and websockets. I am attempting to make my code interoperable with various gremlin servers, all support roughly the same version of Gremlin.

A strange behaviour that I don’t quite grasp is the use of ‘types=false’ being added to the mimeType for some server configurations, i.e:

driver = new gremlin.driver.Client(`ws://localhost:8182/gremlin`,
{
  traversalsource: 'g',
  rejectUnauthorized: false,
  ssl: false,
  mimeType: 'application/vnd.gremlin-v3.0+json;types=false'
}

I understand, the above mimetype to be the default for Tinkerpop.

In some systems I’m testing against, with types=false, gremlin queries result in the following error (which is not present when types=false is omitted):

ResponseError: Server error (no request information): Invalid OpProcessor requested [null] (499)
    at /dev/node_modules/gremlin/lib/driver/connection.js:260:13
    at Array.forEach (<anonymous>)
    at Connection._handleMessage (/dev/node_modules/gremlin/lib/driver/connection.js:254:43)
    at WebSocket.<anonymous> (/dev/node_modules/gremlin/lib/driver/connection.js:131:43)
    at WebSocket.emit (node:events:507:28)
    at Receiver.receiverOnMessage (/dev/node_modules/ws/lib/websocket.js:789:20)
    at Receiver.emit (node:events:507:28)
    at Receiver.dataMessage (/dev/node_modules/ws/lib/receiver.js:413:14)
    at Receiver.getData (/dev/node_modules/ws/lib/receiver.js:352:17)
    at Receiver.startLoop (/dev/node_modules/ws/lib/receiver.js:138:22) {
  statusCode: 499,
  statusMessage: 'Invalid OpProcessor requested [null]',
  statusAttributes: {}

I’d like to understand what types=false does. I understand requests are matched with various opcodes for de-serialization, and eval’ed. When I stepped into Gremlin javascript, I saw both (opcode and bindings) as being undefined but can’t determine why.

In the documentation for GraphSON3, the section begins with:

Version 3.0

Version 3.0 of GraphSON was first introduced on TinkerPop 3.3.0 and is
the default format when not specified as of this version. It is quite
similar to GraphSON 2.0 and in most cases will appear compatible to
the eye, however there are some critical differences:

GraphSON 3.0 does not have an option to be typeless. Types are always
embedded.

GraphSON 2.0 relied on JSON data types for collections like Map and
List. In GraphSON 3.0, there is explicit typed support for Map, List
and Set as Gremlin relies on those types in quite specific ways that
are not directly compatible with the JSON definitions of those
collections. In the case of List and Set, it was important to
distinguish between the two and for Map it was necessary to have the
ability to return Map instances that did not have String keys (e.g.
g.V().out().groupCount()).

Does this imply types=false is invalid in my context? (incidentally, the same error occurs if I switch the mimeType to 'application/vnd.gremlin-v3.0+json;types=false')

Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react

I am trying to run a React microfrontend application using Webpack Module Federation. The container app (container-app) loads remote apps (mfe-dashboard, mfe-portfolio) dynamically using promise new Promise(…).
But I am getting error in chrome console as

main.js:995 Uncaught Error: Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react
    at __webpack_require__.m.<computed> (main.js:995:54)
    at __webpack_require__ (main.js:228:32)
    at fn (main.js:508:21)
    at eval (index.js:2:63)
    at ./src/index.js (main.js:201:1)
    at __webpack_require__ (main.js:228:32)
    at main.js:1623:37
    at main.js:1625:12

I have shared my code as below. Can anyone please suggest some solution.

container-app/webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");
const { ModuleFederationPlugin } = require("webpack").container;
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  mode: "development",
  devServer: {
    port: 3000,
    historyApiFallback: true,
  },
  output: {
    publicPath: "auto",
  },
  module: {
    rules: [
      {
        test: /.jsx?$/,
        loader: "babel-loader",
        exclude: /node_modules/,
        options: {
          presets: ["@babel/preset-env", "@babel/preset-react"],
        },
      },
    ],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "container",
      remotes: {
        portfolio: "portfolio@promise new Promise(resolve => {n    const script = document.createElement('script');n    script.src = 'http://localhost:3001/remoteEntry.js';n    script.onload = () => {n      resolve(window.portfolio);n    };n    document.head.appendChild(script);n  })",
        dashboard: "dashboard@promise new Promise(resolve => {n    const script = document.createElement('script');n    script.src = 'http://localhost:3003/remoteEntry.js';n    script.onload = () => {n      resolve(window.dashboard);n    };n    document.head.appendChild(script);n  })"
      },
      shared: {
        react: { singleton: true, strictVersion: true, requiredVersion: "18.2.0" },
        "react-dom": { singleton: true, strictVersion: true, requiredVersion: "18.2.0" },
      },
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
  resolve: {
    extensions: [".js", ".jsx"],
  },
};

mfe-dashboard/webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require("webpack").container;

module.exports = {
  entry: './src/index.js',
  mode: 'development',
  devServer: {
    port: 3003,
    historyApiFallback: true
  },
  output: {
    publicPath: 'auto'
  },
  resolve: {
    extensions: ['.js', '.jsx']
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'dashboard',
      filename: 'remoteEntry.js',
      exposes: {
        './Dashboard': './src/components/Dashboard'
      },
     shared: {
        react: { singleton: true, strictVersion: true, requiredVersion: "18.2.0" },
        "react-dom": { singleton: true, strictVersion: true, requiredVersion: "18.2.0" },
      },
    }),
    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ]
};

mfe-portfolio/webpack.config.js

-------------------------------------
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require("webpack").container;
const path = require('path');

module.exports = {
  entry: './src/index.js',
  mode: 'development',
  devServer: {
    port: 3001
  },
  output: {
    publicPath: 'auto'
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  },
    resolve: {
    extensions: ['.js', '.jsx']
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'portfolio',
      filename: 'remoteEntry.js',
      exposes: {
        './Portfolio': './src/components/Portfolio'
      },
      shared: {
        react: { singleton: true, strictVersion: true, requiredVersion: "18.2.0" },
        "react-dom": { singleton: true, strictVersion: true, requiredVersion: "18.2.0" },
      },
    }),
    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ],
  resolve: {
    extensions: ['.js', '.jsx']
  }
};

enter image description here

enter image description here

Canvas svg manipulation and glsl

I am trying to build a 3d configurator application which you can select a pattern or sticker etc.. and it applies on model.

Before i was using glsl and shaders and it was perfect but i needed to switch to canvas, now i have a canvas and im trying to implement everything on it and canvas implemented on model through shaders.

right now im trying draw selected svg to canvas but it is very slow, inefficient, bad resolution and not all svg’s are working

Is there any way to do it better?
thank you

export const drawPatternsOnCanvas = (ctx, itemsOnTshirt, uvConditions) => {
  itemsOnTshirt.forEach((item) => {
    if (item.type !== "pattern" || !item.img) return;

    const uv = uvConditions[item.part];
    if (!uv) return;
    const canvasSize = 100;
    const img = new Image();
    img.src = item.pattern; //item.pattern="/pattern/pattern01.svg"

    img.crossOrigin = "anonymous";

    img.onload = () => {
      const minX = uv[0];
      const maxX = uv[1];
      const minY = uv[2];
      const maxY = uv[3];

      const regionWidth = maxX - minX;
      const regionHeight = maxY - minY;

      const coloredPattern = document.createElement("canvas");
      coloredPattern.width = img.width;
      coloredPattern.height = img.height;
      const cpCtx = coloredPattern.getContext("2d");

      cpCtx.drawImage(img, 0, 0);

      cpCtx.globalCompositeOperation = "source-atop";
      cpCtx.fillStyle = `rgb(${Math.floor(item.color[0] * 255)}, ${Math.floor(
        item.color[1] * 255
      )}, ${Math.floor(item.color[2] * 255)})`;
      cpCtx.fillRect(0, 0, img.width, img.height);
      cpCtx.globalCompositeOperation = "source-over";

      const fillPattern = ctx.createPattern(coloredPattern, "repeat");

      if (fillPattern.setTransform) {
        const rotationDegrees = parseFloat(item.rotation) || 0;
        const patternRatioX = img.width / canvasSize;
        const patternRatioY = img.height / canvasSize;

        const center = canvasSize * 0.5;

        const matrix = new DOMMatrix()
          .translateSelf(center, center)
          .rotateSelf(-rotationDegrees)
          .scaleSelf(item.scale / patternRatioX, -item.scale / patternRatioY)
          .translateSelf(item.moveX * canvasSize, item.moveY * canvasSize)
          .translateSelf(-center, -center);

        fillPattern.setTransform(matrix);
      }
      ctx.save();
      ctx.beginPath();
      ctx.rect(minX, minY, regionWidth, regionHeight);
      ctx.clip();

      ctx.fillStyle = fillPattern;
      ctx.fillRect(minX, minY, regionWidth, regionHeight);
      ctx.restore();
    };
  });
};

this is the code which implies pattern svg into canvas

export const createUnifiedCanvasTexture = (
  uvConditions,
  colorsForparts,
  itemsOnTshirt
) => {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  const width = (canvas.width = 1000);
  const height = (canvas.height = 1000)
  
  //drawing colors
  drawUVRegions(ctx, uvConditions, colorsForparts);

  // Draw patterns
  drawPatternsOnCanvas(ctx, itemsOnTshirt, uvConditions);
  //inside color
  ctx.fillStyle = "#ffffff";
  ctx.fillRect(1, 180, 124, -179);

  const texture = new THREE.CanvasTexture(canvas);
  texture.flipY = false;
  texture.needsUpdate = true;

  return texture;
};

and this is my main canvas which is connected to shaders and model

Displaying Gantt Chart with Partial Date Data in Highcharts

How can I display this using a Highcharts Gantt chart? I reviewed this example: https://www.highcharts.com/demo/gantt/subtasks, but I only have start/end dates for Phase 3 — not for the other phases. I have the following code but not sure if thats the best way to display. Also I am not sure why the display for May 2025 is cut off? Any thoughts? Thanks in advance.

const statusColorMap = {
      "Completed": "#90ee90",
      "In Progress": "#f4e542",
      "Not Started": "#d3d3d3"
    };

    Highcharts.ganttChart('container', {
      title: { text: 'Project Timeline with Status' },
      tooltip: {
        pointFormatter: function () {
          return `<b>${this.name}</b><br/>Status: ${this.status || 'N/A'}<br/>` +
            (this.milestone ? `Milestone: ${Highcharts.dateFormat('%b %e, %Y', this.start)}` :
              `From: ${Highcharts.dateFormat('%b %e, %Y', this.start)} to ${Highcharts.dateFormat('%b %e, %Y', this.end)}`);
        }
      },
      series: [{
        name: 'Project',
        data: [
          // Parent Phases
          { id: 'phase1', name: 'Phase I: DEV' },
          { id: 'phase2', name: 'Phase II: TEST' },
          { id: 'phase3', name: 'Phase III: DEPLOY' },

          // Phase I
          { name: 'ABC', parent: 'phase1', start: Date.UTC(2025, 4, 14), milestone: true, status: 'Completed', color: statusColorMap['Completed'] },
          { name: 'XYZ', parent: 'phase1', start: Date.UTC(2025, 4, 15), milestone: true, status: 'Completed', color: statusColorMap['Completed'] },
          { name: 'XXXY', parent: 'phase1', start: Date.UTC(2025, 5, 30), milestone: true, status: 'In Progress', color: statusColorMap['In Progress'] },
          { name: 'SDD', parent: 'phase1', milestone: true, status: 'Not Started', color: statusColorMap['Not Started'] },
          { name: 'DFF', parent: 'phase1', start: Date.UTC(2025, 5, 30), milestone: true, status: 'Completed', color: statusColorMap['Completed'] },
          { name: 'DSD', parent: 'phase1', start: Date.UTC(2025, 7, 1), milestone: true, status: 'Not Started', color: statusColorMap['Not Started'] },

          // Phase II
          { name: 'SDEWR', parent: 'phase2', start: Date.UTC(2025, 5, 25), milestone: true, status: 'Completed', color: statusColorMap['Completed'] },
          { name: 'RERRE', parent: 'phase2', start: Date.UTC(2025, 5, 30), milestone: true, status: 'Completed', color: statusColorMap['Completed'] },
          { name: 'FDR', parent: 'phase2', start: Date.UTC(2025, 6, 30), milestone: true, status: 'In Progress', color: statusColorMap['In Progress'] },
          { name: 'DFFG', parent: 'phase2', start: Date.UTC(2025, 8, 30), milestone: true, status: 'Not Started', color: statusColorMap['Not Started'] },
          { name: 'ASSA', parent: 'phase2', start: Date.UTC(2025, 9, 1), milestone: true, status: 'Not Started', color: statusColorMap['Not Started'] },

          // Phase III
          { name: 'GF', parent: 'phase3', start: Date.UTC(2025, 9, 1), end: Date.UTC(2026, 8, 30), status: 'Not Started', color: statusColorMap['Not Started'] },
          { name: 'DFTT', parent: 'phase3', start: Date.UTC(2026, 9, 1), end: Date.UTC(2027, 8, 30), status: 'Not Started', color: statusColorMap['Not Started'] },
          { name: 'SERR', parent: 'phase3', start: Date.UTC(2027, 9, 1), end: Date.UTC(2028, 8, 30), status: 'Not Started', color: statusColorMap['Not Started'] }
        ]
      }]
    });
<!DOCTYPE html>
<html>
<head>
 
  <script src="https://code.highcharts.com/gantt/highcharts-gantt.js"></script>
</head>
<body>
  <div id="container" style="height: 900px; min-width: 1000px;"></div>

Slick Slider Ticker Gets Jittery After Window Resize

I have a Slick Slider on a page, and I have it setup as a ticker. It is setup to be responsive so it shows different amount of slides at different breakpoints. All seems to be working fine, but when you resize the browser window and it crosses one of these breakpoints everything becomes jittery. The slides jump back and forth instead of running smooth like before the resize.

I have a CodePen here: https://codepen.io/tmurren/pen/ByojoNZ

These are the Slick settings I’m using:

$('.ticker').slick({
  slidesToShow: 2,
  slidesToScroll: 1,
  infinite: true,
  autoplay: true,
  autoplaySpeed: 0,
  speed: 3000,
  cssEase:'linear',
  arrows: false,
  dots: false,
  pauseOnHover: false,
  pauseOnFocus: false,
  swipe: false,
  swipeToSlide: false,
  mobileFirst: true,
  responsive: [
    {
      breakpoint: 600,
      settings: {
        slidesToShow: 3,
      }
    },
    {
      breakpoint: 768,
      settings: {
        slidesToShow: 4,
      }
    },
    {
      breakpoint: 992,
      settings: {
        slidesToShow: 5,
      }
    },
    {
      breakpoint: 1200,
      settings: {
        slidesToShow: 6,
      }
    },
    {
      breakpoint: 1440,
      settings: {
        slidesToShow: 7,
      }
    }
  ]
});

Deploy/update file without functions in it – Firebase Functions

I am trying to update a file named blues.cts because a function named fetchAllPacks uses it to update the client. I was wondering if, without updating the functions, I could update the JSON data in that file? The following is blues.cts that I would like to update. It has this data object, interfaces, and a few functions.

export const data = {
    "specials": {
        "Alien Cat": {
            "cost": 0,
            "bluedata": "Alien Cat",
...

This is my functions script, and I see there is no need to update this function.

export const fetchAllPacks = onCall({enforceAppCheck: true}, async (req) => {
    if (req.auth == null) {return {success: false, error: ReturnError.auth.invalid}}
    return {success:true, packs: shop.getAllPacks()};
});