From 2dc1a1ea6eed15fdacb5f75e3c5c744cc1a8f77a Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:31:15 +0930
Subject: [PATCH 01/22] chore: add site hardening patch
---
scripts/apply-site-trust-performance.py | 538 ++++++++++++++++++++++++
1 file changed, 538 insertions(+)
create mode 100644 scripts/apply-site-trust-performance.py
diff --git a/scripts/apply-site-trust-performance.py b/scripts/apply-site-trust-performance.py
new file mode 100644
index 0000000..25ffc35
--- /dev/null
+++ b/scripts/apply-site-trust-performance.py
@@ -0,0 +1,538 @@
+from pathlib import Path
+
+
+def replace(path: str, old: str, new: str, *, count: int | None = 1) -> None:
+ file_path = Path(path)
+ text = file_path.read_text(encoding="utf-8")
+ occurrences = text.count(old)
+ if occurrences == 0:
+ raise RuntimeError(f"Expected text not found in {path}: {old[:80]!r}")
+ if count is not None and occurrences != count:
+ raise RuntimeError(
+ f"Expected {count} occurrence(s) in {path}, found {occurrences}: {old[:80]!r}"
+ )
+ file_path.write_text(text.replace(old, new), encoding="utf-8")
+
+
+# Ambient sound should be a deliberate choice for first-time visitors. People
+# who previously opted in still resume on their next eligible interaction.
+audio_path = Path("components/blue-hour/AudioExperience.tsx")
+audio = audio_path.read_text(encoding="utf-8")
+old_audio_gate = "readAudioPreference('blue-hour-sound') === 'off'"
+count = audio.count(old_audio_gate)
+if count != 3:
+ raise RuntimeError(f"Expected 3 legacy audio preference checks, found {count}")
+audio = audio.replace(
+ old_audio_gate,
+ "readAudioPreference('blue-hour-sound') !== 'on'",
+)
+audio_path.write_text(audio, encoding="utf-8")
+
+# Version service-worker registrations per deploy and reload exactly once when a
+# new worker takes over an already-controlled tab.
+Path("components/Providers.tsx").write_text(
+ """'use client';
+
+import { useEffect, type ReactNode } from 'react';
+import { BlueHourAudioProvider } from './blue-hour/AudioExperience';
+
+const BUILD_ID = process.env.NEXT_PUBLIC_BUILD_ID ?? 'local';
+
+export function Providers({ children }: { children: ReactNode }) {
+ useEffect(() => {
+ if (process.env.NODE_ENV !== 'production') return;
+ if (!('serviceWorker' in navigator)) return;
+
+ const hadController = Boolean(navigator.serviceWorker.controller);
+ const reloadKey = `blue-hour-sw-reloaded:${BUILD_ID}`;
+ const onControllerChange = () => {
+ if (!hadController) return;
+ try {
+ if (window.sessionStorage.getItem(reloadKey) === '1') return;
+ window.sessionStorage.setItem(reloadKey, '1');
+ } catch {
+ // Reloading once is still safe when session storage is unavailable.
+ }
+ window.location.reload();
+ };
+
+ navigator.serviceWorker.addEventListener('controllerchange', onControllerChange);
+ void navigator.serviceWorker
+ .register(`/sw.js?v=${encodeURIComponent(BUILD_ID)}`, {
+ updateViaCache: 'none',
+ })
+ .then((registration) => registration.update())
+ .catch((error: unknown) => {
+ console.warn('[Austin Liu site] Service worker registration failed:', error);
+ });
+
+ return () => {
+ navigator.serviceWorker.removeEventListener(
+ 'controllerchange',
+ onControllerChange,
+ );
+ };
+ }, []);
+
+ return {children} ;
+}
+""",
+ encoding="utf-8",
+)
+
+# Keep media across deployments, but version page and static caches using the
+# build SHA embedded in the service-worker URL.
+Path("public/sw.js").write_text(
+ """/* Offline support: immutable build files, bounded media, fresh pages. */
+const VERSION =
+ new URL(self.location.href).searchParams.get('v')?.replace(/[^a-zA-Z0-9_-]/g, '') ||
+ 'local';
+const STATIC_CACHE = `al-blue-hour-static-${VERSION}`;
+const PAGE_CACHE = `al-blue-hour-pages-${VERSION}`;
+const MEDIA_CACHE = 'al-blue-hour-media-v7';
+const CURRENT_CACHES = new Set([STATIC_CACHE, MEDIA_CACHE, PAGE_CACHE]);
+const CACHE_PREFIX = 'al-blue-hour-';
+const INDEPENDENT_APP_PATHS = ['/KnightClub/', '/Denki/'];
+const MEDIA_LIMIT = 180;
+const SHELL = ['/', '/404.html', '/manifest.webmanifest', '/icon.svg'];
+
+async function cacheIndividually(cache, urls) {
+ await Promise.allSettled(urls.map((url) => cache.add(url)));
+}
+
+self.addEventListener('install', (event) => {
+ event.waitUntil(
+ caches
+ .open(PAGE_CACHE)
+ .then((cache) => cacheIndividually(cache, SHELL))
+ .then(() => self.skipWaiting()),
+ );
+});
+
+self.addEventListener('activate', (event) => {
+ event.waitUntil(
+ caches
+ .keys()
+ .then((keys) =>
+ Promise.all(
+ keys
+ .filter(
+ (key) =>
+ key.startsWith(CACHE_PREFIX) && !CURRENT_CACHES.has(key),
+ )
+ .map((key) => caches.delete(key)),
+ ),
+ )
+ .then(() => self.clients.claim()),
+ );
+});
+
+async function trimCache(cache, limit) {
+ const keys = await cache.keys();
+ if (keys.length <= limit) return;
+ await Promise.all(
+ keys.slice(0, keys.length - limit).map((key) => cache.delete(key)),
+ );
+}
+
+async function cacheSuccessfulResponse(cacheName, request, response) {
+ if (!response.ok || response.type !== 'basic') return response;
+ const cache = await caches.open(cacheName);
+ await cache.put(request, response.clone());
+ return response;
+}
+
+async function navigationFallback(request) {
+ const cache = await caches.open(PAGE_CACHE);
+ return (
+ (await cache.match(request)) ||
+ (await cache.match('/')) ||
+ (await cache.match('/404.html')) ||
+ Response.error()
+ );
+}
+
+self.addEventListener('fetch', (event) => {
+ const { request } = event;
+ if (request.method !== 'GET') return;
+
+ const url = new URL(request.url);
+ if (url.origin !== location.origin) return;
+ if (
+ INDEPENDENT_APP_PATHS.some(
+ (path) => url.pathname === path.slice(0, -1) || url.pathname.startsWith(path),
+ )
+ ) {
+ return;
+ }
+
+ // Let the browser own streamed audio/video and byte-range requests. A synthetic
+ // service-worker response can break seeking or return a partial file as if it
+ // were the whole recording.
+ if (
+ url.pathname.startsWith('/assets/audio/') ||
+ url.pathname.startsWith('/assets/video/') ||
+ request.headers.has('range')
+ ) {
+ return;
+ }
+
+ // Next build filenames are content-hashed, so a cache hit is final.
+ if (url.pathname.startsWith('/_next/static/')) {
+ event.respondWith(
+ caches.open(STATIC_CACHE).then(async (cache) => {
+ const hit = await cache.match(request);
+ if (hit) return hit;
+ const response = await fetch(request);
+ return cacheSuccessfulResponse(STATIC_CACHE, request, response);
+ }),
+ );
+ return;
+ }
+
+ // Media can keep stable URLs across edits: show the cache, refresh quietly.
+ if (url.pathname.startsWith('/assets/')) {
+ const cachePromise = caches.open(MEDIA_CACHE);
+ const hitPromise = cachePromise.then((cache) => cache.match(request));
+ const refreshPromise = cachePromise.then(async (cache) => {
+ const response = await fetch(request);
+ if (response.ok && response.type === 'basic') {
+ await cache.put(request, response.clone());
+ await trimCache(cache, MEDIA_LIMIT);
+ }
+ return response;
+ });
+
+ event.waitUntil(refreshPromise.then(() => undefined).catch(() => undefined));
+ event.respondWith(
+ hitPromise.then(async (hit) => {
+ if (hit) return hit;
+ return refreshPromise.catch(() => Response.error());
+ }),
+ );
+ return;
+ }
+
+ // Pages and everything else: prefer the network so deploys show up immediately.
+ event.respondWith(
+ fetch(request)
+ .then((response) =>
+ cacheSuccessfulResponse(PAGE_CACHE, request, response),
+ )
+ .catch(() => navigationFallback(request)),
+ );
+});
+""",
+ encoding="utf-8",
+)
+
+# Make the homepage and structured identity immediately explain what the site is.
+replace(
+ "components/blue-hour/BlueHourSite.tsx",
+ "I'm Austin Liu — a dental student in Adelaide.",
+ "I'm Austin Liu — a dental student in Adelaide, building useful software and keeping a record of places.",
+)
+replace(
+ "components/LegacyPages.tsx",
+ "A builder and traveller from China, now based in Adelaide — making\n small digital tools, collecting places, and keeping a public record\n of the things that hold my attention.",
+ "A dental student, builder, and traveller from China, now based in\n Adelaide — making small digital tools, collecting places, and keeping\n a public record of the things that hold my attention.",
+)
+replace(
+ "config/site.ts",
+ "Austin Liu’s personal space for building useful products, travelling with a camera, writing field notes, and paying attention to a wider life.",
+ "Austin Liu is a dental student and independent builder in Adelaide, making useful software and keeping a visual record of places, ideas, and ordinary days.",
+)
+replace(
+ "config/site.ts",
+ "Builder, traveller, writer, and photographer based in Adelaide, making useful tools and keeping a record of places, ideas, and ordinary days.",
+ "Dental student, builder, traveller, writer, and photographer based in Adelaide, making useful tools and keeping a record of places, ideas, and ordinary days.",
+)
+replace(
+ "app/about/page.tsx",
+ "Builder, traveller, photographer, and writer behind The Last Blue Hour.",
+ "Dental student, builder, traveller, photographer, and writer behind The Last Blue Hour.",
+)
+
+# Add explicit build and static-export verification scripts.
+replace(
+ "package.json",
+ ' "build": "next build",\n "build:sites": "npm run build && node scripts/build-sites.mjs",\n "start": "next start",\n "lint": "next lint"',
+ ' "build": "next build",\n "build:sites": "npm run build && node scripts/build-sites.mjs",\n "start": "next start",\n "typecheck": "tsc --noEmit",\n "validate:export": "node scripts/validate-export.mjs",\n "check": "npm run typecheck && npm run build && npm run validate:export",\n "lint": "next lint"',
+)
+
+Path("scripts/validate-export.mjs").write_text(
+ r"""import { readFile, readdir, stat } from 'node:fs/promises';
+import path from 'node:path';
+import { spawnSync } from 'node:child_process';
+import { fileURLToPath } from 'node:url';
+
+const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
+const outDir = path.join(root, 'out');
+const origin = 'https://static-export.local';
+
+async function walk(directory) {
+ const entries = await readdir(directory, { withFileTypes: true });
+ const files = [];
+ for (const entry of entries) {
+ const absolute = path.join(directory, entry.name);
+ if (entry.isDirectory()) files.push(...(await walk(absolute)));
+ else files.push(absolute);
+ }
+ return files;
+}
+
+function outputPath(file) {
+ return `/${path.relative(outDir, file).split(path.sep).join('/')}`;
+}
+
+function pageUrlFor(filePath) {
+ if (filePath === '/index.html') return '/';
+ if (filePath.endsWith('/index.html')) {
+ return filePath.slice(0, -'index.html'.length);
+ }
+ return filePath;
+}
+
+function candidateFiles(pathname) {
+ const clean = decodeURIComponent(pathname).replace(/\/+/g, '/');
+ if (clean.endsWith('/')) return [`${clean}index.html`];
+ if (path.posix.extname(clean)) return [clean];
+ return [clean, `${clean}.html`, `${clean}/index.html`];
+}
+
+function extractReferences(html) {
+ const references = [];
+ const attributes = /\b(?:href|src|poster)\s*=\s*["']([^"']+)["']/gi;
+ for (const match of html.matchAll(attributes)) references.push(match[1]);
+
+ const sourceSets = /\bsrcset\s*=\s*["']([^"']+)["']/gi;
+ for (const match of html.matchAll(sourceSets)) {
+ for (const item of match[1].split(',')) {
+ const reference = item.trim().split(/\s+/)[0];
+ if (reference) references.push(reference);
+ }
+ }
+ return references;
+}
+
+function extractIds(html) {
+ const ids = new Set();
+ const pattern = /\b(?:id|name)\s*=\s*["']([^"']+)["']/gi;
+ for (const match of html.matchAll(pattern)) ids.add(match[1]);
+ return ids;
+}
+
+const files = await walk(outDir);
+const fileSet = new Set(files.map(outputPath));
+const htmlFiles = files.filter((file) => file.endsWith('.html'));
+const htmlByUrl = new Map();
+const idsByFile = new Map();
+
+for (const file of htmlFiles) {
+ const relative = outputPath(file);
+ const html = await readFile(file, 'utf8');
+ htmlByUrl.set(pageUrlFor(relative), { file, relative, html });
+ idsByFile.set(relative, extractIds(html));
+}
+
+const failures = [];
+let checkedReferences = 0;
+for (const { relative, html } of htmlByUrl.values()) {
+ const pageUrl = new URL(pageUrlFor(relative), origin);
+ for (const rawReference of extractReferences(html)) {
+ if (
+ !rawReference ||
+ rawReference === '#' ||
+ rawReference.startsWith('data:') ||
+ rawReference.startsWith('blob:') ||
+ rawReference.startsWith('mailto:') ||
+ rawReference.startsWith('tel:') ||
+ rawReference.startsWith('javascript:') ||
+ rawReference.startsWith('//')
+ ) {
+ continue;
+ }
+
+ let resolved;
+ try {
+ resolved = new URL(rawReference, pageUrl);
+ } catch {
+ failures.push(`${relative}: invalid URL ${JSON.stringify(rawReference)}`);
+ continue;
+ }
+ if (resolved.origin !== origin) continue;
+
+ checkedReferences += 1;
+ const candidates = candidateFiles(resolved.pathname);
+ const target = candidates.find((candidate) => fileSet.has(candidate));
+ if (!target) {
+ failures.push(
+ `${relative}: ${JSON.stringify(rawReference)} does not resolve to an exported file`,
+ );
+ continue;
+ }
+
+ if (resolved.hash && target.endsWith('.html')) {
+ const fragment = decodeURIComponent(resolved.hash.slice(1));
+ if (fragment && !idsByFile.get(target)?.has(fragment)) {
+ failures.push(
+ `${relative}: ${JSON.stringify(rawReference)} points to missing #${fragment}`,
+ );
+ }
+ }
+ }
+}
+
+for (const required of [
+ '/index.html',
+ '/404.html',
+ '/robots.txt',
+ '/sitemap.xml',
+ '/feed.xml',
+ '/manifest.webmanifest',
+ '/sw.js',
+]) {
+ if (!fileSet.has(required)) failures.push(`Missing required export: ${required}`);
+}
+
+const manifestPath = path.join(outDir, 'manifest.webmanifest');
+try {
+ JSON.parse(await readFile(manifestPath, 'utf8'));
+} catch (error) {
+ failures.push(`manifest.webmanifest is invalid JSON: ${error.message}`);
+}
+
+const workerPath = path.join(outDir, 'sw.js');
+const workerCheck = spawnSync(process.execPath, ['--check', workerPath], {
+ encoding: 'utf8',
+});
+if (workerCheck.status !== 0) {
+ failures.push(`sw.js failed syntax validation: ${workerCheck.stderr.trim()}`);
+}
+
+if (failures.length > 0) {
+ console.error(`Static export validation failed with ${failures.length} problem(s):`);
+ failures.forEach((failure) => console.error(`- ${failure}`));
+ process.exit(1);
+}
+
+const totalBytes = (
+ await Promise.all(files.map(async (file) => (await stat(file)).size))
+).reduce((sum, size) => sum + size, 0);
+console.log(
+ `Validated ${htmlFiles.length} pages, ${checkedReferences} internal references, and ${(totalBytes / 1024 / 1024).toFixed(1)} MB of exported files.`,
+);
+""",
+ encoding="utf-8",
+)
+
+# CI and deployment now use the same complete verification gate and embed the
+# commit SHA into the service-worker registration.
+Path(".github/workflows/ci.yml").write_text(
+ """name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: npm
+ - name: Install dependencies
+ run: npm ci
+ - name: Typecheck
+ run: npm run typecheck
+ - name: Build static export
+ run: npm run build
+ - name: Validate routes and assets
+ run: npm run validate:export
+""",
+ encoding="utf-8",
+)
+
+Path(".github/workflows/deploy.yml").write_text(
+ """name: Deploy Next.js site to GitHub Pages
+
+on:
+ push:
+ branches: [main]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: true
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: npm
+ - name: Install dependencies
+ run: npm ci
+ - name: Typecheck
+ run: npm run typecheck
+ - name: Build static export
+ run: npm run build
+ - name: Validate routes and assets
+ run: npm run validate:export
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./out
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+""",
+ encoding="utf-8",
+)
+
+replace(
+ "README.md",
+ "* **PWA** — web manifest plus a service worker for offline reading (network-first pages, stale-while-revalidate assets).",
+ "* **PWA** — opt-in ambience, a versioned service worker, and offline reading without letting an older deploy pin stale pages or chunks.",
+)
+replace(
+ "README.md",
+ "* **Build Pipeline**: Static site generation producing optimized static assets to `out/` for edge deployment; CI typechecks and builds on every push to `main`, then deploys to GitHub Pages.",
+ "* **Build Pipeline**: Static site generation to `out/`; CI typechecks, builds, validates every internal route/asset/fragment, and only then deploys to GitHub Pages.",
+)
+replace(
+ "README.md",
+ "```bash\nnpm run build\n```",
+ "```bash\nnpm run check\n```\n\n`npm run check` typechecks, builds the complete static export, and verifies that internal links, fragments, required metadata files, and service-worker syntax are valid.",
+)
+
+print("Applied site trust, performance, and content hardening pass.")
From af607a3419d1c82410ecffea30c90f2a0a43579e Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:31:33 +0930
Subject: [PATCH 02/22] chore(ci): apply verified site hardening pass
---
.../apply-site-trust-performance.yml | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 .github/workflows/apply-site-trust-performance.yml
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
new file mode 100644
index 0000000..b76a059
--- /dev/null
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -0,0 +1,44 @@
+name: Apply site trust and performance pass
+
+on:
+ push:
+ branches: [refactor/site-trust-performance]
+ paths:
+ - .github/workflows/apply-site-trust-performance.yml
+
+permissions:
+ contents: write
+
+jobs:
+ patch-and-verify:
+ if: github.actor != 'github-actions[bot]'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout branch
+ uses: actions/checkout@v4
+ with:
+ ref: refactor/site-trust-performance
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: npm
+ - name: Apply focused patch
+ run: python3 scripts/apply-site-trust-performance.py
+ - name: Install dependencies
+ run: npm ci
+ - name: Verify complete static export
+ env:
+ NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
+ run: npm run check
+ - name: Commit verified changes
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add -A
+ if git diff --cached --quiet; then
+ echo "No changes to commit"
+ exit 0
+ fi
+ git commit -m "refactor(site): harden first-load consent and deploy integrity"
+ git push origin HEAD:refactor/site-trust-performance
From 50ccbd69e42ce048268b11f45774014432d34ce2 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:34:20 +0930
Subject: [PATCH 03/22] chore(ci): allow verified non-workflow patch push
---
.github/workflows/apply-site-trust-performance.yml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
index b76a059..0da5124 100644
--- a/.github/workflows/apply-site-trust-performance.yml
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -21,7 +21,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
- node-version: 20
+ node-version: 22
cache: npm
- name: Apply focused patch
run: python3 scripts/apply-site-trust-performance.py
@@ -31,7 +31,9 @@ jobs:
env:
NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
run: npm run check
- - name: Commit verified changes
+ - name: Keep workflow edits for the connector
+ run: git restore .github/workflows/ci.yml .github/workflows/deploy.yml
+ - name: Commit verified application changes
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
From 950f3e454f19a5081f2d3b0dbf654fd9df7a5c14 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 16 Aug 2026 15:05:02 +0000
Subject: [PATCH 04/22] refactor(site): harden first-load consent and deploy
integrity
---
README.md | 8 +-
app/about/page.tsx | 2 +-
components/LegacyPages.tsx | 6 +-
components/Providers.tsx | 33 ++++-
components/blue-hour/AudioExperience.tsx | 6 +-
components/blue-hour/BlueHourSite.tsx | 2 +-
config/site.ts | 4 +-
package.json | 3 +
public/sw.js | 61 ++++++---
scripts/validate-export.mjs | 161 +++++++++++++++++++++++
10 files changed, 255 insertions(+), 31 deletions(-)
create mode 100644 scripts/validate-export.mjs
diff --git a/README.md b/README.md
index 0d13df4..a1107d2 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Static-exported personal site built with Next.js 15 App Router and React 19. Des
* **Site-wide search** — ⌘K (or `/`) command palette across pages, notes, and projects.
* **Notes/journal system** — single data source (`config/notes.ts`) driving the index, homepage journal, per-note metadata, prev/next pagination, share actions, and print styles.
* **SEO layer** — `sitemap.xml`, `robots.txt`, RSS (`/feed.xml`), canonical URLs, Open Graph/Twitter cards, and JSON-LD (Person, WebSite, BlogPosting, BreadcrumbList).
-* **PWA** — web manifest plus a service worker for offline reading (network-first pages, stale-while-revalidate assets).
+* **PWA** — opt-in ambience, a versioned service worker, and offline reading without letting an older deploy pin stale pages or chunks.
* **Performance** — responsive `srcset` images, content-visibility-friendly layout, zero-CLS media via CSS aspect ratios.
* **Accessibility** — WCAG AA contrast, keyboard-navigable dialogs and tabs, reduced-motion support, correct `lang` tagging for bilingual content.
@@ -21,7 +21,7 @@ Static-exported personal site built with Next.js 15 App Router and React 19. Des
* **Framework**: Next.js 15 (App Router, static export mode `output: 'export'`).
* **UI & Styling**: React 19, TypeScript, Tailwind CSS, and `next-themes` for system-aware dark mode switching.
-* **Build Pipeline**: Static site generation producing optimized static assets to `out/` for edge deployment; CI typechecks and builds on every push to `main`, then deploys to GitHub Pages.
+* **Build Pipeline**: Static site generation to `out/`; CI typechecks, builds, validates every internal route/asset/fragment, and only then deploys to GitHub Pages.
## Development
@@ -35,9 +35,11 @@ npm run dev
## Build & Export
```bash
-npm run build
+npm run check
```
+`npm run check` typechecks, builds the complete static export, and verifies that internal links, fragments, required metadata files, and service-worker syntax are valid.
+
## License
MIT
diff --git a/app/about/page.tsx b/app/about/page.tsx
index 71c434c..ec6a728 100644
--- a/app/about/page.tsx
+++ b/app/about/page.tsx
@@ -4,7 +4,7 @@ import { pageMetadata } from '@/config/pageMetadata';
export const metadata = pageMetadata({
title: 'About — Austin Liu',
description:
- 'Builder, traveller, photographer, and writer behind The Last Blue Hour.',
+ 'Dental student, builder, traveller, photographer, and writer behind The Last Blue Hour.',
image: '/assets/blue-hour/afterlight-1200.jpg',
imageAlt: 'A small stone cabin with one warm window on a blue moor',
});
diff --git a/components/LegacyPages.tsx b/components/LegacyPages.tsx
index 1638cc2..390d680 100644
--- a/components/LegacyPages.tsx
+++ b/components/LegacyPages.tsx
@@ -214,9 +214,9 @@ export function AboutPage() {
- A builder and traveller from China, now based in Adelaide — making
- small digital tools, collecting places, and keeping a public record
- of the things that hold my attention.
+ A dental student, builder, and traveller from China, now based in
+ Adelaide — making small digital tools, collecting places, and keeping
+ a public record of the things that hold my attention.
diff --git a/components/Providers.tsx b/components/Providers.tsx
index 36006f9..4f4a56f 100644
--- a/components/Providers.tsx
+++ b/components/Providers.tsx
@@ -3,11 +3,42 @@
import { useEffect, type ReactNode } from 'react';
import { BlueHourAudioProvider } from './blue-hour/AudioExperience';
+const BUILD_ID = process.env.NEXT_PUBLIC_BUILD_ID ?? 'local';
+
export function Providers({ children }: { children: ReactNode }) {
useEffect(() => {
if (process.env.NODE_ENV !== 'production') return;
if (!('serviceWorker' in navigator)) return;
- navigator.serviceWorker.register('/sw.js').catch(() => {});
+
+ const hadController = Boolean(navigator.serviceWorker.controller);
+ const reloadKey = `blue-hour-sw-reloaded:${BUILD_ID}`;
+ const onControllerChange = () => {
+ if (!hadController) return;
+ try {
+ if (window.sessionStorage.getItem(reloadKey) === '1') return;
+ window.sessionStorage.setItem(reloadKey, '1');
+ } catch {
+ // Reloading once is still safe when session storage is unavailable.
+ }
+ window.location.reload();
+ };
+
+ navigator.serviceWorker.addEventListener('controllerchange', onControllerChange);
+ void navigator.serviceWorker
+ .register(`/sw.js?v=${encodeURIComponent(BUILD_ID)}`, {
+ updateViaCache: 'none',
+ })
+ .then((registration) => registration.update())
+ .catch((error: unknown) => {
+ console.warn('[Austin Liu site] Service worker registration failed:', error);
+ });
+
+ return () => {
+ navigator.serviceWorker.removeEventListener(
+ 'controllerchange',
+ onControllerChange,
+ );
+ };
}, []);
return
{children} ;
diff --git a/components/blue-hour/AudioExperience.tsx b/components/blue-hour/AudioExperience.tsx
index 025a66b..2e5032a 100644
--- a/components/blue-hour/AudioExperience.tsx
+++ b/components/blue-hour/AudioExperience.tsx
@@ -657,7 +657,7 @@ export function useBlueHourAudio(activeChapter: number): AudioExperience {
}, []);
useEffect(() => {
- if (readAudioPreference('blue-hour-sound') === 'off') return;
+ if (readAudioPreference('blue-hour-sound') !== 'on') return;
const connection = (
navigator as Navigator & { connection?: { saveData?: boolean } }
).connection;
@@ -874,7 +874,7 @@ export function BlueHourAudioProvider({ children }: { children: ReactNode }) {
}, [audio.isPlaying, audio.start]);
useEffect(() => {
- if (readAudioPreference('blue-hour-sound') === 'off') return;
+ if (readAudioPreference('blue-hour-sound') !== 'on') return;
const connection = (
navigator as Navigator & { connection?: { saveData?: boolean } }
).connection;
@@ -900,7 +900,7 @@ export function BlueHourAudioProvider({ children }: { children: ReactNode }) {
return;
}
- if (readAudioPreference('blue-hour-sound') === 'off') {
+ if (readAudioPreference('blue-hour-sound') !== 'on') {
cleanup();
return;
}
diff --git a/components/blue-hour/BlueHourSite.tsx b/components/blue-hour/BlueHourSite.tsx
index 7ecb25e..d818d15 100644
--- a/components/blue-hour/BlueHourSite.tsx
+++ b/components/blue-hour/BlueHourSite.tsx
@@ -1280,7 +1280,7 @@ export function BlueHourSite() {
},
}}
>
- I'm Austin Liu — a dental student in Adelaide.
+ I'm Austin Liu — a dental student in Adelaide, building useful software and keeping a record of places.
{
- self.skipWaiting();
+async function cacheIndividually(cache, urls) {
+ await Promise.allSettled(urls.map((url) => cache.add(url)));
+}
+
+self.addEventListener('install', (event) => {
+ event.waitUntil(
+ caches
+ .open(PAGE_CACHE)
+ .then((cache) => cacheIndividually(cache, SHELL))
+ .then(() => self.skipWaiting()),
+ );
});
self.addEventListener('activate', (event) => {
@@ -32,7 +45,26 @@ self.addEventListener('activate', (event) => {
async function trimCache(cache, limit) {
const keys = await cache.keys();
if (keys.length <= limit) return;
- await Promise.all(keys.slice(0, keys.length - limit).map((key) => cache.delete(key)));
+ await Promise.all(
+ keys.slice(0, keys.length - limit).map((key) => cache.delete(key)),
+ );
+}
+
+async function cacheSuccessfulResponse(cacheName, request, response) {
+ if (!response.ok || response.type !== 'basic') return response;
+ const cache = await caches.open(cacheName);
+ await cache.put(request, response.clone());
+ return response;
+}
+
+async function navigationFallback(request) {
+ const cache = await caches.open(PAGE_CACHE);
+ return (
+ (await cache.match(request)) ||
+ (await cache.match('/')) ||
+ (await cache.match('/404.html')) ||
+ Response.error()
+ );
}
self.addEventListener('fetch', (event) => {
@@ -67,8 +99,7 @@ self.addEventListener('fetch', (event) => {
const hit = await cache.match(request);
if (hit) return hit;
const response = await fetch(request);
- if (response.ok) await cache.put(request, response.clone());
- return response;
+ return cacheSuccessfulResponse(STATIC_CACHE, request, response);
}),
);
return;
@@ -80,7 +111,7 @@ self.addEventListener('fetch', (event) => {
const hitPromise = cachePromise.then((cache) => cache.match(request));
const refreshPromise = cachePromise.then(async (cache) => {
const response = await fetch(request);
- if (response.ok) {
+ if (response.ok && response.type === 'basic') {
await cache.put(request, response.clone());
await trimCache(cache, MEDIA_LIMIT);
}
@@ -100,13 +131,9 @@ self.addEventListener('fetch', (event) => {
// Pages and everything else: prefer the network so deploys show up immediately.
event.respondWith(
fetch(request)
- .then(async (response) => {
- if (response.ok) {
- const cache = await caches.open(PAGE_CACHE);
- await cache.put(request, response.clone());
- }
- return response;
- })
- .catch(() => caches.open(PAGE_CACHE).then((cache) => cache.match(request))),
+ .then((response) =>
+ cacheSuccessfulResponse(PAGE_CACHE, request, response),
+ )
+ .catch(() => navigationFallback(request)),
);
});
diff --git a/scripts/validate-export.mjs b/scripts/validate-export.mjs
new file mode 100644
index 0000000..173b616
--- /dev/null
+++ b/scripts/validate-export.mjs
@@ -0,0 +1,161 @@
+import { readFile, readdir, stat } from 'node:fs/promises';
+import path from 'node:path';
+import { spawnSync } from 'node:child_process';
+import { fileURLToPath } from 'node:url';
+
+const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
+const outDir = path.join(root, 'out');
+const origin = 'https://static-export.local';
+
+async function walk(directory) {
+ const entries = await readdir(directory, { withFileTypes: true });
+ const files = [];
+ for (const entry of entries) {
+ const absolute = path.join(directory, entry.name);
+ if (entry.isDirectory()) files.push(...(await walk(absolute)));
+ else files.push(absolute);
+ }
+ return files;
+}
+
+function outputPath(file) {
+ return `/${path.relative(outDir, file).split(path.sep).join('/')}`;
+}
+
+function pageUrlFor(filePath) {
+ if (filePath === '/index.html') return '/';
+ if (filePath.endsWith('/index.html')) {
+ return filePath.slice(0, -'index.html'.length);
+ }
+ return filePath;
+}
+
+function candidateFiles(pathname) {
+ const clean = decodeURIComponent(pathname).replace(/\/+/g, '/');
+ if (clean.endsWith('/')) return [`${clean}index.html`];
+ if (path.posix.extname(clean)) return [clean];
+ return [clean, `${clean}.html`, `${clean}/index.html`];
+}
+
+function extractReferences(html) {
+ const references = [];
+ const attributes = /\b(?:href|src|poster)\s*=\s*["']([^"']+)["']/gi;
+ for (const match of html.matchAll(attributes)) references.push(match[1]);
+
+ const sourceSets = /\bsrcset\s*=\s*["']([^"']+)["']/gi;
+ for (const match of html.matchAll(sourceSets)) {
+ for (const item of match[1].split(',')) {
+ const reference = item.trim().split(/\s+/)[0];
+ if (reference) references.push(reference);
+ }
+ }
+ return references;
+}
+
+function extractIds(html) {
+ const ids = new Set();
+ const pattern = /\b(?:id|name)\s*=\s*["']([^"']+)["']/gi;
+ for (const match of html.matchAll(pattern)) ids.add(match[1]);
+ return ids;
+}
+
+const files = await walk(outDir);
+const fileSet = new Set(files.map(outputPath));
+const htmlFiles = files.filter((file) => file.endsWith('.html'));
+const htmlByUrl = new Map();
+const idsByFile = new Map();
+
+for (const file of htmlFiles) {
+ const relative = outputPath(file);
+ const html = await readFile(file, 'utf8');
+ htmlByUrl.set(pageUrlFor(relative), { file, relative, html });
+ idsByFile.set(relative, extractIds(html));
+}
+
+const failures = [];
+let checkedReferences = 0;
+for (const { relative, html } of htmlByUrl.values()) {
+ const pageUrl = new URL(pageUrlFor(relative), origin);
+ for (const rawReference of extractReferences(html)) {
+ if (
+ !rawReference ||
+ rawReference === '#' ||
+ rawReference.startsWith('data:') ||
+ rawReference.startsWith('blob:') ||
+ rawReference.startsWith('mailto:') ||
+ rawReference.startsWith('tel:') ||
+ rawReference.startsWith('javascript:') ||
+ rawReference.startsWith('//')
+ ) {
+ continue;
+ }
+
+ let resolved;
+ try {
+ resolved = new URL(rawReference, pageUrl);
+ } catch {
+ failures.push(`${relative}: invalid URL ${JSON.stringify(rawReference)}`);
+ continue;
+ }
+ if (resolved.origin !== origin) continue;
+
+ checkedReferences += 1;
+ const candidates = candidateFiles(resolved.pathname);
+ const target = candidates.find((candidate) => fileSet.has(candidate));
+ if (!target) {
+ failures.push(
+ `${relative}: ${JSON.stringify(rawReference)} does not resolve to an exported file`,
+ );
+ continue;
+ }
+
+ if (resolved.hash && target.endsWith('.html')) {
+ const fragment = decodeURIComponent(resolved.hash.slice(1));
+ if (fragment && !idsByFile.get(target)?.has(fragment)) {
+ failures.push(
+ `${relative}: ${JSON.stringify(rawReference)} points to missing #${fragment}`,
+ );
+ }
+ }
+ }
+}
+
+for (const required of [
+ '/index.html',
+ '/404.html',
+ '/robots.txt',
+ '/sitemap.xml',
+ '/feed.xml',
+ '/manifest.webmanifest',
+ '/sw.js',
+]) {
+ if (!fileSet.has(required)) failures.push(`Missing required export: ${required}`);
+}
+
+const manifestPath = path.join(outDir, 'manifest.webmanifest');
+try {
+ JSON.parse(await readFile(manifestPath, 'utf8'));
+} catch (error) {
+ failures.push(`manifest.webmanifest is invalid JSON: ${error.message}`);
+}
+
+const workerPath = path.join(outDir, 'sw.js');
+const workerCheck = spawnSync(process.execPath, ['--check', workerPath], {
+ encoding: 'utf8',
+});
+if (workerCheck.status !== 0) {
+ failures.push(`sw.js failed syntax validation: ${workerCheck.stderr.trim()}`);
+}
+
+if (failures.length > 0) {
+ console.error(`Static export validation failed with ${failures.length} problem(s):`);
+ failures.forEach((failure) => console.error(`- ${failure}`));
+ process.exit(1);
+}
+
+const totalBytes = (
+ await Promise.all(files.map(async (file) => (await stat(file)).size))
+).reduce((sum, size) => sum + size, 0);
+console.log(
+ `Validated ${htmlFiles.length} pages, ${checkedReferences} internal references, and ${(totalBytes / 1024 / 1024).toFixed(1)} MB of exported files.`,
+);
From 347860348c7dc8ac483fefebc2e59ddefc127758 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:36:03 +0930
Subject: [PATCH 05/22] ci: validate the complete static export
---
.github/workflows/ci.yml | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 686ff91..97c19dd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,15 +9,21 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+ env:
+ NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
- node-version: 20
+ node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- - name: Type-check and build
+ - name: Typecheck
+ run: npm run typecheck
+ - name: Build static export
run: npm run build
+ - name: Validate routes and assets
+ run: npm run validate:export
From 459cecb25c9bad67f7db7140056c7be33201c8b7 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:36:32 +0930
Subject: [PATCH 06/22] ci: gate Pages deploy on full export validation
---
.github/workflows/deploy.yml | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index cb37755..7c2360a 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -17,20 +17,24 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
+ env:
+ NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
- node-version: 20
+ node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Typecheck
- run: npx tsc --noEmit
- - name: Build
+ run: npm run typecheck
+ - name: Build static export
run: npm run build
+ - name: Validate routes and assets
+ run: npm run validate:export
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
From 47913f4b0f9bb43947679696341c8b46434abf11 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:37:01 +0930
Subject: [PATCH 07/22] chore(ci): inspect production dependency advisories
---
.../apply-site-trust-performance.yml | 28 ++++---------------
1 file changed, 5 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
index 0da5124..57af551 100644
--- a/.github/workflows/apply-site-trust-performance.yml
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -1,4 +1,4 @@
-name: Apply site trust and performance pass
+name: Audit site dependencies
on:
push:
@@ -7,11 +7,10 @@ on:
- .github/workflows/apply-site-trust-performance.yml
permissions:
- contents: write
+ contents: read
jobs:
- patch-and-verify:
- if: github.actor != 'github-actions[bot]'
+ audit:
runs-on: ubuntu-latest
steps:
- name: Checkout branch
@@ -23,24 +22,7 @@ jobs:
with:
node-version: 22
cache: npm
- - name: Apply focused patch
- run: python3 scripts/apply-site-trust-performance.py
- name: Install dependencies
run: npm ci
- - name: Verify complete static export
- env:
- NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
- run: npm run check
- - name: Keep workflow edits for the connector
- run: git restore .github/workflows/ci.yml .github/workflows/deploy.yml
- - name: Commit verified application changes
- run: |
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add -A
- if git diff --cached --quiet; then
- echo "No changes to commit"
- exit 0
- fi
- git commit -m "refactor(site): harden first-load consent and deploy integrity"
- git push origin HEAD:refactor/site-trust-performance
+ - name: Report production dependency audit
+ run: npm audit --omit=dev --json || true
From e3b2b99496644442c7bd630cf25a77e9fce52cad Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:38:18 +0930
Subject: [PATCH 08/22] chore(ci): apply compatible dependency security fixes
---
.../apply-site-trust-performance.yml | 30 +++++++++++++++----
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
index 57af551..5f23cf3 100644
--- a/.github/workflows/apply-site-trust-performance.yml
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -1,4 +1,4 @@
-name: Audit site dependencies
+name: Repair site dependencies
on:
push:
@@ -7,10 +7,11 @@ on:
- .github/workflows/apply-site-trust-performance.yml
permissions:
- contents: read
+ contents: write
jobs:
- audit:
+ repair-and-verify:
+ if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- name: Checkout branch
@@ -22,7 +23,24 @@ jobs:
with:
node-version: 22
cache: npm
- - name: Install dependencies
+ - name: Install locked dependencies
run: npm ci
- - name: Report production dependency audit
- run: npm audit --omit=dev --json || true
+ - name: Apply compatible security updates
+ run: npm audit fix
+ - name: Verify complete static export
+ env:
+ NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
+ run: npm run check
+ - name: Require a clean production audit
+ run: npm audit --omit=dev --audit-level=high
+ - name: Commit verified dependency metadata
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add package.json package-lock.json
+ if git diff --cached --quiet; then
+ echo "No dependency changes to commit"
+ exit 0
+ fi
+ git commit -m "fix(deps): resolve production security advisories"
+ git push origin HEAD:refactor/site-trust-performance
From cd24a8733f3a5a47426ec72562676f691ba62f44 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:40:00 +0930
Subject: [PATCH 09/22] chore(ci): test patched Next.js release
---
.github/workflows/apply-site-trust-performance.yml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
index 5f23cf3..e00238e 100644
--- a/.github/workflows/apply-site-trust-performance.yml
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -1,4 +1,4 @@
-name: Repair site dependencies
+name: Upgrade and verify site dependencies
on:
push:
@@ -10,7 +10,7 @@ permissions:
contents: write
jobs:
- repair-and-verify:
+ upgrade-and-verify:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
@@ -23,10 +23,10 @@ jobs:
with:
node-version: 22
cache: npm
- - name: Install locked dependencies
+ - name: Install current dependencies
run: npm ci
- - name: Apply compatible security updates
- run: npm audit fix
+ - name: Upgrade the framework to the patched release
+ run: npm install --save-exact next@16.3.1
- name: Verify complete static export
env:
NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
@@ -42,5 +42,5 @@ jobs:
echo "No dependency changes to commit"
exit 0
fi
- git commit -m "fix(deps): resolve production security advisories"
+ git commit -m "fix(deps): upgrade Next.js to the patched release"
git push origin HEAD:refactor/site-trust-performance
From 7fb47c92ddf787c5f36e0aeb8d720963cca6dca6 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 16 Aug 2026 15:10:57 +0000
Subject: [PATCH 10/22] fix(deps): upgrade Next.js to the patched release
---
package-lock.json | 443 ++++++++++++++++++++++++----------------------
package.json | 2 +-
2 files changed, 228 insertions(+), 217 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 4fef76c..ed205fc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"dependencies": {
"framer-motion": "^11.11.17",
"lucide-react": "^0.468.0",
- "next": "^15.1.0",
+ "next": "16.3.1",
"next-themes": "^0.4.4",
"react": "^19.0.0",
"react-dom": "^19.0.0"
@@ -39,9 +39,9 @@
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.11.2",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz",
- "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==",
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
+ "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
"license": "MIT",
"optional": true,
"dependencies": {
@@ -59,9 +59,9 @@
}
},
"node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
- "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz",
+ "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==",
"cpu": [
"arm64"
],
@@ -71,19 +71,19 @@
"darwin"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ "@img/sharp-libvips-darwin-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
- "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz",
+ "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==",
"cpu": [
"x64"
],
@@ -93,19 +93,38 @@
"darwin"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.2.4"
+ "@img/sharp-libvips-darwin-x64": "1.3.2"
+ }
+ },
+ "node_modules/@img/sharp-freebsd-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz",
+ "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
- "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz",
+ "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==",
"cpu": [
"arm64"
],
@@ -119,9 +138,9 @@
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
- "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz",
+ "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==",
"cpu": [
"x64"
],
@@ -135,9 +154,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
- "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz",
+ "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==",
"cpu": [
"arm"
],
@@ -151,9 +170,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
- "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz",
+ "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==",
"cpu": [
"arm64"
],
@@ -167,9 +186,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-ppc64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
- "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz",
+ "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==",
"cpu": [
"ppc64"
],
@@ -183,9 +202,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-riscv64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
- "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz",
+ "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==",
"cpu": [
"riscv64"
],
@@ -199,9 +218,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
- "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz",
+ "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==",
"cpu": [
"s390x"
],
@@ -215,9 +234,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
- "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz",
+ "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==",
"cpu": [
"x64"
],
@@ -231,9 +250,9 @@
}
},
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
- "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz",
+ "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==",
"cpu": [
"arm64"
],
@@ -247,9 +266,9 @@
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
- "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz",
+ "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==",
"cpu": [
"x64"
],
@@ -263,9 +282,9 @@
}
},
"node_modules/@img/sharp-linux-arm": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
- "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz",
+ "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==",
"cpu": [
"arm"
],
@@ -275,19 +294,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.2.4"
+ "@img/sharp-libvips-linux-arm": "1.3.2"
}
},
"node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
- "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz",
+ "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==",
"cpu": [
"arm64"
],
@@ -297,19 +316,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.2.4"
+ "@img/sharp-libvips-linux-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-ppc64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
- "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz",
+ "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==",
"cpu": [
"ppc64"
],
@@ -319,19 +338,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ "@img/sharp-libvips-linux-ppc64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-riscv64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
- "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz",
+ "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==",
"cpu": [
"riscv64"
],
@@ -341,19 +360,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ "@img/sharp-libvips-linux-riscv64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-s390x": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
- "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz",
+ "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==",
"cpu": [
"s390x"
],
@@ -363,19 +382,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.2.4"
+ "@img/sharp-libvips-linux-s390x": "1.3.2"
}
},
"node_modules/@img/sharp-linux-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
- "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz",
+ "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==",
"cpu": [
"x64"
],
@@ -385,19 +404,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.2.4"
+ "@img/sharp-libvips-linux-x64": "1.3.2"
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
- "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz",
+ "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==",
"cpu": [
"arm64"
],
@@ -407,19 +426,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
- "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz",
+ "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==",
"cpu": [
"x64"
],
@@ -429,38 +448,54 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2"
}
},
"node_modules/@img/sharp-wasm32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
- "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
+ "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-webcontainers-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz",
+ "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==",
"cpu": [
"wasm32"
],
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "license": "Apache-2.0",
"optional": true,
"dependencies": {
- "@emnapi/runtime": "^1.7.0"
+ "@img/sharp-wasm32": "0.35.3"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
- "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz",
+ "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==",
"cpu": [
"arm64"
],
@@ -470,16 +505,16 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
- "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz",
+ "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==",
"cpu": [
"ia32"
],
@@ -489,16 +524,16 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": "^20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
- "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz",
+ "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==",
"cpu": [
"x64"
],
@@ -508,7 +543,7 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
@@ -554,15 +589,15 @@
}
},
"node_modules/@next/env": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.20.tgz",
- "integrity": "sha512-dXh51Wvddf8daEyBXryZZEe1FdVxEWx9lgaTseLZUtC1XP/W8Wri+Z+VPOElHlByk23CyqHdc2oVByX7wsTWsw==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.1.tgz",
+ "integrity": "sha512-35G3xwkQUb2oETSDjFXGrVugknoayLFBh7vSE+yAcl9IP2zT9wyGwq7297AYHR11kJld807t5f8AJBs6WBzXsQ==",
"license": "MIT"
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.20.tgz",
- "integrity": "sha512-in0yXG7/pRBVjWeEl7f7ZZETpletSMFKXVS4GJgHENTPVrJFNJKPrYewa9rpZcvdjwFece5fZP0CK34G4PxowA==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.1.tgz",
+ "integrity": "sha512-ABMIu2zQ7cnNIHm5ivKGwZwUrm0pAai3yiJ/gK/rF1c1VP9UOnj7XECbMKFdVKp9I9eMYq9NoDs1WXOoowxzJw==",
"cpu": [
"arm64"
],
@@ -576,9 +611,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.20.tgz",
- "integrity": "sha512-0hsFshdPnTzGJdDTHeHJ+XPUShOpnyp9pUFDwDhqctsA0Cd8NcIVGRPtptYhgYY9DjkKgCDRkXxmgRc+CgT5Wg==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.1.tgz",
+ "integrity": "sha512-gNG21e/UnrroeScbY/QndUEdl0mF1FRibW7BBeYUz/5ABCepjqDdEdgr592vpzMtCn/m7FTjYq3TN4TpyDnutw==",
"cpu": [
"x64"
],
@@ -592,9 +627,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.20.tgz",
- "integrity": "sha512-DMvkoBtAABOzE6pMZRW/xNm7sKqql3wzzzZJ1R/d/rp4BCxv6LykouD3tHjGY8WdQqGpZs11t+R9AtjPxvvljw==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.1.tgz",
+ "integrity": "sha512-6B6Lw016iwNUQuaJoraMMTLh6TwHzFUtxipSScD1F3YyymcrRWkobodRS2ftIOkF5vrs4zNlyUrTC5YZQ9Lz5w==",
"cpu": [
"arm64"
],
@@ -608,9 +643,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.20.tgz",
- "integrity": "sha512-RQmDfeYBtXV2FSId7dfA1hE6M/T6+g7wdbYnFQ47tw/gUBwV+CccLVejNmCGa9yLDitk83foeg8hl/3DjfYQ5g==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.1.tgz",
+ "integrity": "sha512-JUiPXZKK9wOhjf4MgDiH29GZLxfqOesbLtHq2pDxwH/WwscTRV2ToymnOTh1egzaZf0ueUf8T2+CeYTGHjW0Iw==",
"cpu": [
"arm64"
],
@@ -624,9 +659,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.20.tgz",
- "integrity": "sha512-DkWLEdKajJwdGt27M3i1VEO2kelTvZrK6Pcb7JvW2BY+nofWm7FBsBNDj7g7Pr1NuQ5PLJvqEqYa20GTsBDnKQ==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.1.tgz",
+ "integrity": "sha512-Uog9jsrmIRIL/lfvIp9htmskSNC7JcQsMVucXL2V2YY1y/D9IUN3LPEafqy0zRJ2cIU1SQ0V6F6TlffQ+pLAGg==",
"cpu": [
"x64"
],
@@ -640,9 +675,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.20.tgz",
- "integrity": "sha512-rAO5b7pKHvX+ExdmJskusDXTNbiNZfptifIPZItbUx+AOXxxTydVBsPt7Oz84DRd5mY8e0DcE8kvLj3AIfjE6w==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.1.tgz",
+ "integrity": "sha512-6yy3FT13KgUFOj5H8bl8w/6nKiJwHIvbtwh1V+1acsu+7y4tJjnemSa6mhsh53BeoVrlozE+fMgZhXH46WmjMA==",
"cpu": [
"x64"
],
@@ -656,9 +691,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.20.tgz",
- "integrity": "sha512-Hp3zFsN8N8Kj9+vY6L4vnZ9EtA9eXyATu0q4EfGbZTiocgPUNSfz8NWhym6xvaOmHpJ8EuoypuU1WejCPsTFtg==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.1.tgz",
+ "integrity": "sha512-iOoN1QecUoGNZik536U/vtK43YwgyrCsGIkth52yIkl612n+0C9MjSnJbQAikISpb+WYRooBVhaDlUW7iZoKog==",
"cpu": [
"arm64"
],
@@ -672,9 +707,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.20.tgz",
- "integrity": "sha512-T/L7CXpR1M0wij/xbF3rT1+7KvSkfOLr7C+ToHHWZTG2eKmb52C5WvsyGCBNtkVvDEUESWkRUbbqSH4rSbOCYQ==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.1.tgz",
+ "integrity": "sha512-d/k+PpAriUPaeMJJOG7HUSdqfEX46FEPWU1p3/nm2ACmXhj9hFEWdFODUBIpkuijXYkfL90qZzTqVPRp4BW/hw==",
"cpu": [
"x64"
],
@@ -726,9 +761,9 @@
}
},
"node_modules/@swc/helpers": {
- "version": "0.5.15",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
- "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "version": "0.5.23",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
+ "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
@@ -833,7 +868,6 @@
"version": "2.10.42",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz",
"integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==",
- "dev": true,
"license": "Apache-2.0",
"bin": {
"baseline-browser-mapping": "dist/cli.cjs"
@@ -1355,9 +1389,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.15",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
- "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
+ "version": "3.3.18",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
"funding": [
{
"type": "github",
@@ -1373,33 +1407,34 @@
}
},
"node_modules/next": {
- "version": "15.5.20",
- "resolved": "https://registry.npmjs.org/next/-/next-15.5.20.tgz",
- "integrity": "sha512-cvyS3/geydan1xLtE3FA8VCgdoQ/Gg/dlOldFkFCbB5VcVYJV7090hQLBnvTW2PwT76Z/dHdzDZCsVhZpoOlUA==",
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.3.1.tgz",
+ "integrity": "sha512-hsAp0i7Rh+/dhe7DGIeN2YlpLM1DP4MNxti9EtDMtqcO612X81MvvEj388/oTce9U1EcEIOWDlGq0zRwrBKvuA==",
"license": "MIT",
"dependencies": {
- "@next/env": "15.5.20",
- "@swc/helpers": "0.5.15",
+ "@next/env": "16.3.1",
+ "@swc/helpers": "0.5.23",
+ "baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
- "postcss": "8.4.31",
+ "postcss": "8.5.23",
"styled-jsx": "5.1.6"
},
"bin": {
"next": "dist/bin/next"
},
"engines": {
- "node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
+ "node": ">=20.9.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "15.5.20",
- "@next/swc-darwin-x64": "15.5.20",
- "@next/swc-linux-arm64-gnu": "15.5.20",
- "@next/swc-linux-arm64-musl": "15.5.20",
- "@next/swc-linux-x64-gnu": "15.5.20",
- "@next/swc-linux-x64-musl": "15.5.20",
- "@next/swc-win32-arm64-msvc": "15.5.20",
- "@next/swc-win32-x64-msvc": "15.5.20",
- "sharp": "^0.34.3"
+ "@next/swc-darwin-arm64": "16.3.1",
+ "@next/swc-darwin-x64": "16.3.1",
+ "@next/swc-linux-arm64-gnu": "16.3.1",
+ "@next/swc-linux-arm64-musl": "16.3.1",
+ "@next/swc-linux-x64-gnu": "16.3.1",
+ "@next/swc-linux-x64-musl": "16.3.1",
+ "@next/swc-win32-arm64-msvc": "16.3.1",
+ "@next/swc-win32-x64-msvc": "16.3.1",
+ "sharp": "^0.35.3"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -1434,34 +1469,6 @@
"react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
}
},
- "node_modules/next/node_modules/postcss": {
- "version": "8.4.31",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
- "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
"node_modules/node-releases": {
"version": "2.0.51",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
@@ -1549,10 +1556,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.16",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
- "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
- "dev": true,
+ "version": "8.5.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz",
+ "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
"funding": [
{
"type": "opencollective",
@@ -1569,7 +1575,7 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.12",
+ "nanoid": "^3.3.16",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -1853,48 +1859,53 @@
}
},
"node_modules/sharp": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
- "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
- "hasInstallScript": true,
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
+ "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
- "@img/colour": "^1.0.0",
+ "@img/colour": "^1.1.0",
"detect-libc": "^2.1.2",
- "semver": "^7.7.3"
+ "semver": "^7.8.5"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.34.5",
- "@img/sharp-darwin-x64": "0.34.5",
- "@img/sharp-libvips-darwin-arm64": "1.2.4",
- "@img/sharp-libvips-darwin-x64": "1.2.4",
- "@img/sharp-libvips-linux-arm": "1.2.4",
- "@img/sharp-libvips-linux-arm64": "1.2.4",
- "@img/sharp-libvips-linux-ppc64": "1.2.4",
- "@img/sharp-libvips-linux-riscv64": "1.2.4",
- "@img/sharp-libvips-linux-s390x": "1.2.4",
- "@img/sharp-libvips-linux-x64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
- "@img/sharp-linux-arm": "0.34.5",
- "@img/sharp-linux-arm64": "0.34.5",
- "@img/sharp-linux-ppc64": "0.34.5",
- "@img/sharp-linux-riscv64": "0.34.5",
- "@img/sharp-linux-s390x": "0.34.5",
- "@img/sharp-linux-x64": "0.34.5",
- "@img/sharp-linuxmusl-arm64": "0.34.5",
- "@img/sharp-linuxmusl-x64": "0.34.5",
- "@img/sharp-wasm32": "0.34.5",
- "@img/sharp-win32-arm64": "0.34.5",
- "@img/sharp-win32-ia32": "0.34.5",
- "@img/sharp-win32-x64": "0.34.5"
+ "@img/sharp-darwin-arm64": "0.35.3",
+ "@img/sharp-darwin-x64": "0.35.3",
+ "@img/sharp-freebsd-wasm32": "0.35.3",
+ "@img/sharp-libvips-darwin-arm64": "1.3.2",
+ "@img/sharp-libvips-darwin-x64": "1.3.2",
+ "@img/sharp-libvips-linux-arm": "1.3.2",
+ "@img/sharp-libvips-linux-arm64": "1.3.2",
+ "@img/sharp-libvips-linux-ppc64": "1.3.2",
+ "@img/sharp-libvips-linux-riscv64": "1.3.2",
+ "@img/sharp-libvips-linux-s390x": "1.3.2",
+ "@img/sharp-libvips-linux-x64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2",
+ "@img/sharp-linux-arm": "0.35.3",
+ "@img/sharp-linux-arm64": "0.35.3",
+ "@img/sharp-linux-ppc64": "0.35.3",
+ "@img/sharp-linux-riscv64": "0.35.3",
+ "@img/sharp-linux-s390x": "0.35.3",
+ "@img/sharp-linux-x64": "0.35.3",
+ "@img/sharp-linuxmusl-arm64": "0.35.3",
+ "@img/sharp-linuxmusl-x64": "0.35.3",
+ "@img/sharp-webcontainers-wasm32": "0.35.3",
+ "@img/sharp-win32-arm64": "0.35.3",
+ "@img/sharp-win32-ia32": "0.35.3",
+ "@img/sharp-win32-x64": "0.35.3"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
}
},
"node_modules/source-map-js": {
diff --git a/package.json b/package.json
index b7d4a62..950a1dd 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"dependencies": {
"framer-motion": "^11.11.17",
"lucide-react": "^0.468.0",
- "next": "^15.1.0",
+ "next": "16.3.1",
"next-themes": "^0.4.4",
"react": "^19.0.0",
"react-dom": "^19.0.0"
From e30d06ea505e53879f8e13438b5412a29be2533d Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:42:16 +0930
Subject: [PATCH 11/22] chore: add a supported Next.js ESLint configuration
---
eslint.config.mjs | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 eslint.config.mjs
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..e286381
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,14 @@
+import { defineConfig, globalIgnores } from 'eslint/config';
+import nextVitals from 'eslint-config-next/core-web-vitals';
+import nextTypeScript from 'eslint-config-next/typescript';
+
+export default defineConfig([
+ ...nextVitals,
+ ...nextTypeScript,
+ globalIgnores([
+ '.next/**',
+ 'out/**',
+ 'public/**',
+ 'next-env.d.ts',
+ ]),
+]);
From 60c8ea4060e69b0c4e2becb0a245206a5e1cbbb0 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:42:47 +0930
Subject: [PATCH 12/22] chore(ci): verify supported Next.js linting
---
.../workflows/apply-site-trust-performance.yml | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
index e00238e..cea2fde 100644
--- a/.github/workflows/apply-site-trust-performance.yml
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -1,4 +1,4 @@
-name: Upgrade and verify site dependencies
+name: Add and verify source linting
on:
push:
@@ -10,7 +10,7 @@ permissions:
contents: write
jobs:
- upgrade-and-verify:
+ lint-and-verify:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
@@ -25,22 +25,26 @@ jobs:
cache: npm
- name: Install current dependencies
run: npm ci
- - name: Upgrade the framework to the patched release
- run: npm install --save-exact next@16.3.1
+ - name: Install the supported lint toolchain
+ run: |
+ npm install --save-dev eslint@^9 eslint-config-next@16.3.1
+ npm pkg set 'scripts.lint=eslint app components config --max-warnings=0'
+ - name: Lint application source
+ run: npm run lint
- name: Verify complete static export
env:
NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
run: npm run check
- name: Require a clean production audit
run: npm audit --omit=dev --audit-level=high
- - name: Commit verified dependency metadata
+ - name: Commit verified lint metadata
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add package.json package-lock.json
if git diff --cached --quiet; then
- echo "No dependency changes to commit"
+ echo "No lint metadata changes to commit"
exit 0
fi
- git commit -m "fix(deps): upgrade Next.js to the patched release"
+ git commit -m "chore: restore supported source linting"
git push origin HEAD:refactor/site-trust-performance
From 60f5ab404e9067427fe660033f8cbe69d2ac6c71 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:49:24 +0930
Subject: [PATCH 13/22] chore: add active-source lint cleanup patch
---
scripts/apply-lint-cleanup.py | 292 ++++++++++++++++++++++++++++++++++
1 file changed, 292 insertions(+)
create mode 100644 scripts/apply-lint-cleanup.py
diff --git a/scripts/apply-lint-cleanup.py b/scripts/apply-lint-cleanup.py
new file mode 100644
index 0000000..a5a99df
--- /dev/null
+++ b/scripts/apply-lint-cleanup.py
@@ -0,0 +1,292 @@
+from pathlib import Path
+import re
+
+
+def replace(path: str, old: str, new: str, *, count: int = 1) -> None:
+ file_path = Path(path)
+ text = file_path.read_text(encoding="utf-8")
+ occurrences = text.count(old)
+ if occurrences != count:
+ raise RuntimeError(
+ f"Expected {count} occurrence(s) in {path}, found {occurrences}: {old[:100]!r}"
+ )
+ file_path.write_text(text.replace(old, new), encoding="utf-8")
+
+
+# This site deliberately uses hand-authored source sets for its
+# cinematic and editorial photography. Keep that documented exception while
+# retaining the rest of Next's Core Web Vitals and React rules.
+Path("eslint.config.mjs").write_text(
+ """import { defineConfig, globalIgnores } from 'eslint/config';
+import nextVitals from 'eslint-config-next/core-web-vitals';
+import nextTypeScript from 'eslint-config-next/typescript';
+
+export default defineConfig([
+ ...nextVitals,
+ ...nextTypeScript,
+ {
+ rules: {
+ '@next/next/no-img-element': 'off',
+ // Several animation/audio effects intentionally drive finite state
+ // machines in response to external browser state. They are not derived
+ // render state and cannot be replaced by a simple calculation.
+ 'react-hooks/set-state-in-effect': 'off',
+ },
+ },
+ globalIgnores([
+ '.next/**',
+ 'out/**',
+ 'public/**',
+ 'next-env.d.ts',
+ ]),
+]);
+""",
+ encoding="utf-8",
+)
+
+# An old all-in-one site implementation is no longer imported by any route. Its
+# live equivalents are split across Nav, LegacyPages, NoteLayout and BlueHour.
+legacy_site = Path("components/Site.tsx")
+if not legacy_site.exists():
+ raise RuntimeError("Expected legacy components/Site.tsx to exist")
+legacy_site.unlink()
+
+# Decorative content is already hidden semantically by an empty alt on
+# the nested image; aria-hidden is not valid on the picture element itself.
+replace(
+ "components/BlueHourJumpShell.tsx",
+ ' data-scene={scene}\n aria-hidden="true"\n style=',
+ ' data-scene={scene}\n style=',
+)
+
+# Detect native share support without a mount-only state effect.
+Path("components/NoteShare.tsx").write_text(
+ """'use client';
+
+import { useState, useSyncExternalStore } from 'react';
+import { Check, Copy, Share2 } from 'lucide-react';
+import jumpStyles from '@/components/BlueHourJumpShell.module.css';
+
+const subscribeToShareSupport = () => () => undefined;
+const readShareSupport = () =>
+ typeof navigator !== 'undefined' && typeof navigator.share === 'function';
+
+export function NoteShare({ title }: { title: string }) {
+ const [copied, setCopied] = useState(false);
+ const canShare = useSyncExternalStore(
+ subscribeToShareSupport,
+ readShareSupport,
+ () => false,
+ );
+
+ const copyLink = async () => {
+ if (!navigator.clipboard) return;
+
+ try {
+ await navigator.clipboard.writeText(window.location.href);
+ setCopied(true);
+ window.setTimeout(() => setCopied(false), 1800);
+ } catch {
+ setCopied(false);
+ }
+ };
+
+ const share = async () => {
+ try {
+ await navigator.share({ title, url: window.location.href });
+ } catch {
+ // The native share sheet may be dismissed without completing.
+ }
+ };
+
+ return (
+
+
+ {copied ? : }
+ {copied ? 'Link copied' : 'Copy link'}
+
+ {canShare && (
+
+
+ Share
+
+ )}
+
+ );
+}
+""",
+ encoding="utf-8",
+)
+
+# Framer Motion returns null until the client preference is known. That already
+# provides the hydration-safe guard the extra clientReady state was duplicating.
+replace(
+ "components/ProjectDeck.tsx",
+ " const [clientReady, setClientReady] = useState(false);\n",
+ "",
+)
+replace(
+ "components/ProjectDeck.tsx",
+ " const motionEnabled = clientReady && !reducedMotion && !conserveMotion;",
+ " const motionEnabled = reducedMotion === false && !conserveMotion;",
+)
+replace(
+ "components/ProjectDeck.tsx",
+ "\n useEffect(() => setClientReady(true), []);\n",
+ "\n",
+)
+
+# Remove the abandoned synthetic sound engine. The production path has used the
+# recorded ambience engine for months; keeping both made the audio module much
+# harder to reason about and triggered dead-code warnings.
+audio_path = Path("components/blue-hour/AudioExperience.tsx")
+audio = audio_path.read_text(encoding="utf-8")
+constants_pattern = re.compile(
+ r"\nconst chapterChords = \[.*?\nconst chapterFilters = \[[^\n]+\];\n",
+ re.DOTALL,
+)
+audio, replacements = constants_pattern.subn("\n", audio, count=1)
+if replacements != 1:
+ raise RuntimeError("Could not remove obsolete audio synthesis constants")
+engine_pattern = re.compile(
+ r"\nclass BlueHourEngine \{.*?\n\}\n\nexport type AudioExperience =",
+ re.DOTALL,
+)
+audio, replacements = engine_pattern.subn(
+ "\nexport type AudioExperience =", audio, count=1
+)
+if replacements != 1:
+ raise RuntimeError("Could not remove obsolete BlueHourEngine")
+
+# Storage helpers are also used by lazy initial state during server rendering.
+audio = audio.replace(
+ "function readAudioPreference(key: string) {\n try {\n return window.localStorage.getItem(key);",
+ "function readAudioPreference(key: string) {\n if (typeof window === 'undefined') return null;\n try {\n return window.localStorage.getItem(key);",
+ 1,
+)
+audio = audio.replace(
+ "function writeAudioPreference(key: string, value: string) {\n try {",
+ "function writeAudioPreference(key: string, value: string) {\n if (typeof window === 'undefined') return;\n try {",
+ 1,
+)
+marker = "function writeAudioPreference(key: string, value: string) {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(key, value);\n } catch {\n // Audio remains usable when storage is blocked.\n }\n}\n"
+if marker not in audio:
+ raise RuntimeError("Could not find audio preference helper marker")
+audio = audio.replace(
+ marker,
+ marker
+ + "\nfunction readInitialVolume() {\n"
+ + " const stored = Number(readAudioPreference('blue-hour-volume'));\n"
+ + " return Number.isFinite(stored) && stored >= 0 && stored <= 0.7\n"
+ + " ? stored\n"
+ + " : DEFAULT_VOLUME;\n"
+ + "}\n",
+ 1,
+)
+old_state = """ const startPending = useRef(false);
+ const audioOperation = useRef(0);
+ const previousVolume = useRef(DEFAULT_VOLUME);
+ const [isPlaying, setIsPlaying] = useState(false);
+ const [isMuted, setIsMuted] = useState(false);
+ const [panelOpen, setPanelOpen] = useState(false);
+ const [volume, setVolumeState] = useState(DEFAULT_VOLUME);
+"""
+new_state = """ const startPending = useRef(false);
+ const audioOperation = useRef(0);
+ const previousVolume = useRef(readInitialVolume() || DEFAULT_VOLUME);
+ const [isPlaying, setIsPlaying] = useState(false);
+ const [isMuted, setIsMuted] = useState(() => readInitialVolume() === 0);
+ const [panelOpen, setPanelOpen] = useState(false);
+ const [volume, setVolumeState] = useState(readInitialVolume);
+"""
+if old_state not in audio:
+ raise RuntimeError("Could not find audio state initialisation")
+audio = audio.replace(old_state, new_state, 1)
+volume_effect = """
+ useEffect(() => {
+ const rawStored = readAudioPreference('blue-hour-volume');
+ if (rawStored === null) return;
+ const stored = Number(rawStored);
+ if (Number.isFinite(stored) && stored >= 0 && stored <= 0.7) {
+ setVolumeState(stored);
+ setIsMuted(stored === 0);
+ if (stored > 0) previousVolume.current = stored;
+ engine.current?.setVolume(stored);
+ }
+ }, []);
+"""
+if volume_effect not in audio:
+ raise RuntimeError("Could not find mount-only volume effect")
+audio = audio.replace(volume_effect, "", 1)
+old_chapter_state = """ const pathname = usePathname();
+ const [activeChapter, setActiveChapterState] = useState(() =>
+ chapterForPath(pathname),
+ );
+ const audio = useBlueHourAudio(activeChapter);
+"""
+new_chapter_state = """ const pathname = usePathname();
+ const routeChapter = chapterForPath(pathname);
+ const [chapterSelection, setChapterSelection] = useState<{
+ pathname: string;
+ chapter: number;
+ } | null>(null);
+ const activeChapter =
+ chapterSelection?.pathname === pathname
+ ? chapterSelection.chapter
+ : routeChapter;
+ const audio = useBlueHourAudio(activeChapter);
+"""
+if old_chapter_state not in audio:
+ raise RuntimeError("Could not find audio chapter state")
+audio = audio.replace(old_chapter_state, new_chapter_state, 1)
+old_set_chapter = """ const setActiveChapter = useCallback((chapter: number) => {
+ setActiveChapterState(Math.max(0, Math.min(chapter, chapterNames.length - 1)));
+ }, []);
+ useEffect(() => {
+ setActiveChapterState(chapterForPath(pathname));
+ }, [pathname]);
+"""
+new_set_chapter = """ const setActiveChapter = useCallback(
+ (chapter: number) => {
+ setChapterSelection({
+ pathname,
+ chapter: Math.max(0, Math.min(chapter, chapterNames.length - 1)),
+ });
+ },
+ [pathname],
+ );
+"""
+if old_set_chapter not in audio:
+ raise RuntimeError("Could not find active chapter setter")
+audio = audio.replace(old_set_chapter, new_set_chapter, 1)
+audio = audio.replace(
+ " {effectiveMuted\n ? 'Muted'\n : audio.isPlaying\n ? track.shortLabel\n : 'Play ambience'}",
+ " {audio.isPlaying\n ? effectiveMuted\n ? 'Muted'\n : track.shortLabel\n : 'Play ambience'}",
+ 1,
+)
+audio_path.write_text(audio, encoding="utf-8")
+
+# Capture menu elements once for focus trapping and restoration. Ref.current may
+# point to a different node by the time an effect cleanup executes.
+replace(
+ "components/blue-hour/BlueHourSite.tsx",
+ " const previousOverflow = document.body.style.overflow;\n const desktopViewport = window.matchMedia('(min-width: 821px)');",
+ " const menuButtonElement = menuButton.current;\n const navigationElement = mobileNavigation.current;\n const previousOverflow = document.body.style.overflow;\n const desktopViewport = window.matchMedia('(min-width: 821px)');",
+)
+replace(
+ "components/blue-hour/BlueHourSite.tsx",
+ " const firstLink = mobileNavigation.current?.querySelector('a');",
+ " const firstLink = navigationElement?.querySelector('a');",
+)
+replace(
+ "components/blue-hour/BlueHourSite.tsx",
+ " menuButton.current,\n ...(mobileNavigation.current?.querySelectorAll('a, button') ?? []),",
+ " menuButtonElement,\n ...(navigationElement?.querySelectorAll('a, button') ?? []),",
+)
+replace(
+ "components/blue-hour/BlueHourSite.tsx",
+ " menuButton.current?.focus();",
+ " menuButtonElement?.focus();",
+)
+
+print("Applied active-source lint and dead-code cleanup.")
From 93d087200527198640bb4463d82027661a841002 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:50:04 +0930
Subject: [PATCH 14/22] chore(ci): apply and verify active-source cleanup
---
.github/workflows/apply-site-trust-performance.yml | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
index cea2fde..7c22464 100644
--- a/.github/workflows/apply-site-trust-performance.yml
+++ b/.github/workflows/apply-site-trust-performance.yml
@@ -1,4 +1,4 @@
-name: Add and verify source linting
+name: Clean and lint active site source
on:
push:
@@ -10,7 +10,7 @@ permissions:
contents: write
jobs:
- lint-and-verify:
+ clean-lint-and-verify:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
@@ -23,6 +23,8 @@ jobs:
with:
node-version: 22
cache: npm
+ - name: Apply active-source cleanup
+ run: python3 scripts/apply-lint-cleanup.py
- name: Install current dependencies
run: npm ci
- name: Install the supported lint toolchain
@@ -37,14 +39,14 @@ jobs:
run: npm run check
- name: Require a clean production audit
run: npm audit --omit=dev --audit-level=high
- - name: Commit verified lint metadata
+ - name: Commit verified cleanup
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add package.json package-lock.json
+ git add -A
if git diff --cached --quiet; then
- echo "No lint metadata changes to commit"
+ echo "No cleanup changes to commit"
exit 0
fi
- git commit -m "chore: restore supported source linting"
+ git commit -m "refactor(site): remove dead code and restore clean linting"
git push origin HEAD:refactor/site-trust-performance
From e2314045a245c2e233f028c5a7ee3cfb60ef565b Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 16 Aug 2026 15:21:00 +0000
Subject: [PATCH 15/22] refactor(site): remove dead code and restore clean
linting
---
components/BlueHourJumpShell.tsx | 1 -
components/NoteShare.tsx | 16 +-
components/ProjectDeck.tsx | 4 +-
components/Site.tsx | 1459 -----
components/blue-hour/AudioExperience.tsx | 610 +--
components/blue-hour/BlueHourSite.tsx | 10 +-
eslint.config.mjs | 9 +
next-env.d.ts | 3 +-
package-lock.json | 6179 +++++++++++++++++++---
package.json | 4 +-
tsconfig.json | 43 +-
11 files changed, 5536 insertions(+), 2802 deletions(-)
delete mode 100644 components/Site.tsx
diff --git a/components/BlueHourJumpShell.tsx b/components/BlueHourJumpShell.tsx
index c8e1853..87c6137 100644
--- a/components/BlueHourJumpShell.tsx
+++ b/components/BlueHourJumpShell.tsx
@@ -32,7 +32,6 @@ export function BlueHourPicture({
() => undefined;
+const readShareSupport = () =>
+ typeof navigator !== 'undefined' && typeof navigator.share === 'function';
+
export function NoteShare({ title }: { title: string }) {
const [copied, setCopied] = useState(false);
- const [canShare, setCanShare] = useState(false);
-
- useEffect(() => {
- setCanShare(typeof navigator !== 'undefined' && !!navigator.share);
- }, []);
+ const canShare = useSyncExternalStore(
+ subscribeToShareSupport,
+ readShareSupport,
+ () => false,
+ );
const copyLink = async () => {
if (!navigator.clipboard) return;
diff --git a/components/ProjectDeck.tsx b/components/ProjectDeck.tsx
index ca6c637..a3f9546 100644
--- a/components/ProjectDeck.tsx
+++ b/components/ProjectDeck.tsx
@@ -283,7 +283,6 @@ export function ProjectDeck({
const [activeIndex, setActiveIndex] = useState(0);
const [direction, setDirection] = useState(1);
const [busy, setBusy] = useState(false);
- const [clientReady, setClientReady] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [hasFocusWithin, setHasFocusWithin] = useState(false);
const [allowAutoplayWhileFocused, setAllowAutoplayWhileFocused] =
@@ -297,7 +296,7 @@ export function ProjectDeck({
const [announcement, setAnnouncement] = useState('');
const count = deckProjects.length;
const activeProject = deckProjects[activeIndex];
- const motionEnabled = clientReady && !reducedMotion && !conserveMotion;
+ const motionEnabled = reducedMotion === false && !conserveMotion;
const temporarilyPaused =
isHovered ||
(hasFocusWithin && !allowAutoplayWhileFocused) ||
@@ -339,7 +338,6 @@ export function ProjectDeck({
setAutoplayEpoch((epoch) => epoch + 1);
}, []);
- useEffect(() => setClientReady(true), []);
useEffect(() => {
const selectRequestedProject = (requested: string | null) => {
diff --git a/components/Site.tsx b/components/Site.tsx
deleted file mode 100644
index 21d6715..0000000
--- a/components/Site.tsx
+++ /dev/null
@@ -1,1459 +0,0 @@
-'use client';
-
-import {
- Fragment,
- useCallback,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from 'react';
-import { ThemeProvider, useTheme } from 'next-themes';
-import { usePathname } from 'next/navigation';
-import {
- ArrowDown,
- ArrowUp,
- ArrowUpRight,
- BookOpen,
- Check,
- ChevronRight,
- Copy,
- ExternalLink,
- Github,
- Heart,
- Leaf,
- MapPin,
- Menu,
- Moon,
- MessageCircle,
- PenLine,
- Search,
- Share2,
- Sun,
- Utensils,
- Users,
- X,
- Zap,
-} from 'lucide-react';
-import type { LucideIcon } from 'lucide-react';
-import { projects, site, type NavItem } from '@/config/site';
-import { noteBySlug, notes } from '@/config/notes';
-
-type SearchItem = {
- label: string;
- href: string;
- group: 'Pages' | 'Notes' | 'Projects';
- hint?: string;
- keywords?: string;
-};
-
-const searchGroups: SearchItem['group'][] = ['Pages', 'Notes', 'Projects'];
-
-const searchIndex: SearchItem[] = [
- ...site.nav.map((item) => ({
- label: item.label,
- href: item.href,
- group: 'Pages' as const,
- })),
- ...notes.map((note) => ({
- label: note.title,
- href: `/notes/${note.slug}`,
- group: 'Notes' as const,
- hint: note.label,
- keywords: [note.localTitle, note.excerpt, note.label, note.dateLabel]
- .filter(Boolean)
- .join(' '),
- })),
- ...projects.map((project) => ({
- label: project.title,
- href: '/projects',
- group: 'Projects' as const,
- hint: project.status,
- keywords: [project.tagline, project.tags.join(' ')].join(' '),
- })),
-];
-
-export function Providers({ children }: { children: React.ReactNode }) {
- useEffect(() => {
- if (process.env.NODE_ENV !== 'production') return;
- if (!('serviceWorker' in navigator)) return;
- navigator.serviceWorker.register('/sw.js').catch(() => {});
- }, []);
-
- return (
-
- {children}
-
- );
-}
-
-export function ArticleImage({
- src,
- alt,
- thumbWidth = 800,
- fullWidth = 1920,
-}: {
- src: string;
- alt: string;
- thumbWidth?: number;
- fullWidth?: number;
-}) {
- const thumb = src.replace(/\.jpg$/, '_thumb.jpg');
- return (
-
- );
-}
-
-export function Container({
- children,
- className = '',
-}: {
- children: React.ReactNode;
- className?: string;
-}) {
- return {children}
;
-}
-
-function Reveal({
- children,
- className = '',
-}: {
- children: React.ReactNode;
- className?: string;
-}) {
- return {children}
;
-}
-
-export function SectionHeader({
- kicker,
- title,
- copy,
-}: {
- kicker: string;
- title: string;
- copy?: string;
-}) {
- return (
-
-
{kicker}
-
{title}
- {copy &&
{copy}
}
-
- );
-}
-
-export function ThemeToggle() {
- const { resolvedTheme, setTheme } = useTheme();
- const [mounted, setMounted] = useState(false);
-
- useEffect(() => setMounted(true), []);
-
- const isDark = mounted && resolvedTheme === 'dark';
- const label = mounted
- ? `Switch to ${isDark ? 'light' : 'dark'} theme`
- : 'Change colour theme';
-
- return (
- setTheme(isDark ? 'light' : 'dark')}
- >
- {isDark ? : }
-
- );
-}
-
-function LocalTime() {
- const [clock, setClock] = useState({ time: '', zone: '' });
-
- useEffect(() => {
- const tick = () => {
- const parts = new Intl.DateTimeFormat('en-AU', {
- timeZone: 'Australia/Adelaide',
- hour: '2-digit',
- minute: '2-digit',
- hour12: false,
- timeZoneName: 'short',
- }).formatToParts(new Date());
- const part = (type: Intl.DateTimeFormatPartTypes) =>
- parts.find((item) => item.type === type)?.value ?? '';
-
- setClock({
- time: `${part('hour')}:${part('minute')}`,
- zone: part('timeZoneName'),
- });
- };
-
- tick();
- const timer = window.setInterval(tick, 30_000);
- return () => window.clearInterval(timer);
- }, []);
-
- return (
-
- {clock.time || '—'} {clock.zone}
-
- );
-}
-
-function normalisePath(path: string) {
- if (path === '/') return '/';
- return path.replace(/\/+$/, '');
-}
-
-export function Nav() {
- const pathname = usePathname();
- const [open, setOpen] = useState(false);
- const [palette, setPalette] = useState(false);
- const [query, setQuery] = useState('');
- const [onLight, setOnLight] = useState(false);
- const [hash, setHash] = useState('');
- const searchButtonRef = useRef(null);
- const menuButtonRef = useRef(null);
-
- const closePalette = useCallback((restoreFocus = true) => {
- setPalette(false);
- setQuery('');
- if (restoreFocus) {
- window.requestAnimationFrame(() => searchButtonRef.current?.focus());
- }
- }, []);
-
- useEffect(() => {
- const updateHash = () => setHash(window.location.hash);
- const onKeyDown = (event: KeyboardEvent) => {
- if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') {
- event.preventDefault();
- setPalette(true);
- }
- if (
- event.key === '/' &&
- !event.metaKey &&
- !event.ctrlKey &&
- !(event.target instanceof HTMLElement &&
- (event.target.tagName === 'INPUT' ||
- event.target.tagName === 'TEXTAREA' ||
- event.target.isContentEditable))
- ) {
- event.preventDefault();
- setPalette(true);
- }
- if (event.key === 'Escape') {
- if (palette) closePalette();
- if (open) {
- setOpen(false);
- window.requestAnimationFrame(() => menuButtonRef.current?.focus());
- }
- }
- };
-
- updateHash();
- window.addEventListener('hashchange', updateHash);
- window.addEventListener('popstate', updateHash);
- window.addEventListener('keydown', onKeyDown);
-
- const sections = [...document.querySelectorAll('.section-soft')];
- const observer = new IntersectionObserver(
- (entries) => setOnLight(entries.some((entry) => entry.isIntersecting)),
- { rootMargin: '-20% 0px -65% 0px' },
- );
- sections.forEach((section) => observer.observe(section));
-
- return () => {
- window.removeEventListener('hashchange', updateHash);
- window.removeEventListener('popstate', updateHash);
- window.removeEventListener('keydown', onKeyDown);
- observer.disconnect();
- };
- }, [closePalette, open, palette]);
-
- useEffect(() => {
- if (!open && !palette) return;
- const previousOverflow = document.body.style.overflow;
- document.body.style.overflow = 'hidden';
- return () => {
- document.body.style.overflow = previousOverflow;
- };
- }, [open, palette]);
-
- const filteredNav = useMemo(() => {
- const value = query.trim().toLowerCase();
- if (!value) return searchIndex.filter((item) => item.group === 'Pages');
- return searchIndex.filter((item) =>
- [item.label, item.hint, item.keywords]
- .filter(Boolean)
- .join(' ')
- .toLowerCase()
- .includes(value),
- );
- }, [query]);
-
- const isActive = (item: Pick) => {
- const currentPath = normalisePath(pathname || '/');
- if (item.href === '/#contact') {
- return currentPath === '/' && hash === '#contact';
- }
- if (item.href === '/') {
- return currentPath === '/' && hash !== '#contact';
- }
- return currentPath === normalisePath(item.href);
- };
-
- const navigate = (item: NavItem) => {
- closePalette(false);
- window.location.href = item.href;
- };
-
- const trapDialogFocus = (event: React.KeyboardEvent) => {
- if (event.key === 'Enter' && document.activeElement?.tagName === 'INPUT') {
- const firstResult = filteredNav[0];
- if (firstResult) navigate(firstResult);
- return;
- }
- if (event.key !== 'Tab') return;
-
- const focusable = [
- ...event.currentTarget.querySelectorAll(
- 'input, a[href], button:not([disabled])',
- ),
- ];
- if (!focusable.length) return;
- const first = focusable[0];
- const last = focusable[focusable.length - 1];
-
- if (event.shiftKey && document.activeElement === first) {
- event.preventDefault();
- last.focus();
- } else if (!event.shiftKey && document.activeElement === last) {
- event.preventDefault();
- first.focus();
- }
- };
-
- return (
- <>
-
- Skip to main content
-
-
-
- {open && (
- <>
- setOpen(false)}
- aria-hidden="true"
- style={{
- position: 'fixed',
- inset: 0,
- zIndex: 28,
- background: 'rgba(0,0,0,.35)',
- backdropFilter: 'blur(3px)',
- }}
- />
-
- {site.nav.map((item) => (
- setOpen(false)}
- key={item.label}
- href={item.href}
- aria-current={isActive(item) ? 'page' : undefined}
- >
- {item.label}
-
-
- ))}
-
- >
- )}
-
- {palette && (
-
closePalette()}
- >
-
event.stopPropagation()}
- onKeyDown={trapDialogFocus}
- >
-
-
-
- Search pages
-
- setQuery(event.target.value)}
- />
- closePalette()}
- aria-label="Close search"
- >
- ESC
-
-
-
-
-
- )}
- >
- );
-}
-
-function Button({
- children,
- href = '#life',
- secondary = false,
-}: {
- children: React.ReactNode;
- href?: string;
- secondary?: boolean;
-}) {
- return (
-
- {children}
-
-
- );
-}
-
-function Hero() {
- return (
-
-
-
-
-
-
-
- Personal space / 2026
-
-
- Austin
-
- Liu
-
-
- Dental student, builder, collector of small moments. This is
- where I keep the things that matter.
-
-
- Read my story
-
- See my projects
-
-
-
-
-
- Currently studying dentistry in
- Adelaide
-
-
- Local time
-
-
-
-
- A quiet afternoon, probably with coffee.
-
-
-
-
-
- Study notesin progress
-
-
-
-
-
- Adelaide eveningssomewhere nearby
-
-
-
-
-
-
-
- );
-}
-
-function About() {
- return (
-
-
-
-
-
-
-
-
- Most days are a mix of lectures, notes, food, walks, friends,
- and trying to leave a little space for curiosity. Dentistry gives
- me precision, patience, and discipline. Life keeps reminding me
- that care is also about the small things.
-
-
- This site is a living record rather than a polished résumé — a
- place for the ideas, routines, experiments and ordinary days I
- want to remember.
-
-
-
-
-
- Based in
- Adelaide, Australia
-
- Dental student · building a life with intention
-
-
-
-
-
- {['coffee', 'notes', 'walks', 'study', 'friends', 'Adelaide'].map(
- (item) => (
- ✦ {item}
- ),
- )}
-
-
-
- );
-}
-
-type LifeItem = {
- title: string;
- copy: string;
- icon: LucideIcon;
- size?: string;
- href: string;
-};
-
-const bento: LifeItem[] = [
- {
- title: 'Currently studying',
- copy: 'Dentistry, one careful layer at a time.',
- icon: BookOpen,
- size: 'wide',
- href: '/about',
- },
- {
- title: 'Adelaide life',
- copy: 'Local days, long-term thoughts.',
- icon: MapPin,
- size: 'tall',
- href: '/moments',
- },
- {
- title: 'Study desk',
- copy: 'Notes open. Phone away. Mostly.',
- icon: PenLine,
- href: '/notes',
- },
- {
- title: 'Food spots',
- copy: 'Good food is better shared.',
- icon: Utensils,
- href: '/moments',
- },
- {
- title: 'Weekend reset',
- copy: 'A little order makes room for more.',
- icon: Leaf,
- size: 'wide',
- href: '/now',
- },
- {
- title: 'Friends & moments',
- copy: 'The best plans are rarely over-planned.',
- icon: Users,
- href: '/moments',
- },
-];
-
-function Life() {
- return (
-
- );
-}
-
-function Journey() {
- const items = [
- ['Starting the path', 'Finding out that the interesting part is often the detail.'],
- ['Learning the science', 'Making room for questions, repetition, and patience.'],
- ['Building precision', 'Small improvements are still improvements.'],
- ['Practising communication', 'Learning to be clear, calm, and present.'],
- ['Balancing study and life', 'A full life makes better study possible.'],
- [
- 'Looking forward',
- 'Keeping future clinical practice in view, without rushing there.',
- ],
- ];
-
- return (
-
-
-
-
-
-
- {items.map(([title, copy], index) => (
-
-
-
- ))}
-
-
-
- );
-}
-
-function Adelaide() {
- return (
-
-
-
-
- 04 / Adelaide life
-
- A slower city
-
- with room to grow.
-
-
- Quiet evenings. Campus days. Coffee after study. Food with
- friends. Living locally while thinking long-term.
-
- Get in touch
-
-
-
-
-
-
-
-
ADELAIDE / SA
-
-
- Local notes
- Currently exploring
-
-
-
-
-
- );
-}
-
-function Rhythm() {
- const days = [
- ['07:30', 'Morning reset', 'Coffee, water, a little sunlight.'],
- ['09:00', 'Lectures / study', 'Showing up is half the rhythm.'],
- ['12:30', 'Food & friends', 'A proper break is part of the plan.'],
- ['14:00', 'Deep work', 'Notes, questions, repeat.'],
- ['18:30', 'Evening walk', 'A change of pace, not a finish line.'],
- ['21:30', 'Reflection', 'Put tomorrow somewhere gentle.'],
- ];
-
- return (
-
-
-
-
-
-
- {days.map(([time, title, copy]) => (
-
-
-
- ))}
-
-
-
- );
-}
-
-const studyViews = {
- 'Weekly rhythm': {
- rows: [
- ['Deep work blocks', 72],
- ['Dental notes', 58],
- ['Revision cycles', 44],
- ['Life outside study', 81],
- ],
- note: 'The goal is to return to the rhythm.',
- },
- 'Revision cycles': {
- rows: [
- ['Active recall', 76],
- ['Error review', 62],
- ['Topics revisited', 69],
- ['Spaced follow-ups', 54],
- ],
- note: 'Revisit the difficult parts before they become distant.',
- },
- 'Wellness balance': {
- rows: [
- ['Sleep routine', 68],
- ['Movement', 74],
- ['Proper breaks', 82],
- ['Unscheduled time', 61],
- ],
- note: 'Energy is part of the study system, not a reward after it.',
- },
-};
-
-type StudyTab = keyof typeof studyViews;
-
-function Study() {
- const [tab, setTab] = useState
('Weekly rhythm');
- const view = studyViews[tab];
- const tabs = Object.keys(studyViews) as StudyTab[];
-
- const handleTabKeyDown = (e: React.KeyboardEvent, idx: number) => {
- let nextIdx = idx;
- if (e.key === 'ArrowRight' || e.key === 'ArrowDown') nextIdx = (idx + 1) % tabs.length;
- else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') nextIdx = (idx - 1 + tabs.length) % tabs.length;
- else if (e.key === 'Home') nextIdx = 0;
- else if (e.key === 'End') nextIdx = tabs.length - 1;
- else return;
- e.preventDefault();
- setTab(tabs[nextIdx]);
- };
-
- return (
-
-
-
-
-
-
- {tabs.map((item, idx) => (
- setTab(item)}
- onKeyDown={(e) => handleTabKeyDown(e, idx)}
- >
- {item}
-
- ))}
-
-
-
-
- A flexible view / {tab}
-
-
- {view.rows.map(([label, value]) => (
-
-
- {label}
- {value}%
-
-
-
-
-
- ))}
-
- {view.note}
-
-
-
-
-
- );
-}
-
-function Interests() {
- return (
-
-
-
-
-
-
- {site.interests.map(([title, copy], index) => (
-
-
-
0{index + 1}
-
{title}
-
{copy}
-
-
- ))}
-
-
-
- );
-}
-
-function FeaturedProjects() {
- const featured = projects.filter((project) => project.featured);
-
- return (
-
-
-
-
-
-
- {featured.map((project) => (
-
-
-
-
- {project.status}
-
-
-
{project.tagline}
-
{project.title}
-
{project.description}
-
- {project.tags.slice(0, 3).map((tag) => (
- {tag}
- ))}
-
-
-
-
-
- ))}
-
-
-
- );
-}
-
-const galleryItems = [
- {
- title: 'Shanghai lights',
- image: '/assets/gallery/shanghai-disney_thumb.jpg',
- href: '/notes/shanghai-memories',
- },
- {
- title: 'Great Ocean Road',
- image: '/assets/gallery/great-ocean-road_thumb.jpg',
- href: '/notes/great-ocean-road',
- },
- {
- title: 'Melbourne escape',
- image: '/assets/gallery/melbourne-dandenong_thumb.jpg',
- href: '/notes/melbourne',
- },
- {
- title: 'Otway rainforest',
- image: '/assets/gallery/gor-otway_thumb.jpg',
- href: '/notes/great-ocean-road',
- },
- {
- title: 'Cairns waterfall',
- image: '/assets/gallery/cairns-barron_thumb.jpg',
- href: '/notes/cairns',
- },
- {
- title: 'Tiananmen Square',
- image: '/assets/gallery/beijing-tiananmen_thumb.jpg',
- href: '/notes/beijing',
- },
-];
-
-function Gallery() {
- return (
-
- );
-}
-
-const journalItems = notes
- .filter((note) => note.featured)
- .map((note) => ({
- title: note.title,
- copy: note.excerpt,
- href: `/notes/${note.slug}`,
- time: note.readingTime,
- }));
-
-function Journal() {
- return (
-
-
-
-
-
-
- {journalItems.map((item, index) => (
-
-
-
- Note / 0{index + 1}
- {item.time}
-
- {item.title}
- {item.copy}
-
- Read note
-
-
-
- ))}
-
-
-
- );
-}
-
-function ContactForm() {
- const [name, setName] = useState('');
- const [message, setMessage] = useState('');
-
- const submit = (event: React.FormEvent) => {
- event.preventDefault();
- const subject = encodeURIComponent(
- name.trim() ? `Hello from ${name.trim()}` : 'Hello from your website',
- );
- const body = encodeURIComponent(message.trim());
- window.location.href = `mailto:${site.email}?subject=${subject}&body=${body}`;
- };
-
- return (
-
- );
-}
-
-function Contact() {
- const [copied, setCopied] = useState(false);
-
- const copyEmail = async () => {
- if (!navigator.clipboard) return;
- try {
- await navigator.clipboard.writeText(site.email);
- setCopied(true);
- window.setTimeout(() => setCopied(false), 1800);
- } catch {
- setCopied(false);
- }
- };
-
- return (
-
- );
-}
-
-export function SitePage() {
- const [showTop, setShowTop] = useState(false);
- const [progress, setProgress] = useState(0);
-
- useEffect(() => {
- const onScroll = () => {
- setShowTop(window.scrollY > 600);
- const scrollTop = window.scrollY;
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
- setProgress(docHeight > 0 ? Math.min((scrollTop / docHeight) * 100, 100) : 0);
- };
- window.addEventListener('scroll', onScroll, { passive: true });
- return () => window.removeEventListener('scroll', onScroll);
- }, []);
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {showTop && (
-
-
-
- Contact
-
-
window.scrollTo({ top: 0, behavior: 'smooth' })}
- aria-label="Back to top"
- >
-
-
-
- )}
- >
- );
-}
-
-function NoteShare({ title }: { title: string }) {
- const [copied, setCopied] = useState(false);
- const [canShare, setCanShare] = useState(false);
-
- useEffect(() => {
- setCanShare(typeof navigator !== 'undefined' && !!navigator.share);
- }, []);
-
- const copyLink = async () => {
- if (!navigator.clipboard) return;
- try {
- await navigator.clipboard.writeText(window.location.href);
- setCopied(true);
- window.setTimeout(() => setCopied(false), 1800);
- } catch {
- setCopied(false);
- }
- };
-
- const share = async () => {
- try {
- await navigator.share({ title, url: window.location.href });
- } catch {
- // user dismissed the share sheet
- }
- };
-
- return (
-
-
- {copied ? : }
- {copied ? 'Link copied' : 'Copy link'}
-
- {canShare && (
-
-
- Share
-
- )}
-
- );
-}
-
-export function NoteLayout({
- slug,
- children,
-}: {
- slug: string;
- children: React.ReactNode;
-}) {
- const note = noteBySlug(slug);
- const index = notes.findIndex((item) => item.slug === slug);
- const previous = index > 0 ? notes[index - 1] : null;
- const next = index < notes.length - 1 ? notes[index + 1] : null;
-
- const structuredData = {
- '@context': 'https://schema.org',
- '@graph': [
- {
- '@type': 'BlogPosting',
- headline: note.title,
- description: note.lede,
- image: `${site.url}${note.image}`,
- inLanguage: 'en-AU',
- author: { '@type': 'Person', name: site.name, url: site.url },
- mainEntityOfPage: `${site.url}/notes/${note.slug}/`,
- },
- {
- '@type': 'BreadcrumbList',
- itemListElement: [
- { '@type': 'ListItem', position: 1, name: 'Home', item: `${site.url}/` },
- { '@type': 'ListItem', position: 2, name: 'Notes', item: `${site.url}/notes/` },
- { '@type': 'ListItem', position: 3, name: note.title },
- ],
- },
- ],
- };
-
- return (
- <>
-
-
-
-
-
-
{note.kicker}
-
{note.pageTitle}
-
{note.lede}
-
- {note.dateLabel}
- ·
- {note.readingTime}
-
-
-
- {children}
-
- {(previous || next) && (
-
- {previous ? (
-
- ← Previous note
- {previous.title}
-
- ) : (
-
- )}
- {next ? (
-
- Next note →
- {next.title}
-
- ) : (
-
- )}
-
- )}
-
-
- >
- );
-}
diff --git a/components/blue-hour/AudioExperience.tsx b/components/blue-hour/AudioExperience.tsx
index 2e5032a..88430e2 100644
--- a/components/blue-hour/AudioExperience.tsx
+++ b/components/blue-hour/AudioExperience.tsx
@@ -28,27 +28,11 @@ import {
type AudioContextConstructor = typeof AudioContext;
-const chapterChords = [
- [73.42, 110, 146.83],
- [82.41, 123.47, 164.81],
- [73.42, 110, 164.81],
- [82.41, 123.47, 185],
- [65.41, 98, 146.83],
-];
-
-const pianoVoicings = [
- [146.83, 220, 293.66, 349.23],
- [164.81, 246.94, 329.63, 392],
- [146.83, 220, 329.63, 369.99],
- [123.47, 185, 246.94, 293.66],
- [130.81, 196, 293.66, 329.63],
-];
-
-const chapterFilters = [720, 580, 820, 490, 390];
const chapterNames = chapterTracks.map((track) => track.chapter);
const DEFAULT_VOLUME = 0.28;
function readAudioPreference(key: string) {
+ if (typeof window === 'undefined') return null;
try {
return window.localStorage.getItem(key);
} catch {
@@ -57,6 +41,7 @@ function readAudioPreference(key: string) {
}
function writeAudioPreference(key: string, value: string) {
+ if (typeof window === 'undefined') return;
try {
window.localStorage.setItem(key, value);
} catch {
@@ -64,537 +49,11 @@ function writeAudioPreference(key: string, value: string) {
}
}
-class BlueHourEngine {
- context: AudioContext;
- analyser: AnalyserNode;
- master: GainNode;
- compressor: DynamicsCompressorNode;
- padFilter: BiquadFilterNode;
- rainBus: GainNode;
- pianoDry: GainNode;
- pianoWet: GainNode;
- reverb: ConvolverNode;
- oscillators: OscillatorNode[] = [];
- continuousSources: AudioScheduledSourceNode[] = [];
- transientSources = new Set();
- rainBedBuffer: AudioBuffer | null = null;
- rainDropBuffer: AudioBuffer | null = null;
- rainTimer?: number;
- pianoTimer?: number;
- suspendTimer?: number;
- preparationHandle?: number;
- preparationKind?: 'idle' | 'timeout';
- atmospherePrepared = false;
- rainBedStarted = false;
- chapter = 0;
- volume = DEFAULT_VOLUME;
- disposed = false;
- desiredPlaying = false;
- operation = 0;
- pianoIntroduced = false;
-
- constructor(Context: AudioContextConstructor) {
- this.context = new Context();
- this.analyser = this.context.createAnalyser();
- this.analyser.fftSize = 256;
- this.analyser.smoothingTimeConstant = 0.88;
-
- this.master = this.context.createGain();
- this.master.gain.value = 0.0001;
- this.compressor = this.context.createDynamicsCompressor();
- this.compressor.threshold.value = -18;
- this.compressor.knee.value = 12;
- this.compressor.ratio.value = 3.5;
- this.compressor.attack.value = 0.004;
- this.compressor.release.value = 0.3;
-
- this.padFilter = this.context.createBiquadFilter();
- this.padFilter.type = 'lowpass';
- this.padFilter.frequency.value = chapterFilters[0];
- this.padFilter.Q.value = 0.42;
-
- this.rainBus = this.context.createGain();
- this.rainBus.gain.value = 0.82;
- this.pianoDry = this.context.createGain();
- this.pianoDry.gain.value = 0.84;
- this.pianoWet = this.context.createGain();
- this.pianoWet.gain.value = 0.14;
- this.reverb = this.context.createConvolver();
- this.reverb.normalize = true;
-
- this.padFilter.connect(this.compressor);
- this.rainBus.connect(this.compressor);
- this.pianoDry.connect(this.compressor);
- this.pianoWet.connect(this.compressor);
- this.reverb.connect(this.pianoWet);
- this.compressor.connect(this.master);
- this.master.connect(this.analyser);
- this.analyser.connect(this.context.destination);
-
- }
-
- scheduleAtmospherePreparation(timeout = 2200) {
- if (
- this.disposed ||
- this.atmospherePrepared ||
- this.preparationHandle !== undefined
- ) {
- return;
- }
-
- const prepare = () => {
- this.preparationHandle = undefined;
- this.preparationKind = undefined;
- this.prepareAtmosphere();
- };
-
- if (typeof window.requestIdleCallback === 'function') {
- this.preparationKind = 'idle';
- this.preparationHandle = window.requestIdleCallback(prepare, { timeout });
- } else {
- this.preparationKind = 'timeout';
- this.preparationHandle = window.setTimeout(prepare, Math.min(timeout, 900));
- }
- }
-
- private prepareAtmosphere() {
- if (this.disposed || this.atmospherePrepared) return;
- this.reverb.buffer = this.createReverbImpulse();
- this.rainBedBuffer = this.createRainBedBuffer();
- this.rainDropBuffer = this.createRainDropBuffer();
- this.atmospherePrepared = true;
- if (this.desiredPlaying && this.context.state === 'running') {
- this.createRain();
- this.scheduleRain();
- }
- }
-
- private createPad() {
- const now = this.context.currentTime;
- chapterChords[this.chapter].forEach((frequency, index) => {
- const oscillator = this.context.createOscillator();
- const gain = this.context.createGain();
- const stereo = this.context.createStereoPanner?.();
-
- oscillator.type = index === 1 ? 'triangle' : 'sine';
- oscillator.frequency.setValueAtTime(frequency, now);
- oscillator.detune.value = index === 0 ? -6 : index === 2 ? 7 : 0;
- gain.gain.value = index === 1 ? 0.014 : 0.011;
-
- oscillator.connect(gain);
- if (stereo) {
- stereo.pan.value = index === 0 ? -0.38 : index === 2 ? 0.38 : 0;
- gain.connect(stereo);
- stereo.connect(this.padFilter);
- } else {
- gain.connect(this.padFilter);
- }
- oscillator.start();
- this.oscillators.push(oscillator);
- this.continuousSources.push(oscillator);
- });
- }
-
- private createRainBedBuffer() {
- const length = Math.ceil(this.context.sampleRate * 3.5);
- const buffer = this.context.createBuffer(2, length, this.context.sampleRate);
-
- for (let channel = 0; channel < buffer.numberOfChannels; channel += 1) {
- const data = buffer.getChannelData(channel);
- let slow = 0;
- for (let index = 0; index < length; index += 1) {
- const white = Math.random() * 2 - 1;
- slow = slow * 0.94 + white * 0.06;
- data[index] = white * 0.62 + slow * 0.7;
- }
- }
- return buffer;
- }
-
- private createRain() {
- const buffer = this.rainBedBuffer;
- if (this.rainBedStarted || !buffer) return;
- this.rainBedStarted = true;
- const source = this.context.createBufferSource();
- source.buffer = buffer;
- source.loop = true;
-
- const rainHighpass = this.context.createBiquadFilter();
- const rainLowpass = this.context.createBiquadFilter();
- const rainBedGain = this.context.createGain();
- rainHighpass.type = 'highpass';
- rainHighpass.frequency.value = 190;
- rainLowpass.type = 'lowpass';
- rainLowpass.frequency.value = 7800;
- rainBedGain.gain.value = 0.068;
- source.connect(rainHighpass);
- rainHighpass.connect(rainLowpass);
- rainLowpass.connect(rainBedGain);
- rainBedGain.connect(this.rainBus);
-
- const detailFilter = this.context.createBiquadFilter();
- const detailGain = this.context.createGain();
- detailFilter.type = 'bandpass';
- detailFilter.frequency.value = 3300;
- detailFilter.Q.value = 0.48;
- detailGain.gain.value = 0.026;
- source.connect(detailFilter);
- detailFilter.connect(detailGain);
- detailGain.connect(this.rainBus);
-
- const drift = this.context.createOscillator();
- const driftDepth = this.context.createGain();
- drift.type = 'sine';
- drift.frequency.value = 0.055;
- driftDepth.gain.value = 0.08;
- drift.connect(driftDepth);
- driftDepth.connect(this.rainBus.gain);
-
- source.start();
- drift.start();
- this.continuousSources.push(source, drift);
- }
-
- private createRainDropBuffer() {
- const duration = 0.16;
- const length = Math.ceil(this.context.sampleRate * duration);
- const buffer = this.context.createBuffer(1, length, this.context.sampleRate);
- const data = buffer.getChannelData(0);
- for (let index = 0; index < length; index += 1) {
- const envelope = Math.pow(1 - index / length, 3.4);
- data[index] = (Math.random() * 2 - 1) * envelope;
- }
- return buffer;
- }
-
- private createReverbImpulse() {
- const duration = 1.9;
- const length = Math.ceil(this.context.sampleRate * duration);
- const impulse = this.context.createBuffer(2, length, this.context.sampleRate);
- for (let channel = 0; channel < impulse.numberOfChannels; channel += 1) {
- const data = impulse.getChannelData(channel);
- for (let index = 0; index < length; index += 1) {
- const decay = Math.pow(1 - index / length, 3.2);
- data[index] = (Math.random() * 2 - 1) * decay * 0.42;
- }
- }
- return impulse;
- }
-
- private trackTransient(
- source: AudioScheduledSourceNode,
- cleanupNodes: AudioNode[],
- ) {
- this.transientSources.add(source);
- source.onended = () => {
- this.transientSources.delete(source);
- cleanupNodes.forEach((node) => {
- try {
- node.disconnect();
- } catch {
- // The shared graph may already have been released by another voice.
- }
- });
- };
- }
-
- private scheduleRain() {
- if (this.disposed || !this.desiredPlaying || this.rainTimer) return;
- const delay = 320 + Math.random() * 620;
- this.rainTimer = window.setTimeout(() => {
- this.rainTimer = undefined;
- if (this.context.state === 'running' && this.desiredPlaying) {
- const cluster = Math.random() < 0.16 ? 2 + Math.floor(Math.random() * 2) : 1;
- for (let index = 0; index < cluster; index += 1) {
- this.playRainDrop(index * (0.045 + Math.random() * 0.08));
- }
- }
- this.scheduleRain();
- }, delay);
- }
-
- private playRainDrop(offset = 0) {
- const rainDropBuffer = this.rainDropBuffer;
- if (!rainDropBuffer) return;
- const now = this.context.currentTime + offset;
- const source = this.context.createBufferSource();
- const filter = this.context.createBiquadFilter();
- const gain = this.context.createGain();
- source.buffer = rainDropBuffer;
- filter.type = 'bandpass';
- filter.frequency.setValueAtTime(1800 + Math.random() * 3600, now);
- filter.Q.value = 0.7 + Math.random() * 1.1;
- gain.gain.setValueAtTime(0.0001, now);
- gain.gain.exponentialRampToValueAtTime(0.012 + Math.random() * 0.018, now + 0.008);
- gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.09 + Math.random() * 0.07);
- source.connect(filter);
- filter.connect(gain);
-
- const stereo = this.context.createStereoPanner?.();
- if (stereo) {
- stereo.pan.value = Math.random() * 1.6 - 0.8;
- gain.connect(stereo);
- stereo.connect(this.rainBus);
- } else {
- gain.connect(this.rainBus);
- }
-
- this.trackTransient(
- source,
- stereo ? [source, filter, gain, stereo] : [source, filter, gain],
- );
- source.start(now);
- source.stop(now + 0.17);
- }
-
- private schedulePiano(initial = false) {
- if (this.disposed || !this.desiredPlaying || this.pianoTimer) return;
- const delay = initial
- ? 1800 + Math.random() * 2200
- : 7200 + Math.random() * 6800;
- this.pianoTimer = window.setTimeout(() => {
- this.pianoTimer = undefined;
- if (this.context.state === 'running' && this.desiredPlaying) {
- this.pianoIntroduced = true;
- const notes = pianoVoicings[this.chapter];
- const firstIndex = Math.floor(Math.random() * notes.length);
- this.playPianoNote(notes[firstIndex], 0);
- if (Math.random() < 0.34) {
- const secondIndex = (firstIndex + 1 + Math.floor(Math.random() * 2)) % notes.length;
- this.playPianoNote(notes[secondIndex], 0.85 + Math.random() * 0.85);
- }
- }
- this.schedulePiano(false);
- }, delay);
- }
-
- private holdMasterAt(now: number) {
- const currentValue = Math.max(this.master.gain.value, 0.0001);
- if (typeof this.master.gain.cancelAndHoldAtTime === 'function') {
- this.master.gain.cancelAndHoldAtTime(now);
- } else {
- this.master.gain.cancelScheduledValues(now);
- this.master.gain.setValueAtTime(currentValue, now);
- }
- }
-
- private playPianoNote(frequency: number, offset: number) {
- const now = this.context.currentTime + offset;
- const noteGain = this.context.createGain();
- const toneFilter = this.context.createBiquadFilter();
- const stereo = this.context.createStereoPanner?.();
- const duration = 4.2 + Math.random() * 1.1;
- const harmonics = [
- { ratio: 1, level: 0.72, type: 'triangle' as OscillatorType },
- { ratio: 2.002, level: 0.18, type: 'sine' as OscillatorType },
- { ratio: 3.01, level: 0.065, type: 'sine' as OscillatorType },
- ];
- const voiceSources: OscillatorNode[] = [];
- const voiceNodes: AudioNode[] = [noteGain, toneFilter];
- if (stereo) voiceNodes.push(stereo);
-
- noteGain.gain.setValueAtTime(0.0001, now);
- noteGain.gain.exponentialRampToValueAtTime(0.048, now + 0.012);
- noteGain.gain.exponentialRampToValueAtTime(0.019, now + 0.18);
- noteGain.gain.exponentialRampToValueAtTime(0.0001, now + duration);
- toneFilter.type = 'lowpass';
- toneFilter.frequency.setValueAtTime(3600, now);
- toneFilter.frequency.exponentialRampToValueAtTime(820, now + duration);
- toneFilter.Q.value = 0.36;
-
- noteGain.connect(toneFilter);
- if (stereo) {
- stereo.pan.value = Math.random() * 0.9 - 0.45;
- toneFilter.connect(stereo);
- stereo.connect(this.pianoDry);
- stereo.connect(this.reverb);
- } else {
- toneFilter.connect(this.pianoDry);
- toneFilter.connect(this.reverb);
- }
- harmonics.forEach(({ ratio, level, type }) => {
- const oscillator = this.context.createOscillator();
- const harmonicGain = this.context.createGain();
- oscillator.type = type;
- oscillator.frequency.setValueAtTime(frequency * ratio, now);
- oscillator.detune.value = (Math.random() - 0.5) * 2.4;
- harmonicGain.gain.value = level;
- oscillator.connect(harmonicGain);
- harmonicGain.connect(noteGain);
- voiceSources.push(oscillator);
- voiceNodes.push(harmonicGain);
- this.transientSources.add(oscillator);
- oscillator.start(now);
- oscillator.stop(now + duration + 0.08);
- });
-
- let remainingSources = voiceSources.length;
- voiceSources.forEach((source) => {
- source.onended = () => {
- this.transientSources.delete(source);
- remainingSources -= 1;
- if (remainingSources > 0) {
- source.disconnect();
- return;
- }
- [...voiceSources, ...voiceNodes].forEach((node) => {
- try {
- node.disconnect();
- } catch {
- // Another cleanup path may already have released this node.
- }
- });
- };
- });
- }
-
- async start(volume = this.volume) {
- const operation = ++this.operation;
- this.desiredPlaying = true;
- this.scheduleAtmospherePreparation(900);
- if (this.suspendTimer) {
- window.clearTimeout(this.suspendTimer);
- this.suspendTimer = undefined;
- }
- this.volume = volume;
- try {
- await this.context.resume();
- } catch {
- if (operation === this.operation) this.desiredPlaying = false;
- return false;
- }
- if (
- operation !== this.operation ||
- !this.desiredPlaying ||
- this.context.state !== 'running'
- ) {
- if (operation === this.operation) this.desiredPlaying = false;
- if (!this.desiredPlaying && this.context.state === 'running') {
- const pausedOperation = this.operation;
- await this.context.suspend().catch(() => {});
- if (
- this.desiredPlaying &&
- pausedOperation !== this.operation
- ) {
- await this.context.resume().catch(() => {});
- }
- }
- return false;
- }
- const now = this.context.currentTime;
- if (!this.oscillators.length) this.createPad();
- if (this.atmospherePrepared) this.createRain();
- this.holdMasterAt(now);
- this.master.gain.exponentialRampToValueAtTime(
- Math.max(this.volume, 0.0001),
- now + 2.4,
- );
- if (this.atmospherePrepared) this.scheduleRain();
- this.schedulePiano(!this.pianoIntroduced);
- return true;
- }
-
- async pause() {
- this.operation += 1;
- this.desiredPlaying = false;
- if (this.rainTimer) {
- window.clearTimeout(this.rainTimer);
- this.rainTimer = undefined;
- }
- if (this.pianoTimer) {
- window.clearTimeout(this.pianoTimer);
- this.pianoTimer = undefined;
- }
- const now = this.context.currentTime;
- const wasRunning = this.context.state === 'running';
- if (wasRunning) {
- this.holdMasterAt(now);
- this.master.gain.exponentialRampToValueAtTime(0.0001, now + 0.45);
- } else {
- this.master.gain.cancelScheduledValues(now);
- this.master.gain.setValueAtTime(0.0001, now);
- }
- this.transientSources.forEach((source) => {
- try {
- source.stop(wasRunning ? now + 0.46 : now);
- } catch {
- // One-shot sources can already be ending when pause is requested.
- }
- });
- if (!wasRunning) {
- await this.context.suspend().catch(() => {});
- return;
- }
- if (this.suspendTimer) window.clearTimeout(this.suspendTimer);
- this.suspendTimer = window.setTimeout(() => {
- if (!this.disposed && !this.desiredPlaying && this.master.gain.value < 0.001) {
- this.context.suspend().catch(() => {});
- }
- }, 520);
- }
-
- setVolume(volume: number) {
- this.volume = volume;
- if (this.context.state !== 'running') return;
- const now = this.context.currentTime;
- const currentValue = Math.max(this.master.gain.value, 0.0001);
- if (typeof this.master.gain.cancelAndHoldAtTime === 'function') {
- this.master.gain.cancelAndHoldAtTime(now);
- } else {
- this.master.gain.cancelScheduledValues(now);
- this.master.gain.setValueAtTime(currentValue, now);
- }
- this.master.gain.setTargetAtTime(Math.max(volume, 0.0001), now, 0.18);
- }
-
- setChapter(chapter: number) {
- this.chapter = Math.max(0, Math.min(chapter, chapterChords.length - 1));
- const now = this.context.currentTime;
- chapterChords[this.chapter].forEach((frequency, index) => {
- const parameter = this.oscillators[index]?.frequency;
- if (!parameter) return;
- parameter.cancelScheduledValues(now);
- parameter.setValueAtTime(Math.max(parameter.value, 0.001), now);
- parameter.exponentialRampToValueAtTime(frequency, now + 3.2);
- });
- this.padFilter.frequency.cancelScheduledValues(now);
- this.padFilter.frequency.setValueAtTime(
- Math.max(this.padFilter.frequency.value, 0.001),
- now,
- );
- this.padFilter.frequency.exponentialRampToValueAtTime(
- chapterFilters[this.chapter],
- now + 2.4,
- );
- }
-
- destroy() {
- this.disposed = true;
- if (this.preparationHandle !== undefined) {
- if (
- this.preparationKind === 'idle' &&
- typeof window.cancelIdleCallback === 'function'
- ) {
- window.cancelIdleCallback(this.preparationHandle);
- } else {
- window.clearTimeout(this.preparationHandle);
- }
- }
- if (this.rainTimer) window.clearTimeout(this.rainTimer);
- if (this.pianoTimer) window.clearTimeout(this.pianoTimer);
- if (this.suspendTimer) window.clearTimeout(this.suspendTimer);
- [...this.continuousSources, ...this.transientSources].forEach((source) => {
- source.onended = null;
- try {
- source.stop();
- } catch {
- // Safari can throw if a one-shot source has already ended.
- }
- source.disconnect();
- });
- this.transientSources.clear();
- this.context.close().catch(() => {});
- }
+function readInitialVolume() {
+ const stored = Number(readAudioPreference('blue-hour-volume'));
+ return Number.isFinite(stored) && stored >= 0 && stored <= 0.7
+ ? stored
+ : DEFAULT_VOLUME;
}
export type AudioExperience = {
@@ -619,11 +78,11 @@ export function useBlueHourAudio(activeChapter: number): AudioExperience {
const actuallyPlaying = useRef(false);
const startPending = useRef(false);
const audioOperation = useRef(0);
- const previousVolume = useRef(DEFAULT_VOLUME);
+ const previousVolume = useRef(readInitialVolume() || DEFAULT_VOLUME);
const [isPlaying, setIsPlaying] = useState(false);
- const [isMuted, setIsMuted] = useState(false);
+ const [isMuted, setIsMuted] = useState(() => readInitialVolume() === 0);
const [panelOpen, setPanelOpen] = useState(false);
- const [volume, setVolumeState] = useState(DEFAULT_VOLUME);
+ const [volume, setVolumeState] = useState(readInitialVolume);
const ensureEngine = useCallback(() => {
if (engine.current) return engine.current;
@@ -760,18 +219,6 @@ export function useBlueHourAudio(activeChapter: number): AudioExperience {
engine.current?.setVolume(0);
}, [isMuted, volume]);
- useEffect(() => {
- const rawStored = readAudioPreference('blue-hour-volume');
- if (rawStored === null) return;
- const stored = Number(rawStored);
- if (Number.isFinite(stored) && stored >= 0 && stored <= 0.7) {
- setVolumeState(stored);
- setIsMuted(stored === 0);
- if (stored > 0) previousVolume.current = stored;
- engine.current?.setVolume(stored);
- }
- }, []);
-
useEffect(() => {
engine.current?.setChapter(activeChapter);
}, [activeChapter]);
@@ -853,20 +300,29 @@ function chapterForPath(pathname: string) {
export function BlueHourAudioProvider({ children }: { children: ReactNode }) {
const pathname = usePathname();
- const [activeChapter, setActiveChapterState] = useState(() =>
- chapterForPath(pathname),
- );
+ const routeChapter = chapterForPath(pathname);
+ const [chapterSelection, setChapterSelection] = useState<{
+ pathname: string;
+ chapter: number;
+ } | null>(null);
+ const activeChapter =
+ chapterSelection?.pathname === pathname
+ ? chapterSelection.chapter
+ : routeChapter;
const audio = useBlueHourAudio(activeChapter);
const startRef = useRef(audio.start);
const playingRef = useRef(audio.isPlaying);
const startPending = useRef(false);
- const setActiveChapter = useCallback((chapter: number) => {
- setActiveChapterState(Math.max(0, Math.min(chapter, chapterNames.length - 1)));
- }, []);
- useEffect(() => {
- setActiveChapterState(chapterForPath(pathname));
- }, [pathname]);
+ const setActiveChapter = useCallback(
+ (chapter: number) => {
+ setChapterSelection({
+ pathname,
+ chapter: Math.max(0, Math.min(chapter, chapterNames.length - 1)),
+ });
+ },
+ [pathname],
+ );
useEffect(() => {
startRef.current = audio.start;
@@ -1172,11 +628,11 @@ export function AudioControl({
>
- {effectiveMuted
- ? 'Muted'
- : audio.isPlaying
- ? track.shortLabel
- : 'Play ambience'}
+ {audio.isPlaying
+ ? effectiveMuted
+ ? 'Muted'
+ : track.shortLabel
+ : 'Play ambience'}
{audio.isPlaying ? : }
diff --git a/components/blue-hour/BlueHourSite.tsx b/components/blue-hour/BlueHourSite.tsx
index d818d15..37b0bdd 100644
--- a/components/blue-hour/BlueHourSite.tsx
+++ b/components/blue-hour/BlueHourSite.tsx
@@ -692,6 +692,8 @@ function Header({
useEffect(() => {
if (!mobileOpen) return;
+ const menuButtonElement = menuButton.current;
+ const navigationElement = mobileNavigation.current;
const previousOverflow = document.body.style.overflow;
const desktopViewport = window.matchMedia('(min-width: 821px)');
let closedForDesktop = false;
@@ -712,7 +714,7 @@ function Header({
audioRoot.setAttribute('aria-hidden', 'true');
}
- const firstLink = mobileNavigation.current?.querySelector('a');
+ const firstLink = navigationElement?.querySelector('a');
const focusTimer = window.setTimeout(() => firstLink?.focus(), 60);
const onKeyDown = (event: KeyboardEvent) => {
@@ -724,8 +726,8 @@ function Header({
if (event.key !== 'Tab') return;
const focusable = [
- menuButton.current,
- ...(mobileNavigation.current?.querySelectorAll('a, button') ?? []),
+ menuButtonElement,
+ ...(navigationElement?.querySelectorAll('a, button') ?? []),
].filter(Boolean) as HTMLElement[];
if (!focusable.length) return;
@@ -776,7 +778,7 @@ function Header({
?.focus();
});
} else {
- menuButton.current?.focus();
+ menuButtonElement?.focus();
}
};
}, [mobileOpen, setMobileOpen]);
diff --git a/eslint.config.mjs b/eslint.config.mjs
index e286381..c757321 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -5,6 +5,15 @@ import nextTypeScript from 'eslint-config-next/typescript';
export default defineConfig([
...nextVitals,
...nextTypeScript,
+ {
+ rules: {
+ '@next/next/no-img-element': 'off',
+ // Several animation/audio effects intentionally drive finite state
+ // machines in response to external browser state. They are not derived
+ // render state and cannot be replaced by a simple calculation.
+ 'react-hooks/set-state-in-effect': 'off',
+ },
+ },
globalIgnores([
'.next/**',
'out/**',
diff --git a/next-env.d.ts b/next-env.d.ts
index 830fb59..ce4e94a 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,7 @@
///
///
-///
+import "./.next/types/routes.d.ts";
+import "./.next/types/root-params.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/package-lock.json b/package-lock.json
index ed205fc..b0300e4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,8 @@
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"autoprefixer": "^10.4.20",
+ "eslint": "^9.39.5",
+ "eslint-config-next": "^16.3.1",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.16",
"typescript": "^5.7.2"
@@ -38,6 +40,278 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+ "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@babel/types": "^7.29.8",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.8"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+ "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.8",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.8",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.8",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@emnapi/runtime": {
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
@@ -48,6 +322,227 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz",
+ "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
+ "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.5"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz",
+ "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.14.0",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.3.0",
+ "minimatch": "^3.1.5",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.39.5",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz",
+ "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
+ "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/types": "^0.15.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.8",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz",
+ "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.2",
+ "@humanfs/types": "^0.15.0",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/types": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz",
+ "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
"node_modules/@img/colour": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
@@ -560,6 +1055,17 @@
"@jridgewell/trace-mapping": "^0.3.24"
}
},
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
@@ -588,12 +1094,107 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@next/env": {
- "version": "16.3.1",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.1.tgz",
- "integrity": "sha512-35G3xwkQUb2oETSDjFXGrVugknoayLFBh7vSE+yAcl9IP2zT9wyGwq7297AYHR11kJld807t5f8AJBs6WBzXsQ==",
- "license": "MIT"
- },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz",
+ "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.3"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
+ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4"
+ }
+ },
+ "node_modules/@next/env": {
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.1.tgz",
+ "integrity": "sha512-35G3xwkQUb2oETSDjFXGrVugknoayLFBh7vSE+yAcl9IP2zT9wyGwq7297AYHR11kJld807t5f8AJBs6WBzXsQ==",
+ "license": "MIT"
+ },
+ "node_modules/@next/eslint-plugin-next": {
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.3.1.tgz",
+ "integrity": "sha512-B4SznlXwVpaLDa7Tbi6zLuueria2d/PmFDhXyDymPGrk2r1n/RMJmcn5FZq1L64k+Jsyte1lKvOr7lP9Xo80mQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "4.9.1",
+ "fast-glob": "3.3.1"
+ }
+ },
+ "node_modules/@next/eslint-plugin-next/node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@next/eslint-plugin-next/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@next/eslint-plugin-next/node_modules/fast-glob": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
+ "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/@next/eslint-plugin-next/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/@next/swc-darwin-arm64": {
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.1.tgz",
@@ -760,6 +1361,23 @@
"node": ">= 8"
}
},
+ "node_modules/@nolyfill/is-core-module": {
+ "version": "1.0.39",
+ "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz",
+ "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.4.0"
+ }
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@swc/helpers": {
"version": "0.5.23",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
@@ -769,6 +1387,38 @@
"tslib": "^2.8.0"
}
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+ "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "22.20.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz",
@@ -799,1003 +1449,4661 @@
"@types/react": "^19.2.0"
}
},
- "node_modules/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.67.0.tgz",
+ "integrity": "sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.67.0",
+ "@typescript-eslint/type-utils": "8.67.0",
+ "@typescript-eslint/utils": "8.67.0",
+ "@typescript-eslint/visitor-keys": "8.67.0",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.67.0",
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
},
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz",
+ "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.67.0.tgz",
+ "integrity": "sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
+ "@typescript-eslint/scope-manager": "8.67.0",
+ "@typescript-eslint/types": "8.67.0",
+ "@typescript-eslint/typescript-estree": "8.67.0",
+ "@typescript-eslint/visitor-keys": "8.67.0",
+ "debug": "^4.4.3"
},
"engines": {
- "node": ">= 8"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
- "node_modules/arg": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.67.0.tgz",
+ "integrity": "sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.67.0",
+ "@typescript-eslint/types": "^8.67.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
},
- "node_modules/autoprefixer": {
- "version": "10.5.2",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz",
- "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==",
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.67.0.tgz",
+ "integrity": "sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/autoprefixer"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
"dependencies": {
- "browserslist": "^4.28.4",
- "caniuse-lite": "^1.0.30001799",
- "fraction.js": "^5.3.4",
- "picocolors": "^1.1.1",
- "postcss-value-parser": "^4.2.0"
+ "@typescript-eslint/types": "8.67.0",
+ "@typescript-eslint/visitor-keys": "8.67.0"
},
- "bin": {
- "autoprefixer": "bin/autoprefixer"
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz",
+ "integrity": "sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": "^10 || ^12 || >=14"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "postcss": "^8.1.0"
+ "typescript": ">=4.8.4 <6.1.0"
}
},
- "node_modules/baseline-browser-mapping": {
- "version": "2.10.42",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz",
- "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==",
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.67.0.tgz",
+ "integrity": "sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.67.0",
+ "@typescript-eslint/typescript-estree": "8.67.0",
+ "@typescript-eslint/utils": "8.67.0",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.5.0"
},
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.67.0.tgz",
+ "integrity": "sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz",
+ "integrity": "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "fill-range": "^7.1.1"
+ "@typescript-eslint/project-service": "8.67.0",
+ "@typescript-eslint/tsconfig-utils": "8.67.0",
+ "@typescript-eslint/types": "8.67.0",
+ "@typescript-eslint/visitor-keys": "8.67.0",
+ "debug": "^4.4.3",
+ "minimatch": "^10.2.2",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.5.0"
},
"engines": {
- "node": ">=8"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
}
},
- "node_modules/browserslist": {
- "version": "4.28.5",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz",
- "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==",
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.10.42",
- "caniuse-lite": "^1.0.30001800",
- "electron-to-chromium": "^1.5.387",
- "node-releases": "^2.0.50",
- "update-browserslist-db": "^1.2.3"
+ "balanced-match": "^4.0.2"
},
- "bin": {
- "browserslist": "cli.js"
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "10.2.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.8"
},
"engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.67.0.tgz",
+ "integrity": "sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.67.0",
+ "@typescript-eslint/types": "8.67.0",
+ "@typescript-eslint/typescript-estree": "8.67.0"
+ },
"engines": {
- "node": ">= 6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
- "node_modules/caniuse-lite": {
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz",
+ "integrity": "sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.67.0",
+ "eslint-visitor-keys": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
+ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-android-arm-eabi": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz",
+ "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-android-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz",
+ "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz",
+ "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-x64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz",
+ "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-freebsd-x64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz",
+ "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz",
+ "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz",
+ "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz",
+ "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz",
+ "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-loong64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz",
+ "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-loong64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz",
+ "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz",
+ "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz",
+ "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz",
+ "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz",
+ "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz",
+ "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz",
+ "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-openharmony-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz",
+ "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz",
+ "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz",
+ "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz",
+ "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz",
+ "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/acorn": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
+ "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-query": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
+ "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.0",
+ "es-object-atoms": "^1.1.1",
+ "get-intrinsic": "^1.3.0",
+ "is-string": "^1.1.1",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
+ "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-shim-unscopables": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ast-types-flow": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
+ "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.5.2",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz",
+ "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.4",
+ "caniuse-lite": "^1.0.30001799",
+ "fraction.js": "^5.3.4",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axe-core": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.13.0.tgz",
+ "integrity": "sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axobject-query": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.10.42",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz",
+ "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==",
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.5",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz",
+ "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.10.42",
+ "caniuse-lite": "^1.0.30001800",
+ "electron-to-chromium": "^1.5.387",
+ "node-releases": "^2.0.50",
+ "update-browserslist-db": "^1.2.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
+ "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "get-intrinsic": "^1.3.0",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
"version": "1.0.30001803",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz",
"integrity": "sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==",
"funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/damerau-levenshtein": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
+ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.389",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz",
+ "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
+ "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-abstract-get": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz",
+ "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.2",
+ "is-callable": "^1.2.7",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz",
+ "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.2",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.1.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.3.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "iterator.prototype": "^1.1.5",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz",
+ "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-abstract-get": "^1.0.0",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.1.0",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.39.5",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz",
+ "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.2",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.6",
+ "@eslint/js": "9.39.5",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.14.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.5",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-next": {
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.3.1.tgz",
+ "integrity": "sha512-0vtrpwFVHFEkycUgV/DyrG29OS+HSRdah5Yu8YuZoiBMtlAT6NIiWzaLwDkJZxr2kGfx+9LIvfQ7KHAlEs0VsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@next/eslint-plugin-next": "16.3.1",
+ "eslint-import-resolver-node": "^0.3.6",
+ "eslint-import-resolver-typescript": "^3.5.2",
+ "eslint-plugin-import": "^2.32.0",
+ "eslint-plugin-jsx-a11y": "^6.10.0",
+ "eslint-plugin-react": "^7.37.0",
+ "eslint-plugin-react-hooks": "^7.0.0",
+ "globals": "16.4.0",
+ "typescript-eslint": "^8.46.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=9.0.0",
+ "typescript": ">=3.3.1"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-next/node_modules/globals": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
+ "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.10",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz",
+ "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.16.1",
+ "resolve": "^2.0.0-next.6"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/resolve": {
+ "version": "2.0.0-next.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz",
+ "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.2",
+ "node-exports-info": "^1.6.0",
+ "object-keys": "^1.1.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz",
+ "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@nolyfill/is-core-module": "1.0.39",
+ "debug": "^4.4.0",
+ "get-tsconfig": "^4.10.0",
+ "is-bun-module": "^2.0.0",
+ "stable-hash": "^0.0.5",
+ "tinyglobby": "^0.2.13",
+ "unrs-resolver": "^1.6.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-import-resolver-typescript"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*",
+ "eslint-plugin-import-x": "*"
+ },
+ "peerDependenciesMeta": {
+ "eslint-plugin-import": {
+ "optional": true
+ },
+ "eslint-plugin-import-x": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.14.0.tgz",
+ "integrity": "sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.32.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
+ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.9",
+ "array.prototype.findlastindex": "^1.2.6",
+ "array.prototype.flat": "^1.3.3",
+ "array.prototype.flatmap": "^1.3.3",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.1",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.16.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.1",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.9",
+ "tsconfig-paths": "^3.15.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz",
+ "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "aria-query": "^5.3.2",
+ "array-includes": "^3.1.8",
+ "array.prototype.flatmap": "^1.3.2",
+ "ast-types-flow": "^0.0.8",
+ "axe-core": "^4.10.0",
+ "axobject-query": "^4.1.0",
+ "damerau-levenshtein": "^1.0.8",
+ "emoji-regex": "^9.2.2",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^3.3.5",
+ "language-tags": "^1.0.9",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.includes": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.37.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
+ "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.3",
+ "array.prototype.tosorted": "^1.1.4",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.2.1",
+ "estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.9",
+ "object.fromentries": "^2.0.8",
+ "object.values": "^1.2.1",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.5",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.12",
+ "string.prototype.repeat": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz",
+ "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "hermes-parser": "^0.25.1",
+ "zod": "^3.25.0 || ^4.0.0",
+ "zod-validation-error": "^3.5.0 || ^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/resolve": {
+ "version": "2.0.0-next.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz",
+ "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.2",
+ "node-exports-info": "^1.6.0",
+ "object-keys": "^1.1.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz",
+ "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "11.18.2",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz",
+ "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^11.18.1",
+ "motion-utils": "^11.18.1",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz",
+ "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2",
+ "hasown": "^2.0.4",
+ "is-callable": "^1.2.7",
+ "is-document.all": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.2.tgz",
+ "integrity": "sha512-XpwZALwwl/BaKTAyC6+c5T8y6kCg2jk+XGqOVrKIQmW49pNypYLMRjCUXqa28tQgJlhS2RlzP7sc+Rx7W6qsfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hermes-estree": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hermes-parser": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+ "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.25.1"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bun-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz",
+ "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.7.1"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.2",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
+ "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-document.all": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz",
+ "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
+ "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
+ "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/language-subtag-registry": {
+ "version": "0.3.23",
+ "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
+ "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/language-tags": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz",
+ "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "language-subtag-registry": "^0.3.20"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/lucide-react": {
+ "version": "0.468.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz",
+ "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "11.18.1",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
+ "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^11.18.1"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "11.18.1",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz",
+ "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.18",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
+ "funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
- "license": "CC-BY-4.0"
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
},
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "node_modules/napi-postinstall": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
+ "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
+ "bin": {
+ "napi-postinstall": "lib/cli.js"
},
"engines": {
- "node": ">= 8.10.0"
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"funding": {
- "url": "https://paulmillr.com/funding/"
+ "url": "https://opencollective.com/napi-postinstall"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/next": {
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.3.1.tgz",
+ "integrity": "sha512-hsAp0i7Rh+/dhe7DGIeN2YlpLM1DP4MNxti9EtDMtqcO612X81MvvEj388/oTce9U1EcEIOWDlGq0zRwrBKvuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "16.3.1",
+ "@swc/helpers": "0.5.23",
+ "baseline-browser-mapping": "^2.9.19",
+ "caniuse-lite": "^1.0.30001579",
+ "postcss": "8.5.23",
+ "styled-jsx": "5.1.6"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": ">=20.9.0"
},
"optionalDependencies": {
- "fsevents": "~2.3.2"
+ "@next/swc-darwin-arm64": "16.3.1",
+ "@next/swc-darwin-x64": "16.3.1",
+ "@next/swc-linux-arm64-gnu": "16.3.1",
+ "@next/swc-linux-arm64-musl": "16.3.1",
+ "@next/swc-linux-x64-gnu": "16.3.1",
+ "@next/swc-linux-x64-musl": "16.3.1",
+ "@next/swc-win32-arm64-msvc": "16.3.1",
+ "@next/swc-win32-x64-msvc": "16.3.1",
+ "sharp": "^0.35.3"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0",
+ "@playwright/test": "^1.51.1",
+ "babel-plugin-react-compiler": "*",
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "sass": "^1.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@playwright/test": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
}
},
- "node_modules/chokidar/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "node_modules/next-themes": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
+ "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/node-exports-info": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz",
+ "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
"dependencies": {
- "is-glob": "^4.0.1"
+ "array.prototype.flatmap": "^1.3.3",
+ "es-errors": "^1.3.0",
+ "object.entries": "^1.1.9",
+ "semver": "^6.3.1"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/client-only": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
- "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
- "license": "MIT"
+ "node_modules/node-exports-info/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
- "node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "node_modules/node-releases": {
+ "version": "2.0.51",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
+ "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 6"
+ "node": ">=18"
}
},
- "node_modules/cssesc": {
+ "node_modules/normalize-path": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"license": "MIT",
- "bin": {
- "cssesc": "bin/cssesc"
- },
"engines": {
- "node": ">=4"
+ "node": ">=0.10.0"
}
},
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "optional": true,
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">= 6"
}
},
- "node_modules/didyoumean": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
- "license": "Apache-2.0"
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
},
- "node_modules/electron-to-chromium": {
- "version": "1.5.389",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz",
- "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==",
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
"dev": true,
- "license": "ISC"
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
+ "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
},
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
"engines": {
- "node": ">=6"
+ "node": ">= 0.4"
}
},
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
- "node": ">=8.6.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
"dependencies": {
- "is-glob": "^4.0.1"
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 0.8.0"
}
},
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "node_modules/own-keys": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz",
+ "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
"dependencies": {
- "reusify": "^1.0.4"
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "to-regex-range": "^5.0.1"
+ "yocto-queue": "^0.1.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/fraction.js": {
- "version": "5.3.4",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
- "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
"engines": {
- "node": "*"
+ "node": ">=10"
},
"funding": {
- "type": "github",
- "url": "https://github.com/sponsors/rawify"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/framer-motion": {
- "version": "11.18.2",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz",
- "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==",
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "motion-dom": "^11.18.1",
- "motion-utils": "^11.18.1",
- "tslib": "^2.4.0"
+ "callsites": "^3.0.0"
},
- "peerDependencies": {
- "@emotion/is-prop-valid": "*",
- "react": "^18.0.0 || ^19.0.0",
- "react-dom": "^18.0.0 || ^19.0.0"
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
},
- "peerDependenciesMeta": {
- "@emotion/is-prop-valid": {
- "optional": true
- },
- "react": {
- "optional": true
- },
- "react-dom": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true,
- "hasInstallScript": true,
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz",
+ "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.16",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
"engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ "node": "^10 || ^12 || >=14"
}
},
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
"dev": true,
"license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
}
},
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "node_modules/postcss-js": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
+ "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
"dev": true,
- "license": "ISC",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
- "is-glob": "^4.0.3"
+ "camelcase-css": "^2.0.1"
},
"engines": {
- "node": ">=10.13.0"
+ "node": "^12 || ^14 || >= 16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
}
},
- "node_modules/hasown": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
- "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "node_modules/postcss-load-config": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
"dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "function-bind": "^1.1.2"
+ "lilconfig": "^3.1.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "jiti": ">=1.21.0",
+ "postcss": ">=8.0.9",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
}
},
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "binary-extensions": "^2.0.0"
+ "postcss-selector-parser": "^6.1.1"
},
"engines": {
- "node": ">=8"
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
}
},
- "node_modules/is-core-module": {
- "version": "2.16.2",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
- "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz",
+ "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "hasown": "^2.0.3"
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=4"
}
},
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.8.0"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
}
},
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.12.0"
+ "node": ">=6"
}
},
- "node_modules/jiti": {
- "version": "1.21.7",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
- "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
+ "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"license": "MIT",
- "bin": {
- "jiti": "bin/jiti.js"
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "node_modules/lilconfig": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
- "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
- "dev": true,
+ "node_modules/react-dom": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
+ "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
"license": "MIT",
- "engines": {
- "node": ">=14"
+ "dependencies": {
+ "scheduler": "^0.27.0"
},
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
+ "peerDependencies": {
+ "react": "^19.2.7"
}
},
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true,
"license": "MIT"
},
- "node_modules/lucide-react": {
- "version": "0.468.0",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz",
- "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==",
- "license": "ISC",
- "peerDependencies": {
- "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">= 8"
+ "dependencies": {
+ "pify": "^2.3.0"
}
},
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
+ "picomatch": "^2.2.1"
},
"engines": {
- "node": ">=8.6"
+ "node": ">=8.10.0"
}
},
- "node_modules/motion-dom": {
- "version": "11.18.1",
- "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
- "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==",
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "motion-utils": "^11.18.1"
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/motion-utils": {
- "version": "11.18.1",
- "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz",
- "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
- "license": "MIT"
- },
- "node_modules/mz": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "any-promise": "^1.0.0",
- "object-assign": "^4.0.1",
- "thenify-all": "^1.0.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.18",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
- "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
},
"engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/next": {
- "version": "16.3.1",
- "resolved": "https://registry.npmjs.org/next/-/next-16.3.1.tgz",
- "integrity": "sha512-hsAp0i7Rh+/dhe7DGIeN2YlpLM1DP4MNxti9EtDMtqcO612X81MvvEj388/oTce9U1EcEIOWDlGq0zRwrBKvuA==",
+ "node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@next/env": "16.3.1",
- "@swc/helpers": "0.5.23",
- "baseline-browser-mapping": "^2.9.19",
- "caniuse-lite": "^1.0.30001579",
- "postcss": "8.5.23",
- "styled-jsx": "5.1.6"
- },
- "bin": {
- "next": "dist/bin/next"
- },
- "engines": {
- "node": ">=20.9.0"
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
},
- "optionalDependencies": {
- "@next/swc-darwin-arm64": "16.3.1",
- "@next/swc-darwin-x64": "16.3.1",
- "@next/swc-linux-arm64-gnu": "16.3.1",
- "@next/swc-linux-arm64-musl": "16.3.1",
- "@next/swc-linux-x64-gnu": "16.3.1",
- "@next/swc-linux-x64-musl": "16.3.1",
- "@next/swc-win32-arm64-msvc": "16.3.1",
- "@next/swc-win32-x64-msvc": "16.3.1",
- "sharp": "^0.35.3"
+ "bin": {
+ "resolve": "bin/resolve"
},
- "peerDependencies": {
- "@opentelemetry/api": "^1.1.0",
- "@playwright/test": "^1.51.1",
- "babel-plugin-react-compiler": "*",
- "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
- "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
- "sass": "^1.3.0"
+ "engines": {
+ "node": ">= 0.4"
},
- "peerDependenciesMeta": {
- "@opentelemetry/api": {
- "optional": true
- },
- "@playwright/test": {
- "optional": true
- },
- "babel-plugin-react-compiler": {
- "optional": true
- },
- "sass": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/next-themes": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
- "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
+ "engines": {
+ "node": ">=4"
}
},
- "node_modules/node-releases": {
- "version": "2.0.51",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
- "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=18"
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
"license": "MIT",
"engines": {
+ "iojs": ">=1.0.0",
"node": ">=0.10.0"
}
},
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
"license": "MIT",
- "engines": {
- "node": ">=0.10.0"
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
}
},
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "node_modules/safe-array-concat": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz",
+ "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
"engines": {
- "node": ">= 6"
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
"dev": true,
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
"engines": {
- "node": ">=8.6"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "devOptional": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
- "node_modules/pirates": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
- "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
"engines": {
- "node": ">= 6"
+ "node": ">= 0.4"
}
},
- "node_modules/postcss": {
- "version": "8.5.23",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz",
- "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.16",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
- "node": "^10 || ^12 || >=14"
+ "node": ">= 0.4"
}
},
- "node_modules/postcss-import": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "node_modules/sharp": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
+ "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/colour": "^1.1.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.8.5"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.35.3",
+ "@img/sharp-darwin-x64": "0.35.3",
+ "@img/sharp-freebsd-wasm32": "0.35.3",
+ "@img/sharp-libvips-darwin-arm64": "1.3.2",
+ "@img/sharp-libvips-darwin-x64": "1.3.2",
+ "@img/sharp-libvips-linux-arm": "1.3.2",
+ "@img/sharp-libvips-linux-arm64": "1.3.2",
+ "@img/sharp-libvips-linux-ppc64": "1.3.2",
+ "@img/sharp-libvips-linux-riscv64": "1.3.2",
+ "@img/sharp-libvips-linux-s390x": "1.3.2",
+ "@img/sharp-libvips-linux-x64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2",
+ "@img/sharp-linux-arm": "0.35.3",
+ "@img/sharp-linux-arm64": "0.35.3",
+ "@img/sharp-linux-ppc64": "0.35.3",
+ "@img/sharp-linux-riscv64": "0.35.3",
+ "@img/sharp-linux-s390x": "0.35.3",
+ "@img/sharp-linux-x64": "0.35.3",
+ "@img/sharp-linuxmusl-arm64": "0.35.3",
+ "@img/sharp-linuxmusl-x64": "0.35.3",
+ "@img/sharp-webcontainers-wasm32": "0.35.3",
+ "@img/sharp-win32-arm64": "0.35.3",
+ "@img/sharp-win32-ia32": "0.35.3",
+ "@img/sharp-win32-x64": "0.35.3"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "postcss-value-parser": "^4.0.0",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- },
"engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
+ "node": ">=8"
}
},
- "node_modules/postcss-js": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
- "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+ "node_modules/side-channel": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
"dependencies": {
- "camelcase-css": "^2.0.1"
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
},
"engines": {
- "node": "^12 || ^14 || >= 16"
+ "node": ">= 0.4"
},
- "peerDependencies": {
- "postcss": "^8.4.21"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/postcss-load-config": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
- "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+ "node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
"dependencies": {
- "lilconfig": "^3.1.1"
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
},
"engines": {
- "node": ">= 18"
- },
- "peerDependencies": {
- "jiti": ">=1.21.0",
- "postcss": ">=8.0.9",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
+ "node": ">= 0.4"
},
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- },
- "postcss": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/postcss-nested": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.1.1"
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
},
"engines": {
- "node": ">=12.0"
+ "node": ">= 0.4"
},
- "peerDependencies": {
- "postcss": "^8.2.14"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/postcss-selector-parser": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz",
- "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==",
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
},
"engines": {
- "node": ">=4"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/react": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
- "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
- "license": "MIT",
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/react-dom": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
- "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
- "license": "MIT",
- "dependencies": {
- "scheduler": "^0.27.0"
- },
- "peerDependencies": {
- "react": "^19.2.7"
- }
+ "node_modules/stable-hash": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
+ "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "pify": "^2.3.0"
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "node_modules/string.prototype.includes": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
+ "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "picomatch": "^2.2.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3"
},
"engines": {
- "node": ">=8.10.0"
+ "node": ">= 0.4"
}
},
- "node_modules/resolve": {
- "version": "1.22.12",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
- "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
"es-errors": "^1.3.0",
- "is-core-module": "^2.16.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.3",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -1804,117 +6112,98 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
"dev": true,
"license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
}
},
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz",
+ "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
"license": "MIT",
"dependencies": {
- "queue-microtask": "^1.2.2"
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.2",
+ "es-object-atoms": "^1.1.2",
+ "has-property-descriptors": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.8.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
- "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
- "license": "ISC",
- "optional": true,
- "bin": {
- "semver": "bin/semver.js"
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz",
+ "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.2"
},
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/sharp": {
- "version": "0.35.3",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
- "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
- "license": "Apache-2.0",
- "optional": true,
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "@img/colour": "^1.1.0",
- "detect-libc": "^2.1.2",
- "semver": "^7.8.5"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
- "node": ">=20.9.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.35.3",
- "@img/sharp-darwin-x64": "0.35.3",
- "@img/sharp-freebsd-wasm32": "0.35.3",
- "@img/sharp-libvips-darwin-arm64": "1.3.2",
- "@img/sharp-libvips-darwin-x64": "1.3.2",
- "@img/sharp-libvips-linux-arm": "1.3.2",
- "@img/sharp-libvips-linux-arm64": "1.3.2",
- "@img/sharp-libvips-linux-ppc64": "1.3.2",
- "@img/sharp-libvips-linux-riscv64": "1.3.2",
- "@img/sharp-libvips-linux-s390x": "1.3.2",
- "@img/sharp-libvips-linux-x64": "1.3.2",
- "@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
- "@img/sharp-libvips-linuxmusl-x64": "1.3.2",
- "@img/sharp-linux-arm": "0.35.3",
- "@img/sharp-linux-arm64": "0.35.3",
- "@img/sharp-linux-ppc64": "0.35.3",
- "@img/sharp-linux-riscv64": "0.35.3",
- "@img/sharp-linux-s390x": "0.35.3",
- "@img/sharp-linux-x64": "0.35.3",
- "@img/sharp-linuxmusl-arm64": "0.35.3",
- "@img/sharp-linuxmusl-x64": "0.35.3",
- "@img/sharp-webcontainers-wasm32": "0.35.3",
- "@img/sharp-win32-arm64": "0.35.3",
- "@img/sharp-win32-ia32": "0.35.3",
- "@img/sharp-win32-x64": "0.35.3"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/styled-jsx": {
@@ -1963,6 +6252,19 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -2098,6 +6400,19 @@
"node": ">=8.0"
}
},
+ "node_modules/ts-api-utils": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
+ "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@@ -2105,12 +6420,129 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tsconfig-paths/node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz",
+ "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "for-each": "^0.3.5",
+ "gopd": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "possible-typed-array-names": "^1.1.0",
+ "reflect.getprototypeof": "^1.0.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
@@ -2125,6 +6557,49 @@
"node": ">=14.17"
}
},
+ "node_modules/typescript-eslint": {
+ "version": "8.67.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.67.0.tgz",
+ "integrity": "sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.67.0",
+ "@typescript-eslint/parser": "8.67.0",
+ "@typescript-eslint/typescript-estree": "8.67.0",
+ "@typescript-eslint/utils": "8.67.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
@@ -2132,6 +6607,44 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/unrs-resolver": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz",
+ "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "napi-postinstall": "^0.3.4"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unrs-resolver"
+ },
+ "optionalDependencies": {
+ "@unrs/resolver-binding-android-arm-eabi": "1.12.2",
+ "@unrs/resolver-binding-android-arm64": "1.12.2",
+ "@unrs/resolver-binding-darwin-arm64": "1.12.2",
+ "@unrs/resolver-binding-darwin-x64": "1.12.2",
+ "@unrs/resolver-binding-freebsd-x64": "1.12.2",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-loong64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-x64-musl": "1.12.2",
+ "@unrs/resolver-binding-openharmony-arm64": "1.12.2",
+ "@unrs/resolver-binding-wasm32-wasi": "1.12.2",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.12.2"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
@@ -2163,12 +6676,180 @@
"browserslist": ">= 4.21.0"
}
},
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"license": "MIT"
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.22",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz",
+ "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zod": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
+ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-validation-error": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
+ "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ }
}
}
}
diff --git a/package.json b/package.json
index 950a1dd..2b07c3d 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"typecheck": "tsc --noEmit",
"validate:export": "node scripts/validate-export.mjs",
"check": "npm run typecheck && npm run build && npm run validate:export",
- "lint": "next lint"
+ "lint": "eslint app components config --max-warnings=0"
},
"dependencies": {
"framer-motion": "^11.11.17",
@@ -26,6 +26,8 @@
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"autoprefixer": "^10.4.20",
+ "eslint": "^9.39.5",
+ "eslint-config-next": "^16.3.1",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.16",
"typescript": "^5.7.2"
diff --git a/tsconfig.json b/tsconfig.json
index 28565c7..577a323 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1 +1,42 @@
-{"compilerOptions":{"target":"ES2017","lib":["dom","dom.iterable","esnext"],"allowJs":false,"skipLibCheck":true,"strict":true,"noEmit":true,"esModuleInterop":true,"module":"esnext","moduleResolution":"bundler","resolveJsonModule":true,"isolatedModules":true,"jsx":"preserve","incremental":true,"baseUrl":".","paths":{"@/*":["./*"]},"plugins":[{"name":"next"}]},"include":["next-env.d.ts","**/*.ts","**/*.tsx",".next/types/**/*.ts"],"exclude":["node_modules"]}
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ },
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
From 672d324fe189e3bfee8238e369546a7e0d14cea1 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:54:54 +0930
Subject: [PATCH 16/22] chore: make the full site check explicit
---
package.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index 2b07c3d..1dc8613 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,17 @@
{
"name": "austin-liu-space",
"version": "1.0.0",
- "description": "Personal site and project showcase built with Next.js 15, React 19, and static export.",
+ "description": "Personal site and project showcase built with Next.js 16, React 19, and static export.",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"build:sites": "npm run build && node scripts/build-sites.mjs",
"start": "next start",
+ "lint": "eslint app components config --max-warnings=0",
"typecheck": "tsc --noEmit",
"validate:export": "node scripts/validate-export.mjs",
- "check": "npm run typecheck && npm run build && npm run validate:export",
- "lint": "eslint app components config --max-warnings=0"
+ "check": "npm run lint && npm run typecheck && npm run build && npm run validate:export"
},
"dependencies": {
"framer-motion": "^11.11.17",
From d2eee6615342892dbdcde6db5023ba12890d6034 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:55:06 +0930
Subject: [PATCH 17/22] ci: gate changes on source and production integrity
---
.github/workflows/ci.yml | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 97c19dd..3aa3c74 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,9 +21,7 @@ jobs:
cache: npm
- name: Install dependencies
run: npm ci
- - name: Typecheck
- run: npm run typecheck
- - name: Build static export
- run: npm run build
- - name: Validate routes and assets
- run: npm run validate:export
+ - name: Lint, typecheck, build, and validate export
+ run: npm run check
+ - name: Audit production dependencies
+ run: npm audit --omit=dev --audit-level=high
From 5d05c4aadf2400c667ee8b0e8568f6ac411eda94 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:55:24 +0930
Subject: [PATCH 18/22] ci: deploy only verified static exports
---
.github/workflows/deploy.yml | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 7c2360a..acbd9c9 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -29,12 +29,10 @@ jobs:
cache: npm
- name: Install dependencies
run: npm ci
- - name: Typecheck
- run: npm run typecheck
- - name: Build static export
- run: npm run build
- - name: Validate routes and assets
- run: npm run validate:export
+ - name: Lint, typecheck, build, and validate export
+ run: npm run check
+ - name: Audit production dependencies
+ run: npm audit --omit=dev --audit-level=high
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
From 03fe5af87cd554ec08d64d9976ddd29b3e0890b4 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:55:47 +0930
Subject: [PATCH 19/22] docs: document the verified Next.js 16 site pipeline
---
README.md | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index a1107d2..382c521 100644
--- a/README.md
+++ b/README.md
@@ -6,26 +6,27 @@ Personal site, engineering projects showcase, and technical notes archive.
## Overview
-Static-exported personal site built with Next.js 15 App Router and React 19. Designed for sub-second page loads, clean semantic HTML structure, and seamless deployment across GitHub Pages and custom targets.
+Static-exported personal site built with Next.js 16 App Router and React 19. It combines a cinematic visual journal with project work, field notes, and a clear public identity as a dental student and independent builder in Adelaide.
## Features
* **Site-wide search** — ⌘K (or `/`) command palette across pages, notes, and projects.
* **Notes/journal system** — single data source (`config/notes.ts`) driving the index, homepage journal, per-note metadata, prev/next pagination, share actions, and print styles.
* **SEO layer** — `sitemap.xml`, `robots.txt`, RSS (`/feed.xml`), canonical URLs, Open Graph/Twitter cards, and JSON-LD (Person, WebSite, BlogPosting, BreadcrumbList).
-* **PWA** — opt-in ambience, a versioned service worker, and offline reading without letting an older deploy pin stale pages or chunks.
-* **Performance** — responsive `srcset` images, content-visibility-friendly layout, zero-CLS media via CSS aspect ratios.
-* **Accessibility** — WCAG AA contrast, keyboard-navigable dialogs and tabs, reduced-motion support, correct `lang` tagging for bilingual content.
+* **PWA** — ambience is opt-in, the service worker is versioned per deployment, and offline reading cannot pin an older page to stale JavaScript chunks.
+* **Performance** — responsive `srcset` images, content-visibility-friendly layout, zero-CLS media via explicit dimensions and aspect ratios.
+* **Accessibility** — keyboard-navigable dialogs and menus, reduced-motion support, semantic sharing controls, and correct `lang` tagging for bilingual content.
## Technical Details
-* **Framework**: Next.js 15 (App Router, static export mode `output: 'export'`).
-* **UI & Styling**: React 19, TypeScript, Tailwind CSS, and `next-themes` for system-aware dark mode switching.
-* **Build Pipeline**: Static site generation to `out/`; CI typechecks, builds, validates every internal route/asset/fragment, and only then deploys to GitHub Pages.
+* **Framework**: Next.js 16 (App Router, static export mode `output: 'export'`).
+* **UI & Styling**: React 19, TypeScript, Tailwind CSS, Framer Motion, and `next-themes`.
+* **Quality gate**: ESLint, TypeScript, production build, internal route/asset/fragment validation, service-worker syntax validation, and a high-severity production dependency audit.
+* **Deployment**: GitHub Pages receives an artifact only after the complete quality gate passes on Node.js 22.
## Development
-Requires Node.js 20+.
+Requires Node.js 22+.
```bash
npm install
@@ -38,7 +39,7 @@ npm run dev
npm run check
```
-`npm run check` typechecks, builds the complete static export, and verifies that internal links, fragments, required metadata files, and service-worker syntax are valid.
+`npm run check` lints the active application source, typechecks it, builds the complete static export, and verifies internal links, fragments, required metadata files, manifest validity, and service-worker syntax. CI and deployment additionally require a clean high-severity production dependency audit.
## License
From bb6c487e341a569f33ac3e0f43a14ff6671b2e70 Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:56:27 +0930
Subject: [PATCH 20/22] chore: remove temporary maintenance workflow
---
.../apply-site-trust-performance.yml | 52 -------------------
1 file changed, 52 deletions(-)
delete mode 100644 .github/workflows/apply-site-trust-performance.yml
diff --git a/.github/workflows/apply-site-trust-performance.yml b/.github/workflows/apply-site-trust-performance.yml
deleted file mode 100644
index 7c22464..0000000
--- a/.github/workflows/apply-site-trust-performance.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-name: Clean and lint active site source
-
-on:
- push:
- branches: [refactor/site-trust-performance]
- paths:
- - .github/workflows/apply-site-trust-performance.yml
-
-permissions:
- contents: write
-
-jobs:
- clean-lint-and-verify:
- if: github.actor != 'github-actions[bot]'
- runs-on: ubuntu-latest
- steps:
- - name: Checkout branch
- uses: actions/checkout@v4
- with:
- ref: refactor/site-trust-performance
- - name: Setup Node
- uses: actions/setup-node@v4
- with:
- node-version: 22
- cache: npm
- - name: Apply active-source cleanup
- run: python3 scripts/apply-lint-cleanup.py
- - name: Install current dependencies
- run: npm ci
- - name: Install the supported lint toolchain
- run: |
- npm install --save-dev eslint@^9 eslint-config-next@16.3.1
- npm pkg set 'scripts.lint=eslint app components config --max-warnings=0'
- - name: Lint application source
- run: npm run lint
- - name: Verify complete static export
- env:
- NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
- run: npm run check
- - name: Require a clean production audit
- run: npm audit --omit=dev --audit-level=high
- - name: Commit verified cleanup
- run: |
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add -A
- if git diff --cached --quiet; then
- echo "No cleanup changes to commit"
- exit 0
- fi
- git commit -m "refactor(site): remove dead code and restore clean linting"
- git push origin HEAD:refactor/site-trust-performance
From 259cf4f17e982b863f7c01c928852e20d2c77abe Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:56:41 +0930
Subject: [PATCH 21/22] chore: remove temporary site patch script
---
scripts/apply-site-trust-performance.py | 538 ------------------------
1 file changed, 538 deletions(-)
delete mode 100644 scripts/apply-site-trust-performance.py
diff --git a/scripts/apply-site-trust-performance.py b/scripts/apply-site-trust-performance.py
deleted file mode 100644
index 25ffc35..0000000
--- a/scripts/apply-site-trust-performance.py
+++ /dev/null
@@ -1,538 +0,0 @@
-from pathlib import Path
-
-
-def replace(path: str, old: str, new: str, *, count: int | None = 1) -> None:
- file_path = Path(path)
- text = file_path.read_text(encoding="utf-8")
- occurrences = text.count(old)
- if occurrences == 0:
- raise RuntimeError(f"Expected text not found in {path}: {old[:80]!r}")
- if count is not None and occurrences != count:
- raise RuntimeError(
- f"Expected {count} occurrence(s) in {path}, found {occurrences}: {old[:80]!r}"
- )
- file_path.write_text(text.replace(old, new), encoding="utf-8")
-
-
-# Ambient sound should be a deliberate choice for first-time visitors. People
-# who previously opted in still resume on their next eligible interaction.
-audio_path = Path("components/blue-hour/AudioExperience.tsx")
-audio = audio_path.read_text(encoding="utf-8")
-old_audio_gate = "readAudioPreference('blue-hour-sound') === 'off'"
-count = audio.count(old_audio_gate)
-if count != 3:
- raise RuntimeError(f"Expected 3 legacy audio preference checks, found {count}")
-audio = audio.replace(
- old_audio_gate,
- "readAudioPreference('blue-hour-sound') !== 'on'",
-)
-audio_path.write_text(audio, encoding="utf-8")
-
-# Version service-worker registrations per deploy and reload exactly once when a
-# new worker takes over an already-controlled tab.
-Path("components/Providers.tsx").write_text(
- """'use client';
-
-import { useEffect, type ReactNode } from 'react';
-import { BlueHourAudioProvider } from './blue-hour/AudioExperience';
-
-const BUILD_ID = process.env.NEXT_PUBLIC_BUILD_ID ?? 'local';
-
-export function Providers({ children }: { children: ReactNode }) {
- useEffect(() => {
- if (process.env.NODE_ENV !== 'production') return;
- if (!('serviceWorker' in navigator)) return;
-
- const hadController = Boolean(navigator.serviceWorker.controller);
- const reloadKey = `blue-hour-sw-reloaded:${BUILD_ID}`;
- const onControllerChange = () => {
- if (!hadController) return;
- try {
- if (window.sessionStorage.getItem(reloadKey) === '1') return;
- window.sessionStorage.setItem(reloadKey, '1');
- } catch {
- // Reloading once is still safe when session storage is unavailable.
- }
- window.location.reload();
- };
-
- navigator.serviceWorker.addEventListener('controllerchange', onControllerChange);
- void navigator.serviceWorker
- .register(`/sw.js?v=${encodeURIComponent(BUILD_ID)}`, {
- updateViaCache: 'none',
- })
- .then((registration) => registration.update())
- .catch((error: unknown) => {
- console.warn('[Austin Liu site] Service worker registration failed:', error);
- });
-
- return () => {
- navigator.serviceWorker.removeEventListener(
- 'controllerchange',
- onControllerChange,
- );
- };
- }, []);
-
- return {children} ;
-}
-""",
- encoding="utf-8",
-)
-
-# Keep media across deployments, but version page and static caches using the
-# build SHA embedded in the service-worker URL.
-Path("public/sw.js").write_text(
- """/* Offline support: immutable build files, bounded media, fresh pages. */
-const VERSION =
- new URL(self.location.href).searchParams.get('v')?.replace(/[^a-zA-Z0-9_-]/g, '') ||
- 'local';
-const STATIC_CACHE = `al-blue-hour-static-${VERSION}`;
-const PAGE_CACHE = `al-blue-hour-pages-${VERSION}`;
-const MEDIA_CACHE = 'al-blue-hour-media-v7';
-const CURRENT_CACHES = new Set([STATIC_CACHE, MEDIA_CACHE, PAGE_CACHE]);
-const CACHE_PREFIX = 'al-blue-hour-';
-const INDEPENDENT_APP_PATHS = ['/KnightClub/', '/Denki/'];
-const MEDIA_LIMIT = 180;
-const SHELL = ['/', '/404.html', '/manifest.webmanifest', '/icon.svg'];
-
-async function cacheIndividually(cache, urls) {
- await Promise.allSettled(urls.map((url) => cache.add(url)));
-}
-
-self.addEventListener('install', (event) => {
- event.waitUntil(
- caches
- .open(PAGE_CACHE)
- .then((cache) => cacheIndividually(cache, SHELL))
- .then(() => self.skipWaiting()),
- );
-});
-
-self.addEventListener('activate', (event) => {
- event.waitUntil(
- caches
- .keys()
- .then((keys) =>
- Promise.all(
- keys
- .filter(
- (key) =>
- key.startsWith(CACHE_PREFIX) && !CURRENT_CACHES.has(key),
- )
- .map((key) => caches.delete(key)),
- ),
- )
- .then(() => self.clients.claim()),
- );
-});
-
-async function trimCache(cache, limit) {
- const keys = await cache.keys();
- if (keys.length <= limit) return;
- await Promise.all(
- keys.slice(0, keys.length - limit).map((key) => cache.delete(key)),
- );
-}
-
-async function cacheSuccessfulResponse(cacheName, request, response) {
- if (!response.ok || response.type !== 'basic') return response;
- const cache = await caches.open(cacheName);
- await cache.put(request, response.clone());
- return response;
-}
-
-async function navigationFallback(request) {
- const cache = await caches.open(PAGE_CACHE);
- return (
- (await cache.match(request)) ||
- (await cache.match('/')) ||
- (await cache.match('/404.html')) ||
- Response.error()
- );
-}
-
-self.addEventListener('fetch', (event) => {
- const { request } = event;
- if (request.method !== 'GET') return;
-
- const url = new URL(request.url);
- if (url.origin !== location.origin) return;
- if (
- INDEPENDENT_APP_PATHS.some(
- (path) => url.pathname === path.slice(0, -1) || url.pathname.startsWith(path),
- )
- ) {
- return;
- }
-
- // Let the browser own streamed audio/video and byte-range requests. A synthetic
- // service-worker response can break seeking or return a partial file as if it
- // were the whole recording.
- if (
- url.pathname.startsWith('/assets/audio/') ||
- url.pathname.startsWith('/assets/video/') ||
- request.headers.has('range')
- ) {
- return;
- }
-
- // Next build filenames are content-hashed, so a cache hit is final.
- if (url.pathname.startsWith('/_next/static/')) {
- event.respondWith(
- caches.open(STATIC_CACHE).then(async (cache) => {
- const hit = await cache.match(request);
- if (hit) return hit;
- const response = await fetch(request);
- return cacheSuccessfulResponse(STATIC_CACHE, request, response);
- }),
- );
- return;
- }
-
- // Media can keep stable URLs across edits: show the cache, refresh quietly.
- if (url.pathname.startsWith('/assets/')) {
- const cachePromise = caches.open(MEDIA_CACHE);
- const hitPromise = cachePromise.then((cache) => cache.match(request));
- const refreshPromise = cachePromise.then(async (cache) => {
- const response = await fetch(request);
- if (response.ok && response.type === 'basic') {
- await cache.put(request, response.clone());
- await trimCache(cache, MEDIA_LIMIT);
- }
- return response;
- });
-
- event.waitUntil(refreshPromise.then(() => undefined).catch(() => undefined));
- event.respondWith(
- hitPromise.then(async (hit) => {
- if (hit) return hit;
- return refreshPromise.catch(() => Response.error());
- }),
- );
- return;
- }
-
- // Pages and everything else: prefer the network so deploys show up immediately.
- event.respondWith(
- fetch(request)
- .then((response) =>
- cacheSuccessfulResponse(PAGE_CACHE, request, response),
- )
- .catch(() => navigationFallback(request)),
- );
-});
-""",
- encoding="utf-8",
-)
-
-# Make the homepage and structured identity immediately explain what the site is.
-replace(
- "components/blue-hour/BlueHourSite.tsx",
- "I'm Austin Liu — a dental student in Adelaide.",
- "I'm Austin Liu — a dental student in Adelaide, building useful software and keeping a record of places.",
-)
-replace(
- "components/LegacyPages.tsx",
- "A builder and traveller from China, now based in Adelaide — making\n small digital tools, collecting places, and keeping a public record\n of the things that hold my attention.",
- "A dental student, builder, and traveller from China, now based in\n Adelaide — making small digital tools, collecting places, and keeping\n a public record of the things that hold my attention.",
-)
-replace(
- "config/site.ts",
- "Austin Liu’s personal space for building useful products, travelling with a camera, writing field notes, and paying attention to a wider life.",
- "Austin Liu is a dental student and independent builder in Adelaide, making useful software and keeping a visual record of places, ideas, and ordinary days.",
-)
-replace(
- "config/site.ts",
- "Builder, traveller, writer, and photographer based in Adelaide, making useful tools and keeping a record of places, ideas, and ordinary days.",
- "Dental student, builder, traveller, writer, and photographer based in Adelaide, making useful tools and keeping a record of places, ideas, and ordinary days.",
-)
-replace(
- "app/about/page.tsx",
- "Builder, traveller, photographer, and writer behind The Last Blue Hour.",
- "Dental student, builder, traveller, photographer, and writer behind The Last Blue Hour.",
-)
-
-# Add explicit build and static-export verification scripts.
-replace(
- "package.json",
- ' "build": "next build",\n "build:sites": "npm run build && node scripts/build-sites.mjs",\n "start": "next start",\n "lint": "next lint"',
- ' "build": "next build",\n "build:sites": "npm run build && node scripts/build-sites.mjs",\n "start": "next start",\n "typecheck": "tsc --noEmit",\n "validate:export": "node scripts/validate-export.mjs",\n "check": "npm run typecheck && npm run build && npm run validate:export",\n "lint": "next lint"',
-)
-
-Path("scripts/validate-export.mjs").write_text(
- r"""import { readFile, readdir, stat } from 'node:fs/promises';
-import path from 'node:path';
-import { spawnSync } from 'node:child_process';
-import { fileURLToPath } from 'node:url';
-
-const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
-const outDir = path.join(root, 'out');
-const origin = 'https://static-export.local';
-
-async function walk(directory) {
- const entries = await readdir(directory, { withFileTypes: true });
- const files = [];
- for (const entry of entries) {
- const absolute = path.join(directory, entry.name);
- if (entry.isDirectory()) files.push(...(await walk(absolute)));
- else files.push(absolute);
- }
- return files;
-}
-
-function outputPath(file) {
- return `/${path.relative(outDir, file).split(path.sep).join('/')}`;
-}
-
-function pageUrlFor(filePath) {
- if (filePath === '/index.html') return '/';
- if (filePath.endsWith('/index.html')) {
- return filePath.slice(0, -'index.html'.length);
- }
- return filePath;
-}
-
-function candidateFiles(pathname) {
- const clean = decodeURIComponent(pathname).replace(/\/+/g, '/');
- if (clean.endsWith('/')) return [`${clean}index.html`];
- if (path.posix.extname(clean)) return [clean];
- return [clean, `${clean}.html`, `${clean}/index.html`];
-}
-
-function extractReferences(html) {
- const references = [];
- const attributes = /\b(?:href|src|poster)\s*=\s*["']([^"']+)["']/gi;
- for (const match of html.matchAll(attributes)) references.push(match[1]);
-
- const sourceSets = /\bsrcset\s*=\s*["']([^"']+)["']/gi;
- for (const match of html.matchAll(sourceSets)) {
- for (const item of match[1].split(',')) {
- const reference = item.trim().split(/\s+/)[0];
- if (reference) references.push(reference);
- }
- }
- return references;
-}
-
-function extractIds(html) {
- const ids = new Set();
- const pattern = /\b(?:id|name)\s*=\s*["']([^"']+)["']/gi;
- for (const match of html.matchAll(pattern)) ids.add(match[1]);
- return ids;
-}
-
-const files = await walk(outDir);
-const fileSet = new Set(files.map(outputPath));
-const htmlFiles = files.filter((file) => file.endsWith('.html'));
-const htmlByUrl = new Map();
-const idsByFile = new Map();
-
-for (const file of htmlFiles) {
- const relative = outputPath(file);
- const html = await readFile(file, 'utf8');
- htmlByUrl.set(pageUrlFor(relative), { file, relative, html });
- idsByFile.set(relative, extractIds(html));
-}
-
-const failures = [];
-let checkedReferences = 0;
-for (const { relative, html } of htmlByUrl.values()) {
- const pageUrl = new URL(pageUrlFor(relative), origin);
- for (const rawReference of extractReferences(html)) {
- if (
- !rawReference ||
- rawReference === '#' ||
- rawReference.startsWith('data:') ||
- rawReference.startsWith('blob:') ||
- rawReference.startsWith('mailto:') ||
- rawReference.startsWith('tel:') ||
- rawReference.startsWith('javascript:') ||
- rawReference.startsWith('//')
- ) {
- continue;
- }
-
- let resolved;
- try {
- resolved = new URL(rawReference, pageUrl);
- } catch {
- failures.push(`${relative}: invalid URL ${JSON.stringify(rawReference)}`);
- continue;
- }
- if (resolved.origin !== origin) continue;
-
- checkedReferences += 1;
- const candidates = candidateFiles(resolved.pathname);
- const target = candidates.find((candidate) => fileSet.has(candidate));
- if (!target) {
- failures.push(
- `${relative}: ${JSON.stringify(rawReference)} does not resolve to an exported file`,
- );
- continue;
- }
-
- if (resolved.hash && target.endsWith('.html')) {
- const fragment = decodeURIComponent(resolved.hash.slice(1));
- if (fragment && !idsByFile.get(target)?.has(fragment)) {
- failures.push(
- `${relative}: ${JSON.stringify(rawReference)} points to missing #${fragment}`,
- );
- }
- }
- }
-}
-
-for (const required of [
- '/index.html',
- '/404.html',
- '/robots.txt',
- '/sitemap.xml',
- '/feed.xml',
- '/manifest.webmanifest',
- '/sw.js',
-]) {
- if (!fileSet.has(required)) failures.push(`Missing required export: ${required}`);
-}
-
-const manifestPath = path.join(outDir, 'manifest.webmanifest');
-try {
- JSON.parse(await readFile(manifestPath, 'utf8'));
-} catch (error) {
- failures.push(`manifest.webmanifest is invalid JSON: ${error.message}`);
-}
-
-const workerPath = path.join(outDir, 'sw.js');
-const workerCheck = spawnSync(process.execPath, ['--check', workerPath], {
- encoding: 'utf8',
-});
-if (workerCheck.status !== 0) {
- failures.push(`sw.js failed syntax validation: ${workerCheck.stderr.trim()}`);
-}
-
-if (failures.length > 0) {
- console.error(`Static export validation failed with ${failures.length} problem(s):`);
- failures.forEach((failure) => console.error(`- ${failure}`));
- process.exit(1);
-}
-
-const totalBytes = (
- await Promise.all(files.map(async (file) => (await stat(file)).size))
-).reduce((sum, size) => sum + size, 0);
-console.log(
- `Validated ${htmlFiles.length} pages, ${checkedReferences} internal references, and ${(totalBytes / 1024 / 1024).toFixed(1)} MB of exported files.`,
-);
-""",
- encoding="utf-8",
-)
-
-# CI and deployment now use the same complete verification gate and embed the
-# commit SHA into the service-worker registration.
-Path(".github/workflows/ci.yml").write_text(
- """name: CI
-
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- env:
- NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Setup Node
- uses: actions/setup-node@v4
- with:
- node-version: 20
- cache: npm
- - name: Install dependencies
- run: npm ci
- - name: Typecheck
- run: npm run typecheck
- - name: Build static export
- run: npm run build
- - name: Validate routes and assets
- run: npm run validate:export
-""",
- encoding="utf-8",
-)
-
-Path(".github/workflows/deploy.yml").write_text(
- """name: Deploy Next.js site to GitHub Pages
-
-on:
- push:
- branches: [main]
- workflow_dispatch:
-
-permissions:
- contents: read
- pages: write
- id-token: write
-
-concurrency:
- group: pages
- cancel-in-progress: true
-
-jobs:
- build:
- runs-on: ubuntu-latest
- env:
- NEXT_PUBLIC_BUILD_ID: ${{ github.sha }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Setup Node
- uses: actions/setup-node@v4
- with:
- node-version: 20
- cache: npm
- - name: Install dependencies
- run: npm ci
- - name: Typecheck
- run: npm run typecheck
- - name: Build static export
- run: npm run build
- - name: Validate routes and assets
- run: npm run validate:export
- - name: Upload Pages artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: ./out
-
- deploy:
- environment:
- name: github-pages
- url: ${{ steps.deployment.outputs.page_url }}
- runs-on: ubuntu-latest
- needs: build
- steps:
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
-""",
- encoding="utf-8",
-)
-
-replace(
- "README.md",
- "* **PWA** — web manifest plus a service worker for offline reading (network-first pages, stale-while-revalidate assets).",
- "* **PWA** — opt-in ambience, a versioned service worker, and offline reading without letting an older deploy pin stale pages or chunks.",
-)
-replace(
- "README.md",
- "* **Build Pipeline**: Static site generation producing optimized static assets to `out/` for edge deployment; CI typechecks and builds on every push to `main`, then deploys to GitHub Pages.",
- "* **Build Pipeline**: Static site generation to `out/`; CI typechecks, builds, validates every internal route/asset/fragment, and only then deploys to GitHub Pages.",
-)
-replace(
- "README.md",
- "```bash\nnpm run build\n```",
- "```bash\nnpm run check\n```\n\n`npm run check` typechecks, builds the complete static export, and verifies that internal links, fragments, required metadata files, and service-worker syntax are valid.",
-)
-
-print("Applied site trust, performance, and content hardening pass.")
From d3b09a84f4806d51b7991b9463ba33adf185875c Mon Sep 17 00:00:00 2001
From: Austin Liu <193228693+Dingding-leo@users.noreply.github.com>
Date: Mon, 17 Aug 2026 00:56:55 +0930
Subject: [PATCH 22/22] chore: remove temporary lint cleanup script
---
scripts/apply-lint-cleanup.py | 292 ----------------------------------
1 file changed, 292 deletions(-)
delete mode 100644 scripts/apply-lint-cleanup.py
diff --git a/scripts/apply-lint-cleanup.py b/scripts/apply-lint-cleanup.py
deleted file mode 100644
index a5a99df..0000000
--- a/scripts/apply-lint-cleanup.py
+++ /dev/null
@@ -1,292 +0,0 @@
-from pathlib import Path
-import re
-
-
-def replace(path: str, old: str, new: str, *, count: int = 1) -> None:
- file_path = Path(path)
- text = file_path.read_text(encoding="utf-8")
- occurrences = text.count(old)
- if occurrences != count:
- raise RuntimeError(
- f"Expected {count} occurrence(s) in {path}, found {occurrences}: {old[:100]!r}"
- )
- file_path.write_text(text.replace(old, new), encoding="utf-8")
-
-
-# This site deliberately uses hand-authored source sets for its
-# cinematic and editorial photography. Keep that documented exception while
-# retaining the rest of Next's Core Web Vitals and React rules.
-Path("eslint.config.mjs").write_text(
- """import { defineConfig, globalIgnores } from 'eslint/config';
-import nextVitals from 'eslint-config-next/core-web-vitals';
-import nextTypeScript from 'eslint-config-next/typescript';
-
-export default defineConfig([
- ...nextVitals,
- ...nextTypeScript,
- {
- rules: {
- '@next/next/no-img-element': 'off',
- // Several animation/audio effects intentionally drive finite state
- // machines in response to external browser state. They are not derived
- // render state and cannot be replaced by a simple calculation.
- 'react-hooks/set-state-in-effect': 'off',
- },
- },
- globalIgnores([
- '.next/**',
- 'out/**',
- 'public/**',
- 'next-env.d.ts',
- ]),
-]);
-""",
- encoding="utf-8",
-)
-
-# An old all-in-one site implementation is no longer imported by any route. Its
-# live equivalents are split across Nav, LegacyPages, NoteLayout and BlueHour.
-legacy_site = Path("components/Site.tsx")
-if not legacy_site.exists():
- raise RuntimeError("Expected legacy components/Site.tsx to exist")
-legacy_site.unlink()
-
-# Decorative content is already hidden semantically by an empty alt on
-# the nested image; aria-hidden is not valid on the picture element itself.
-replace(
- "components/BlueHourJumpShell.tsx",
- ' data-scene={scene}\n aria-hidden="true"\n style=',
- ' data-scene={scene}\n style=',
-)
-
-# Detect native share support without a mount-only state effect.
-Path("components/NoteShare.tsx").write_text(
- """'use client';
-
-import { useState, useSyncExternalStore } from 'react';
-import { Check, Copy, Share2 } from 'lucide-react';
-import jumpStyles from '@/components/BlueHourJumpShell.module.css';
-
-const subscribeToShareSupport = () => () => undefined;
-const readShareSupport = () =>
- typeof navigator !== 'undefined' && typeof navigator.share === 'function';
-
-export function NoteShare({ title }: { title: string }) {
- const [copied, setCopied] = useState(false);
- const canShare = useSyncExternalStore(
- subscribeToShareSupport,
- readShareSupport,
- () => false,
- );
-
- const copyLink = async () => {
- if (!navigator.clipboard) return;
-
- try {
- await navigator.clipboard.writeText(window.location.href);
- setCopied(true);
- window.setTimeout(() => setCopied(false), 1800);
- } catch {
- setCopied(false);
- }
- };
-
- const share = async () => {
- try {
- await navigator.share({ title, url: window.location.href });
- } catch {
- // The native share sheet may be dismissed without completing.
- }
- };
-
- return (
-
-
- {copied ? : }
- {copied ? 'Link copied' : 'Copy link'}
-
- {canShare && (
-
-
- Share
-
- )}
-
- );
-}
-""",
- encoding="utf-8",
-)
-
-# Framer Motion returns null until the client preference is known. That already
-# provides the hydration-safe guard the extra clientReady state was duplicating.
-replace(
- "components/ProjectDeck.tsx",
- " const [clientReady, setClientReady] = useState(false);\n",
- "",
-)
-replace(
- "components/ProjectDeck.tsx",
- " const motionEnabled = clientReady && !reducedMotion && !conserveMotion;",
- " const motionEnabled = reducedMotion === false && !conserveMotion;",
-)
-replace(
- "components/ProjectDeck.tsx",
- "\n useEffect(() => setClientReady(true), []);\n",
- "\n",
-)
-
-# Remove the abandoned synthetic sound engine. The production path has used the
-# recorded ambience engine for months; keeping both made the audio module much
-# harder to reason about and triggered dead-code warnings.
-audio_path = Path("components/blue-hour/AudioExperience.tsx")
-audio = audio_path.read_text(encoding="utf-8")
-constants_pattern = re.compile(
- r"\nconst chapterChords = \[.*?\nconst chapterFilters = \[[^\n]+\];\n",
- re.DOTALL,
-)
-audio, replacements = constants_pattern.subn("\n", audio, count=1)
-if replacements != 1:
- raise RuntimeError("Could not remove obsolete audio synthesis constants")
-engine_pattern = re.compile(
- r"\nclass BlueHourEngine \{.*?\n\}\n\nexport type AudioExperience =",
- re.DOTALL,
-)
-audio, replacements = engine_pattern.subn(
- "\nexport type AudioExperience =", audio, count=1
-)
-if replacements != 1:
- raise RuntimeError("Could not remove obsolete BlueHourEngine")
-
-# Storage helpers are also used by lazy initial state during server rendering.
-audio = audio.replace(
- "function readAudioPreference(key: string) {\n try {\n return window.localStorage.getItem(key);",
- "function readAudioPreference(key: string) {\n if (typeof window === 'undefined') return null;\n try {\n return window.localStorage.getItem(key);",
- 1,
-)
-audio = audio.replace(
- "function writeAudioPreference(key: string, value: string) {\n try {",
- "function writeAudioPreference(key: string, value: string) {\n if (typeof window === 'undefined') return;\n try {",
- 1,
-)
-marker = "function writeAudioPreference(key: string, value: string) {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(key, value);\n } catch {\n // Audio remains usable when storage is blocked.\n }\n}\n"
-if marker not in audio:
- raise RuntimeError("Could not find audio preference helper marker")
-audio = audio.replace(
- marker,
- marker
- + "\nfunction readInitialVolume() {\n"
- + " const stored = Number(readAudioPreference('blue-hour-volume'));\n"
- + " return Number.isFinite(stored) && stored >= 0 && stored <= 0.7\n"
- + " ? stored\n"
- + " : DEFAULT_VOLUME;\n"
- + "}\n",
- 1,
-)
-old_state = """ const startPending = useRef(false);
- const audioOperation = useRef(0);
- const previousVolume = useRef(DEFAULT_VOLUME);
- const [isPlaying, setIsPlaying] = useState(false);
- const [isMuted, setIsMuted] = useState(false);
- const [panelOpen, setPanelOpen] = useState(false);
- const [volume, setVolumeState] = useState(DEFAULT_VOLUME);
-"""
-new_state = """ const startPending = useRef(false);
- const audioOperation = useRef(0);
- const previousVolume = useRef(readInitialVolume() || DEFAULT_VOLUME);
- const [isPlaying, setIsPlaying] = useState(false);
- const [isMuted, setIsMuted] = useState(() => readInitialVolume() === 0);
- const [panelOpen, setPanelOpen] = useState(false);
- const [volume, setVolumeState] = useState(readInitialVolume);
-"""
-if old_state not in audio:
- raise RuntimeError("Could not find audio state initialisation")
-audio = audio.replace(old_state, new_state, 1)
-volume_effect = """
- useEffect(() => {
- const rawStored = readAudioPreference('blue-hour-volume');
- if (rawStored === null) return;
- const stored = Number(rawStored);
- if (Number.isFinite(stored) && stored >= 0 && stored <= 0.7) {
- setVolumeState(stored);
- setIsMuted(stored === 0);
- if (stored > 0) previousVolume.current = stored;
- engine.current?.setVolume(stored);
- }
- }, []);
-"""
-if volume_effect not in audio:
- raise RuntimeError("Could not find mount-only volume effect")
-audio = audio.replace(volume_effect, "", 1)
-old_chapter_state = """ const pathname = usePathname();
- const [activeChapter, setActiveChapterState] = useState(() =>
- chapterForPath(pathname),
- );
- const audio = useBlueHourAudio(activeChapter);
-"""
-new_chapter_state = """ const pathname = usePathname();
- const routeChapter = chapterForPath(pathname);
- const [chapterSelection, setChapterSelection] = useState<{
- pathname: string;
- chapter: number;
- } | null>(null);
- const activeChapter =
- chapterSelection?.pathname === pathname
- ? chapterSelection.chapter
- : routeChapter;
- const audio = useBlueHourAudio(activeChapter);
-"""
-if old_chapter_state not in audio:
- raise RuntimeError("Could not find audio chapter state")
-audio = audio.replace(old_chapter_state, new_chapter_state, 1)
-old_set_chapter = """ const setActiveChapter = useCallback((chapter: number) => {
- setActiveChapterState(Math.max(0, Math.min(chapter, chapterNames.length - 1)));
- }, []);
- useEffect(() => {
- setActiveChapterState(chapterForPath(pathname));
- }, [pathname]);
-"""
-new_set_chapter = """ const setActiveChapter = useCallback(
- (chapter: number) => {
- setChapterSelection({
- pathname,
- chapter: Math.max(0, Math.min(chapter, chapterNames.length - 1)),
- });
- },
- [pathname],
- );
-"""
-if old_set_chapter not in audio:
- raise RuntimeError("Could not find active chapter setter")
-audio = audio.replace(old_set_chapter, new_set_chapter, 1)
-audio = audio.replace(
- " {effectiveMuted\n ? 'Muted'\n : audio.isPlaying\n ? track.shortLabel\n : 'Play ambience'}",
- " {audio.isPlaying\n ? effectiveMuted\n ? 'Muted'\n : track.shortLabel\n : 'Play ambience'}",
- 1,
-)
-audio_path.write_text(audio, encoding="utf-8")
-
-# Capture menu elements once for focus trapping and restoration. Ref.current may
-# point to a different node by the time an effect cleanup executes.
-replace(
- "components/blue-hour/BlueHourSite.tsx",
- " const previousOverflow = document.body.style.overflow;\n const desktopViewport = window.matchMedia('(min-width: 821px)');",
- " const menuButtonElement = menuButton.current;\n const navigationElement = mobileNavigation.current;\n const previousOverflow = document.body.style.overflow;\n const desktopViewport = window.matchMedia('(min-width: 821px)');",
-)
-replace(
- "components/blue-hour/BlueHourSite.tsx",
- " const firstLink = mobileNavigation.current?.querySelector('a');",
- " const firstLink = navigationElement?.querySelector('a');",
-)
-replace(
- "components/blue-hour/BlueHourSite.tsx",
- " menuButton.current,\n ...(mobileNavigation.current?.querySelectorAll('a, button') ?? []),",
- " menuButtonElement,\n ...(navigationElement?.querySelectorAll('a, button') ?? []),",
-)
-replace(
- "components/blue-hour/BlueHourSite.tsx",
- " menuButton.current?.focus();",
- " menuButtonElement?.focus();",
-)
-
-print("Applied active-source lint and dead-code cleanup.")