From b2ad445f76b0efb56b59b7cdf79afc5debe5e0ef Mon Sep 17 00:00:00 2001 From: Robert Goniszewski Date: Tue, 22 Sep 2026 10:52:16 +0200 Subject: [PATCH 01/14] fix(cors): support trusted reverse proxy origins --- API.md | 8 ++--- README.md | 1 + SECURITY.md | 21 ++++++----- daemon/src/server.ts | 9 +++-- .../integration/security-hardening.test.ts | 36 ++++++++++++++++++- docker-compose.yml | 3 ++ docs/06-remote-access.md | 14 ++++++++ docs/docker-deployment.md | 33 +++++++++++++---- docs/faq.md | 3 +- scripts/api-docs-generator.test.ts | 4 ++- scripts/api-docs-generator.ts | 8 ++--- 11 files changed, 112 insertions(+), 28 deletions(-) diff --git a/API.md b/API.md index f7933f8b..b0d4d339 100644 --- a/API.md +++ b/API.md @@ -19,15 +19,15 @@ Local integration surfaces such as `/mcp` and `/capture` require a managed beare ## Browser Origin And CORS -Grimoire keeps browser access loopback-only. The daemon trusts the first-party app from `http://127.0.0.1:3210`, `http://localhost:3210`, and configured loopback development origins. Requests without an `Origin` header are treated as non-browser local client traffic and do not receive CORS headers. +Grimoire defaults browser access to loopback origins. The daemon trusts the first-party app from `http://127.0.0.1:3210`, `http://localhost:3210`, configured loopback development origins, and any exact origins explicitly listed in `CORS_ORIGINS`. Requests without an `Origin` header are treated as non-browser local client traffic and do not receive CORS headers. -Configure additional local browser clients with `CORS_ORIGINS` as a comma-separated list of loopback origins: +Configure additional trusted browser clients with `CORS_ORIGINS` as a comma-separated list of exact origins: ```sh -CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173,http://localhost:4321 littleimpd +CORS_ORIGINS=http://localhost:5173,https://grimoire.example.com littleimpd ``` -Only full `http` or `https` origins are accepted, including scheme, host, and any port used by the client. Non-loopback origins are ignored even when configured, unsafe browser writes from rejected origins return `403`, and rejected preflight requests return `403` without reflecting `Access-Control-Allow-Origin`. Protected local capture clients must use loopback origins and a managed integration bearer token. +Only exact `http` or `https` origins are accepted, including scheme, host, and any port used by the client. Explicit non-loopback origins are intended for authenticated reverse proxies or VPNs; paths, credentials, and wildcards are rejected, and the allowlist is not authentication. Unsafe browser writes from rejected origins return `403` with configuration guidance, and rejected preflight requests return `403` without reflecting `Access-Control-Allow-Origin`. Protected capture clients still require a managed integration bearer token. ## Response Conventions diff --git a/README.md b/README.md index d4efee75..435db85f 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ The daemon reads install-time defaults from `~/.local/share/littleimp/.env`. | `HOST` | `127.0.0.1` | Bind address. Keep localhost for security. | | `PORT` | `3210` | Daemon HTTP port. | | `DATA_DIR` | `~/.local/share/littleimp` | Database, backups, and logs. | +| `CORS_ORIGINS` | local development origins | Comma-separated exact browser origins trusted for writes. Required for an authenticated reverse proxy or a non-default browser-facing port, for example `https://grimoire.example.com`. Paths, credentials, and wildcards are not accepted. | | `NODE_ENV` | `production` | Use `development` for local development logging. | | `LOG_FORMAT` | `json` | `json` or `pretty`. | diff --git a/SECURITY.md b/SECURITY.md index 4f40b253..5622c073 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -34,10 +34,12 @@ Grimoire is local-first, single-user, and loopback-first for `1.1.0`. - Native daemon default: `127.0.0.1:3210`. - Docker host port default: `127.0.0.1:3210:3210`. -- The first-party browser UI is trusted only from the daemon origin or - configured loopback development origins. -- General REST routes remain loopback-only and tokenless for first-party local - use. +- The first-party browser UI is trusted from the daemon origin, configured + loopback development origins, or exact origins explicitly allowlisted for an + authenticated reverse proxy or VPN. +- General REST routes remain tokenless and are intended only for first-party + loopback use or access through an authenticated proxy or VPN with an exact + configured browser origin. - MCP and protected local capture endpoints require managed local integration bearer tokens. - Public-network exposure is not a supported Grimoire mode. Any remote access @@ -48,8 +50,8 @@ Grimoire is local-first, single-user, and loopback-first for `1.1.0`. an in-browser fixture router, keeps session state in memory, and contains no server database, secrets, cookies, third-party scripts, or fingerprinting. -Any future non-loopback mode requires a separate security review and explicit -authentication, origin, secrets, and network-exposure controls. +Any broader public or multi-user mode requires a separate security review and +explicit authentication, origin, secrets, and network-exposure controls. ## Implemented Controls @@ -57,8 +59,11 @@ authentication, origin, secrets, and network-exposure controls. - Localhost-only native binding. - Loopback-only Docker port publishing. -- Unsafe browser requests are accepted only from configured loopback origins. -- Non-loopback `CORS_ORIGINS` entries are ignored by the daemon. +- Unsafe browser requests are accepted only from default loopback origins or + exact origins explicitly configured with `CORS_ORIGINS`. +- Explicit non-loopback origins are intended only for authenticated reverse + proxies or VPNs. Wildcard origins are not accepted, and the origin allowlist + is not a substitute for authentication. - Private, loopback, link-local, and unspecified hosts are blocked for bookmark fetching and update-source handling where route behavior requires public targets. diff --git a/daemon/src/server.ts b/daemon/src/server.ts index b29e0ec9..3eae6c25 100644 --- a/daemon/src/server.ts +++ b/daemon/src/server.ts @@ -46,6 +46,8 @@ const LOCAL_JSON_BODY_MAX_BYTES = 64 * 1024; const CAPTURE_JSON_BODY_MAX_BYTES = 256 * 1024; /** Default cap for mutating routes that are not on the allowlist below. */ const DEFAULT_JSON_BODY_MAX_BYTES = 256 * 1024; +const ORIGIN_REJECTED_MESSAGE = + "Origin is not allowed for this local daemon. Add the exact trusted browser origin to CORS_ORIGINS."; const LOCAL_JSON_BODY_LIMIT_PATHS = new Set([ "/backup", @@ -79,6 +81,9 @@ function normalizeOrigin(origin: string): string | null { try { const parsed = new URL(origin); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null; + if (parsed.username || parsed.password) return null; + if (parsed.pathname !== "/" || parsed.search || parsed.hash) return null; + if (parsed.hostname.includes("*")) return null; return parsed.origin; } catch { return null; @@ -176,12 +181,12 @@ async function enforceLocalOrigin(c: Context, next: Next): Promise { expect(res.status).toBe(403); const json = (await res.json()) as { error: string }; expect(json.error).toContain("Origin is not allowed"); + expect(json.error).toContain("CORS_ORIGINS"); }); it("allows same-daemon local browser writes", async () => { @@ -145,7 +146,14 @@ describe("Security hardening", () => { it("allows explicitly configured remote origins while rejecting unconfigured origins", async () => { const originalOrigins = Config.CORS_ORIGINS; - (Config as MutableConfig).CORS_ORIGINS = ["https://roberts-mac-mini.tailae45c7.ts.net:8443", "http://localhost:4567"]; + (Config as MutableConfig).CORS_ORIGINS = [ + "https://roberts-mac-mini.tailae45c7.ts.net:8443", + "http://localhost:4567", + "*", + "https://*.example.com", + "https://path.example/admin", + "https://user:password@credential.example", + ]; try { const app = createApp({ db, queue, startTime: new Date(), version: "0.0.0-test", staticDir: false }); @@ -171,6 +179,32 @@ describe("Security hardening", () => { expect(remote.status).toBe(201); expect(remote.headers.get("access-control-allow-origin")).toBe("https://roberts-mac-mini.tailae45c7.ts.net:8443"); + const remotePreflight = await app.request("/import", { + method: "OPTIONS", + headers: { + Origin: "https://roberts-mac-mini.tailae45c7.ts.net:8443", + "Access-Control-Request-Method": "POST", + "Access-Control-Request-Headers": "Content-Type", + }, + }); + expect(remotePreflight.status).toBe(204); + expect(remotePreflight.headers.get("access-control-allow-origin")).toBe( + "https://roberts-mac-mini.tailae45c7.ts.net:8443" + ); + + for (const origin of ["https://*.example.com", "https://path.example", "https://credential.example"]) { + const invalid = await app.request("/bookmarks", { + method: "POST", + headers: { + "Content-Type": "application/json", + Origin: origin, + }, + body: JSON.stringify({ url: "https://example.com/invalid-configured-origin" }), + }); + expect(invalid.status).toBe(403); + expect(invalid.headers.get("access-control-allow-origin")).toBeNull(); + } + const allowed = await app.request("/bookmarks", { method: "POST", headers: { diff --git a/docker-compose.yml b/docker-compose.yml index ea9aa107..79ddc1a7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,9 @@ services: - NODE_ENV=production - LOG_FORMAT=json - LITTLEIMP_IN_CONTAINER=1 + # Exact browser origin(s) allowed to write through an authenticated + # reverse proxy. Leave unset for built-in defaults; comma-separate more. + - CORS_ORIGINS # Optional: seed OpenAI defaults for first start or unattended deployments. # Runtime settings saved through the UI/API remain the source of truth. # - LLM_API_KEY=your-api-key diff --git a/docs/06-remote-access.md b/docs/06-remote-access.md index e7c5c370..c7ee20bd 100644 --- a/docs/06-remote-access.md +++ b/docs/06-remote-access.md @@ -33,4 +33,18 @@ Use the Serve URL Tailscale prints. Prefer this over opening firewall ports. Det - Do not treat Grimoire as a multi-user public web app — it is single-user and local-trust - If you use a reverse proxy, terminate auth at the proxy or VPN and keep Grimoire on `127.0.0.1` +## Browser access through a reverse proxy + +The browser-facing origin must be explicitly trusted for write requests. With +the repository Compose file, pass the exact origin when creating the container: + +```sh +CORS_ORIGINS=https://grimoire.example.com docker compose up -d --force-recreate +``` + +Include the scheme and any non-default port. Use commas for more than one exact +origin. Paths, credentials, and wildcards are rejected. `CORS_ORIGINS` only +controls the browser origin check; it does not authenticate users, so keep +authentication at the proxy or VPN. + Threat model: [SECURITY.md](../SECURITY.md). Docker notes: [docker-deployment.md](./docker-deployment.md). diff --git a/docs/docker-deployment.md b/docs/docker-deployment.md index 9befb23d..6cdd92ec 100644 --- a/docs/docker-deployment.md +++ b/docs/docker-deployment.md @@ -5,9 +5,9 @@ container that serves both the React frontend and the daemon API on port 3210. Grimoire has scoped bearer-token authentication for local integration surfaces such as MCP, but the first-party browser app and general REST API -still rely on the loopback trust boundary. Do not publish the daemon on a -public interface unless you put it behind authentication, a VPN, or another -trusted access control layer. +still rely on the deployment's network and browser-origin boundary. Do not +publish the daemon on a public interface unless you put it behind +authentication, a VPN, or another trusted access control layer. ## Prerequisites @@ -55,6 +55,7 @@ The Docker image sets these runtime defaults: | `DATA_DIR` | `/data` | SQLite database, backups, and runtime data. | | `XDG_CONFIG_HOME` | `/data/config` | Persisted settings directory inside the data volume. | | `HOME` | `/data` | Writable home directory for the non-root container user. | +| `CORS_ORIGINS` | built-in loopback development origins | Comma-separated exact browser origins trusted for writes through an authenticated reverse proxy or non-default browser-facing port. | | `NODE_ENV` | `production` | Production error responses and logging defaults. | | `LOG_FORMAT` | `json` | Structured container logs. | @@ -164,14 +165,32 @@ services: Then open `http://127.0.0.1:3211`. +Because the browser origin includes the host-side port, also trust that exact +origin when recreating the container: + +```sh +CORS_ORIGINS=http://127.0.0.1:3211 docker compose up -d --force-recreate +``` + ## Remote Access Grimoire is designed for local-first, single-user use. Integration token auth does not turn the daemon into a public server because most first-party REST -routes remain loopback-trusted. Public reverse proxy examples are intentionally -omitted. If you need remote access, put the service behind an authenticated -tunnel, VPN, or reverse proxy that enforces authentication before traffic -reaches Grimoire. +routes remain tokenless. Public reverse proxy configurations are intentionally +omitted because authentication varies by deployment. If you need remote access, +put the service behind an authenticated tunnel, VPN, or reverse proxy that +enforces authentication before traffic reaches Grimoire. Set `CORS_ORIGINS` to +the exact browser-facing origin so the first-party UI can make writes through +that proxy: + +```sh +CORS_ORIGINS=https://grimoire.example.com docker compose up -d --force-recreate +``` + +The value must include the scheme and any non-default port, and may contain +comma-separated origins. Paths, credentials, and wildcards are rejected. +Changing this variable requires recreating the container. This allowlist is not +authentication; the proxy or VPN must still enforce access control. Do not use these unsafe port mappings: diff --git a/docs/faq.md b/docs/faq.md index 6012f508..445357ae 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -74,6 +74,7 @@ static, client-only showcase with synthetic session data; it has no hosted library. For a private library, you can run Grimoire through Docker, but Grimoire itself is not a public-server product in `1.1.0`. Keep the daemon loopback-bound or put an authenticated tunnel, VPN, or reverse proxy in front -of it before traffic reaches Grimoire. See +of it before traffic reaches Grimoire. Reverse-proxy browser access also +requires the exact public origin in `CORS_ORIGINS`. See [remote access](./06-remote-access.md), [SECURITY.md](../SECURITY.md), and [docker-deployment.md](./docker-deployment.md). diff --git a/scripts/api-docs-generator.test.ts b/scripts/api-docs-generator.test.ts index 4c22e457..300dc3e0 100644 --- a/scripts/api-docs-generator.test.ts +++ b/scripts/api-docs-generator.test.ts @@ -299,7 +299,9 @@ describe("API documentation generator", () => { expect(markdown).toContain("CORS_ORIGINS"); expect(markdown).toContain("http://localhost:5173"); expect(markdown).toContain("http://127.0.0.1:3210"); - expect(markdown).toContain("Non-loopback origins are ignored"); + expect(markdown).toContain("https://grimoire.example.com"); + expect(markdown).toContain("Explicit non-loopback origins are intended for authenticated reverse proxies or VPNs"); + expect(markdown).toContain("paths, credentials, and wildcards are rejected"); expect(markdown).not.toMatch(/browser extension/i); // The bookmarklet endpoint appears in the route table but not in the CORS setup prose expect(markdown).toContain("/capture/bookmarklet"); diff --git a/scripts/api-docs-generator.ts b/scripts/api-docs-generator.ts index aceee062..73aff293 100644 --- a/scripts/api-docs-generator.ts +++ b/scripts/api-docs-generator.ts @@ -358,15 +358,15 @@ export function buildApiMarkdown(document: ApiContractDocument): string { lines.push(""); lines.push("## Browser Origin And CORS"); lines.push(""); - lines.push("Grimoire keeps browser access loopback-only. The daemon trusts the first-party app from `http://127.0.0.1:3210`, `http://localhost:3210`, and configured loopback development origins. Requests without an `Origin` header are treated as non-browser local client traffic and do not receive CORS headers."); + lines.push("Grimoire defaults browser access to loopback origins. The daemon trusts the first-party app from `http://127.0.0.1:3210`, `http://localhost:3210`, configured loopback development origins, and any exact origins explicitly listed in `CORS_ORIGINS`. Requests without an `Origin` header are treated as non-browser local client traffic and do not receive CORS headers."); lines.push(""); - lines.push("Configure additional local browser clients with `CORS_ORIGINS` as a comma-separated list of loopback origins:"); + lines.push("Configure additional trusted browser clients with `CORS_ORIGINS` as a comma-separated list of exact origins:"); lines.push(""); lines.push("```sh"); - lines.push("CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173,http://localhost:4321 littleimpd"); + lines.push("CORS_ORIGINS=http://localhost:5173,https://grimoire.example.com littleimpd"); lines.push("```"); lines.push(""); - lines.push("Only full `http` or `https` origins are accepted, including scheme, host, and any port used by the client. Non-loopback origins are ignored even when configured, unsafe browser writes from rejected origins return `403`, and rejected preflight requests return `403` without reflecting `Access-Control-Allow-Origin`. Protected local capture clients must use loopback origins and a managed integration bearer token."); + lines.push("Only exact `http` or `https` origins are accepted, including scheme, host, and any port used by the client. Explicit non-loopback origins are intended for authenticated reverse proxies or VPNs; paths, credentials, and wildcards are rejected, and the allowlist is not authentication. Unsafe browser writes from rejected origins return `403` with configuration guidance, and rejected preflight requests return `403` without reflecting `Access-Control-Allow-Origin`. Protected capture clients still require a managed integration bearer token."); lines.push(""); lines.push("## Response Conventions"); lines.push(""); From c4ebaf5bdef6d83ed1390165c90e0769efe7082b Mon Sep 17 00:00:00 2001 From: Robert Goniszewski Date: Wed, 23 Sep 2026 16:37:58 +0200 Subject: [PATCH 02/14] fix(cors): address reverse proxy origin review feedback --- daemon/src/server.ts | 2 ++ daemon/src/test/integration/security-hardening.test.ts | 10 +++++++++- docs/docker-deployment.md | 2 ++ src/lib/api.test.ts | 9 +++++++++ src/lib/api.ts | 5 +++-- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/daemon/src/server.ts b/daemon/src/server.ts index 3eae6c25..7f03bb7d 100644 --- a/daemon/src/server.ts +++ b/daemon/src/server.ts @@ -78,6 +78,8 @@ function isFrontendNavigation(c: Context): boolean { } function normalizeOrigin(origin: string): string | null { + // Reject raw path syntax before URL parsing can normalize dot segments away. + if (!/^https?:\/\/[^/?#\\]+\/?$/i.test(origin)) return null; try { const parsed = new URL(origin); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null; diff --git a/daemon/src/test/integration/security-hardening.test.ts b/daemon/src/test/integration/security-hardening.test.ts index 42accf06..f69780b4 100644 --- a/daemon/src/test/integration/security-hardening.test.ts +++ b/daemon/src/test/integration/security-hardening.test.ts @@ -152,6 +152,8 @@ describe("Security hardening", () => { "*", "https://*.example.com", "https://path.example/admin", + "https://normalized-path.example/admin/..", + "https://encoded-path.example/%2e", "https://user:password@credential.example", ]; @@ -192,7 +194,13 @@ describe("Security hardening", () => { "https://roberts-mac-mini.tailae45c7.ts.net:8443" ); - for (const origin of ["https://*.example.com", "https://path.example", "https://credential.example"]) { + for (const origin of [ + "https://*.example.com", + "https://path.example", + "https://normalized-path.example", + "https://encoded-path.example", + "https://credential.example", + ]) { const invalid = await app.request("/bookmarks", { method: "POST", headers: { diff --git a/docs/docker-deployment.md b/docs/docker-deployment.md index 6cdd92ec..92afd113 100644 --- a/docs/docker-deployment.md +++ b/docs/docker-deployment.md @@ -164,6 +164,8 @@ services: ``` Then open `http://127.0.0.1:3211`. +The built frontend sends API requests to that same browser origin, including +the host-side port. Because the browser origin includes the host-side port, also trust that exact origin when recreating the container: diff --git a/src/lib/api.test.ts b/src/lib/api.test.ts index 0d840fb5..bacaa097 100644 --- a/src/lib/api.test.ts +++ b/src/lib/api.test.ts @@ -33,6 +33,15 @@ describe("daemon URL resolution", () => { ); }); + it("uses the current loopback origin for a packaged frontend on an alternate port", () => { + expect(resolveDaemonUrl(undefined, "http://127.0.0.1:3211", false)).toBe("http://127.0.0.1:3211"); + expect(resolveDaemonUrl(undefined, "http://localhost:3211", false)).toBe("http://localhost:3211"); + }); + + it("keeps the Vite development frontend pointed at the daemon port", () => { + expect(resolveDaemonUrl(undefined, "http://127.0.0.1:8080", true)).toBe("http://127.0.0.1:3210"); + }); + it("rejects non-loopback daemon URL overrides", () => { expect(() => resolveDaemonUrl("https://example.com:3220")).toThrow( "VITE_DAEMON_URL must point to localhost, 127.0.0.1, or ::1" diff --git a/src/lib/api.ts b/src/lib/api.ts index 85a9b808..19bc6750 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -84,13 +84,14 @@ function isLoopbackHostname(hostname: string): boolean { export function resolveDaemonUrl( rawUrl = import.meta.env.VITE_DAEMON_URL, - currentOrigin = typeof window !== "undefined" ? window.location.origin : undefined + currentOrigin = typeof window !== "undefined" ? window.location.origin : undefined, + isDev = import.meta.env.DEV ): string { const trimmedUrl = rawUrl?.trim(); if (!trimmedUrl) { if (currentOrigin) { const parsedOrigin = new URL(currentOrigin); - if (!isLoopbackHostname(parsedOrigin.hostname)) return parsedOrigin.origin; + if (!isDev || !isLoopbackHostname(parsedOrigin.hostname)) return parsedOrigin.origin; } return DEFAULT_DAEMON_URL; } From d88ea99dde71f1b44ac3d60935873775ce411db8 Mon Sep 17 00:00:00 2001 From: Robert Goniszewski Date: Mon, 28 Sep 2026 17:27:32 +0200 Subject: [PATCH 03/14] chore(release): publish v1.3.0 distribution metadata --- AGENTS.md | 2 +- CHANGELOG.md | 2 +- Formula/grimoire.rb | 8 ++++---- Formula/release.json | 14 +++++++++----- README.md | 2 +- SECURITY.md | 10 ++++++---- docs/04-development.md | 5 ++--- docs/05-install-without-docker.md | 2 +- docs/faq.md | 6 +++--- install.sh | 2 +- scripts/release-metadata.test.ts | 3 ++- 11 files changed, 31 insertions(+), 25 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 445ac1d7..862258d4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ Guidance for coding agents working in this repository. - Grimoire is a local-first bookmark manager. - The frontend is a React 18 + Vite + TypeScript SPA under `src/`. - The background daemon is a Bun service under `daemon/` that listens on `127.0.0.1:3210`, stores data in SQLite, and exposes the REST API used by the frontend. -- Current published release: `1.2.0`; the next release candidate is `1.3.0`. +- Current published release: `1.3.0`. ## First Reads diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b27ebaa..70cc699b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to Grimoire will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). -## [1.3.0] - Unreleased +## [1.3.0] - 2026-09-28 ### Added - Later / Revisit rounds present a small shuffled stack of saved bookmarks, diff --git a/Formula/grimoire.rb b/Formula/grimoire.rb index 5d271506..ca23b143 100644 --- a/Formula/grimoire.rb +++ b/Formula/grimoire.rb @@ -6,11 +6,11 @@ class Grimoire < Formula depends_on "bun" if OS.mac? - url "https://github.com/goniszewski/grimoire/releases/download/v1.2.0/little-imp-1.2.0-macos.tar.gz" - sha256 "5b99fc6c4d92cd4516b64c1651e847905457775112859eae6bddee40d132635b" + url "https://github.com/goniszewski/grimoire/releases/download/v1.3.0/little-imp-1.3.0-macos.tar.gz" + sha256 "8e87d6631e7ba0bcef91c68a4035b42b7e7eb8c7562791fe3cdd3fd1b9adcf83" elsif OS.linux? - url "https://github.com/goniszewski/grimoire/releases/download/v1.2.0/little-imp-1.2.0-linux.tar.gz" - sha256 "5217a85217518ccb1e3d2e594b5e85194dccf5fa32ddd673262553f01e70e485" + url "https://github.com/goniszewski/grimoire/releases/download/v1.3.0/little-imp-1.3.0-linux.tar.gz" + sha256 "d12a1e74f75c449a81b9ef0eaa053d1e602a4565cbb6536962962a1da5367c61" end def install diff --git a/Formula/release.json b/Formula/release.json index 4e2b9f68..d433f7e9 100644 --- a/Formula/release.json +++ b/Formula/release.json @@ -1,15 +1,19 @@ { - "version": "1.2.0", + "version": "1.3.0", "artifacts": [ { "platform": "macos", - "archive": "little-imp-1.2.0-macos.tar.gz", - "sha256": "5b99fc6c4d92cd4516b64c1651e847905457775112859eae6bddee40d132635b" + "archive": "little-imp-1.3.0-macos.tar.gz", + "checksum": "little-imp-1.3.0-macos.tar.gz.sha256", + "sha256": "8e87d6631e7ba0bcef91c68a4035b42b7e7eb8c7562791fe3cdd3fd1b9adcf83", + "signature": "little-imp-1.3.0-macos.tar.gz.asc" }, { "platform": "linux", - "archive": "little-imp-1.2.0-linux.tar.gz", - "sha256": "5217a85217518ccb1e3d2e594b5e85194dccf5fa32ddd673262553f01e70e485" + "archive": "little-imp-1.3.0-linux.tar.gz", + "checksum": "little-imp-1.3.0-linux.tar.gz.sha256", + "sha256": "d12a1e74f75c449a81b9ef0eaa053d1e602a4565cbb6536962962a1da5367c61", + "signature": "little-imp-1.3.0-linux.tar.gz.asc" } ] } diff --git a/README.md b/README.md index e7516f08..7cd5537f 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ cd daemon ### Homebrew -Grimoire v1.2.0 is available through Homebrew. The main Grimoire repository +Grimoire v1.3.0 is available through Homebrew. The main Grimoire repository serves as the tap; the explicit URL avoids requiring a separate `homebrew-grimoire` repository. Install it with: diff --git a/SECURITY.md b/SECURITY.md index 57aca137..58b404e6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,6 +4,8 @@ | Version | Supported | | --- | --- | +| `1.3.0` | Yes | +| `1.2.0` | Yes | | `1.1.0` | Yes | | `1.0.x` | No | | `0.1.0-beta` | No | @@ -16,9 +18,9 @@ for the repository, that is also an appropriate channel. Do not report security vulnerabilities through public GitHub issues. -No project-specific PGP key is currently published. If you need encrypted -coordination, ask the maintainer for a preferred secure channel before sharing -sensitive exploit details. +The PGP key attached to GitHub releases verifies release artifacts; it is not +an encrypted-reporting channel. Ask the maintainer for a preferred secure +channel before sharing sensitive exploit details. Please include: @@ -30,7 +32,7 @@ Please include: ## Security Boundary Summary -Grimoire is local-first, single-user, and loopback-first for `1.1.0`. +Grimoire is local-first, single-user, and loopback-first for `1.3.0`. - Native daemon default: `127.0.0.1:3210`. - Docker host port default: `127.0.0.1:3210:3210`. diff --git a/docs/04-development.md b/docs/04-development.md index 1b0148ca..2316cdca 100644 --- a/docs/04-development.md +++ b/docs/04-development.md @@ -81,8 +81,7 @@ For pre-publication testing, download and verify the signed release archives first, then provide their directory in local mode. Homebrew verifies the formula SHA-256 against the supplied archive; this does not prove public asset availability. Set the working-tree formula URLs and checksums to those -exact candidate archives before running this command; the tracked formula -still points to the published v1.2.0 assets: +exact candidate archives before running this command: ```sh HOMEBREW_TEST_ARCHIVE_DIR=/absolute/path/to/verified-archives \ @@ -99,7 +98,7 @@ It requires the version to change and verifies preservation and service health at the requested target version. Supply both archives when using local cache mode. Without the older formula, the test exercises a same-version reinstall. -For the v1.3 release candidate, after merging an approved PR into `main`: +For the v1.3 release, after merging an approved PR into `main`: 1. Require a clean `main` at the exact remote commit and a `v1.3.0` tag at that commit. Build both archives from that checkout with diff --git a/docs/05-install-without-docker.md b/docs/05-install-without-docker.md index c577f292..e98a8b70 100644 --- a/docs/05-install-without-docker.md +++ b/docs/05-install-without-docker.md @@ -63,7 +63,7 @@ cd daemon For day-to-day coding, prefer [Development](./04-development.md) (`npm run daemon:dev` + `npm run dev`) instead of reinstalling. -The published v1.2.0 Homebrew path is validated on macOS, including service startup, reinstall, v1.1 to v1.2 upgrade, and data preservation after uninstall. Linux Homebrew remains unverified; use the native Linux installer above. The explicit repository URL uses Grimoire itself as the tap; no separate tap repository is required. Trust only this formula before tapping: +The published v1.3.0 Homebrew formula targets the signed macOS and Linux archives. The macOS path has passed local install and service checks; public v1.2 to v1.3 upgrade validation follows publication. Linux Homebrew remains unverified; use the native Linux installer above. The explicit repository URL uses Grimoire itself as the tap; no separate tap repository is required. Trust only this formula before tapping: ```sh brew trust --formula goniszewski/grimoire/grimoire diff --git a/docs/faq.md b/docs/faq.md index 52fa1d63..29e8bcdd 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -4,7 +4,7 @@ Also published at [goniszewski.com/grimoire/faq](https://goniszewski.com/grimoir ## Can I sync my bookmarks across devices? -Not yet. Grimoire is local-first and single-user for `1.1.0`. Backups are snapshot-based, so you can move or restore a saved backup, but there is no continuous multi-device sync service. +Not yet. Grimoire is local-first and single-user for `1.3.0`. Backups are snapshot-based, so you can move or restore a saved backup, but there is no continuous multi-device sync service. ## Is my data private? @@ -68,14 +68,14 @@ the rename and uses `littleimp` as its direct archive command. ## Does it work on Windows? -There is no native Windows installer in `1.1.0`. Docker on Windows with WSL2 is the supported path. Keep Docker port publishing bound to loopback, for example `127.0.0.1:3210:3210`. +There is no native Windows installer in `1.3.0`. Docker on Windows with WSL2 is the supported path. Keep Docker port publishing bound to loopback, for example `127.0.0.1:3210:3210`. ## Can I run it on a server? The [hosted public demo](https://goniszewski.com/grimoire/demo/) is only a static, client-only showcase with synthetic session data; it has no hosted library. For a private library, you can run Grimoire through Docker, but -Grimoire itself is not a public-server product in `1.1.0`. Keep the daemon +Grimoire itself is not a public-server product in `1.3.0`. Keep the daemon loopback-bound or put an authenticated tunnel, VPN, or reverse proxy in front of it before traffic reaches Grimoire. See [remote access](./06-remote-access.md), [SECURITY.md](../SECURITY.md), and diff --git a/install.sh b/install.sh index e2b3d20f..e6db1045 100755 --- a/install.sh +++ b/install.sh @@ -5,7 +5,7 @@ set -euo pipefail APP_NAME="Grimoire" REPO="goniszewski/grimoire" -VERSION="${LITTLEIMP_VERSION:-1.2.0}" +VERSION="${LITTLEIMP_VERSION:-1.3.0}" RELEASE_BASE_URL="${LITTLEIMP_RELEASE_BASE_URL:-https://github.com/${REPO}/releases/download/v${VERSION}}" MODE_ARGS=() diff --git a/scripts/release-metadata.test.ts b/scripts/release-metadata.test.ts index 5225e4d5..003f9f8e 100644 --- a/scripts/release-metadata.test.ts +++ b/scripts/release-metadata.test.ts @@ -24,8 +24,9 @@ describe("release metadata", () => { const root = fixtureRoot(); try { expect(checkReleaseMetadata(root)).toEqual([]); + const publishedVersion = JSON.parse(readFileSync(join(root, "Formula/release.json"), "utf8")).version as string; const installerPath = join(root, "install.sh"); - writeFileSync(installerPath, readFileSync(installerPath, "utf8").replace("LITTLEIMP_VERSION:-1.2.0", "LITTLEIMP_VERSION:-1.1.0")); + writeFileSync(installerPath, readFileSync(installerPath, "utf8").replace(`LITTLEIMP_VERSION:-${publishedVersion}`, "LITTLEIMP_VERSION:-0.0.0")); expect(checkReleaseMetadata(root)).toContain("One-command installer default differs from published release"); const daemonPath = join(root, "daemon/package.json"); writeFileSync(daemonPath, readFileSync(daemonPath, "utf8").replace('"version": "1.3.0"', '"version": "1.2.0"')); From 87ff1de5957c1e8645b9cb376cbedc57aa270b9e Mon Sep 17 00:00:00 2001 From: Robert Goniszewski Date: Mon, 28 Sep 2026 17:31:44 +0200 Subject: [PATCH 04/14] fix(release): satisfy Homebrew formula style --- Formula/grimoire.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Formula/grimoire.rb b/Formula/grimoire.rb index ca23b143..f63cdaee 100644 --- a/Formula/grimoire.rb +++ b/Formula/grimoire.rb @@ -1,3 +1,6 @@ +# frozen_string_literal: true + +# Install the Grimoire bookmark manager and local daemon. class Grimoire < Formula desc "Local-first bookmark manager and search daemon" homepage "https://github.com/goniszewski/grimoire" From 0613f071eab3687afb4d4d83f23355e81fe12de7 Mon Sep 17 00:00:00 2001 From: Robert Goniszewski Date: Mon, 28 Sep 2026 17:36:52 +0200 Subject: [PATCH 05/14] docs(release): record verified v1.3.0 Homebrew upgrade --- README.md | 2 +- docs/05-install-without-docker.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7cd5537f..e7b50b20 100644 --- a/README.md +++ b/README.md @@ -206,7 +206,7 @@ kept under `$(brew --prefix)/var/little-imp`; it is separate from the native `~/.local/share/littleimp` directory and is not migrated automatically. The public macOS Homebrew path has passed install, service startup, reinstall, -and uninstall checks with data preservation. Upgrading from v1.1 to v1.2 was +and uninstall checks with data preservation. Upgrading from v1.2 to v1.3 was also validated. Linux Homebrew remains unverified; use the native Linux archive or Docker Compose there. diff --git a/docs/05-install-without-docker.md b/docs/05-install-without-docker.md index e98a8b70..62b2349b 100644 --- a/docs/05-install-without-docker.md +++ b/docs/05-install-without-docker.md @@ -63,7 +63,7 @@ cd daemon For day-to-day coding, prefer [Development](./04-development.md) (`npm run daemon:dev` + `npm run dev`) instead of reinstalling. -The published v1.3.0 Homebrew formula targets the signed macOS and Linux archives. The macOS path has passed local install and service checks; public v1.2 to v1.3 upgrade validation follows publication. Linux Homebrew remains unverified; use the native Linux installer above. The explicit repository URL uses Grimoire itself as the tap; no separate tap repository is required. Trust only this formula before tapping: +The published v1.3.0 Homebrew formula targets the signed macOS and Linux archives. The macOS path passed public download, install, service, reinstall, and uninstall checks, plus a v1.2 to v1.3 upgrade with bookmark and configuration preservation. Linux Homebrew remains unverified; use the native Linux installer above. The explicit repository URL uses Grimoire itself as the tap; no separate tap repository is required. Trust only this formula before tapping: ```sh brew trust --formula goniszewski/grimoire/grimoire From 376f293228ab67ae04da976af866e8cae1b3c53b Mon Sep 17 00:00:00 2001 From: Robert Goniszewski Date: Mon, 28 Sep 2026 18:01:29 +0200 Subject: [PATCH 06/14] feat(release): use Grimoire archive names after v1.3.0 --- daemon/src/test/cli-update.test.ts | 8 +++- daemon/src/update/release-names.ts | 10 ++++ daemon/src/update/upgrade.ts | 3 +- docs/04-development.md | 5 ++ install.sh | 14 +++++- scripts/homebrew-formula.test.ts | 5 +- scripts/install-release.test.ts | 15 ++++-- scripts/installed-app-smoke.test.ts | 6 ++- scripts/installed-app-smoke.ts | 5 +- scripts/release-final-check.ts | 5 +- scripts/release-metadata.test.ts | 18 ++++++++ scripts/release-metadata.ts | 3 +- scripts/release-packager.test.ts | 21 ++++++++- scripts/release-packager.ts | 4 +- scripts/sign-release-artifacts.sh | 40 ++++++++++++---- scripts/sign-release-artifacts.test.ts | 54 ++++++++++++++++++++++ scripts/validate-linux-installer-matrix.sh | 12 ++++- 17 files changed, 199 insertions(+), 29 deletions(-) create mode 100644 daemon/src/update/release-names.ts create mode 100644 scripts/sign-release-artifacts.test.ts diff --git a/daemon/src/test/cli-update.test.ts b/daemon/src/test/cli-update.test.ts index f1172a37..c0029a44 100644 --- a/daemon/src/test/cli-update.test.ts +++ b/daemon/src/test/cli-update.test.ts @@ -6,6 +6,7 @@ import { dirname, join } from "path"; import { spawnSync } from "child_process"; import { runLittleImpCli } from "../cli.js"; import { version as PACKAGE_VERSION } from "../../package.json"; +import { releaseArchiveName } from "../update/upgrade.js"; type FetchCall = { url: string; @@ -17,6 +18,11 @@ type SpawnCall = { args: string[]; }; +it("uses branded archive downloads only after the published 1.3.0 release", () => { + expect(releaseArchiveName("1.3.0", "linux")).toBe("little-imp-1.3.0-linux.tar.gz"); + expect(releaseArchiveName("1.3.1", "linux")).toBe("grimoire-1.3.1-linux.tar.gz"); +}); + function makeUpdateHarness(response: unknown, status = 200, env: Record = {}) { const stdout: string[] = []; const stderr: string[] = []; @@ -65,7 +71,7 @@ function createUpgradeArchiveFixture(options: { badChecksum?: boolean; signature const version = options.version ?? "0.2.0-beta"; const platform = platformName(); const archiveRoot = `little-imp-${version}-${platform}`; - const archiveName = `${archiveRoot}.tar.gz`; + const archiveName = releaseArchiveName(version, platform); const archivePath = join(releaseDir, archiveName); const checksumPath = `${archivePath}.sha256`; const signaturePath = `${archivePath}.asc`; diff --git a/daemon/src/update/release-names.ts b/daemon/src/update/release-names.ts new file mode 100644 index 00000000..0dda96ed --- /dev/null +++ b/daemon/src/update/release-names.ts @@ -0,0 +1,10 @@ +export type ReleasePlatform = "macos" | "linux"; + +/** Published releases through 1.3.0 retain their original download names. */ +export function releaseArchiveFileName(version: string, platform: ReleasePlatform): string { + const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+][0-9A-Za-z.+-]+)?$/.exec(version); + if (!match) throw new Error(`Unsupported release version: ${version}`); + const [major, minor, patch] = match.slice(1, 4).map(Number); + const isAfterRename = major > 1 || (major === 1 && (minor > 3 || (minor === 3 && patch > 0))); + return `${isAfterRename ? "grimoire" : "little-imp"}-${version}-${platform}.tar.gz`; +} diff --git a/daemon/src/update/upgrade.ts b/daemon/src/update/upgrade.ts index db9a593b..ac174415 100644 --- a/daemon/src/update/upgrade.ts +++ b/daemon/src/update/upgrade.ts @@ -10,6 +10,7 @@ import { createHash } from "crypto"; import { tmpdir } from "os"; import { basename, join, resolve } from "path"; import { spawnSync } from "child_process"; +import { releaseArchiveFileName } from "./release-names.js"; export type ReleasePlatform = "macos" | "linux"; @@ -56,7 +57,7 @@ export function detectReleasePlatform(platform = process.platform): ReleasePlatf export function releaseArchiveName(version: string, platform = detectReleasePlatform()): string { assertSafeReleaseVersion(version); - return `little-imp-${version}-${platform}.tar.gz`; + return releaseArchiveFileName(version, platform); } export function defaultReleaseBaseUrl(version: string): string { diff --git a/docs/04-development.md b/docs/04-development.md index 2316cdca..9d538dd1 100644 --- a/docs/04-development.md +++ b/docs/04-development.md @@ -83,6 +83,11 @@ formula SHA-256 against the supplied archive; this does not prove public asset availability. Set the working-tree formula URLs and checksums to those exact candidate archives before running this command: +Archives after v1.3.0 use `grimoire--.tar.gz`, with matching +`.sha256` and `.asc` files. Published v1.3.0 and older downloads keep their +`little-imp-` names. The directory inside each archive remains `little-imp-` +for installer compatibility. + ```sh HOMEBREW_TEST_ARCHIVE_DIR=/absolute/path/to/verified-archives \ HOMEBREW_TEST_EXPECTED_VERSION=1.3.0 \ diff --git a/install.sh b/install.sh index e6db1045..a990cb56 100755 --- a/install.sh +++ b/install.sh @@ -61,6 +61,18 @@ assert_safe_version() { fi } +release_archive_prefix() { + if [[ ! "${VERSION}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)([-+][A-Za-z0-9.+-]+)?$ ]]; then + die "Unsupported release version: ${VERSION}" + fi + local major="${BASH_REMATCH[1]}" minor="${BASH_REMATCH[2]}" patch="${BASH_REMATCH[3]}" + if (( 10#${major} > 1 || (10#${major} == 1 && (10#${minor} > 3 || (10#${minor} == 3 && 10#${patch} > 0))) )); then + echo "grimoire" + else + echo "little-imp" + fi +} + detect_platform() { case "$(uname -s)" in Darwin) echo "macos" ;; @@ -300,7 +312,7 @@ main() { local platform archive_root archive_name archive_url checksum_url signature_url platform="$(detect_platform)" archive_root="little-imp-${VERSION}-${platform}" - archive_name="${archive_root}.tar.gz" + archive_name="$(release_archive_prefix)-${VERSION}-${platform}.tar.gz" archive_url="${RELEASE_BASE_URL%/}/${archive_name}" checksum_url="${archive_url}.sha256" signature_url="${archive_url}.asc" diff --git a/scripts/homebrew-formula.test.ts b/scripts/homebrew-formula.test.ts index 3f7219a1..eb40b534 100644 --- a/scripts/homebrew-formula.test.ts +++ b/scripts/homebrew-formula.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; +import { releaseArchiveFileName } from "../daemon/src/update/release-names"; type PackageJson = { version: string; @@ -40,7 +41,7 @@ function expectedReleaseChecksums(version: string): ReleaseChecksumBaseline { const artifacts = manifest.artifacts.filter((entry) => entry.platform === platform); expect(artifacts).toHaveLength(1); const artifact = artifacts[0]; - expect(artifact.archive).toBe(`little-imp-${version}-${platform}.tar.gz`); + expect(artifact.archive).toBe(releaseArchiveFileName(version, platform)); expect(artifact.sha256).toMatch(/^[a-f0-9]{64}$/); return [platform, artifact.sha256]; })) as ReleaseChecksumBaseline; @@ -100,7 +101,7 @@ describe("Homebrew formula packaging", () => { const formula = readFileSync(formulaPath, "utf8"); for (const platform of platforms) { - const archive = `little-imp-${version}-${platform}.tar.gz`; + const archive = releaseArchiveFileName(version, platform); const releaseUrl = `https://github.com/goniszewski/grimoire/releases/download/v${version}/${archive}`; const urlLine = `url "${releaseUrl}"`; const snippet = formulaSnippetAfter(formula, urlLine); diff --git a/scripts/install-release.test.ts b/scripts/install-release.test.ts index 71786d7f..7bbcffc7 100644 --- a/scripts/install-release.test.ts +++ b/scripts/install-release.test.ts @@ -104,13 +104,13 @@ function createFakeBin( return binDir; } -function createReleaseFixture(options: { signature?: boolean } = {}) { +function createReleaseFixture(options: { signature?: boolean; version?: string } = {}) { const releaseDir = mkdtempSync(join(tmpdir(), "little-imp-install-release-")); const payloadStage = join(releaseDir, "payload"); - const version = "1.2.3-beta"; + const version = options.version ?? "1.2.3-beta"; const platform = platformName(); const archiveRoot = `little-imp-${version}-${platform}`; - const archiveName = `${archiveRoot}.tar.gz`; + const archiveName = `${version === "1.3.1" ? "grimoire" : "little-imp"}-${version}-${platform}.tar.gz`; const archivePath = join(releaseDir, archiveName); const markerPath = join(releaseDir, "installer-called.txt"); const payloadRoot = join(payloadStage, archiveRoot); @@ -241,6 +241,15 @@ function runInstaller(fixture: ReturnType, args: st } describe("one-command release installer", () => { + it("downloads future releases with Grimoire archive filenames", () => { + const fixture = createReleaseFixture({ version: "1.3.1" }); + const result = runInstaller(fixture, ["--upgrade"]); + expect(result.status).toBe(0); + expect(fixture.archiveName).toMatch(/^grimoire-1\.3\.1-/); + expect(result.stdout).toContain(`Checksum verified: ${fixture.archiveName}`); + expect(readFileSync(fixture.markerPath, "utf8").trim()).toBe("--upgrade"); + }); + it("downloads the platform archive, verifies its checksum, and runs the native installer", () => { const fixture = createReleaseFixture(); diff --git a/scripts/installed-app-smoke.test.ts b/scripts/installed-app-smoke.test.ts index 45c73c89..e4617358 100644 --- a/scripts/installed-app-smoke.test.ts +++ b/scripts/installed-app-smoke.test.ts @@ -51,6 +51,8 @@ describe("installed-app smoke suite", () => { expect(() => detectReleasePlatform("win32")).toThrow("Unsupported installed-app smoke platform"); expect(releaseArchiveName("0.1.0-beta", "linux")).toBe("little-imp-0.1.0-beta-linux.tar.gz"); expect(releaseArchiveName("0.1.0-beta", "macos")).toBe("little-imp-0.1.0-beta-macos.tar.gz"); + expect(releaseArchiveName("1.3.0", "macos")).toBe("little-imp-1.3.0-macos.tar.gz"); + expect(releaseArchiveName("1.3.1", "macos")).toBe("grimoire-1.3.1-macos.tar.gz"); expect(defaultPublishedReleaseBaseUrl("0.1.0-beta")).toBe( "https://github.com/goniszewski/grimoire/releases/download/v0.1.0-beta" ); @@ -60,7 +62,7 @@ describe("installed-app smoke suite", () => { }); it("downloads and verifies published release artifacts before running the smoke", async () => { - const version = "1.2.3-beta"; + const version = "1.3.1"; const platform = "linux"; const archiveName = releaseArchiveName(version, platform); const releaseDir = mkdtempSync(join(tmpdir(), "little-imp-published-release-")); @@ -80,7 +82,7 @@ describe("installed-app smoke suite", () => { const result = await downloadPublishedReleaseArtifact({ version, platform, - releaseBaseUrl: "https://downloads.example.test/releases/v1.2.3-beta", + releaseBaseUrl: "https://downloads.example.test/releases/v1.3.1", downloadDir, fetchImpl: fetchFromReleaseDir(releaseDir), signatureRunner, diff --git a/scripts/installed-app-smoke.ts b/scripts/installed-app-smoke.ts index 7ddf7333..fe9a874b 100644 --- a/scripts/installed-app-smoke.ts +++ b/scripts/installed-app-smoke.ts @@ -20,6 +20,7 @@ import { basename, isAbsolute, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { spawn, spawnSync, type ChildProcess } from "node:child_process"; import { packageRelease } from "./release-packager"; +import { releaseArchiveFileName } from "../daemon/src/update/release-names"; export type ReleasePlatform = "macos" | "linux"; type SmokeArtifactSource = "local" | "published"; @@ -113,7 +114,7 @@ export function detectReleasePlatform(nodePlatform = process.platform): ReleaseP export function releaseArchiveName(version: string, platform: ReleasePlatform): string { assertSafeReleaseVersion(version); - return `little-imp-${version}-${platform}.tar.gz`; + return releaseArchiveFileName(version, platform); } export function defaultPublishedReleaseBaseUrl(version: string): string { @@ -212,7 +213,7 @@ function usage(): string { "Options:", " --source local|published", " Artifact source (default: local)", - " --archive FILE Release archive to validate (default: release/little-imp--.tar.gz)", + " --archive FILE Release archive to validate (default: release/--.tar.gz)", " --release-base-url URL", " Published source base URL (default: GitHub release URL for --version)", " --version VERSION", diff --git a/scripts/release-final-check.ts b/scripts/release-final-check.ts index e183b67a..b879bb5b 100644 --- a/scripts/release-final-check.ts +++ b/scripts/release-final-check.ts @@ -3,6 +3,7 @@ import { join } from "node:path"; import { spawnSync } from "node:child_process"; import { validateReleaseArtifacts } from "./release-artifacts-validator"; import type { ReleaseManifest } from "./release-packager"; +import { releaseArchiveFileName } from "../daemon/src/update/release-names"; function command(name: string, args: string[]): string { const result = spawnSync(name, args, { encoding: "utf8" }); @@ -30,8 +31,8 @@ export function checkFinalRelease(root: string): void { } const result = validateReleaseArtifacts({ releaseDir, requireSignatures: true }); if (!result.ok) throw new Error(result.errors.join("\n")); - for (const platform of ["macos", "linux"]) { - const archive = `little-imp-${version}-${platform}.tar.gz`; + for (const platform of ["macos", "linux"] as const) { + const archive = releaseArchiveFileName(version, platform); if (!result.checkedArtifacts.includes(archive)) throw new Error(`Missing ${platform} release archive`); command("gpg", ["--verify", join(releaseDir, `${archive}.asc`), join(releaseDir, archive)]); } diff --git a/scripts/release-metadata.test.ts b/scripts/release-metadata.test.ts index 003f9f8e..b9fa6391 100644 --- a/scripts/release-metadata.test.ts +++ b/scripts/release-metadata.test.ts @@ -51,4 +51,22 @@ describe("release metadata", () => { expect(() => prepareHomebrewFormula(formula, { ...manifest, artifacts: manifest.artifacts.slice(0, 1) })) .toThrow("Expected one linux release artifact"); }); + + it("prepares both formula pins for future Grimoire-named archives", () => { + const formula = readFileSync(join(projectRoot, "Formula/grimoire.rb"), "utf8"); + const manifest = { + version: "1.3.1", + artifacts: [ + { platform: "macos" as const, archive: "grimoire-1.3.1-macos.tar.gz", sha256: "a".repeat(64) }, + { platform: "linux" as const, archive: "grimoire-1.3.1-linux.tar.gz", sha256: "b".repeat(64) }, + ], + }; + const prepared = prepareHomebrewFormula(formula, manifest); + expect(prepared).toContain("v1.3.1/grimoire-1.3.1-macos.tar.gz"); + expect(prepared).toContain("v1.3.1/grimoire-1.3.1-linux.tar.gz"); + expect(() => prepareHomebrewFormula(formula, { + ...manifest, + artifacts: [{ ...manifest.artifacts[0], archive: "little-imp-1.3.1-macos.tar.gz" }, manifest.artifacts[1]], + })).toThrow("Wrong macos archive name"); + }); }); diff --git a/scripts/release-metadata.ts b/scripts/release-metadata.ts index 6724be78..3938f40c 100644 --- a/scripts/release-metadata.ts +++ b/scripts/release-metadata.ts @@ -1,6 +1,7 @@ import { readFileSync, writeFileSync } from "node:fs"; import { join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; +import { releaseArchiveFileName } from "../daemon/src/update/release-names"; type Platform = "macos" | "linux"; const platforms: Platform[] = ["macos", "linux"]; @@ -36,7 +37,7 @@ function checkedArtifacts(manifest: Manifest): Artifact[] { const entries = manifest.artifacts.filter((artifact) => artifact.platform === platform); if (entries.length !== 1) throw new Error(`Expected one ${platform} release artifact`); const artifact = entries[0]; - if (artifact.archive !== `little-imp-${manifest.version}-${platform}.tar.gz`) { + if (artifact.archive !== releaseArchiveFileName(manifest.version, platform)) { throw new Error(`Wrong ${platform} archive name`); } if (!/^[a-f0-9]{64}$/.test(artifact.sha256)) throw new Error(`Invalid ${platform} SHA-256`); diff --git a/scripts/release-packager.test.ts b/scripts/release-packager.test.ts index 855068ba..52ad8317 100644 --- a/scripts/release-packager.test.ts +++ b/scripts/release-packager.test.ts @@ -6,6 +6,7 @@ import { buildPayloadChecksums, createReleaseManifest, packageRelease, + releaseArchiveName, stageReleasePayload, } from "./release-packager"; @@ -15,10 +16,10 @@ function writeFixtureFile(root: string, path: string, contents: string): void { writeFileSync(fullPath, contents); } -function createProjectFixture(): string { +function createProjectFixture(version = "1.2.3-beta"): string { const root = mkdtempSync(join(tmpdir(), "little-imp-release-fixture-")); - writeFixtureFile(root, "package.json", JSON.stringify({ name: "little-imp", version: "1.2.3-beta" })); + writeFixtureFile(root, "package.json", JSON.stringify({ name: "little-imp", version })); writeFixtureFile(root, "LICENSE", "license\n"); writeFixtureFile(root, "README.md", "# Little Imp\n"); writeFixtureFile(root, "dist/index.html", "
\n"); @@ -40,6 +41,22 @@ function createProjectFixture(): string { } describe("release packager", () => { + it("renames future archive files while keeping published names and payload roots", () => { + expect(releaseArchiveName("1.3.0", "linux")).toBe("little-imp-1.3.0-linux.tar.gz"); + expect(releaseArchiveName("1.3.1", "linux")).toBe("grimoire-1.3.1-linux.tar.gz"); + expect(releaseArchiveName("1.4.0-beta.1", "macos")).toBe("grimoire-1.4.0-beta.1-macos.tar.gz"); + + const projectRoot = createProjectFixture("1.3.1"); + const outputDir = mkdtempSync(join(tmpdir(), "grimoire-release-output-")); + const result = packageRelease({ + projectRoot, outputDir, version: "1.3.1", platforms: ["linux"], skipBuild: true, + logger: { log: () => undefined }, + }); + expect(result.manifest.artifacts[0].archive).toBe("grimoire-1.3.1-linux.tar.gz"); + expect(existsSync(join(outputDir, "grimoire-1.3.1-linux.tar.gz"))).toBe(true); + expect(existsSync(join(outputDir, "grimoire-1.3.1-linux.tar.gz.sha256"))).toBe(true); + }); + it("stages the installable payload with daemon runtime files, frontend bundle, CLI, and metadata", () => { const projectRoot = createProjectFixture(); const stageRoot = join(mkdtempSync(join(tmpdir(), "little-imp-release-stage-")), "payload"); diff --git a/scripts/release-packager.ts b/scripts/release-packager.ts index b8072ef5..0e0df2a3 100644 --- a/scripts/release-packager.ts +++ b/scripts/release-packager.ts @@ -12,6 +12,7 @@ import { import { createHash } from "node:crypto"; import { dirname, join, relative, resolve, sep } from "node:path"; import { spawnSync } from "node:child_process"; +import { releaseArchiveFileName } from "../daemon/src/update/release-names"; export type ReleasePlatform = "macos" | "linux"; @@ -99,7 +100,8 @@ export function releaseRootDirectoryName(version: string, platform: ReleasePlatf } export function releaseArchiveName(version: string, platform: ReleasePlatform): string { - return `${releaseRootDirectoryName(version, platform)}.tar.gz`; + assertSafeReleaseVersion(version); + return releaseArchiveFileName(version, platform); } export function readPackageVersion(projectRoot: string): string { diff --git a/scripts/sign-release-artifacts.sh b/scripts/sign-release-artifacts.sh index 29b975fe..031d66bd 100755 --- a/scripts/sign-release-artifacts.sh +++ b/scripts/sign-release-artifacts.sh @@ -2,8 +2,9 @@ # # sign-release-artifacts.sh — sign Grimoire release archives, verify, validate. # -# Signs every release/*.tar.gz with a detached gpg signature, verifies the -# signatures, runs the strict release validator (--require-signatures), and +# Signs the archives listed in release/release-manifest.json with detached +# GPG signatures, verifies them, runs the strict release validator +# (--require-signatures), and # exports the public key + fingerprint for the release notes. # # Usage: @@ -55,14 +56,33 @@ if [[ -z "$KEY_ID" ]]; then fi echo "Signing key: $KEY_ID ($(gpg --list-keys --with-colons "$KEY_ID" 2>/dev/null | awk -F: '$1=="uid"{print $10; exit}'))" -# ─── Sign every release archive ───────────────────────────────────────────── -shopt -s nullglob -ARCHIVES=("$RELEASE_DIR"/*.tar.gz) -shopt -u nullglob -if [[ ${#ARCHIVES[@]} -eq 0 ]]; then - echo "error: no release archives found in $RELEASE_DIR" >&2 - exit 1 -fi +# ─── Sign only the current manifest's release archives ───────────────────── +artifact_names="$(node -e ' + const fs = require("fs"); + const manifest = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); + const pkg = JSON.parse(fs.readFileSync(process.argv[2], "utf8")); + if (manifest.version !== pkg.version) throw new Error("Release manifest version differs from package.json"); + for (const platform of ["macos", "linux"]) { + const artifacts = manifest.artifacts.filter((entry) => entry.platform === platform); + if (artifacts.length !== 1) throw new Error(`Expected one ${platform} archive`); + const archive = artifacts[0].archive; + if (!/^(?:little-imp|grimoire)-[0-9A-Za-z][0-9A-Za-z._+-]*-(?:macos|linux)\.tar\.gz$/.test(archive) || + !archive.endsWith(`-${platform}.tar.gz`)) { + throw new Error(`Invalid release archive name: ${archive}`); + } + console.log(archive); + } +' "$RELEASE_DIR/release-manifest.json" "$REPO_ROOT/package.json")" +ARCHIVES=() +while IFS= read -r archive_name; do + ARCHIVES+=("$RELEASE_DIR/$archive_name") +done <<< "$artifact_names" +for archive in "${ARCHIVES[@]}"; do + if [[ ! -f "$archive" ]]; then + echo "error: release archive is missing: $archive" >&2 + exit 1 + fi +done for archive in "${ARCHIVES[@]}"; do asc="$archive.asc" diff --git a/scripts/sign-release-artifacts.test.ts b/scripts/sign-release-artifacts.test.ts new file mode 100644 index 00000000..7e275fd8 --- /dev/null +++ b/scripts/sign-release-artifacts.test.ts @@ -0,0 +1,54 @@ +import { spawnSync } from "node:child_process"; +import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { describe, expect, it } from "vitest"; + +describe("release signing", () => { + it("signs only archives listed in the current manifest", () => { + const root = mkdtempSync(join(tmpdir(), "grimoire-signing-")); + const releaseDir = join(root, "release"); + const scriptsDir = join(root, "scripts"); + const binDir = join(root, "bin"); + mkdirSync(releaseDir); + mkdirSync(scriptsDir); + mkdirSync(binDir); + copyFileSync(join(process.cwd(), "scripts/sign-release-artifacts.sh"), join(scriptsDir, "sign-release-artifacts.sh")); + writeFileSync(join(root, "package.json"), JSON.stringify({ version: "1.3.1" })); + const archives = ["grimoire-1.3.1-macos.tar.gz", "grimoire-1.3.1-linux.tar.gz"]; + writeFileSync(join(releaseDir, "release-manifest.json"), JSON.stringify({ + version: "1.3.1", + artifacts: archives.map((archive, index) => ({ platform: index === 0 ? "macos" : "linux", archive })), + })); + for (const archive of archives) writeFileSync(join(releaseDir, archive), "current archive\n"); + const staleArchive = "little-imp-1.3.0-linux.tar.gz"; + writeFileSync(join(releaseDir, staleArchive), "old archive\n"); + const marker = join(root, "signed.txt"); + writeFileSync(join(binDir, "gpg"), `#!/usr/bin/env bash +set -euo pipefail +case "$1" in + --list-keys) exit 0 ;; + --batch) + for ((i=1; i<=$#; i++)); do + if [[ "\${!i}" == "--output" ]]; then + next=$((i+1)); touch "\${!next}" + fi + done + printf '%s\\n' "\${!#}" >> "$SIGN_MARKER" + ;; + --verify) exit 0 ;; + --armor) printf 'test key\\n' ;; + --fingerprint) printf 'pub test\\n ABCD\\n' ;; +esac +`, { mode: 0o755 }); + writeFileSync(join(binDir, "npm"), "#!/usr/bin/env bash\nexit 0\n", { mode: 0o755 }); + const result = spawnSync("bash", [join(scriptsDir, "sign-release-artifacts.sh"), "TESTKEY"], { + encoding: "utf8", + env: { ...process.env, PATH: `${binDir}:${process.env.PATH ?? ""}`, SIGN_MARKER: marker }, + }); + expect(result.status, result.stderr).toBe(0); + expect(readFileSync(marker, "utf8").trim().split("\n").map((path) => path.split("/").pop())) + .toEqual(archives); + expect(existsSync(join(releaseDir, `${staleArchive}.asc`))).toBe(false); + }); +}); diff --git a/scripts/validate-linux-installer-matrix.sh b/scripts/validate-linux-installer-matrix.sh index c4df2379..16bdf78b 100755 --- a/scripts/validate-linux-installer-matrix.sh +++ b/scripts/validate-linux-installer-matrix.sh @@ -4,7 +4,17 @@ set -euo pipefail PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" RELEASE_DIR="${PROJECT_ROOT}/release" PACKAGE_VERSION="$(node -e "console.log(JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8')).version)" "${PROJECT_ROOT}/package.json")" -RELEASE_ARCHIVE_NAME="${LITTLEIMP_RELEASE_ARCHIVE_NAME:-little-imp-${PACKAGE_VERSION}-linux.tar.gz}" +if [[ -n "${LITTLEIMP_RELEASE_ARCHIVE_NAME:-}" ]]; then + RELEASE_ARCHIVE_NAME="${LITTLEIMP_RELEASE_ARCHIVE_NAME}" +else + RELEASE_ARCHIVE_NAME="$(node -e ' + const fs = require("fs"); + const manifest = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); + const artifact = manifest.artifacts.find((entry) => entry.platform === "linux"); + if (manifest.version !== process.argv[2] || !artifact) process.exit(1); + console.log(artifact.archive); + ' "${RELEASE_DIR}/release-manifest.json" "${PACKAGE_VERSION}")" +fi RELEASE_ARCHIVE_PATH="${RELEASE_DIR}/${RELEASE_ARCHIVE_NAME}" DEFAULT_TARGETS=("ubuntu:24.04" "debian:12") TARGETS=("$@") From 99de762a066a36b2870890579b427c3fb0328d21 Mon Sep 17 00:00:00 2001 From: Robert Goniszewski <43510122+goniszewski@users.noreply.github.com> Date: Mon, 2 Nov 2026 14:47:50 +0100 Subject: [PATCH 07/14] fix(security): resolve DNS and block reserved ranges in outbound fetches (#238) * fix(security): resolve DNS and block reserved ranges in outbound fetches isPrivateHost now classifies addresses numerically and blocks the remaining reserved IPv4 ranges, NAT64/6to4/Teredo-embedded IPv6, and internal-only hostnames. safe-fetch and media fetching resolve each hop's hostname and reject any private result before connecting. * fix(security): make DNS validation respect the abort signal Race the pre-fetch lookup against the caller's AbortSignal so request timeouts still bound safe-fetch and media fetching when DNS stalls. * fix(security): avoid backtracking regex when normalising hostnames --- daemon/src/lib/network.ts | 187 +++++++++++++----- daemon/src/lib/safe-fetch.ts | 9 +- daemon/src/media/bookmark-media.ts | 6 +- .../src/test/lib/network-private-host.test.ts | 113 ++++++++++- daemon/src/test/lib/safe-fetch.test.ts | 49 ++++- 5 files changed, 307 insertions(+), 57 deletions(-) diff --git a/daemon/src/lib/network.ts b/daemon/src/lib/network.ts index 94e35ca3..f88592ab 100644 --- a/daemon/src/lib/network.ts +++ b/daemon/src/lib/network.ts @@ -2,79 +2,164 @@ * Shared network utilities. */ +import { lookup } from "node:dns/promises"; + /** - * Returns true if the hostname resolves to a private, loopback, link-local, - * or otherwise non-routable address. + * Returns true if the hostname is, or syntactically names, a private, + * loopback, link-local, or otherwise non-routable destination. * - * Used in SSRF mitigations across the codebase. - * NOTE: This is a best-effort syntactic check. DNS rebinding (a public hostname - * that resolves to a private IP at fetch time) is not mitigated here and is - * considered an accepted risk for a local-only daemon. + * Used in SSRF mitigations across the codebase. This check is purely + * syntactic and never touches DNS; callers that fetch over the network should + * also run {@link resolvesToPrivateAddress} so a public name that points at a + * private address is rejected. */ export function isPrivateHost(hostname: string): boolean { - // Strip brackets, trailing FQDN dots (localhost. / localhost..), and case-fold. - const host = hostname - .replace(/^\[|\]$/g, "") - .replace(/\.+$/g, "") - .toLowerCase(); + // Strip brackets, zone ids, trailing FQDN dots (localhost. / localhost..), + // and case-fold. + const host = stripTrailingDots(hostname.replace(/^\[|\]$/g, "").split("%")[0]).toLowerCase(); - if (isPrivateIpv4(host)) return true; + if (!host) return true; - // IPv4-mapped and IPv4-compatible IPv6 literals can address the same - // private services as their dotted-quad forms. Classify the embedded address - // before applying the IPv6-only checks below. - const embeddedIpv4 = embeddedIpv4Address(host); - if (embeddedIpv4 && isPrivateIpv4(embeddedIpv4)) return true; + if (host.includes(":")) return isPrivateIpv6(host); - // Loopback - if (host === "localhost" || host === "::1") return true; + const ipv4 = parseIpv4(host); + if (ipv4) return isPrivateIpv4Octets(ipv4); - // Link-local IPv6 - if (/^fe80:/i.test(host)) return true; + return isInternalHostname(host); +} - // IPv6 ULA (Unique Local Address, RFC 4193) — fc00::/7 covers fc** and fd** - if (/^f[cd][0-9a-f]{2}:/i.test(host)) return true; +/** + * Resolves `hostname` and returns true if ANY returned address is private. + * IP literals are classified without a lookup. Lookup failures return false: + * the subsequent fetch fails on the same name, so there is nothing to protect. + * + * Note: the later `fetch` resolves the name again, so a DNS server that + * answers differently between the two lookups can still win the race. This + * check defeats static public-name-to-private-IP records, not that race. + * + * When `signal` aborts, the pending lookup is abandoned and the abort reason + * is thrown so callers' timeouts still bound the whole operation. + */ +export async function resolvesToPrivateAddress( + hostname: string, + resolver: HostResolver = defaultResolver, + signal?: AbortSignal +): Promise { + if (isPrivateHost(hostname)) return true; + + const host = stripTrailingDots(hostname.replace(/^\[|\]$/g, "")); + if (host.includes(":") || parseIpv4(host)) return false; + + signal?.throwIfAborted(); + + let addresses: string[]; + try { + addresses = await raceAbort(resolver(host), signal); + } catch (error) { + // Cancellation must propagate; only genuine lookup failures are ignored. + if (signal?.aborted) throw error; + return false; + } + return addresses.some((address) => isPrivateHost(address)); +} - // IPv6 site-local (deprecated but still routable internally) - if (/^fec[0-9a-f]:/i.test(host)) return true; +function stripTrailingDots(value: string): string { + let end = value.length; + while (end > 0 && value.charCodeAt(end - 1) === 46) end -= 1; + return value.slice(0, end); +} - // Unspecified IPv6 - if (host === "::") return true; +function raceAbort(promise: Promise, signal?: AbortSignal): Promise { + if (!signal) return promise; + return new Promise((resolve, reject) => { + const onAbort = () => reject(signal.reason); + signal.addEventListener("abort", onAbort, { once: true }); + promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort)); + }); +} - return false; +export type HostResolver = (hostname: string) => Promise; + +const defaultResolver: HostResolver = async (hostname) => { + const results = await lookup(hostname, { all: true }); + return results.map((result) => result.address); +}; + +const INTERNAL_SUFFIXES = [ + ".localhost", + ".local", + ".localdomain", + ".internal", + ".home.arpa", +]; + +function isInternalHostname(host: string): boolean { + if (host === "localhost") return true; + // Public hosts always have at least two labels; bare names resolve through + // the local search domain or hosts file (e.g. `instance-data`, `router`). + if (!host.includes(".")) return true; + return INTERNAL_SUFFIXES.some((suffix) => host.endsWith(suffix)); } -function isPrivateIpv4(host: string): boolean { - // Loopback - if (/^127\./.test(host)) return true; +function parseIpv4(host: string): [number, number, number, number] | null { + const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host); + if (!match) return null; + const octets = match.slice(1).map(Number); + if (octets.some((octet) => octet > 255)) return null; + return octets as [number, number, number, number]; +} - // Link-local (AWS IMDS, etc.) - if (/^169\.254\./.test(host)) return true; +function isPrivateIpv4Octets([a, b, c]: [number, number, number, number]): boolean { + if (a === 0) return true; // 0.0.0.0/8 "this network" + if (a === 10) return true; // RFC 1918 + if (a === 100 && b >= 64 && b <= 127) return true; // CGNAT, RFC 6598 + if (a === 127) return true; // loopback + if (a === 169 && b === 254) return true; // link-local (AWS IMDS, etc.) + if (a === 172 && b >= 16 && b <= 31) return true; // RFC 1918 + if (a === 192 && b === 0 && c === 0) return true; // IETF protocol assignments + if (a === 192 && b === 0 && c === 2) return true; // TEST-NET-1 + if (a === 192 && b === 168) return true; // RFC 1918 + if (a === 198 && (b === 18 || b === 19)) return true; // benchmarking + if (a === 198 && b === 51 && c === 100) return true; // TEST-NET-2 + if (a === 203 && b === 0 && c === 113) return true; // TEST-NET-3 + return a >= 224; // multicast, reserved, broadcast +} - // Private ranges - if (/^10\./.test(host)) return true; - if (/^172\.(1[6-9]|2\d|3[01])\./.test(host)) return true; - if (/^192\.168\./.test(host)) return true; +function isPrivateIpv6(host: string): boolean { + const words = parseIpv6Words(host); + // Unparseable IPv6 never reaches a legitimate public server. + if (!words) return true; - // CGNAT / shared address space (RFC 6598) - if (/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./.test(host)) return true; + const [w0, w1, w2, w3, w4, w5, w6, w7] = words; + const embedded = (hi: number, lo: number) => + isPrivateIpv4Octets([hi >> 8, hi & 0xff, lo >> 8, lo & 0xff]); - // Unspecified / broadcast - return host === "0.0.0.0"; -} + // ::, ::1 + if (words.slice(0, 7).every((word) => word === 0) && w7 <= 1) return true; -function embeddedIpv4Address(host: string): string | null { - if (!host.includes(":")) return null; - const words = parseIpv6Words(host); - if (!words || words.length !== 8) return null; + // IPv4-compatible (::/96) and IPv4-mapped (::ffff:0:0/96). + if (words.slice(0, 5).every((word) => word === 0) && (w5 === 0 || w5 === 0xffff)) { + return embedded(w6, w7); + } - // The first 80 bits are zero for IPv4-compatible and IPv4-mapped - // addresses. The sixth word is 0 for compatible or ffff for mapped. - if (!words.slice(0, 5).every((word) => word === 0) || (words[5] !== 0 && words[5] !== 0xffff)) { - return null; + if ((w0 & 0xffc0) === 0xfe80) return true; // fe80::/10 link-local + if ((w0 & 0xffc0) === 0xfec0) return true; // fec0::/10 site-local (deprecated) + if ((w0 & 0xfe00) === 0xfc00) return true; // fc00::/7 ULA + if ((w0 & 0xff00) === 0xff00) return true; // ff00::/8 multicast + if (w0 === 0x2001 && w1 === 0x0db8) return true; // 2001:db8::/32 documentation + if (w0 === 0x2001 && w1 === 0) return true; // 2001::/32 Teredo (client IP is obfuscated) + if (w0 === 0x0100 && w1 === 0 && w2 === 0 && w3 === 0) return true; // 100::/64 discard + + // NAT64: 64:ff9b::/96 embeds an IPv4 address; 64:ff9b:1::/48 is local-use. + if (w0 === 0x0064 && w1 === 0xff9b) { + if (w2 === 1) return true; + if (w2 === 0 && w3 === 0 && w4 === 0 && w5 === 0) return embedded(w6, w7); } - return [words[6] >> 8, words[6] & 0xff, words[7] >> 8, words[7] & 0xff].join("."); + // 6to4: 2002:AABB:CCDD::/48 embeds the IPv4 address in words 1-2. + if (w0 === 0x2002) return embedded(w1, w2); + + return false; } function parseIpv6Words(host: string): number[] | null { diff --git a/daemon/src/lib/safe-fetch.ts b/daemon/src/lib/safe-fetch.ts index 110caf5c..333a139c 100644 --- a/daemon/src/lib/safe-fetch.ts +++ b/daemon/src/lib/safe-fetch.ts @@ -2,7 +2,7 @@ * Outbound fetch helpers with manual redirect validation (SSRF defense). */ -import { isPrivateHost } from "./network.js"; +import { isPrivateHost, resolvesToPrivateAddress, type HostResolver } from "./network.js"; import { parsePublicHttpUrl } from "./public-url.js"; const DEFAULT_MAX_REDIRECTS = 10; @@ -36,11 +36,15 @@ export interface SafeFetchOptions { maxRedirects?: number; /** When true, skip the initial private-host check (caller already validated). */ skipInitialHostCheck?: boolean; + /** Overrides DNS resolution (tests). Defaults to the system resolver. */ + resolveHost?: HostResolver; } /** * Fetch a URL while validating every redirect target before following it. * Never uses automatic redirect following, so private intermediates are never contacted. + * Each hop's hostname is also resolved and rejected if any address is private, so a + * public name pointing at an internal address is blocked before it is contacted. */ export async function fetchFollowingSafeRedirects( inputUrl: string, @@ -61,6 +65,9 @@ export async function fetchFollowingSafeRedirects( let response: Response | null = null; for (let redirectCount = 0; redirectCount <= maxRedirects; redirectCount += 1) { + if (await resolvesToPrivateAddress(current.hostname, options.resolveHost, options.signal)) { + throw new Error(`Fetch to private host blocked: ${current.toString()}`); + } response = await fetch(current.toString(), { headers: options.headers, redirect: "manual", diff --git a/daemon/src/media/bookmark-media.ts b/daemon/src/media/bookmark-media.ts index 1403abd8..451b2d91 100644 --- a/daemon/src/media/bookmark-media.ts +++ b/daemon/src/media/bookmark-media.ts @@ -3,7 +3,8 @@ import { createHash, randomUUID } from "node:crypto"; import { existsSync, rmSync } from "node:fs"; import { mkdir } from "node:fs/promises"; import { join, resolve, sep } from "node:path"; -import { isPrivateHost } from "../lib/network.js"; +import { isPrivateHost, resolvesToPrivateAddress } from "../lib/network.js"; +import { isRedirectStatus as isFetchRedirectStatus } from "../lib/safe-fetch.js"; import { version as APP_VERSION } from "../../package.json"; import type { BookmarkMediaKind, BookmarkMediaRow } from "../db/types.js"; @@ -211,7 +212,7 @@ function safeHttpMediaUrl(value: string, base?: URL): URL | null { } function isRedirectStatus(status: number): boolean { - return status >= 300 && status < 400; + return isFetchRedirectStatus(status); } function isAllowedCachedImageType(mediaType: string): boolean { @@ -279,6 +280,7 @@ async function fetchMedia(candidate: BookmarkMediaCandidate): Promise<{ let response: Response | null = null; try { for (let redirectCount = 0; redirectCount <= MEDIA_FETCH_MAX_REDIRECTS; redirectCount += 1) { + if (await resolvesToPrivateAddress(source.hostname, undefined, controller.signal)) return null; response = await fetch(source.toString(), { headers: { Accept: "image/avif,image/webp,image/png,image/jpeg,image/gif,image/x-icon,*/*;q=0.2", diff --git a/daemon/src/test/lib/network-private-host.test.ts b/daemon/src/test/lib/network-private-host.test.ts index 13bdfce5..f14b2199 100644 --- a/daemon/src/test/lib/network-private-host.test.ts +++ b/daemon/src/test/lib/network-private-host.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "bun:test"; -import { isPrivateHost } from "../../lib/network.js"; +import { isPrivateHost, resolvesToPrivateAddress } from "../../lib/network.js"; import { parsePublicHttpUrl } from "../../lib/public-url.js"; describe("isPrivateHost", () => { @@ -58,3 +58,114 @@ describe("parsePublicHttpUrl IPv4-mapped", () => { if (!parsed.ok) expect(parsed.reason).toBe("private"); }); }); + +describe("isPrivateHost reserved ranges", () => { + it("blocks non-routable IPv4 ranges beyond RFC 1918", () => { + for (const host of [ + "0.0.0.0", + "0.1.2.3", + "100.64.0.1", + "100.127.255.255", + "192.0.0.1", + "192.0.2.1", + "198.18.0.1", + "198.19.255.255", + "198.51.100.7", + "203.0.113.9", + "224.0.0.1", + "240.0.0.1", + "255.255.255.255", + ]) { + expect(isPrivateHost(host)).toBe(true); + } + }); + + it("keeps neighbouring public IPv4 addresses reachable", () => { + for (const host of ["100.63.255.255", "100.128.0.1", "172.15.0.1", "172.32.0.1", "198.17.0.1", "198.20.0.1", "1.1.1.1"]) { + expect(isPrivateHost(host)).toBe(false); + } + }); + + it("blocks IPv6 forms that embed private IPv4 addresses", () => { + expect(isPrivateHost("64:ff9b::7f00:1")).toBe(true); // NAT64 -> 127.0.0.1 + expect(isPrivateHost("64:ff9b::a9fe:a9fe")).toBe(true); // NAT64 -> 169.254.169.254 + expect(isPrivateHost("2002:7f00:1::")).toBe(true); // 6to4 -> 127.0.0.1 + expect(isPrivateHost("2002:a9fe:a9fe::")).toBe(true); // 6to4 -> 169.254.169.254 + expect(isPrivateHost("64:ff9b::808:808")).toBe(false); // NAT64 -> 8.8.8.8 + expect(isPrivateHost("2002:808:808::")).toBe(false); // 6to4 -> 8.8.8.8 + }); + + it("blocks other reserved IPv6 ranges", () => { + for (const host of ["::", "::1", "fe80::1", "fec0::1", "fd00::1", "fc00::1", "ff02::1", "2001:db8::1", "2001:0:4136:e378:8000:63bf:3fff:fdd2", "64:ff9b:1::1"]) { + expect(isPrivateHost(host)).toBe(true); + } + expect(isPrivateHost("2606:4700:4700::1111")).toBe(false); + }); + + it("blocks internal-only hostnames", () => { + for (const host of [ + "foo.localhost", + "printer.local", + "metadata.google.internal", + "router.home.arpa", + "instance-data", + "myhost", + ]) { + expect(isPrivateHost(host)).toBe(true); + } + }); + + it("does not treat public names that look like IP prefixes as private", () => { + expect(isPrivateHost("10.example.com")).toBe(false); + expect(isPrivateHost("192.168.example.com")).toBe(false); + expect(isPrivateHost("example.co.uk")).toBe(false); + }); +}); + +describe("resolvesToPrivateAddress", () => { + const resolver = (map: Record) => async (host: string) => { + if (!(host in map)) throw new Error("ENOTFOUND"); + return map[host]; + }; + + it("rejects public names that resolve to private addresses", async () => { + const r = resolver({ "rebind.example.com": ["93.184.216.34", "127.0.0.1"], "meta.example.com": ["::ffff:a9fe:a9fe"] }); + expect(await resolvesToPrivateAddress("rebind.example.com", r)).toBe(true); + expect(await resolvesToPrivateAddress("meta.example.com", r)).toBe(true); + }); + + it("allows names that resolve only to public addresses", async () => { + const r = resolver({ "example.com": ["93.184.216.34", "2606:2800:220:1:248:1893:25c8:1946"] }); + expect(await resolvesToPrivateAddress("example.com", r)).toBe(false); + }); + + it("classifies IP literals and internal names without a lookup", async () => { + const r = async () => { + throw new Error("resolver must not be called"); + }; + expect(await resolvesToPrivateAddress("127.0.0.1", r)).toBe(true); + expect(await resolvesToPrivateAddress("[::1]", r)).toBe(true); + expect(await resolvesToPrivateAddress("8.8.8.8", r)).toBe(false); + expect(await resolvesToPrivateAddress("foo.localhost", r)).toBe(true); + }); + + it("does not block on lookup failure", async () => { + expect(await resolvesToPrivateAddress("nxdomain.example.com", resolver({}))).toBe(false); + }); + + it("abandons a stalled lookup when the signal aborts", async () => { + const controller = new AbortController(); + const stalled = () => new Promise(() => {}); + const pending = resolvesToPrivateAddress("slow.example.com", stalled, controller.signal); + controller.abort(new Error("timed out")); + await expect(pending).rejects.toThrow("timed out"); + }); + + it("rejects immediately when the signal is already aborted", async () => { + const controller = new AbortController(); + controller.abort(new Error("already aborted")); + await expect( + resolvesToPrivateAddress("slow.example.com", async () => ["93.184.216.34"], controller.signal) + ).rejects.toThrow("already aborted"); + }); +}); diff --git a/daemon/src/test/lib/safe-fetch.test.ts b/daemon/src/test/lib/safe-fetch.test.ts index 47e5ba37..2094df38 100644 --- a/daemon/src/test/lib/safe-fetch.test.ts +++ b/daemon/src/test/lib/safe-fetch.test.ts @@ -1,6 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test"; import { fetchFollowingSafeRedirects, isRedirectStatus } from "../../lib/safe-fetch.js"; +const publicResolver = async () => ["93.184.216.34"]; let fetchBeforeTest: typeof fetch; beforeEach(() => { @@ -30,7 +31,7 @@ describe("safe fetch", () => { return new Response(JSON.stringify({ data: [] }), { status: 200 }); }) as typeof fetch; - const response = await fetchFollowingSafeRedirects("https://catalog.example.test/start"); + const response = await fetchFollowingSafeRedirects("https://catalog.example.test/start", { resolveHost: publicResolver }); expect(response.status).toBe(200); expect(calls).toEqual([ @@ -46,9 +47,53 @@ describe("safe fetch", () => { return new Response(null, { status: 304 }); }) as typeof fetch; - const response = await fetchFollowingSafeRedirects("https://catalog.example.test/models"); + const response = await fetchFollowingSafeRedirects("https://catalog.example.test/models", { resolveHost: publicResolver }); expect(response.status).toBe(304); expect(calls).toEqual(["https://catalog.example.test/models"]); }); + + it("blocks a public name that resolves to a private address before any request", async () => { + let called = false; + globalThis.fetch = (async () => { + called = true; + return new Response("secret"); + }) as unknown as typeof fetch; + + await expect( + fetchFollowingSafeRedirects("https://rebind.example.com/", { + resolveHost: async () => ["169.254.169.254"], + }) + ).rejects.toThrow(/private host blocked/); + expect(called).toBe(false); + }); + + it("re-resolves every redirect hop and blocks a hop that resolves privately", async () => { + const requested: string[] = []; + globalThis.fetch = (async (input) => { + requested.push(String(input)); + return new Response(null, { + status: 302, + headers: { location: "https://internal.example.com/admin" }, + }); + }) as typeof fetch; + + const resolveHost = async (host: string) => + host === "internal.example.com" ? ["10.0.0.5"] : ["93.184.216.34"]; + + await expect( + fetchFollowingSafeRedirects("https://start.example.com/", { resolveHost }) + ).rejects.toThrow(/private host blocked/); + expect(requested).toEqual(["https://start.example.com/"]); + }); + + it("still resolves when the caller skips the initial syntactic check", async () => { + globalThis.fetch = (async () => new Response("ok")) as unknown as typeof fetch; + await expect( + fetchFollowingSafeRedirects("https://rebind.example.com/", { + skipInitialHostCheck: true, + resolveHost: async () => ["127.0.0.1"], + }) + ).rejects.toThrow(/private host blocked/); + }); }); From b32ed3d148df1dca80bedf8eec545b4bffab9202 Mon Sep 17 00:00:00 2001 From: hawaka-joe Date: Mon, 2 Nov 2026 22:38:35 +0800 Subject: [PATCH 08/14] fix: theme switch and persist theme selection (#236) * fix: theme switch and persist theme selection * feat(theme): follow system color scheme by default (#196) Default to the system theme via next-themes and add an e2e check that the theme tracks prefers-color-scheme until the user picks one explicitly. --------- Co-authored-by: Robert Goniszewski --- e2e/first-run.spec.ts | 32 +++++++++++++++++ src/App.tsx | 55 +++++++++++++++-------------- src/components/ThemeToggle.test.tsx | 38 ++++++++++++++++++++ src/components/ThemeToggle.tsx | 18 ++++++---- src/pages/Index.tsx | 7 ---- 5 files changed, 110 insertions(+), 40 deletions(-) create mode 100644 src/components/ThemeToggle.test.tsx diff --git a/e2e/first-run.spec.ts b/e2e/first-run.spec.ts index 56e4f57e..ebcbc103 100644 --- a/e2e/first-run.spec.ts +++ b/e2e/first-run.spec.ts @@ -68,6 +68,38 @@ test.describe("First-run experience", () => { await expect(page.getByRole("button", { name: /import from browser/i })).toBeVisible(); }); + test("theme follows the system setting by default", async ({ page }) => { + await setupBaseMocks(page, []); + await page.emulateMedia({ colorScheme: "light" }); + await page.goto("/"); + + await expect(page.getByText(/your library is empty/i)).toBeVisible({ timeout: 10_000 }); + await expect(page.locator("html")).toHaveClass(/light/); + + await page.emulateMedia({ colorScheme: "dark" }); + await expect(page.locator("html")).toHaveClass(/dark/); + }); + + test("theme changes with one click and persists after reload", async ({ page }) => { + await setupBaseMocks(page, []); + await page.emulateMedia({ colorScheme: "dark" }); + await page.goto("/"); + + await expect(page.getByText(/your library is empty/i)).toBeVisible({ timeout: 10_000 }); + await expect(page.locator("html")).toHaveClass(/dark/); + + await page.getByRole("button", { name: "Switch to light theme" }).click(); + + await expect(page.locator("html")).toHaveClass(/light/); + await expect(page.getByRole("button", { name: "Switch to dark theme" })).toBeVisible(); + await expect.poll(() => page.evaluate(() => localStorage.getItem("grimoire-theme"))).toBe("light"); + + await page.reload(); + + await expect(page.getByText(/your library is empty/i)).toBeVisible({ timeout: 10_000 }); + await expect(page.locator("html")).toHaveClass(/light/); + }); + test("adding a bookmark removes the empty-state", async ({ page }) => { const bookmarks: unknown[] = []; await setupBaseMocks(page, bookmarks); diff --git a/src/App.tsx b/src/App.tsx index 37bcfe94..bea41f3a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import { Toaster } from "@/components/ui/toaster"; import { Toaster as Sonner } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ThemeProvider } from "next-themes"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import { ErrorBoundary } from "./components/ErrorBoundary"; import Index from "./pages/Index"; @@ -22,32 +23,34 @@ import { DemoModeBanner } from "@/components/DemoModeBanner"; const queryClient = new QueryClient(); const App = () => ( - - - - - - {isDemoMode && } - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} - } /> - - - - - + + + + + + + {isDemoMode && } + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} + } /> + + + + + + ); export default App; diff --git a/src/components/ThemeToggle.test.tsx b/src/components/ThemeToggle.test.tsx new file mode 100644 index 00000000..ee6dc0dd --- /dev/null +++ b/src/components/ThemeToggle.test.tsx @@ -0,0 +1,38 @@ +import { fireEvent, render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { ThemeToggle } from "./ThemeToggle"; + +const themeMocks = vi.hoisted(() => ({ + resolvedTheme: "dark", + setTheme: vi.fn(), +})); + +vi.mock("next-themes", () => ({ + useTheme: () => themeMocks, +})); + +describe("ThemeToggle", () => { + beforeEach(() => { + themeMocks.resolvedTheme = "dark"; + themeMocks.setTheme.mockClear(); + }); + + it("switches from dark to light with one click", () => { + render(); + + fireEvent.click(screen.getByRole("button", { name: "Switch to light theme" })); + + expect(themeMocks.setTheme).toHaveBeenCalledOnce(); + expect(themeMocks.setTheme).toHaveBeenCalledWith("light"); + }); + + it("switches from light to dark with one click", () => { + themeMocks.resolvedTheme = "light"; + render(); + + fireEvent.click(screen.getByRole("button", { name: "Switch to dark theme" })); + + expect(themeMocks.setTheme).toHaveBeenCalledOnce(); + expect(themeMocks.setTheme).toHaveBeenCalledWith("dark"); + }); +}); diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx index 2ead2454..d089e451 100644 --- a/src/components/ThemeToggle.tsx +++ b/src/components/ThemeToggle.tsx @@ -1,16 +1,20 @@ import { Moon, Sun } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useEffect, useState } from "react"; +import { useTheme } from "next-themes"; export function ThemeToggle() { - const [dark, setDark] = useState(() => document.documentElement.classList.contains("dark")); - - useEffect(() => { - document.documentElement.classList.toggle("dark", dark); - }, [dark]); + const { resolvedTheme, setTheme } = useTheme(); + const dark = resolvedTheme === "dark"; + const nextTheme = dark ? "light" : "dark"; return ( - ); diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 65dcae2a..3893e3f0 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -104,13 +104,6 @@ const Index = () => { exitSelectionMode(); }, [store.pageSelectionKey, exitSelectionMode]); - // Dark mode by default (only if no prior preference) - useEffect(() => { - if (!document.documentElement.classList.contains("light")) { - document.documentElement.classList.add("dark"); - } - }, []); - useEffect(() => { const nextRouteTag = requestedTag?.trim() || null; if (nextRouteTag) { From b8b080ec632e30a045ef919b0b5e8a96f70d45ea Mon Sep 17 00:00:00 2001 From: aiapienthusiast <327629069+aiapienthusiast@users.noreply.github.com> Date: Mon, 2 Nov 2026 18:45:13 +0400 Subject: [PATCH 09/14] feat(ai): add Cheaper Inference provider (#235) * feat(ai): add Cheaper Inference provider * refactor(ai): share keyed OpenAI-compatible provider handling Fold deepseek and cheaperinference into one lookup table and helpers for LLM config resolution, redaction, and portable backup settings to bring duplication on new code under the SonarCloud gate. --------- Co-authored-by: Robert Goniszewski --- API.md | 32 +++++++++---- README.md | 4 +- daemon/src/ai/llm-provider.ts | 3 +- daemon/src/api/contract.ts | 20 ++++++-- daemon/src/routes/backup.ts | 11 +++-- daemon/src/runtime-settings.ts | 29 +++++++---- daemon/src/settings.ts | 24 +++++++--- daemon/src/test/integration/backup.test.ts | 15 ++++++ .../test/integration/settings-runtime.test.ts | 14 ++++++ docs/01-intro.md | 2 +- docs/api-contract.json | 48 +++++++++++++++++++ docs/docker-deployment.md | 5 +- docs/openapi.json | 47 ++++++++++++++++++ e2e/api-fixtures.ts | 5 ++ scripts/api-docs-generator.test.ts | 1 + src/demo/api/fixtures.ts | 1 + src/hooks/use-settings.test.tsx | 1 + src/lib/api.ts | 5 ++ src/pages/Settings.test.tsx | 5 ++ src/pages/Settings.tsx | 17 ++++++- 20 files changed, 253 insertions(+), 36 deletions(-) diff --git a/API.md b/API.md index 76103e49..56b2a630 100644 --- a/API.md +++ b/API.md @@ -1798,7 +1798,7 @@ Request body: | Field | Type | Required | Description | |---|---|---:|---| | `ai` | object | no | | -| `ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | no | LLM provider | +| `ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | no | LLM provider | | `ai.openai` | object | no | | | `ai.openai.api_key` | string | no | OpenAI API key, empty string clears it | | `ai.openai.model` | string | no | OpenAI chat model | @@ -1821,6 +1821,10 @@ Request body: | `ai.deepseek.api_key` | string | no | DeepSeek API key, empty string clears it | | `ai.deepseek.base_url` | string | no | DeepSeek OpenAI-compatible base URL | | `ai.deepseek.model` | string | no | DeepSeek chat model | +| `ai.cheaperinference` | object | no | | +| `ai.cheaperinference.api_key` | string | no | Cheaper Inference API key, empty string clears it | +| `ai.cheaperinference.base_url` | string | no | Cheaper Inference OpenAI-compatible base URL | +| `ai.cheaperinference.model` | string | no | Cheaper Inference chat model | | `ai.embeddings` | object | no | | | `ai.embeddings.provider` | "openai" \| "ollama" \| "openai_compatible" | no | Embedding provider | | `ai.embeddings.model` | string | no | Embedding model | @@ -4234,7 +4238,7 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. | Field | Type | Required | Description | |---|---|---:|---| | `enabled` | boolean | yes | Whether this runtime feature is usable | -| `provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | yes | Resolved provider | +| `provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | yes | Resolved provider | | `model` | string \| null | yes | Resolved model | | `base_url` | string \| null | yes | Resolved base URL | @@ -4253,7 +4257,7 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. |---|---|---:|---| | `llm` | RuntimeLlmCapability | yes | | | `llm.enabled` | boolean | yes | Whether this runtime feature is usable | -| `llm.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | yes | Resolved provider | +| `llm.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | yes | Resolved provider | | `llm.model` | string \| null | yes | Resolved model | | `llm.base_url` | string \| null | yes | Resolved base URL | | `embeddings` | RuntimeEmbeddingCapability | yes | | @@ -4280,7 +4284,7 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. | Field | Type | Required | Description | |---|---|---:|---| | `ai` | object | yes | | -| `ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | yes | LLM provider | +| `ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | yes | LLM provider | | `ai.openai` | object | yes | | | `ai.openai.api_key` | string | yes | Redacted OpenAI API key. Empty string means unset | | `ai.openai.model` | string | yes | OpenAI chat model | @@ -4303,6 +4307,10 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. | `ai.deepseek.api_key` | string | yes | Redacted DeepSeek API key. Empty string means unset | | `ai.deepseek.base_url` | string | yes | DeepSeek OpenAI-compatible base URL | | `ai.deepseek.model` | string | yes | DeepSeek chat model | +| `ai.cheaperinference` | object | yes | | +| `ai.cheaperinference.api_key` | string | yes | Redacted Cheaper Inference API key. Empty string means unset | +| `ai.cheaperinference.base_url` | string | yes | Cheaper Inference OpenAI-compatible base URL | +| `ai.cheaperinference.model` | string | yes | Cheaper Inference chat model | | `ai.embeddings` | object | yes | | | `ai.embeddings.provider` | "openai" \| "ollama" \| "openai_compatible" | yes | Embedding provider | | `ai.embeddings.model` | string | yes | Embedding model | @@ -4333,7 +4341,7 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. | `runtime` | RuntimeCapabilities | yes | | | `runtime.llm` | RuntimeLlmCapability | yes | | | `runtime.llm.enabled` | boolean | yes | Whether this runtime feature is usable | -| `runtime.llm.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | yes | Resolved provider | +| `runtime.llm.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | yes | Resolved provider | | `runtime.llm.model` | string \| null | yes | Resolved model | | `runtime.llm.base_url` | string \| null | yes | Resolved base URL | | `runtime.embeddings` | RuntimeEmbeddingCapability | yes | | @@ -4352,7 +4360,7 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. | Field | Type | Required | Description | |---|---|---:|---| | `ai` | object | no | | -| `ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | no | LLM provider | +| `ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | no | LLM provider | | `ai.openai` | object | no | | | `ai.openai.api_key` | string | no | OpenAI API key, empty string clears it | | `ai.openai.model` | string | no | OpenAI chat model | @@ -4375,6 +4383,10 @@ Experimental v0.5 migrate request. Provide dataDir, dbPath, or archivePath. | `ai.deepseek.api_key` | string | no | DeepSeek API key, empty string clears it | | `ai.deepseek.base_url` | string | no | DeepSeek OpenAI-compatible base URL | | `ai.deepseek.model` | string | no | DeepSeek chat model | +| `ai.cheaperinference` | object | no | | +| `ai.cheaperinference.api_key` | string | no | Cheaper Inference API key, empty string clears it | +| `ai.cheaperinference.base_url` | string | no | Cheaper Inference OpenAI-compatible base URL | +| `ai.cheaperinference.model` | string | no | Cheaper Inference chat model | | `ai.embeddings` | object | no | | | `ai.embeddings.provider` | "openai" \| "ollama" \| "openai_compatible" | no | Embedding provider | | `ai.embeddings.model` | string | no | Embedding model | @@ -4411,7 +4423,7 @@ Response data |---|---|---:|---| | `data` | Settings | yes | | | `data.ai` | object | yes | | -| `data.ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | yes | LLM provider | +| `data.ai.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | yes | LLM provider | | `data.ai.openai` | object | yes | | | `data.ai.openai.api_key` | string | yes | Redacted OpenAI API key. Empty string means unset | | `data.ai.openai.model` | string | yes | OpenAI chat model | @@ -4434,6 +4446,10 @@ Response data | `data.ai.deepseek.api_key` | string | yes | Redacted DeepSeek API key. Empty string means unset | | `data.ai.deepseek.base_url` | string | yes | DeepSeek OpenAI-compatible base URL | | `data.ai.deepseek.model` | string | yes | DeepSeek chat model | +| `data.ai.cheaperinference` | object | yes | | +| `data.ai.cheaperinference.api_key` | string | yes | Redacted Cheaper Inference API key. Empty string means unset | +| `data.ai.cheaperinference.base_url` | string | yes | Cheaper Inference OpenAI-compatible base URL | +| `data.ai.cheaperinference.model` | string | yes | Cheaper Inference chat model | | `data.ai.embeddings` | object | yes | | | `data.ai.embeddings.provider` | "openai" \| "ollama" \| "openai_compatible" | yes | Embedding provider | | `data.ai.embeddings.model` | string | yes | Embedding model | @@ -4464,7 +4480,7 @@ Response data | `data.runtime` | RuntimeCapabilities | yes | | | `data.runtime.llm` | RuntimeLlmCapability | yes | | | `data.runtime.llm.enabled` | boolean | yes | Whether this runtime feature is usable | -| `data.runtime.llm.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "none" | yes | Resolved provider | +| `data.runtime.llm.provider` | "openai" \| "ollama" \| "anthropic" \| "openrouter" \| "openai_compatible" \| "deepseek" \| "cheaperinference" \| "none" | yes | Resolved provider | | `data.runtime.llm.model` | string \| null | yes | Resolved model | | `data.runtime.llm.base_url` | string \| null | yes | Resolved base URL | | `data.runtime.embeddings` | RuntimeEmbeddingCapability | yes | | diff --git a/README.md b/README.md index 216dbbb8..e8daa895 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,8 @@ Open `http://127.0.0.1:3210`. category/tag management, import/export, backup/restore, diagnostics, and local update checks. - Runs without AI providers. Optional providers include OpenAI, Ollama, - Anthropic, OpenRouter, DeepSeek international, and custom OpenAI-compatible - chat or embeddings endpoints. + Anthropic, OpenRouter, DeepSeek international, Cheaper Inference, and custom + OpenAI-compatible chat or embeddings endpoints. ## How It Works diff --git a/daemon/src/ai/llm-provider.ts b/daemon/src/ai/llm-provider.ts index c08b1962..1ba5ed44 100644 --- a/daemon/src/ai/llm-provider.ts +++ b/daemon/src/ai/llm-provider.ts @@ -12,7 +12,8 @@ export type OpenAiCompatibleLlmProvider = | "ollama" | "openrouter" | "openai_compatible" - | "deepseek"; + | "deepseek" + | "cheaperinference"; export interface OpenAiCompatibleLlmConfig extends LlmConfig { kind: "openai-compatible"; diff --git a/daemon/src/api/contract.ts b/daemon/src/api/contract.ts index cbb7a764..09640f77 100644 --- a/daemon/src/api/contract.ts +++ b/daemon/src/api/contract.ts @@ -1034,7 +1034,7 @@ const schemas = { { enabled: booleanSchema("Whether this runtime feature is usable"), provider: stringSchema("Resolved provider", { - enum: ["openai", "ollama", "anthropic", "openrouter", "openai_compatible", "deepseek", "none"], + enum: ["openai", "ollama", "anthropic", "openrouter", "openai_compatible", "deepseek", "cheaperinference", "none"], }), model: nullable(stringSchema("Resolved model")), base_url: nullable(stringSchema("Resolved base URL", { format: "uri" })), @@ -1081,7 +1081,7 @@ const schemas = { ai: objectSchema( { provider: stringSchema("LLM provider", { - enum: ["openai", "ollama", "anthropic", "openrouter", "openai_compatible", "deepseek", "none"], + enum: ["openai", "ollama", "anthropic", "openrouter", "openai_compatible", "deepseek", "cheaperinference", "none"], }), openai: objectSchema( { @@ -1129,6 +1129,14 @@ const schemas = { }, ["api_key", "base_url", "model"] ), + cheaperinference: objectSchema( + { + api_key: stringSchema("Redacted Cheaper Inference API key. Empty string means unset"), + base_url: stringSchema("Cheaper Inference OpenAI-compatible base URL", { format: "uri" }), + model: stringSchema("Cheaper Inference chat model"), + }, + ["api_key", "base_url", "model"] + ), embeddings: objectSchema( { provider: stringSchema("Embedding provider", { enum: ["openai", "ollama", "openai_compatible"] }), @@ -1153,6 +1161,7 @@ const schemas = { "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "embeddings", ] ), @@ -1200,7 +1209,7 @@ const schemas = { SettingsPatch: objectSchema({ ai: objectSchema({ provider: stringSchema("LLM provider", { - enum: ["openai", "ollama", "anthropic", "openrouter", "openai_compatible", "deepseek", "none"], + enum: ["openai", "ollama", "anthropic", "openrouter", "openai_compatible", "deepseek", "cheaperinference", "none"], }), openai: objectSchema({ api_key: stringSchema("OpenAI API key, empty string clears it"), @@ -1230,6 +1239,11 @@ const schemas = { base_url: stringSchema("DeepSeek OpenAI-compatible base URL", { format: "uri" }), model: stringSchema("DeepSeek chat model"), }), + cheaperinference: objectSchema({ + api_key: stringSchema("Cheaper Inference API key, empty string clears it"), + base_url: stringSchema("Cheaper Inference OpenAI-compatible base URL", { format: "uri" }), + model: stringSchema("Cheaper Inference chat model"), + }), embeddings: objectSchema({ provider: stringSchema("Embedding provider", { enum: ["openai", "ollama", "openai_compatible"] }), model: stringSchema("Embedding model"), diff --git a/daemon/src/routes/backup.ts b/daemon/src/routes/backup.ts index b4e7bd88..1245fa1f 100644 --- a/daemon/src/routes/backup.ts +++ b/daemon/src/routes/backup.ts @@ -71,6 +71,7 @@ type PortableSettings = { openrouter: Omit; openai_compatible: Omit; deepseek: Omit; + cheaperinference: Omit; embeddings: { provider: Settings["ai"]["embeddings"]["provider"]; model: string; @@ -166,6 +167,10 @@ function currentSchemaVersion(db: Database): string { } } +function portableEndpoint(provider: { base_url: string; model: string }) { + return { base_url: provider.base_url, model: provider.model }; +} + function portableSettings(settings: Settings): PortableSettings { return { ai: { @@ -189,10 +194,8 @@ function portableSettings(settings: Settings): PortableSettings { base_url: settings.ai.openai_compatible.base_url, model: settings.ai.openai_compatible.model, }, - deepseek: { - base_url: settings.ai.deepseek.base_url, - model: settings.ai.deepseek.model, - }, + deepseek: portableEndpoint(settings.ai.deepseek), + cheaperinference: portableEndpoint(settings.ai.cheaperinference), embeddings: { provider: settings.ai.embeddings.provider, model: settings.ai.embeddings.model, diff --git a/daemon/src/runtime-settings.ts b/daemon/src/runtime-settings.ts index 357382d8..b1fd7401 100644 --- a/daemon/src/runtime-settings.ts +++ b/daemon/src/runtime-settings.ts @@ -40,7 +40,16 @@ const OPENAI_BASE_URL = "https://api.openai.com/v1"; const OLLAMA_BASE_URL = "http://localhost:11434"; const ANTHROPIC_BASE_URL = "https://api.anthropic.com"; const OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"; -const DEEPSEEK_BASE_URL = "https://api.deepseek.com"; +// Hosted OpenAI-compatible providers that need an API key and share one config shape. +const KEYED_OPENAI_COMPATIBLE_BASE_URLS = { + deepseek: "https://api.deepseek.com", + cheaperinference: "https://api.cheaperinference.com/v1", +} as const; +type KeyedOpenAiCompatibleProvider = keyof typeof KEYED_OPENAI_COMPATIBLE_BASE_URLS; + +function isKeyedOpenAiCompatible(provider: string): provider is KeyedOpenAiCompatibleProvider { + return provider in KEYED_OPENAI_COMPATIBLE_BASE_URLS; +} const OPENROUTER_TITLE = "Grimoire"; const REDACTED_SECRET = "***"; const AI_PROVIDERS = new Set([ @@ -50,6 +59,7 @@ const AI_PROVIDERS = new Set([ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none", ]); const EMBEDDING_PROVIDERS = new Set([ @@ -164,14 +174,15 @@ function resolveLlmConfig(settings: Settings): EffectiveLlmConfig | null { }; } - if (provider === "deepseek") { - const apiKey = cleanSecret(settings.ai.deepseek.api_key); - const model = clean(settings.ai.deepseek.model); + if (isKeyedOpenAiCompatible(provider)) { + const config = settings.ai[provider]; + const apiKey = cleanSecret(config.api_key); + const model = clean(config.model); if (!apiKey || !model) return null; return { kind: "openai-compatible", - provider: "deepseek", - baseUrl: normalizeBaseUrl(settings.ai.deepseek.base_url, DEEPSEEK_BASE_URL), + provider, + baseUrl: normalizeBaseUrl(config.base_url, KEYED_OPENAI_COMPATIBLE_BASE_URLS[provider]), apiKey, model, }; @@ -246,7 +257,7 @@ function configuredLlmModel(settings: Settings): string | null { if (provider === "anthropic") return clean(settings.ai.anthropic.model) || null; if (provider === "openrouter") return clean(settings.ai.openrouter.model) || null; if (provider === "openai_compatible") return clean(settings.ai.openai_compatible.model) || null; - if (provider === "deepseek") return clean(settings.ai.deepseek.model) || null; + if (isKeyedOpenAiCompatible(provider)) return clean(settings.ai[provider].model) || null; return null; } @@ -257,7 +268,9 @@ function configuredLlmBaseUrl(settings: Settings): string | null { if (provider === "anthropic") return normalizeAnthropicBaseUrl(settings.ai.anthropic.base_url); if (provider === "openrouter") return normalizeBaseUrl(settings.ai.openrouter.base_url, OPENROUTER_BASE_URL); if (provider === "openai_compatible") return normalizeBaseUrl(settings.ai.openai_compatible.base_url, ""); - if (provider === "deepseek") return normalizeBaseUrl(settings.ai.deepseek.base_url, DEEPSEEK_BASE_URL); + if (isKeyedOpenAiCompatible(provider)) { + return normalizeBaseUrl(settings.ai[provider].base_url, KEYED_OPENAI_COMPATIBLE_BASE_URLS[provider]); + } return null; } diff --git a/daemon/src/settings.ts b/daemon/src/settings.ts index 26eed152..1dd32727 100644 --- a/daemon/src/settings.ts +++ b/daemon/src/settings.ts @@ -33,6 +33,7 @@ export type AiProvider = | "openrouter" | "openai_compatible" | "deepseek" + | "cheaperinference" | "none"; export type EmbeddingProvider = "openai" | "ollama" | "openai_compatible"; @@ -57,6 +58,7 @@ export interface AiSettings { openrouter: ApiKeyProviderSettings; openai_compatible: ApiKeyProviderSettings; deepseek: ApiKeyProviderSettings; + cheaperinference: ApiKeyProviderSettings; embeddings: { provider: EmbeddingProvider; model: string; @@ -145,6 +147,11 @@ const DEFAULT_SETTINGS: Settings = { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: { + api_key: "", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, embeddings: { provider: "openai", model: Config.EMBEDDING_MODEL, @@ -220,7 +227,9 @@ function removeRedactedSecretPlaceholders(patch: Partial): Partial([ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none", ]); const VALID_EMBEDDING_PROVIDERS = new Set([ @@ -335,7 +345,7 @@ export function validateSettingsPatch(patch: unknown): string | null { if ("model" in oo && (typeof oo.model !== "string" || !(oo.model as string).trim())) return "`ai.ollama.model` must be a non-empty string"; } - for (const provider of ["anthropic", "openrouter", "openai_compatible", "deepseek"] as const) { + for (const provider of ["anthropic", "openrouter", "openai_compatible", "deepseek", "cheaperinference"] as const) { if (provider in a) { const error = validateProviderConfig(`ai.${provider}`, a[provider]); if (error) return error; @@ -460,6 +470,10 @@ export function validateSettingsPatch(patch: unknown): string | null { // ─── Redaction ──────────────────────────────────────────────────────────────── /** Returns settings with API keys replaced by a sentinel so callers know one is set. */ +function redactApiKeyProvider(provider: ApiKeyProviderSettings): ApiKeyProviderSettings { + return { ...provider, api_key: provider.api_key ? "***" : "" }; +} + export function redactSettings(settings: Settings): object { return { ...settings, @@ -481,10 +495,8 @@ export function redactSettings(settings: Settings): object { ...settings.ai.openai_compatible, api_key: settings.ai.openai_compatible.api_key ? "***" : "", }, - deepseek: { - ...settings.ai.deepseek, - api_key: settings.ai.deepseek.api_key ? "***" : "", - }, + deepseek: redactApiKeyProvider(settings.ai.deepseek), + cheaperinference: redactApiKeyProvider(settings.ai.cheaperinference), embeddings: { ...settings.ai.embeddings, openai_compatible: { diff --git a/daemon/src/test/integration/backup.test.ts b/daemon/src/test/integration/backup.test.ts index d8060096..b05eb6da 100644 --- a/daemon/src/test/integration/backup.test.ts +++ b/daemon/src/test/integration/backup.test.ts @@ -186,6 +186,11 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: { + api_key: "backup-cheaperinference-secret", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, embeddings: { provider: "openai_compatible", model: "nomic-embed-text", @@ -858,6 +863,11 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: { + api_key: "backup-cheaperinference-secret", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, embeddings: { provider: "openai_compatible", model: "nomic-embed-text", @@ -912,6 +922,11 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-current", }, + cheaperinference: { + api_key: "current-cheaperinference-secret", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, embeddings: { provider: "openai", model: "embed-current", diff --git a/daemon/src/test/integration/settings-runtime.test.ts b/daemon/src/test/integration/settings-runtime.test.ts index 7f37160a..e999aef2 100644 --- a/daemon/src/test/integration/settings-runtime.test.ts +++ b/daemon/src/test/integration/settings-runtime.test.ts @@ -784,6 +784,20 @@ describe("settings-driven AI runtime configuration", () => { expectedModel: "deepseek-v4-flash", expectedOpenRouterTitle: null, }, + { + provider: "cheaperinference", + patch: { + cheaperinference: { + api_key: "cheaperinference-key", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, + }, + expectedUrl: "https://api.cheaperinference.com/v1/chat/completions", + expectedAuth: "Bearer cheaperinference-key", + expectedModel: "gpt-5.4-mini", + expectedOpenRouterTitle: null, + }, ]; for (const testCase of cases) { diff --git a/docs/01-intro.md b/docs/01-intro.md index 4583841d..4533647b 100644 --- a/docs/01-intro.md +++ b/docs/01-intro.md @@ -13,7 +13,7 @@ your machine while leaving integrations optional. - Tags and nested categories (up to three levels) - Personal notes, pin, read / unread, read later, archive, and trash - Keyword search always; semantic and hybrid search when embeddings are configured -- Optional AI summaries, tags, and categories (OpenAI, Ollama, Anthropic, OpenRouter, DeepSeek, or a custom OpenAI-compatible endpoint) +- Optional AI summaries, tags, and categories (OpenAI, Ollama, Anthropic, OpenRouter, DeepSeek, Cheaper Inference, or a custom OpenAI-compatible endpoint) - Import browser bookmarks (HTML); export JSON or CSV - Local backups, restore, and diagnostics - Single user, loopback by default (`127.0.0.1:3210`) diff --git a/docs/api-contract.json b/docs/api-contract.json index 64bc126a..2f68cbaf 100644 --- a/docs/api-contract.json +++ b/docs/api-contract.json @@ -3582,6 +3582,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none" ] }, @@ -3727,6 +3728,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none" ] }, @@ -3863,6 +3865,30 @@ ], "additionalProperties": false }, + "cheaperinference": { + "type": "object", + "properties": { + "api_key": { + "type": "string", + "description": "Redacted Cheaper Inference API key. Empty string means unset" + }, + "base_url": { + "type": "string", + "description": "Cheaper Inference OpenAI-compatible base URL", + "format": "uri" + }, + "model": { + "type": "string", + "description": "Cheaper Inference chat model" + } + }, + "required": [ + "api_key", + "base_url", + "model" + ], + "additionalProperties": false + }, "embeddings": { "type": "object", "properties": { @@ -3920,6 +3946,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "embeddings" ], "additionalProperties": false @@ -4060,6 +4087,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none" ] }, @@ -4174,6 +4202,26 @@ "required": [], "additionalProperties": false }, + "cheaperinference": { + "type": "object", + "properties": { + "api_key": { + "type": "string", + "description": "Cheaper Inference API key, empty string clears it" + }, + "base_url": { + "type": "string", + "description": "Cheaper Inference OpenAI-compatible base URL", + "format": "uri" + }, + "model": { + "type": "string", + "description": "Cheaper Inference chat model" + } + }, + "required": [], + "additionalProperties": false + }, "embeddings": { "type": "object", "properties": { diff --git a/docs/docker-deployment.md b/docs/docker-deployment.md index 92afd113..ff03f654 100644 --- a/docs/docker-deployment.md +++ b/docs/docker-deployment.md @@ -72,8 +72,9 @@ Environment variables are only first-start or unattended defaults. | `EMBEDDING_MODEL` | Default embedding model. | Additional LLM providers are configured through persisted Settings after -startup: Anthropic, OpenRouter, custom OpenAI-compatible chat endpoints, and -DeepSeek international each have separate API key, base URL, and model fields. +startup: Anthropic, OpenRouter, custom OpenAI-compatible chat endpoints, +DeepSeek international, and Cheaper Inference each have separate API key, base +URL, and model fields. Custom OpenAI-compatible embeddings use their own provider, API key, base URL, and model instead of sharing the selected LLM provider. diff --git a/docs/openapi.json b/docs/openapi.json index 2321836b..4884e3ca 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -8025,6 +8025,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none" ] }, @@ -8170,6 +8171,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none" ] }, @@ -8306,6 +8308,30 @@ ], "additionalProperties": false }, + "cheaperinference": { + "type": "object", + "properties": { + "api_key": { + "type": "string", + "description": "Redacted Cheaper Inference API key. Empty string means unset" + }, + "base_url": { + "type": "string", + "description": "Cheaper Inference OpenAI-compatible base URL", + "format": "uri" + }, + "model": { + "type": "string", + "description": "Cheaper Inference chat model" + } + }, + "required": [ + "api_key", + "base_url", + "model" + ], + "additionalProperties": false + }, "embeddings": { "type": "object", "properties": { @@ -8363,6 +8389,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "embeddings" ], "additionalProperties": false @@ -8503,6 +8530,7 @@ "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none" ] }, @@ -8611,6 +8639,25 @@ }, "additionalProperties": false }, + "cheaperinference": { + "type": "object", + "properties": { + "api_key": { + "type": "string", + "description": "Cheaper Inference API key, empty string clears it" + }, + "base_url": { + "type": "string", + "description": "Cheaper Inference OpenAI-compatible base URL", + "format": "uri" + }, + "model": { + "type": "string", + "description": "Cheaper Inference chat model" + } + }, + "additionalProperties": false + }, "embeddings": { "type": "object", "properties": { diff --git a/e2e/api-fixtures.ts b/e2e/api-fixtures.ts index 1e350948..ce18cac0 100644 --- a/e2e/api-fixtures.ts +++ b/e2e/api-fixtures.ts @@ -69,6 +69,11 @@ export function makeSettings(aiProvider: SettingsDto["ai"]["provider"] = "none") base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: { + api_key: "", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, embeddings: { provider: "openai", model: "text-embedding-3-small", diff --git a/scripts/api-docs-generator.test.ts b/scripts/api-docs-generator.test.ts index 63d1f846..50ed547d 100644 --- a/scripts/api-docs-generator.test.ts +++ b/scripts/api-docs-generator.test.ts @@ -96,6 +96,7 @@ describe("API documentation generator", () => { "openrouter", "openai_compatible", "deepseek", + "cheaperinference", "none", ]); expect(settingsPatch.properties.ai.properties.anthropic.properties.api_key.type).toBe("string"); diff --git a/src/demo/api/fixtures.ts b/src/demo/api/fixtures.ts index 8bc8e16c..2fd87480 100644 --- a/src/demo/api/fixtures.ts +++ b/src/demo/api/fixtures.ts @@ -473,6 +473,7 @@ export const DEMO_SETTINGS: SettingsDto = { openrouter: { api_key: "", base_url: "https://example.invalid/openrouter", model: "openai/gpt-latest" }, openai_compatible: { api_key: "", base_url: "https://example.invalid/ai", model: "custom-chat-model" }, deepseek: { api_key: "", base_url: "https://example.invalid/deepseek", model: "deepseek-chat" }, + cheaperinference: { api_key: "", base_url: "https://example.invalid/cheaperinference", model: "gpt-5.4-mini" }, embeddings: { provider: "openai", model: "text-embedding-3-small", diff --git a/src/hooks/use-settings.test.tsx b/src/hooks/use-settings.test.tsx index 1e068e33..0baaeba9 100644 --- a/src/hooks/use-settings.test.tsx +++ b/src/hooks/use-settings.test.tsx @@ -31,6 +31,7 @@ function settingsResponse(runtimeEnrichment: boolean) { openrouter: { api_key: "", base_url: "https://openrouter.ai/api/v1", model: "openai/gpt-latest" }, openai_compatible: { api_key: "", base_url: "http://localhost:8000/v1", model: "custom-chat-model" }, deepseek: { api_key: "", base_url: "https://api.deepseek.com", model: "deepseek-v4-flash" }, + cheaperinference: { api_key: "", base_url: "https://api.cheaperinference.com/v1", model: "gpt-5.4-mini" }, embeddings: { provider: "openai" as const, model: "text-embedding-3-small", diff --git a/src/lib/api.ts b/src/lib/api.ts index cf73ab33..174c8501 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -383,6 +383,11 @@ export interface ApiSettings { base_url: SettingsDto["ai"]["deepseek"]["base_url"]; model: SettingsDto["ai"]["deepseek"]["model"]; }; + cheaperinference: { + api_key: SettingsDto["ai"]["cheaperinference"]["api_key"]; + base_url: SettingsDto["ai"]["cheaperinference"]["base_url"]; + model: SettingsDto["ai"]["cheaperinference"]["model"]; + }; embeddings: { provider: ApiEmbeddingProvider; model: SettingsDto["ai"]["embeddings"]["model"]; diff --git a/src/pages/Settings.test.tsx b/src/pages/Settings.test.tsx index 90afe563..9f754679 100644 --- a/src/pages/Settings.test.tsx +++ b/src/pages/Settings.test.tsx @@ -100,6 +100,11 @@ function settingsResponse(aiPatch: Record = {}) { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: { + api_key: "", + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }, embeddings: { provider: "openai" as const, model: "text-embedding-3-small", diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index d5fa5237..be07d2cb 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -101,7 +101,7 @@ import DemoSettings from "@/pages/DemoSettings"; // ─── Types ──────────────────────────────────────────────────────────────────── type Provider = ApiAiProvider; -type ApiKeyProvider = "anthropic" | "openrouter" | "openai_compatible" | "deepseek"; +type ApiKeyProvider = "anthropic" | "openrouter" | "openai_compatible" | "deepseek" | "cheaperinference"; interface ApiKeyProviderFormState { api_key: string; @@ -117,6 +117,7 @@ interface AiFormState { openrouter: ApiKeyProviderFormState; openai_compatible: ApiKeyProviderFormState; deepseek: ApiKeyProviderFormState; + cheaperinference: ApiKeyProviderFormState; } interface EmbeddingsFormState { @@ -186,6 +187,11 @@ const apiKeyProviderMeta: Record | undefine }, openai_compatible: mergeApiKeyProvider(defaults.openai_compatible, settings?.openai_compatible), deepseek: mergeApiKeyProvider(defaults.deepseek, settings?.deepseek), + cheaperinference: mergeApiKeyProvider(defaults.cheaperinference, settings?.cheaperinference), }; } @@ -726,6 +738,7 @@ const LocalSettings = () => { openrouter: secretProviderPatch(ai.openrouter), openai_compatible: secretProviderPatch(ai.openai_compatible), deepseek: secretProviderPatch(ai.deepseek), + cheaperinference: secretProviderPatch(ai.cheaperinference), embeddings: { provider: embeddings.provider, model: embeddings.model, @@ -1049,6 +1062,7 @@ const LocalSettings = () => { OpenRouter OpenAI compatible DeepSeek + Cheaper Inference None @@ -1146,6 +1160,7 @@ const LocalSettings = () => { )} {ai.provider === "openai_compatible" && renderApiKeyProviderFields("openai_compatible")} {ai.provider === "deepseek" && renderApiKeyProviderFields("deepseek")} + {ai.provider === "cheaperinference" && renderApiKeyProviderFields("cheaperinference")} {ai.provider !== "none" && (
From 239108808678b352c5954ae9bd48b902747e3895 Mon Sep 17 00:00:00 2001 From: Muhammad Naufal Mahdi <053792227@ecampus.ut.ac.id> Date: Mon, 2 Nov 2026 21:53:20 +0700 Subject: [PATCH 10/14] deps: bump fast-uri from 3.1.6 to 3.1.8 (GHSA-58mr-gqgx-xq4g, GHSA-qw65-cvwx-89v3) (#234) Co-authored-by: katsugtgz --- daemon/bun.lock | 4 ++-- daemon/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/daemon/bun.lock b/daemon/bun.lock index 2f5baded..54866b4f 100644 --- a/daemon/bun.lock +++ b/daemon/bun.lock @@ -20,7 +20,7 @@ "overrides": { "@hono/node-server": "1.19.15", "body-parser": "2.3.0", - "fast-uri": "3.1.6", + "fast-uri": "3.1.8", "ip-address": "10.7.0", "path-to-regexp": "8.4.2", "qs": "6.16.0", @@ -164,7 +164,7 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - "fast-uri": ["fast-uri@3.1.6", "", {}, "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q=="], + "fast-uri": ["fast-uri@3.1.8", "", {}, "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg=="], "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], diff --git a/daemon/package.json b/daemon/package.json index e1895524..12ea63eb 100644 --- a/daemon/package.json +++ b/daemon/package.json @@ -30,7 +30,7 @@ "overrides": { "@hono/node-server": "1.19.15", "body-parser": "2.3.0", - "fast-uri": "3.1.6", + "fast-uri": "3.1.8", "ip-address": "10.7.0", "path-to-regexp": "8.4.2", "qs": "6.16.0" From 17b2b88bf7cb6693ae807b13e88b8b7e6e52e13c Mon Sep 17 00:00:00 2001 From: Robert Goniszewski <43510122+goniszewski@users.noreply.github.com> Date: Wed, 4 Nov 2026 12:28:38 +0100 Subject: [PATCH 11/14] chore(deps): update dependencies and fix audit findings (#239) * chore(deps): update dependencies and fix audit findings - daemon: update in-range deps (MCP SDK 1.32, hono 4.13.16, aws-sdk, sqlite-vec, zod) and bump pinned overrides that were themselves vulnerable (fast-uri, ip-address, body-parser, qs, @hono/node-server); add proxy-addr 2.0.8 override (critical IP spoofing advisory) - frontend: npm audit fix + in-range updates (vite 6.4.5, react-query, radix, eslint 9.39, typescript 5.9); remove unused zod; pin postcss-selector-parser to 6.1.5 - fix daemon type errors from TS 5.9 Uint8Array typing - Tags: call deleteTag explicitly, react-query now passes a second mutationFn argument - tests: await async elements in Settings and TagDetail tests * chore(deps): sync frontend bun.lock with package.json --- bun.lock | 12 +- daemon/bun.lock | 109 +- daemon/package.json | 23 +- daemon/src/backup/package.ts | 8 +- daemon/src/test/bookmark-media.test.ts | 2 +- package-lock.json | 3101 +++++++++++------------- package.json | 6 +- src/pages/Settings.test.tsx | 6 +- src/pages/TagDetail.test.tsx | 4 +- src/pages/Tags.tsx | 2 +- 10 files changed, 1453 insertions(+), 1820 deletions(-) diff --git a/bun.lock b/bun.lock index 8e6ac466..ce5bc189 100644 --- a/bun.lock +++ b/bun.lock @@ -57,7 +57,6 @@ "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", "vaul": "^0.9.9", - "zod": "^3.25.76", }, "devDependencies": { "@eslint/js": "^9.32.0", @@ -86,6 +85,9 @@ }, }, }, + "overrides": { + "postcss-selector-parser": "6.1.5", + }, "packages": { "@adobe/css-tools": ["@adobe/css-tools@4.4.4", "", {}, "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="], @@ -1097,7 +1099,7 @@ "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], - "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="], + "postcss-selector-parser": ["postcss-selector-parser@6.1.5", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-TEHFzb5KRDKaOgJ4TYE+0jyJtFbjLvkdVOu0fZ2b6MTWzoqZd4Le+61aEppWkvTlYePgOX4ATL1wsAIPMLTw6Q=="], "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], @@ -1343,8 +1345,6 @@ "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], - "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], @@ -1389,8 +1389,6 @@ "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - "postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], "pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], @@ -1409,8 +1407,6 @@ "strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], - "tailwindcss/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - "vitest/vite": ["vite@8.3.0", "", { "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", "postcss": "^8.5.28", "rolldown": "~1.2.6", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.7.1", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ=="], "wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], diff --git a/daemon/bun.lock b/daemon/bun.lock index 54866b4f..eebbfd99 100644 --- a/daemon/bun.lock +++ b/daemon/bun.lock @@ -5,66 +5,67 @@ "": { "name": "littleimpd", "dependencies": { - "@aws-sdk/client-s3": "^3.1128.0", - "@modelcontextprotocol/sdk": "^1.30.0", - "hono": "^4.13.7", + "@aws-sdk/client-s3": "^3.1161.0", + "@modelcontextprotocol/sdk": "^1.32.2", + "hono": "^4.13.16", "pdf-parse": "^2.4.5", - "sqlite-vec": "^0.1.7-alpha.2", - "zod": "^4.3.6", + "sqlite-vec": "^0.1.9", + "zod": "^4.6.7", }, "devDependencies": { - "@types/bun": "^1.2", + "@types/bun": "^1.4.4", }, }, }, "overrides": { - "@hono/node-server": "1.19.15", - "body-parser": "2.3.0", - "fast-uri": "3.1.8", - "ip-address": "10.7.0", + "@hono/node-server": "2.1.6", + "body-parser": "2.4.0", + "fast-uri": "3.1.9", + "ip-address": "10.7.6", "path-to-regexp": "8.4.2", - "qs": "6.16.0", + "proxy-addr": "2.0.8", + "qs": "6.17.1", }, "packages": { - "@aws-sdk/checksums": ["@aws-sdk/checksums@3.1000.29", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Dtu0gr4dnATZAPwEYbpCsG+MpLM7OAliy2gTepEFQwl1vZ6DL3QMH2FveMa3HLvPsOdhJsPRB3KtxVhph9T75A=="], + "@aws-sdk/checksums": ["@aws-sdk/checksums@3.1002.1", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-CXNESwkQC9jdrUG6cKXBfudVt1frGcYQykcCYbNclVrsewuGMbo3PlFjRteMe4OftNAqhyc3xC2jTz7SUqLasQ=="], - "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1128.0", "", { "dependencies": { "@aws-sdk/checksums": "^3.1000.29", "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-node": "^3.972.82", "@aws-sdk/middleware-sdk-s3": "^3.972.75", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-tYEB4058LdhTiSS7sCVVSpqSAdjIc1jTaf1dDPoIRJbR/XI5A2ZOuCiV1Aebo/pria/pUJBOT0WjdZVIwaZtDA=="], + "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1161.0", "", { "dependencies": { "@aws-sdk/checksums": "^3.1002.1", "@aws-sdk/core": "^3.979.1", "@aws-sdk/credential-provider-node": "^3.972.92", "@aws-sdk/middleware-sdk-s3": "^3.972.85", "@aws-sdk/signature-v4-multi-region": "^3.996.51", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.14.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-iRZGMsJnYRrI98O+U6o5fHeLPQTP+Dc/w0mWLcBLQcEQ10DA06+XQj0WmdRiCM7vIso7QEtN1fsj9Vzo5/R3LQ=="], - "@aws-sdk/core": ["@aws-sdk/core@3.977.9", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@aws-sdk/xml-builder": "^3.972.40", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.33.3", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-reqPFEQrZxDZpeGj4PFMepBeR5LGYHRqq/L0motTzgFkCRBA4rFdaVXDSLYyGHhxVz7sT2PDnPN9CluGSfgyJA=="], + "@aws-sdk/core": ["@aws-sdk/core@3.979.1", "", { "dependencies": { "@aws-sdk/types": "^3.975.0", "@aws-sdk/xml-builder": "^3.972.42", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.38.0", "@smithy/signature-v4": "^5.7.5", "@smithy/types": "^4.19.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-ayOlV1VhLNMiq8PW9ZkVobG4gkldnUoHjG69yy2b8j+VYFlhz/uAL7ZdYQAoQ+eShtGUdNDnnG5rxDg6yUJrOg=="], - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.70", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-H404B7dJl2mCrBqahDEYsanB0xhdDp6tXnXcTUnXmmpy2Q3J0Ho0bUajZ2jr/RdwzCyS59Gi8xXIFwPLGBl6Uw=="], + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.80", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-uO5TiSvb6j1w9RTe5z28OaOmsrOxVQUPaC5+wZl50RfOXcrYD/KgnS8I9lfyGXc7sGbkCopK6VnhNIAoLqfewQ=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-X98zYOrVOeuosCX+6ktf29FC2N2GHPLia7qv6mzPzTc+RPAuHWCDS++Z6JK7eGYqb/v6uaW7bAXaOvDBfol+0w=="], + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.82", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.14.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-vQzlDHlC24Yz42p+rT4NBoP/5VdetkBoujbOLq9h6QYWC8THuZSPYnXIR9OP3XcOrdMgPBBipOrdssfxnIiWUg=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.15", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-login": "^3.972.77", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Rykg6s5ceBuynMOGWgoowO4N+27JfnqXAnVaSunZl0hOO1XodSrxGNz6sCEbnmS0lAfQZDKyb3fbr46gSuv6Sg=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.25", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/credential-provider-env": "^3.972.80", "@aws-sdk/credential-provider-http": "^3.972.82", "@aws-sdk/credential-provider-login": "^3.972.87", "@aws-sdk/credential-provider-process": "^3.972.80", "@aws-sdk/credential-provider-sso": "^3.973.24", "@aws-sdk/credential-provider-web-identity": "^3.972.86", "@aws-sdk/nested-clients": "^3.997.54", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-b5xl71uCRdWsu7P1VeGpiGuCf6zfYETsSNOv8AmYVTrsgbvTJRXdmmOPVfxkvGGVNsiKkGctClQW3jAn0SZLug=="], - "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.77", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Jb59xfEISoN5mmbnA+HYqdtrSX3CgCtJoof+V5D8/TgUI56W63GEEd5Y58WijU3Ou6+WEgaLD1feVzaRXV5IDQ=="], + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.87", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/nested-clients": "^3.997.54", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-C4ZFmcwM+Zj14Z8huVUk54Gv4uzT1ZdzG9cY3Gdh8FePakq7Bss1OFsgZjAhWFOkFOGpBvFBeu0OWjWf8HNKRQ=="], - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.82", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-ini": "^3.973.15", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-znDkEOGXB8W3kG1LJUKP3foBZY/9qLM0eil/DxWXSp37XsdsRLQHE/d/OaCGGVgKpA6znR38h/+INk8do1FjiA=="], + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.92", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.80", "@aws-sdk/credential-provider-http": "^3.972.82", "@aws-sdk/credential-provider-ini": "^3.973.25", "@aws-sdk/credential-provider-process": "^3.972.80", "@aws-sdk/credential-provider-sso": "^3.973.24", "@aws-sdk/credential-provider-web-identity": "^3.972.86", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-jC3zmOo7Qxlk+oBivvSsS1Ph7sFGm0QfuhqDGbqgRXi4cxUYMG+dWtBwS2XYYXgc8TIVXJiwgQ65sbNpbYupTA=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.70", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-2ry03fGRJr4sV3jI+ocjj5JqALnFD6ymM5KiNCDZMvq8bX2GSbE0vji4aM43TVCl2nXqqLRZaUxdq/KeWRAY4Q=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.80", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-xqfixO5aclje7tbQJDias+iNND5wp/3QZixCdZcVQpgWPTZ0V5DfTW9A804A5Z7ezu7sH3WRO+vzUjtiJBA8yg=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.14", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/token-providers": "3.1116.0", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-jkhg/8ocAAoc0RFyLMhCw+/zZh7gystQgd4F4hznNa8P4Cc501PQmxd+jGLiMHodPJ+7Zv/3znM62gZojyasmA=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.24", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/nested-clients": "^3.997.54", "@aws-sdk/token-providers": "3.1161.0", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-nlg3BKG03Cgzvv/dMnhxvDJPhAhQSpaN0RUdwgU7ziwkasoev7iI8el8Xy4Rd5sqzgaDUbV269fOXck5SargqA=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.76", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-d3AGyVu759PGr35mEB2s22xxlNEA5rpdxtSPJthfPFJvoQ8dt357iVPECqWfUxXp1toJAvKmbtcIYVGigaGsCA=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.86", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/nested-clients": "^3.997.54", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-zKTyLJBEyfQBVlYqT6Jt+mYV4r8kGbWM7dn6v4Y4MRARizhYafjDXP/iMu76UMRhToSPNmIKX1XAb24gtpBFIA=="], - "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.75", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-wMIsNumRVKaNMKhvU/s9VrdEwE8S6gSzXp4RygFG5BEMnGkkXf8cjh8zf7cKJBpUDpqTWqwbz5isEgp9rH6Lng=="], + "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.85", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/signature-v4-multi-region": "^3.996.51", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-Kyl2G6zhIS9qFoeLdlxvXFrWyc6g9D9ZCIRJnGkkfX6JZhxCZB5ebXBc7GKEeetrnhXcail6ALZT0lKbojcaNA=="], - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.44", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-NhEgryjlBF9w38ZXqGymQV28IhkYa1mKhlbYnqIis57AYwWGVYfUPgg/qC2rLRqOUfblxx++irvju10kVTa8Vw=="], + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.54", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/signature-v4-multi-region": "^3.996.51", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.14.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-/OczlavsS7U5sOodRO10Ug4R/AKFVZiXTstKipWe68EfjPkmdDFNXNl9FCJyXWkg1DG6RBm3qAuVB8FNW9O8KQ=="], - "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.46", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ=="], + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.51", "", { "dependencies": { "@aws-sdk/types": "^3.975.0", "@smithy/signature-v4": "^5.7.5", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-+aHvUugVBuMPXxgkPfWnTMyGdE/yWS8GHi5+qQ37HowS0YqzrbuaDLznj+Dtmtu5jgCdqz36gXmujOToUhNNWw=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1116.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/nested-clients": "^3.997.44", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-ygIivKqh8aHzNkucOCXHyIBgBpLPfrSI0mCqXF+vLBsPTUKqj0VSqAY0GFPe7lQl4HntjOcQ+KSyS7oUV2C54Q=="], + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1161.0", "", { "dependencies": { "@aws-sdk/core": "^3.979.1", "@aws-sdk/nested-clients": "^3.997.54", "@aws-sdk/types": "^3.975.0", "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-ypbXSofNcSHwf/KA40bFCXJb0MLaAKrfT7sot4dFaA+2lsuXNah4zLRJIAU7Qmvs9PFJ6rnY0bZFEC+mE7attA=="], - "@aws-sdk/types": ["@aws-sdk/types@3.974.5", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ=="], + "@aws-sdk/types": ["@aws-sdk/types@3.975.0", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-WQlhs6juByzWOzj5fwxOx0mPJaEqMcG/sDpl3Id61B3XhKE63xY+0QWcnG+sWR/sCfprmreyUo1lM7IKZmHMzw=="], - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.40", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA=="], + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.42", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-smX8/gNP8Kjq+CWTBMZQLQ912vOQjiWExzwzvMO+eujPB5RY8IbtF0AGdUUXHKN7KoDWK9dIcuW0WG269kiP6w=="], "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.3.0", "", {}, "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ=="], - "@hono/node-server": ["@hono/node-server@1.19.15", "", { "peerDependencies": { "hono": "^4" } }, "sha512-Za2ai6TLdKjUvnur+eenO6nuYYipVAEhyCAdaV8IRvmU9kK8crOZUSYvIXn72E4f8fJqyAbpcJuTsYYmZp9Deg=="], + "@hono/node-server": ["@hono/node-server@2.1.6", "", { "peerDependencies": { "hono": "^4 || ^5.0.0-0" } }, "sha512-p/KH9MnfNcsm3sR6x4lNgm5j+QN4Et8srKredl9DZfXiyZ1UQ3aQ2YVpFLbqktYN5JI+DB+VZFKM2PqE5hLKjQ=="], - "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.30.0", "", { "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA=="], + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.32.2", "", { "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-SWsVtH/0vULSQStoZ6xxH2K09Li8fXYTMC64ZeogCdpZ3XSi1eCPOByV1OpuJxuI3OcmHhosDWYyii07tpPsLw=="], "@napi-rs/canvas": ["@napi-rs/canvas@0.1.80", "", { "optionalDependencies": { "@napi-rs/canvas-android-arm64": "0.1.80", "@napi-rs/canvas-darwin-arm64": "0.1.80", "@napi-rs/canvas-darwin-x64": "0.1.80", "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.80", "@napi-rs/canvas-linux-arm64-gnu": "0.1.80", "@napi-rs/canvas-linux-arm64-musl": "0.1.80", "@napi-rs/canvas-linux-riscv64-gnu": "0.1.80", "@napi-rs/canvas-linux-x64-gnu": "0.1.80", "@napi-rs/canvas-linux-x64-musl": "0.1.80", "@napi-rs/canvas-win32-x64-msvc": "0.1.80" } }, "sha512-DxuT1ClnIPts1kQx8FBmkk4BQDTfI5kIzywAaMjQSXfNnra5UFU9PwurXrl+Je3bJ6BGsp/zmshVVFbCmyI+ww=="], @@ -88,19 +89,19 @@ "@napi-rs/canvas-win32-x64-msvc": ["@napi-rs/canvas-win32-x64-msvc@0.1.80", "", { "os": "win32", "cpu": "x64" }, "sha512-Z8jPsM6df5V8B1HrCHB05+bDiCxjE9QA//3YrkKIdVDEwn5RKaqOxCJDRJkl48cJbylcrJbW4HxZbTte8juuPg=="], - "@smithy/core": ["@smithy/core@3.33.3", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg=="], + "@smithy/core": ["@smithy/core@3.38.1", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-U/mB2XiwTLaf+NSgLSWwJfptsMT/H8aBi0aTAA/E5e2/TagFeGCqAyhKGG0w0A9IWTkm4qYEmLoD/HB6aYfnRA=="], "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.5.2", "", { "dependencies": { "@smithy/core": "^3.33.2", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg=="], "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.8.0", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA=="], - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.12.1", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw=="], + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.14.1", "", { "dependencies": { "@smithy/core": "^3.38.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-/T6E1jzCL0fErS9uq8JqES/5yYQQ4ppVmmYHwXw2nlov8KFzLb+3QqHR5iAun1BsuAB50IPxZliV8YMgghLwhA=="], - "@smithy/signature-v4": ["@smithy/signature-v4@5.7.3", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow=="], + "@smithy/signature-v4": ["@smithy/signature-v4@5.7.5", "", { "dependencies": { "@smithy/core": "^3.38.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-WPjdr5oWOk1LArpI4pavu+fSo+/evi0Re1olxGvqwuZopd4gYR1UGCi+Soyn/IjmafqbWs+ZC+3AKxJS3ZpwUg=="], - "@smithy/types": ["@smithy/types@4.18.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A=="], + "@smithy/types": ["@smithy/types@4.19.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q=="], - "@types/bun": ["@types/bun@1.4.2", "", { "dependencies": { "bun-types": "1.4.2" } }, "sha512-GimotNn7+ZV0uVArItBbriZsR1oNf0+WTzPkdcFrzShI7k2norL0uzEaJT8T33dWr7O/c9ZDuAFQrctKCi72oQ=="], + "@types/bun": ["@types/bun@1.4.4", "", { "dependencies": { "bun-types": "1.4.4" } }, "sha512-9wkRDXUXK124pEnAutE6n/l18j+i9GC5IAHK8TmX/2nlySETmky0OU6yL5U8pW1AoKh++AN9auDCr647BfurjQ=="], "@types/node": ["@types/node@25.4.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw=="], @@ -110,11 +111,11 @@ "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], - "body-parser": ["body-parser@2.3.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^2.0.0", "debug": "^4.4.3", "http-errors": "^2.0.1", "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", "qs": "^6.15.2", "raw-body": "^3.0.2", "type-is": "^2.1.0" } }, "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw=="], + "body-parser": ["body-parser@2.4.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^2.1.0", "debug": "^4.4.3", "http-errors": "^2.0.1", "iconv-lite": "^0.7.3", "on-finished": "^2.4.1", "qs": "^6.16.1", "raw-body": "^3.0.2", "type-is": "^2.1.0" } }, "sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ=="], "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], - "bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="], + "bun-types": ["bun-types@1.4.4", "", { "dependencies": { "@types/node": "*", "undici-types": "*" } }, "sha512-yjrJh5oGX7mMPKGd19YXyIjmEuj4G4zNC30bs7PM9Az7NQ3ndF3j6hbeRdvJTRQEhJ/FYQwW0a2moweEi2hMxQ=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], @@ -164,7 +165,7 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - "fast-uri": ["fast-uri@3.1.8", "", {}, "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg=="], + "fast-uri": ["fast-uri@3.1.9", "", {}, "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ=="], "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], @@ -184,7 +185,7 @@ "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - "hono": ["hono@4.13.7", "", {}, "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ=="], + "hono": ["hono@4.13.16", "", {}, "sha512-AOLOEhvrV+iH92xXCnFr/5+3KjPKcI3xP63XJtX5spAnkznPdHijlIsUTpi7/9EhWqrTCekw5c5zh1K+YsVw7A=="], "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], @@ -192,7 +193,7 @@ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], - "ip-address": ["ip-address@10.7.0", "", {}, "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA=="], + "ip-address": ["ip-address@10.7.6", "", {}, "sha512-00LYkM6byILa9eQIx6qoaXCM40xTLd56AZ4vyaPW3YTyb49VZYPo5xsiAq4tuQ54GH4R7gVdYScJ1B7B77PuTg=="], "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], @@ -240,9 +241,9 @@ "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], - "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + "proxy-addr": ["proxy-addr@2.0.8", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ=="], - "qs": ["qs@6.16.0", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA=="], + "qs": ["qs@6.17.1", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-jd3COkaKVgGUW+ZHyEHCG9bH7RoaaiWuMgzsIBjUMVjLAaWGWpoUAVwljVvBHxRu/2qEHnadLGZrkutYUBPQJA=="], "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], @@ -272,17 +273,17 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "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" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "sqlite-vec": ["sqlite-vec@0.1.7-alpha.2", "", { "optionalDependencies": { "sqlite-vec-darwin-arm64": "0.1.7-alpha.2", "sqlite-vec-darwin-x64": "0.1.7-alpha.2", "sqlite-vec-linux-arm64": "0.1.7-alpha.2", "sqlite-vec-linux-x64": "0.1.7-alpha.2", "sqlite-vec-windows-x64": "0.1.7-alpha.2" } }, "sha512-rNgRCv+4V4Ed3yc33Qr+nNmjhtrMnnHzXfLVPeGb28Dx5mmDL3Ngw/Wk8vhCGjj76+oC6gnkmMG8y73BZWGBwQ=="], + "sqlite-vec": ["sqlite-vec@0.1.9", "", { "optionalDependencies": { "sqlite-vec-darwin-arm64": "0.1.9", "sqlite-vec-darwin-x64": "0.1.9", "sqlite-vec-linux-arm64": "0.1.9", "sqlite-vec-linux-x64": "0.1.9", "sqlite-vec-windows-x64": "0.1.9" } }, "sha512-L7XJWRIBNvR9O5+vh1FQ+IGkh/3D2AzVksW5gdtk28m78Hy8skFD0pqReKH1Yp0/BUKRGcffgKvyO/EON5JXpA=="], - "sqlite-vec-darwin-arm64": ["sqlite-vec-darwin-arm64@0.1.7-alpha.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-raIATOqFYkeCHhb/t3r7W7Cf2lVYdf4J3ogJ6GFc8PQEgHCPEsi+bYnm2JT84MzLfTlSTIdxr4/NKv+zF7oLPw=="], + "sqlite-vec-darwin-arm64": ["sqlite-vec-darwin-arm64@0.1.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jSsZpE42OfBkGL/ItyJTVCUwl6o6Ka3U5rc4j+UBDIQzC1ulSSKMEhQLthsOnF/MdAf1MuAkYhkdKmmcjaIZQg=="], - "sqlite-vec-darwin-x64": ["sqlite-vec-darwin-x64@0.1.7-alpha.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-jeZEELsQjjRsVojsvU5iKxOvkaVuE+JYC8Y4Ma8U45aAERrDYmqZoHvgSG7cg1PXL3bMlumFTAmHynf1y4pOzA=="], + "sqlite-vec-darwin-x64": ["sqlite-vec-darwin-x64@0.1.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-KDlVyqQT7pnOhU1ymB9gs7dMbSoVmKHitT+k1/xkjarcX8bBqPxWrGlK/R+C5WmWkfvWwyq5FfXfiBYCBs6PlA=="], - "sqlite-vec-linux-arm64": ["sqlite-vec-linux-arm64@0.1.7-alpha.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-6Spj4Nfi7tG13jsUG+W7jnT0bCTWbyPImu2M8nWp20fNrd1SZ4g3CSlDAK8GBdavX7wRlbBHCZ+BDa++rbDewA=="], + "sqlite-vec-linux-arm64": ["sqlite-vec-linux-arm64@0.1.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-5wXVJ9c9kR4CHm/wVqXb/R+XUHTdpZ4nWbPHlS+gc9qQFVHs92Km4bPnCKX4rtcPMzvNis+SIzMJR1SCEwpuUw=="], - "sqlite-vec-linux-x64": ["sqlite-vec-linux-x64@0.1.7-alpha.2", "", { "os": "linux", "cpu": "x64" }, "sha512-IcgrbHaDccTVhXDf8Orwdc2+hgDLAFORl6OBUhcvlmwswwBP1hqBTSEhovClG4NItwTOBNgpwOoQ7Qp3VDPWLg=="], + "sqlite-vec-linux-x64": ["sqlite-vec-linux-x64@0.1.9", "", { "os": "linux", "cpu": "x64" }, "sha512-w3tCH8xK2finW8fQJ/m8uqKodXUZ9KAuAar2UIhz4BHILfpE0WM/MTGCRfa7RjYbrYim5Luk3guvMOGI7T7JQA=="], - "sqlite-vec-windows-x64": ["sqlite-vec-windows-x64@0.1.7-alpha.2", "", { "os": "win32", "cpu": "x64" }, "sha512-TRP6hTjAcwvQ6xpCZvjP00pdlda8J38ArFy1lMYhtQWXiIBmWnhMaMbq4kaeCYwvTTddfidatRS+TJrwIKB/oQ=="], + "sqlite-vec-windows-x64": ["sqlite-vec-windows-x64@0.1.9", "", { "os": "win32", "cpu": "x64" }, "sha512-y3gEIyy/17bq2QFPQOWLE68TYWcRZkBQVA2XLrTPHNTOp55xJi/BBBmOm40tVMDMjtP+Elpk6UBUXdaq+46b0Q=="], "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], @@ -302,12 +303,22 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "zod": ["zod@4.5.4", "", {}, "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA=="], + "zod": ["zod@4.6.7", "", {}, "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg=="], "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "@smithy/credential-provider-imds/@smithy/core": ["@smithy/core@3.33.3", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg=="], + + "@smithy/credential-provider-imds/@smithy/types": ["@smithy/types@4.18.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A=="], + + "@smithy/fetch-http-handler/@smithy/core": ["@smithy/core@3.33.3", "", { "dependencies": { "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg=="], + + "@smithy/fetch-http-handler/@smithy/types": ["@smithy/types@4.18.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A=="], + "body-parser/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="], + "body-parser/iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="], + "body-parser/type-is": ["type-is@2.1.0", "", { "dependencies": { "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA=="], } } diff --git a/daemon/package.json b/daemon/package.json index 12ea63eb..0d12ebb3 100644 --- a/daemon/package.json +++ b/daemon/package.json @@ -17,22 +17,23 @@ "test:performance": "bun run src/test/performance/large-library-performance.ts" }, "dependencies": { - "@aws-sdk/client-s3": "^3.1128.0", - "@modelcontextprotocol/sdk": "^1.30.0", - "hono": "^4.13.7", + "@aws-sdk/client-s3": "^3.1161.0", + "@modelcontextprotocol/sdk": "^1.32.2", + "hono": "^4.13.16", "pdf-parse": "^2.4.5", - "sqlite-vec": "^0.1.7-alpha.2", - "zod": "^4.3.6" + "sqlite-vec": "^0.1.9", + "zod": "^4.6.7" }, "devDependencies": { - "@types/bun": "^1.2" + "@types/bun": "^1.4.4" }, "overrides": { - "@hono/node-server": "1.19.15", - "body-parser": "2.3.0", - "fast-uri": "3.1.8", - "ip-address": "10.7.0", + "@hono/node-server": "2.1.6", + "body-parser": "2.4.0", + "fast-uri": "3.1.9", + "ip-address": "10.7.6", "path-to-regexp": "8.4.2", - "qs": "6.16.0" + "proxy-addr": "2.0.8", + "qs": "6.17.1" } } diff --git a/daemon/src/backup/package.ts b/daemon/src/backup/package.ts index 490f145b..33d5c73f 100644 --- a/daemon/src/backup/package.ts +++ b/daemon/src/backup/package.ts @@ -57,7 +57,7 @@ function assertPassword(password: string): void { } } -function randomBytes(length: number): Uint8Array { +function randomBytes(length: number): Uint8Array { const bytes = new Uint8Array(length); crypto.getRandomValues(bytes); return bytes; @@ -67,7 +67,7 @@ function toBase64(bytes: Uint8Array): string { return Buffer.from(bytes).toString("base64"); } -function fromBase64(value: string): Uint8Array { +function fromBase64(value: string): Uint8Array { return new Uint8Array(Buffer.from(value, "base64")); } @@ -113,7 +113,7 @@ function assertExtractionTargetAvailable(outputDir: string): void { async function deriveKey( password: string, - salt: Uint8Array, + salt: Uint8Array, usages: KeyUsage[] ): Promise { const keyMaterial = await crypto.subtle.importKey( @@ -148,7 +148,7 @@ function encodePackage(metadata: PackageMetadata, ciphertext: Uint8Array): Uint8 return output; } -function decodePackage(bytes: Uint8Array): { metadata: PackageMetadata; ciphertext: Uint8Array } { +function decodePackage(bytes: Uint8Array): { metadata: PackageMetadata; ciphertext: Uint8Array } { if (bytes.length < magicBytes.length + 4) { throw new BackupPackageError("Encrypted backup package is malformed"); } diff --git a/daemon/src/test/bookmark-media.test.ts b/daemon/src/test/bookmark-media.test.ts index 938effae..301b6a1b 100644 --- a/daemon/src/test/bookmark-media.test.ts +++ b/daemon/src/test/bookmark-media.test.ts @@ -16,7 +16,7 @@ import { function imageResponse(opts: { url: string; contentType?: string; - body?: Uint8Array; + body?: Uint8Array; contentLength?: string; }): Response { const headers = new Headers({ diff --git a/package-lock.json b/package-lock.json index 301f3b14..f175dc82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,8 +60,7 @@ "sonner": "^1.7.4", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", - "vaul": "^0.9.9", - "zod": "^3.25.76" + "vaul": "^0.9.9" }, "devDependencies": { "@eslint/js": "^9.32.0", @@ -90,16 +89,16 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", - "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", "dev": true, "license": "MIT" }, "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.3.0.tgz", + "integrity": "sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA==", "license": "MIT", "engines": { "node": ">=10" @@ -109,14 +108,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "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", "peer": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -136,9 +135,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.10.tgz", + "integrity": "sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -640,9 +639,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "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": { @@ -672,9 +671,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "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": { @@ -682,34 +681,37 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "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.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", - "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", + "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.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", + "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": { @@ -720,20 +722,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.7.tgz", + "integrity": "sha512-F42g89Qd5oAWtp0k0nnSrjziAKza7w8SVT4mStc18LZMaRb4J1HQAHLCalEtDCxrTuksx7NU9qsmeLwpOfPqWw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "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.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^4.3.2", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -757,9 +759,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", - "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", + "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": { @@ -770,9 +772,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "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": { @@ -780,13 +782,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", - "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", + "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.15.1", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { @@ -794,31 +796,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", - "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.10" + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", - "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.2", - "@floating-ui/utils": "^0.2.10" + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", - "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.2" + "@floating-ui/dom": "^1.8.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -826,9 +828,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, "node_modules/@hookform/resolvers": { @@ -906,35 +908,14 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -946,51 +927,22 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@napi-rs/lzma-linux-x64-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", - "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1026,59 +978,49 @@ "node": ">= 8" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@playwright/test": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", - "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.64.1.tgz", + "integrity": "sha512-IaYGml/nSOiZWROfPtuIL7neuu9qDOZ3TNvNljUIrhDMxiGTgPjzj/g9p9RxpS2tSepPDRY+UwAaEeiKtUvIAg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.2" + "playwright": "1.64.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz", + "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", - "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.2.0.tgz", + "integrity": "sha512-KABY+VMIRPJL+Vyzv/335FEhXXD/xDv8BMb1kl48/aXJZMH0LtHCTx5ga5RnxaEP3nZHtmTLf1P9vanmFX46bw==", "license": "MIT" }, "node_modules/@radix-ui/react-accordion": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.11.tgz", - "integrity": "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.3.1.tgz", + "integrity": "sha512-lCZ6sbGS/7WO0j84yx4srIgOf0MRJ/sZ13RonADXxvKBym8xrxNCq5f6DibGcr38sIlwPk8/52uYdXeOPsbEDw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collapsible": "1.1.11", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collapsible": "1.2.1", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -1096,17 +1038,16 @@ } }, "node_modules/@radix-ui/react-alert-dialog": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.14.tgz", - "integrity": "sha512-IOZfZ3nPvN6lXpJTBCunFQPRSvK8MDgSc1FB85xnIpUKOw9en0dJj8JmCAxV7BiZdtYlUpmrQjoTFkVYtdoWzQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.2.1.tgz", + "integrity": "sha512-MWC4N7RY+qsbNrFNo7yQ9ZbdoZEW+B5DtpWxJfUnVCqcQxxqqg3qis3RMPTDbCNaTIdHJSn5XDkl9ZdVWXknLg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dialog": "1.1.14", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dialog": "1.3.1", + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -1124,12 +1065,12 @@ } }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.17.tgz", + "integrity": "sha512-67jjcVvxjXCCStnTW3Z+M7jmaFMuMR7M2JgpDzH4w7JSRrikmzhjfYgP/09ECb8n7whnsgh1ifJ+Ie96qEj+pQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -1147,12 +1088,12 @@ } }, "node_modules/@radix-ui/react-aspect-ratio": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", - "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.2.0.tgz", + "integrity": "sha512-gHEU+Lx8DlT/FYIjZQvvBJrFSwUngXTjh7FeL9QvJaNALDLez6pgDj2axCUihBjtPBy82LN0gNb25+sTcSXNmA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -1170,16 +1111,17 @@ } }, "node_modules/@radix-ui/react-avatar": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", - "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.3.1.tgz", + "integrity": "sha512-ssZOkfQNkFpYVmCPQlr978xSaU7moSrGXdwg4j2Xs2WlGl/1KsSZtfpK+WnLnx0Rwll1BAh6oUrAy/uR31SBvQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-is-hydrated": "0.1.0", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1197,19 +1139,18 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz", - "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.4.1.tgz", + "integrity": "sha512-KWtwhh+98ML3seZ9vO9yRY2OwaQG90dCiDAxjpSNY2AaZ3Hik3B0dsk6m0ILywo/no3A9/SozadyPMNweVT8yw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-size": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -1227,19 +1168,19 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz", - "integrity": "sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.2.1.tgz", + "integrity": "sha512-fSzLb/qy1wuZSxQBcxpW0hNXYHDMWiIXDGyJGdA4+FSLknOWZsNRrTCUavxb4PI8b8lvHo/CysO6NVi5zLpo5g==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1257,15 +1198,16 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.2.0.tgz", + "integrity": "sha512-+yiQzqcc7Sy7/5s0jrMCjpPRFB3538VNrXPWdTLZhE/SCfgEws4aI6lHWN/vvcnyhHndROWBzqmqB4QBrITZ9Q==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1283,9 +1225,9 @@ } }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz", + "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1298,9 +1240,9 @@ } }, "node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.3.0.tgz", + "integrity": "sha512-v5AYEocMISkbJ+1fTXzZpiFv7NRr3D2WiYbLIKf+FkmJ8VkP6d503eV2n34MFussHXY1pcoq3yfJiQH77dc4Mg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1313,17 +1255,16 @@ } }, "node_modules/@radix-ui/react-context-menu": { - "version": "2.2.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.15.tgz", - "integrity": "sha512-UsQUMjcYTsBjTSXw0P3GO0werEQvUY2plgRQuKoCTtkNr45q1DiL51j4m7gxhABzZ0BadoXNsIbg7F3KwiUBbw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.4.1.tgz", + "integrity": "sha512-Pddn3Z8lio3/ChxyXaEP3jHTTo1LTHCWwF8+mG1chQlWijP+ttVHBKwezrQTiV6Mj670ojvumqvuGh+mdv33iQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-menu": "2.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -1341,25 +1282,26 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", - "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.3.1.tgz", + "integrity": "sha512-+0E4qvVTwjAWra9sEhJ+9BTsvHE00zkUuNw1VGh7S+Gc13dfYk+S1PVQdchWDj+XYHhAai7Z7IpzXVDCGsDplg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -1377,9 +1319,9 @@ } }, "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.2.0.tgz", + "integrity": "sha512-FtRA52a/r+LKStFT+neLUm+8vSe7wbzkbQGGeU8ixFiwC8NU14Evoq9ATECqL3eGbcUzJR4fyfA4KkK/q6dfqg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1392,16 +1334,16 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", - "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.2.1.tgz", + "integrity": "sha512-KIfDcAsx+oVylFZ4xryVKusJUrLLhTQmfnJW4kwk4Km5myvhHCrj04hnWWUC166+xD4DHdH8tQGylwYX1h6+Pg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-effect-event": "0.0.5" }, "peerDependencies": { "@types/react": "*", @@ -1419,18 +1361,18 @@ } }, "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz", - "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.2.1.tgz", + "integrity": "sha512-XsHcmYG2AcqnvTqrOXXWcMrhquEIlqucizuDH1MV/qMRW+DndpBCMvNeTRXOxqmG1H5j89M/+I0/34Zdd+zDcQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -1448,9 +1390,9 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", - "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.2.0.tgz", + "integrity": "sha512-MPm5R0iRGUDrDnPNxmLBkv+X7pN4XKzt+MbWJEuJQsH3NFH4omrbpXpucyYCCKTSt+na/ZxGhEWQrWTZ0285cA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1463,14 +1405,14 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.3.1.tgz", + "integrity": "sha512-ugeMhbXt4y5S2T1GnIqbWDKEN962PDwnX1fN0eKOOgf5f63Dh2mn8F1FUySlgW0iF6GiVsRF32DzuDIWTUyQJg==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -1488,20 +1430,21 @@ } }, "node_modules/@radix-ui/react-hover-card": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.14.tgz", - "integrity": "sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.2.1.tgz", + "integrity": "sha512-4QooHxgmpCKRjj1Pft+hETKidYcrbPKcVwMGtk2Oa5DcWY2IH1fHuQt9LG6q5hUQBBV2MhQxSvtx6B/C1xfiTw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -1519,12 +1462,12 @@ } }, "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz", + "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1537,12 +1480,12 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", - "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.17.tgz", + "integrity": "sha512-xmj7MN/drx1oUAXkfiFIvyDmGNUIN/omGobvA5oAoNqu9zO2MkISYGZOkBcqSzs/UZXXwV+/3ACRE7q7mGcmkA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -1560,29 +1503,29 @@ } }, "node_modules/@radix-ui/react-menu": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz", - "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.2.1.tgz", + "integrity": "sha512-G34BsU90SBj5foYpz8pQqq/Q0Dlfyyl6KitWEfRwXC0QvfwhWNAwS49DWP2+rRJ0iwv20Z2Qx7Sk+T03bGo5JA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -1600,21 +1543,21 @@ } }, "node_modules/@radix-ui/react-menubar": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.15.tgz", - "integrity": "sha512-Z71C7LGD+YDYo3TV81paUs8f3Zbmkvg6VLRQpKYfzioOE6n7fOhA3ApK/V/2Odolxjoc4ENk8AYCjohCNayd5A==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.2" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.2.1.tgz", + "integrity": "sha512-bRTYtS9JITV2dUYqYZb7+N5SooQBkZrNRejfmyrSKe3Y57aXhKgx//kBUP0kY7pEpsWR/U1AHsAJRzjwCrK3PA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -1632,25 +1575,26 @@ } }, "node_modules/@radix-ui/react-navigation-menu": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.13.tgz", - "integrity": "sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.4.1.tgz", + "integrity": "sha512-XPPZjkeyCSMNNvt0FyDv/PUauG7Ow4GwHQ/XZSwW36F/TS7rR4HFTsXH8ewLnXTOLn3x96/pmTPNQIVoTX/86g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-previous": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13" }, "peerDependencies": { "@types/react": "*", @@ -1668,26 +1612,27 @@ } }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz", - "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.3.1.tgz", + "integrity": "sha512-ZNxvXRx5W2Wos4fXCXb5lpdqN0Z5chf+mStOUOTr4ik7d+62MRvoe9rzCA/eGNg36lxXqSrKEKmwuZEcUrIstw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -1705,21 +1650,21 @@ } }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", - "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.4.0.tgz", + "integrity": "sha512-yCWRvLeGv9Pz3+efwHqGPp70mZ56r3kfIgQVF56Oj2aAa4uP/Tb+IE59wNcc+758rctqbCKx4LbK8II/r7Bn0Q==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" + "@radix-ui/react-arrow": "1.1.17", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-rect": "1.1.4", + "@radix-ui/react-use-size": "1.1.5", + "@radix-ui/rect": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1737,13 +1682,13 @@ } }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.2.0.tgz", + "integrity": "sha512-StX7xXnaRU41VvFtMm9zlhVGz8XF6GmWWTXftkQaY+tqVkbs/R9UmAp5mLzHHapk5hM9RMZQvO/3usyIP/g42g==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1761,13 +1706,12 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", - "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.11.tgz", + "integrity": "sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1785,12 +1729,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.2.0.tgz", + "integrity": "sha512-HCTSPMNqv55Qk0IX4geJbpyXazmqulcimwuyjxTkKi29v+QZbG2Zho9BnbBq4YS2PF+KlNb2CXoLz66uUmblkg==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-slot": "1.5.0" }, "peerDependencies": { "@types/react": "*", @@ -1808,13 +1752,13 @@ } }, "node_modules/@radix-ui/react-progress": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", - "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.2.1.tgz", + "integrity": "sha512-yQBiM6J3YM8Ums1orkEFpbznK47geKxa0igikzcaS1xHgdba3DdAQBsGbCTt5BVfR8zhEvgxQ0poGcINaD3lvw==", "license": "MIT", "dependencies": { - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -1832,21 +1776,20 @@ } }, "node_modules/@radix-ui/react-radio-group": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.7.tgz", - "integrity": "sha512-9w5XhD0KPOrm92OTTE0SysH3sYzHsSTHNvZgUBo/VZ80VdYyB5RneDbc0dKpURS24IxkoFRu/hI0i4XyfFwY6g==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.5.1.tgz", + "integrity": "sha512-QbyVT1ddnjqB9H+CUYKkNWdU9fIK3QHCYtjf7mS6ekSqiuXkWtWn5UZW9mhA8qtl3vrVyIsmR9gePstAtKrqkw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-size": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -1864,20 +1807,22 @@ } }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", - "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.2.1.tgz", + "integrity": "sha512-UwraORzVUeEPMclhO1p0vz0qI+TbdDLO9i+FiOqhJyHKwdpCRCck9yVEscUnAMIzCiuNoQa8D4A9bIpOPXGt6Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1895,20 +1840,21 @@ } }, "node_modules/@radix-ui/react-scroll-area": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.9.tgz", - "integrity": "sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.4.0.tgz", + "integrity": "sha512-CFrLqHNejWq5FhKAcj9V/WPGRsol76HBQto81NdOBVFEOqIEkJkKIJt0Z824A/9hHLCtoiR/Kw3euRgzXP2pxg==", "license": "MIT", "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1926,32 +1872,32 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.5.tgz", - "integrity": "sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.4.1.tgz", + "integrity": "sha512-888ZwW0Md6GyptuqYABRX9nLKgoYfcooCyBBvVaX5Jp3e+8Jp2i4Zo/Uy50Hm+Ysn2JfloQXstW4U36w8teVtg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -1969,12 +1915,12 @@ } }, "node_modules/@radix-ui/react-separator": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", - "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.2.0.tgz", + "integrity": "sha512-1jUAap0wZEqVP05Ou7kJgRxe/W+Qftng+rUNWGa0qkKbv9r5pWTG3E7a3ELKo2eJoHKMECnzuYrZpSyO1YgcYQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -1992,22 +1938,21 @@ } }, "node_modules/@radix-ui/react-slider": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.5.tgz", - "integrity": "sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.6.1.tgz", + "integrity": "sha512-IRNRR90moPqxfwCJ0XbMJIxo70W0/1ZExT/sNCxEHMaPx0SF9HoQrcPEC75+H28cFKa0b+KH63anfLYJmwKacw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-size": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -2025,12 +1970,12 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.5.0.tgz", + "integrity": "sha512-tyYd9ddPXAysAbdbD9eYxgwpCSv6f3PncqVSNKQFSR5lcJVLz3cb/pANDoYrLiHBpXv7skortyUgGUWsYuPPFQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" + "@radix-ui/react-compose-refs": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -2043,18 +1988,17 @@ } }, "node_modules/@radix-ui/react-switch": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.5.tgz", - "integrity": "sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.4.1.tgz", + "integrity": "sha512-NpBGwc40rY02ZmSvuyeKk0Bvc8ZsNeTMi4qHvJ+ZH4EiYCv0zIXEgdCW4bVdzgIUeP9xxbLJSxKOUfqITYNmkA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-size": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -2072,19 +2016,19 @@ } }, "node_modules/@radix-ui/react-tabs": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.12.tgz", - "integrity": "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.2.1.tgz", + "integrity": "sha512-hRoJlode+hg5ZNlR+3tkfkUliIybdTpD5lkAvHQ9yaXseGf7XVO9Ib2GPEIOuaJJbo7YWYbNpDDRfo8Dhf6/xA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -2102,23 +2046,23 @@ } }, "node_modules/@radix-ui/react-toast": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.14.tgz", - "integrity": "sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.3.1.tgz", + "integrity": "sha512-iQvL0J7XK4HtJNGkkWMyYrboNseI7vtotFeUkIno8YNxVA9oM7B6//fh0Mc6TSKI96+zioLWi98lQLso88yJmQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13" }, "peerDependencies": { "@types/react": "*", @@ -2136,14 +2080,14 @@ } }, "node_modules/@radix-ui/react-toggle": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.9.tgz", - "integrity": "sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.2.1.tgz", + "integrity": "sha512-+3MUq+WyiBplXYqQ0EIYlq8R4sLQ0T5NbOK7DMdDLCKO93pe2uE0DUJTWWfTBprpJJXxfoF3eMW0xpakVZrYsg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -2161,18 +2105,18 @@ } }, "node_modules/@radix-ui/react-toggle-group": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.10.tgz", - "integrity": "sha512-kiU694Km3WFLTC75DdqgM/3Jauf3rD9wxeS9XtyWFKsBUeZA337lC+6uUazT7I1DhanZ5gyD5Stf8uf2dbQxOQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.2.1.tgz", + "integrity": "sha512-O8Ldx5ao4p4KoW+DO8/PmkOe5mdKNi3F2SseqjVj88wvDGDHe60cUmO0Zm/uHsKrvNgQGV8Efpuh95Tht/h4vw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-toggle": "1.1.9", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-toggle": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0" }, "peerDependencies": { "@types/react": "*", @@ -2190,23 +2134,25 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", - "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-visually-hidden": "1.2.3" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.4.1.tgz", + "integrity": "sha512-NxLFGSFtZ78zVfcoOhTwR1xwqo5qx1Jh8Pw6FMZ9McCaqfRzz7/gIRahs2Oy5XlPgQ+8QkUcKbN5B0U44J/kCg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13" }, "peerDependencies": { "@types/react": "*", @@ -2224,28 +2170,12 @@ } }, "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.5.tgz", + "integrity": "sha512-Y5GBf4NKeADoXI1geiMlMuMoURT3k9MizzzKhGb/m55H94aGigZ01PIpkvsO6lML13BA6XYAXSJ6gza7vTn5nw==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2257,13 +2187,15 @@ } } }, - "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.3.0.tgz", + "integrity": "sha512-TAcBI7bw2ljYCbv4+zuTSd6zICu8pRt6SDN2vJ/Z06K2MXh6I9WYFe/A9ovlFDtR5HVHGm5iDxDoABm/++dbKg==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2275,13 +2207,13 @@ } } }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz", + "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2294,13 +2226,10 @@ } }, "node_modules/@radix-ui/react-use-is-hydrated": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", - "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz", + "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==", "license": "MIT", - "dependencies": { - "use-sync-external-store": "^1.5.0" - }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2312,9 +2241,9 @@ } }, "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz", + "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2327,9 +2256,9 @@ } }, "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz", + "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2342,12 +2271,12 @@ } }, "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz", + "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==", "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.1" + "@radix-ui/rect": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2360,12 +2289,12 @@ } }, "node_modules/@radix-ui/react-use-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.5.tgz", + "integrity": "sha512-V1McDQkMGzgivwqdu7u96APs7oi0Jvj9LTzgq3WWrDZqxWdAqU9yZnZQqk5OizGFR8badUQwZsrlao7MOlWYOA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2378,12 +2307,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.13.tgz", + "integrity": "sha512-feijiN1oPk4rck4u9Dm9tsU4mT6Wp9oeEEhaz1WUEs1VuqLf8xzsFG+Qk+uWq6TnMH9O+WRECRg0NftyP9E4Fw==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.2.0" }, "peerDependencies": { "@types/react": "*", @@ -2401,9 +2330,9 @@ } }, "node_modules/@radix-ui/rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz", + "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==", "license": "MIT" }, "node_modules/@rolldown/pluginutils": { @@ -2414,9 +2343,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.4.tgz", - "integrity": "sha512-I+BSHzTAhKN2n7ZwGZsegGcZjDpLqFOMAtJz/u6uFGe0pUFbq56dEHjqJV/ZUdRJtNXNxA+hREUatZBvMR3Oiw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.67.5.tgz", + "integrity": "sha512-FdWPeulkH+FH+rBzyKBD59tuVN4tRKvmVilSJm0OcnoYsQTpd9UhD78OaPcsYqo2fX6hCwAG0YIjrDLoQ3pR3g==", "cpu": [ "arm" ], @@ -2428,9 +2357,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.4.tgz", - "integrity": "sha512-pu3BdjS2LtEzRu2elmGzS3fIeWSZy4BMDIaLNwjorO76+k2d0LMluijhsDx3KQyQBQ/lLUZCQA9/s6csvUfuhw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.67.5.tgz", + "integrity": "sha512-bmkDuBGnF+Ji8atWlXcNjxIC52ShCbdXPbW7Nz0lRoCFi1lrvsO0XobJY36kTj7duc1vOmGJeQ9vtVuGjnzihA==", "cpu": [ "arm64" ], @@ -2441,10 +2370,24 @@ "android" ] }, + "node_modules/@rollup/rollup-android-x64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-x64/-/rollup-android-x64-4.67.5.tgz", + "integrity": "sha512-6KvVfnqPTqmbQ5YobMl9HYiSymAsCt8HlNeriDshwJQcveXwT+vIMW6wGL1RcJbXH9+r3BAJvjab5+rIgtSEqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.4.tgz", - "integrity": "sha512-xfSrj9MHnWK9GaSqT9U0ImHtH/N8WZlHLx4cZHiuLcqs640hvZ3hLPd5UR2AZS57FaE8HrRUSpltbZdWRxHiDA==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.67.5.tgz", + "integrity": "sha512-SNamgdrY69oPdBrQV9fKGo6PSmKcVhyn0D0jnDmcqgRJvrxQGGBhtekOHTUJ7TCgkW0nE8XMH9v2CwXmjNIzVA==", "cpu": [ "arm64" ], @@ -2456,9 +2399,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.4.tgz", - "integrity": "sha512-bqU99PLJb/dqb3S0GIMdeuyAEETSUgZBoqXYd3Sd+WCsV+MmPhnN6JrotWyir31+QgH7EvvE5/mwGJlEoci8Fw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.67.5.tgz", + "integrity": "sha512-HNdl34thiJtHDSglogjmAlQ296L8cc8zA7ODH65nnmY7E+jPP55WEbh8J5583rWFLMjxyYywxZuwPOwRvEi5tA==", "cpu": [ "x64" ], @@ -2470,9 +2413,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.4.tgz", - "integrity": "sha512-JinsFZ5G40oXQb+sUuiA5x689vhr6dDYK0H0NL+rwKdL6CqnmYN8PE4ZwfRSoIjrCxqTQG/SLfTtSvHeGxoVlw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.67.5.tgz", + "integrity": "sha512-WvZYtANNswfHzSNHaJAoG6Ipfc4SyZIDYuIjFdHv07xXxhHl+Xx8o+bNDWsxpOADFT2mKXcXVrfOG4OlWTLo8Q==", "cpu": [ "arm64" ], @@ -2484,9 +2427,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.4.tgz", - "integrity": "sha512-GAdA4UxpiNm27cLHr2GqXBpAD0x9FqwYBY7/YSP0Ss0/PNi4k8gbviqpIpYbVSRBaS2ZcegXEzgTQMbRNCwxCw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.67.5.tgz", + "integrity": "sha512-EUU+Wgf9NyHekceC+DxAdm42f6bq2ezH/7DEb/JnCb8SAUhG2xph5BiVukxplWal2m5pP8CzJZE+FLwRopywjQ==", "cpu": [ "x64" ], @@ -2498,9 +2441,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.4.tgz", - "integrity": "sha512-qDd6NoA1znaLjp4jR5U/KWCdLAKDJNB8W9ChbbDaKbo0xA+Atln5HK6LFCZ4oJQpemtRZA288DCirFRjrspptw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.67.5.tgz", + "integrity": "sha512-dgU1CvUuE2IkaJBAeuAbxpDdMHAdZBT5oth5u22DtuoMg4gXXYr2+Sm30RigPJG1F2VEoiGJUziGLuIh9+jPxA==", "cpu": [ "arm" ], @@ -2515,9 +2458,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.4.tgz", - "integrity": "sha512-WtB5Tz5KTNINb8ZA+8sQ7bmjuS1JrRT7YverYIhUGdWWDlpzVWmIwuZE+jidkEXUn1l0zrEkaIMa8dHF3NGcsA==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.67.5.tgz", + "integrity": "sha512-rdgJcJig2VngYlcTCRQw2BA8kLWM6QwDFe9uLFo81lya0jPC1r8wZu92sAvTUIv48GWlkRVi6/fpsa5CoFSKoQ==", "cpu": [ "arm" ], @@ -2532,9 +2475,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.4.tgz", - "integrity": "sha512-VcQ3L1tjnkKzWjryAVaFhHEWcqOfICX9uxVVoDzm2t0DpgKRHd2zOpVrJc0xsWeBZcBFyYROCIBdyR/fS174pg==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.67.5.tgz", + "integrity": "sha512-+jtCiQnrEFHWAUAcUpP7wppb1p6HKOgBP3mXx75cEYpDF2Y5MEqBky2HNz+osFuVx5uX44gnMTmbe5RJauzn6A==", "cpu": [ "arm64" ], @@ -2549,9 +2492,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.4.tgz", - "integrity": "sha512-6+ZQX6P5s0cMDN2Ypb8Lbm2+/sZYmZjdaYny992ujUU9UKi/4CWoJWsl1pNvjWJHNHGK51m+jKGLlh1ylb2ifQ==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.67.5.tgz", + "integrity": "sha512-heflX7ENhL8eHmLcUxDEHCSK8CKLyPprysb2JGoSTh5Ip7nHrzIRc+2USyxul3nxi98H8pGxJIEDEpURlS1X5A==", "cpu": [ "arm64" ], @@ -2566,9 +2509,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.4.tgz", - "integrity": "sha512-D72ZnvkFkBXOfzMMQLcwfPLyGkKb7HZ9/mf97B7v6/P5Lbv4oFOtSY/uHbS8lH6uKUOxoKiuokdb50XZSzzbJw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.67.5.tgz", + "integrity": "sha512-rRtNU0zBfRHkJ8pscHN9qRtUYLq8Rao4EX7aVWvKcFmJUANkCCXFRU7ovNBEMhpEONyUEB/3DRVDXwDDguSfHA==", "cpu": [ "loong64" ], @@ -2583,9 +2526,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.4.tgz", - "integrity": "sha512-piU6BxeqA3O9KSu3kRCIQQtNqFFaTu21SEV4FwaRZowpnj3bLaWPZHw+xFqCs0XlJ+aOH3PTRWGoglH+mKA/OA==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.67.5.tgz", + "integrity": "sha512-/6auyi9yj8MD/Q+8P+f2ay57jQ7a0j7Yp1JK86pecH6ZnRViQZ5GOjoRSjGArFeTSHFznRbM2QPQcBgDPyNMfQ==", "cpu": [ "loong64" ], @@ -2600,9 +2543,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.4.tgz", - "integrity": "sha512-/5PGpHwqt2EEEOUs1XwzubE/ucr0dWDQ+to3zqi4Ds7EWpwtQ79wXc4JBoxqj/OwpawTsKWzJxHfSuBOq3DrWA==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.67.5.tgz", + "integrity": "sha512-Hsc0vlt+vPvqzUkHKffWKf3YE/yexrY+yeFf7IsUvDC6PV7YGCsA/gJvPa+WJdgxGJnwuoO1HmLkbahaLKabYQ==", "cpu": [ "ppc64" ], @@ -2617,9 +2560,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.4.tgz", - "integrity": "sha512-cX3beZDLWt7G2oJF+nhChiT+qtaihs+S2xi7ziGmVB+2pwPng6D0Ed0HmElQOgv2UsUmSJJLGwpBao/3TDx3VA==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.67.5.tgz", + "integrity": "sha512-Jx5TMMSPJwHY7F/JwPdS6nuBwny2ECRK+EsAJV5HZrfiddeSS6ZrohkLkFZm3rjqBUuQ4FPX5gGMtakUuQO6fQ==", "cpu": [ "ppc64" ], @@ -2634,9 +2577,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.4.tgz", - "integrity": "sha512-1uz2mGWHyptR7DgHHrlbdRAjXK7v7elGZ9lMja910/RP+ZYbX6xAmCiU9UZSX4hqmgtHMv6lr5l3kq1HIOpcag==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.67.5.tgz", + "integrity": "sha512-fGWcq2lo/XCqAkBLOokg66D/z+MUouryB8i+QdU9RR6O5knG7rucc0WFPqWYL1Wk/wuiJouDfmyBxmZKRM9bag==", "cpu": [ "riscv64" ], @@ -2651,9 +2594,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.4.tgz", - "integrity": "sha512-nLS8topojxyz7SRpKR2IODRpQ0XPZ+xaOXvT3+hqK/Uy8Lo5HFgkkIBiIrCu5tL5YqzTvgovGw55PwpahTAGig==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.67.5.tgz", + "integrity": "sha512-JwO/Ys3jybc0UW3V5XO2CMnp0RhvoczDDQTgAEE1IctT+HRY3W5parIIWLUpmAK4gHSeeYJofm2iQPFA62K6ag==", "cpu": [ "riscv64" ], @@ -2668,9 +2611,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.4.tgz", - "integrity": "sha512-gs7DRKotr3l3q+jGPQBjH0ng1FjlEDm5ueQrkw5JtQvtLyEIcLASqAEaor56BhkKRzk+IcQzrcanBdb/bBQn8g==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.67.5.tgz", + "integrity": "sha512-vVD4iqel6J6A1xAJlb4mxEO9i1wOJ4/SkcKoDKAuK/wqEBPOA7/P5dDyZvNx46ocHwOUwzo3WjhTdKqET9kEAg==", "cpu": [ "s390x" ], @@ -2685,9 +2628,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.4.tgz", - "integrity": "sha512-791ET7W17NnScOZM7h4dX5hYspxE28htPFsb1awY/NRR8+PRNkS53e475rDdxXXDrP+kwnCcNWg9CX5ztn/Aqw==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.67.5.tgz", + "integrity": "sha512-HmEfNh5Cdd/NHxgqwMzKnjlvicQQA+D+w+vQXDJSV0x/aHiQSjVwh1Th5RoA7QsMieIaxibt/5iJq68BraTSUg==", "cpu": [ "x64" ], @@ -2702,9 +2645,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.4.tgz", - "integrity": "sha512-iwZQRcmj7g88g3tzefIrQY7qvmuA/cfYwhrDtTBhsmukO4U2huVO5W+86XacUMRvdSFVAc6kZUZy21JaRwiB9w==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.67.5.tgz", + "integrity": "sha512-NfmALpbe009nYzZ2QqlSW6nzbGddXpqk3nwualrIr+4QflQCTGMzt3QKK20yARiAnSV9fJdM5WNwIYUf31x3uA==", "cpu": [ "x64" ], @@ -2719,9 +2662,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.4.tgz", - "integrity": "sha512-dVHFp9gRWrdTpnqQuGfCwd7hOQDatK1VCP2iWhLY/cGrOQs/ucFzJ6A5SRqbXX12ZDI8EUuejSM5kwg+ja7Png==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.67.5.tgz", + "integrity": "sha512-ngcE7Udpy/iJ3lexVhYcbpUV2OJIakRGus3snc6K52BnAAJetDBG1Ku5Eh3CECtnW3mpBYWg5VCD4tTaOXKOVQ==", "cpu": [ "x64" ], @@ -2733,9 +2676,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.4.tgz", - "integrity": "sha512-t3NlauOW6gxZVVFcBEnO62Cb4wbyDFL416gTg1uFI/2tgqYQlf69FbSE115Ajre9I+c26Lk4mcmdFUsS/DGifQ==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.67.5.tgz", + "integrity": "sha512-DZ01A2EdTYX8xVeGoGiWkJBRWDh+/BOflwGPVsBay43PDxcq8ez0xuovZnPnk1xjE3CdI0pdZXxsJp/Xjmf7uQ==", "cpu": [ "arm64" ], @@ -2747,9 +2690,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.4.tgz", - "integrity": "sha512-xWuIaSye5FWZF8+UYtVEcHtRJDN5kN9Kfgxx3Kq8XIov9KSKbc1fiqQCm90SKrgQbUXZelbnUhnlUJmfSE7P9A==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.67.5.tgz", + "integrity": "sha512-nJKiMKDO140DUCEcQZl+f4HiGPMBxrW2webjuWJ2E3qPeoruHf2zByml4TP52lA1zDi6L4I92D/5stxeA/6pig==", "cpu": [ "arm64" ], @@ -2761,9 +2704,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.4.tgz", - "integrity": "sha512-9ALJJUOg/ZflMJepVo2PlgsGxSaxN7SQ4Z8GoZfVlarWr6r3rkHUNsd/zAio7p4YMtChSMXPionxej4Hkf6CXQ==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.67.5.tgz", + "integrity": "sha512-ykLkBCf+Kls24QmqM3IRf1T4sGMh0rXPyymtj+hXlWKPJnXbXraHqUUsKtOIxqLasjT1i7DhfQGAaZYeiHbSOw==", "cpu": [ "ia32" ], @@ -2775,9 +2718,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.4.tgz", - "integrity": "sha512-blj9z5qx/Pv4WU0W1NMFDB97e0JH5ed+aZGywW8WCvp/NhWX/4PFAq5uu6Q0AebNn+Vo6KzUYDT++JzTT5ojlQ==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.67.5.tgz", + "integrity": "sha512-NiFPUFw8cHhkmBlL1k1eaz+5AXXm89rztj+DQdDuQ7VGPM0+ADFhezQ2KcBMF50UEFzGUr0+DVjVND743XwKWQ==", "cpu": [ "x64" ], @@ -2789,9 +2732,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.4.tgz", - "integrity": "sha512-Erx822VRBwLa124shbj+wNXe//BOgMEctDV0m1aqTQdNO1S69DgNUCFKC1RCeZfixs1J31l6igk1ziyXErbigQ==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.67.5.tgz", + "integrity": "sha512-Khj/vrKCpdbiAWYbJAeSy4D5iep+qwW/86lNoKvdleJYGxgbRE7h87+5d5T9D7gt8NcqhNFpreRgIg8T4bLzKQ==", "cpu": [ "x64" ], @@ -2810,15 +2753,15 @@ "license": "MIT" }, "node_modules/@swc/core": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.2.tgz", - "integrity": "sha512-YWqn+0IKXDhqVLKoac4v2tV6hJqB/wOh8/Br8zjqeqBkKa77Qb0Kw2i7LOFzjFNZbZaPH6AlMGlBwNrxaauaAg==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.16.21.tgz", + "integrity": "sha512-sE2asan0US6gcp11oBDFJb5+s+ltaAPBcagVQGub1+qo+8TsQET2TmXfJCw/Oy0w1eEPp1rV1wsR/Umx2KXGcw==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.23" + "@swc/types": "^0.1.28" }, "engines": { "node": ">=10" @@ -2828,16 +2771,18 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.13.2", - "@swc/core-darwin-x64": "1.13.2", - "@swc/core-linux-arm-gnueabihf": "1.13.2", - "@swc/core-linux-arm64-gnu": "1.13.2", - "@swc/core-linux-arm64-musl": "1.13.2", - "@swc/core-linux-x64-gnu": "1.13.2", - "@swc/core-linux-x64-musl": "1.13.2", - "@swc/core-win32-arm64-msvc": "1.13.2", - "@swc/core-win32-ia32-msvc": "1.13.2", - "@swc/core-win32-x64-msvc": "1.13.2" + "@swc/core-darwin-arm64": "1.16.21", + "@swc/core-darwin-x64": "1.16.21", + "@swc/core-linux-arm-gnueabihf": "1.16.21", + "@swc/core-linux-arm64-gnu": "1.16.21", + "@swc/core-linux-arm64-musl": "1.16.21", + "@swc/core-linux-ppc64-gnu": "1.16.21", + "@swc/core-linux-s390x-gnu": "1.16.21", + "@swc/core-linux-x64-gnu": "1.16.21", + "@swc/core-linux-x64-musl": "1.16.21", + "@swc/core-win32-arm64-msvc": "1.16.21", + "@swc/core-win32-ia32-msvc": "1.16.21", + "@swc/core-win32-x64-msvc": "1.16.21" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" @@ -2849,9 +2794,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.2.tgz", - "integrity": "sha512-44p7ivuLSGFJ15Vly4ivLJjg3ARo4879LtEBAabcHhSZygpmkP8eyjyWxrH3OxkY1eRZSIJe8yRZPFw4kPXFPw==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.16.21.tgz", + "integrity": "sha512-VRreJpbRygpSD1hj3HBEOIA1xjXYnhB+IfcKsxZRhCIBGRP4UkqxZH4/ipFh/heIRp7EKQ56E8ygwEftLNCWXw==", "cpu": [ "arm64" ], @@ -2866,9 +2811,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.2.tgz", - "integrity": "sha512-Lb9EZi7X2XDAVmuUlBm2UvVAgSCbD3qKqDCxSI4jEOddzVOpNCnyZ/xEampdngUIyDDhhJLYU9duC+Mcsv5Y+A==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.16.21.tgz", + "integrity": "sha512-KqCJ04pMYDBUYpAOFGUFR8TEjqo4h0Vtwe/za9xNRDKsxSDnjgM7HVhfO0uNNpMMlM2ao2E6d0iLpApIRvNGnA==", "cpu": [ "x64" ], @@ -2883,9 +2828,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.2.tgz", - "integrity": "sha512-9TDe/92ee1x57x+0OqL1huG4BeljVx0nWW4QOOxp8CCK67Rpc/HHl2wciJ0Kl9Dxf2NvpNtkPvqj9+BUmM9WVA==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.16.21.tgz", + "integrity": "sha512-tLkw3uWxQj69qBRX5Xm8vbq+5iX5e/ktoPXhrDeFFa2jNMc+AWcxa0bqwatvVGK40v5mcmz6Ulu5Nk9jF8ciMA==", "cpu": [ "arm" ], @@ -2900,13 +2845,16 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.2.tgz", - "integrity": "sha512-KJUSl56DBk7AWMAIEcU83zl5mg3vlQYhLELhjwRFkGFMvghQvdqQ3zFOYa4TexKA7noBZa3C8fb24rI5sw9Exg==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.16.21.tgz", + "integrity": "sha512-lFHVlHB0B5C7FwyprWJQp7b2iF/ohj2RqnMiv8uCnFJc+rYP0Py2I7ftZ+rOX4Zu7Ra9eMk7GnmuxAywCZYUJQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2917,13 +2865,56 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.2.tgz", - "integrity": "sha512-teU27iG1oyWpNh9CzcGQ48ClDRt/RCem7mYO7ehd2FY102UeTws2+OzLESS1TS1tEZipq/5xwx3FzbVgiolCiQ==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.16.21.tgz", + "integrity": "sha512-gXDgrMMDsWT7r5gZsml10snBS9yaoVYwU9vGffa+DAts4ctEMrMHv+G8AH+ZxCV9gr5MfdgtGGQKjXjLay4mXQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.16.21.tgz", + "integrity": "sha512-hZF7J2YzXiADZ4eQxTFOWJcSSy3fbUR8/DcCXqiBHh0bVyLl2Y+O5pVWxk/r/XV5tA9n7DnnLlvkPPsHoajE9w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.16.21.tgz", + "integrity": "sha512-rmtGwkAlbl+fQMGrGUMklUmByueOmt1ju9sKsE5YWVA0KfFYM0W87WVx4lFYQXt+E4P3zkLjeqo/AUa5mFbF1A==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2934,13 +2925,16 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.2.tgz", - "integrity": "sha512-dRPsyPyqpLD0HMRCRpYALIh4kdOir8pPg4AhNQZLehKowigRd30RcLXGNVZcc31Ua8CiPI4QSgjOIxK+EQe4LQ==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.16.21.tgz", + "integrity": "sha512-EUJsyrFw3aNE64iQzk3bDqjADgl4l0vpxfwVMjMuZIooNg35yKqvkw3bYNEhQyrBDY0+5kKoiirGLpth3Wf3lA==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2951,13 +2945,16 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.2.tgz", - "integrity": "sha512-CCxETW+KkYEQDqz1SYC15YIWYheqFC+PJVOW76Maa/8yu8Biw+HTAcblKf2isrlUtK8RvrQN94v3UXkC2NzCEw==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.16.21.tgz", + "integrity": "sha512-ZXUnLjxTHxvNhVmQmYlb8XNKArfi/MiGoW5DmfuME8ttCLH9OJTqJVFy7g1yYxUCgw3tU6dF1uU59N8P/Yr5Pw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2968,9 +2965,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.2.tgz", - "integrity": "sha512-Wv/QTA6PjyRLlmKcN6AmSI4jwSMRl0VTLGs57PHTqYRwwfwd7y4s2fIPJVBNbAlXd795dOEP6d/bGSQSyhOX3A==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.16.21.tgz", + "integrity": "sha512-jnnQpAHiWZgEobVfOPvJJzm1Jh4ZEIKh2IqcDqHv6zJcjvaEkHdkt+qdRsJ9AqvK7g18WBRHTnvKm5IxdbkagA==", "cpu": [ "arm64" ], @@ -2985,9 +2982,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.2.tgz", - "integrity": "sha512-PuCdtNynEkUNbUXX/wsyUC+t4mamIU5y00lT5vJcAvco3/r16Iaxl5UCzhXYaWZSNVZMzPp9qN8NlSL8M5pPxw==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.16.21.tgz", + "integrity": "sha512-TaVTnNm9c1I+VG3hJUt11uspwbTrTQ9+fUPzODlvx4tj/ChYqUm4cKTIHw3O97hILxpmhBR0hbvLEs9seOV59A==", "cpu": [ "ia32" ], @@ -3002,9 +2999,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.2.tgz", - "integrity": "sha512-qlmMkFZJus8cYuBURx1a3YAG2G7IW44i+FEYV5/32ylKkzGNAr9tDJSA53XNnNXkAB5EXSPsOz7bn5C3JlEtdQ==", + "version": "1.16.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.16.21.tgz", + "integrity": "sha512-aPv58Clf6SdAQtouzDYKbEtcCETY2hOXlrHgSFnFIJQOlMWINHSGazaM1Iv63/9wOUDPq6+0ZFytMqnPtER9OQ==", "cpu": [ "x64" ], @@ -3026,9 +3023,9 @@ "license": "Apache-2.0" }, "node_modules/@swc/types": { - "version": "0.1.23", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz", - "integrity": "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==", + "version": "0.1.28", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.28.tgz", + "integrity": "sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3036,38 +3033,22 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", - "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.20.tgz", + "integrity": "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==", "dev": true, "license": "MIT", "dependencies": { - "lodash.castarray": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" - } - }, - "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" + "tailwindcss": ">=3.0.0 || >=4.0.0 || insiders" } }, "node_modules/@tanstack/query-core": { - "version": "5.83.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.0.tgz", - "integrity": "sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==", + "version": "5.105.3", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.105.3.tgz", + "integrity": "sha512-v1rbNy7MB/4Akth7CQH+CerV13K7Ok9hAusEsfz4sCjDdu3/kOSJPoWfoB+YjdEX1eBFBWKNAGE5nqZCgdlHDw==", "license": "MIT", "funding": { "type": "github", @@ -3075,25 +3056,31 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.83.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.83.0.tgz", - "integrity": "sha512-/XGYhZ3foc5H0VM2jLSD/NyBRIOK4q9kfeml4+0x2DlL6xVuAcVEW+hTlTapAmejObg0i3eNqhkr2dT+eciwoQ==", + "version": "5.105.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.105.3.tgz", + "integrity": "sha512-dj5hGWZmwoc9NG4enoXuYbiYwb5FxgJYPVv06eUgicMTfEMTRXn08Xv9D/r1V8TfjAv+BpxdvZFzJ1h3hSWZcQ==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.83.0" + "@tanstack/query-core": "5.105.3" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { + "@types/react": "^18 || ^19", "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@testing-library/dom": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.2.tgz", + "integrity": "sha512-yzr2S9HyAIdhz2/6qHgbs665Q7PKVcDF05vsOlHPxG1mo36gKVesdYVeDLnXgfjJ03CrKRk08knc6+E/9m8v2Q==", "dev": true, "license": "MIT", "peer": true, @@ -3139,9 +3126,9 @@ "license": "MIT" }, "node_modules/@testing-library/react": { - "version": "16.3.2", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", - "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.3.tgz", + "integrity": "sha512-Uo193NgQbPMz6lrrhtRQQFcMC6Re/ELLFbbuVL30WDlZxlpZf9/lMHTAVxPRLw1q1iu9OJmR1c2BLiENRstdBg==", "dev": true, "license": "MIT", "dependencies": { @@ -3167,9 +3154,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "version": "14.6.8", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.8.tgz", + "integrity": "sha512-vgSSqnANMnkcYR/vUNDbwS7aM3OErRLNUG8vCVVlj4oc6cKffUrccX7UAS5AmJQQNZTSibi9z5GvvRZ0aYgUCQ==", "dev": true, "license": "MIT", "engines": { @@ -3210,9 +3197,9 @@ } }, "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", "license": "MIT" }, "node_modules/@types/d3-color": { @@ -3237,33 +3224,33 @@ } }, "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "license": "MIT" }, "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", "license": "MIT", "dependencies": { "@types/d3-time": "*" } }, "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==", "license": "MIT", "dependencies": { "@types/d3-path": "*" } }, "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", "license": "MIT" }, "node_modules/@types/d3-timer": { @@ -3273,9 +3260,9 @@ "license": "MIT" }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -3289,9 +3276,9 @@ "license": "MIT" }, "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==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz", + "integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==", "license": "MIT" }, "node_modules/@types/estree-jsx": { @@ -3304,9 +3291,9 @@ } }, "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -3335,9 +3322,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.16.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.5.tgz", - "integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==", + "version": "22.20.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.5.tgz", + "integrity": "sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==", "dev": true, "license": "MIT", "dependencies": { @@ -3345,19 +3332,19 @@ } }, "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.23", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", - "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", "license": "MIT", "dependencies": { "@types/prop-types": "*", - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { @@ -3377,21 +3364,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", - "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.1.tgz", + "integrity": "sha512-5CokTWXpmbylfFabsbvHC0CAw3XLaGnoa+nFJX5FR592h/LoZsENUE6p/rg5xvkKrFEXz6pYmgI29AgXc2N3BQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/type-utils": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.72.1", + "@typescript-eslint/type-utils": "8.72.1", + "@typescript-eslint/utils": "8.72.1", + "@typescript-eslint/visitor-keys": "8.72.1", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3401,15 +3387,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.38.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "@typescript-eslint/parser": "^8.72.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz", + "integrity": "sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ==", "dev": true, "license": "MIT", "engines": { @@ -3417,17 +3403,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", - "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.1.tgz", + "integrity": "sha512-ZGwZP4OCfyA0AQTpEAMWz+rtX01DRhQWW5hB0ucKDEIX5U7jdmPSaMx94rQfaPAQzIYz2BimOgKOJtjfpRFQ9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.72.1", + "@typescript-eslint/types": "8.72.1", + "@typescript-eslint/typescript-estree": "8.72.1", + "@typescript-eslint/visitor-keys": "8.72.1", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3437,20 +3423,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", - "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.1.tgz", + "integrity": "sha512-fAuVMkwdO/huI8nyo/WKnNKf6Gag93S56Rh3Ts5mGcavwSdaN8tRg1gCeIGX8PF+nzp1BjGfO4gHhGzW1J6jTg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.38.0", - "@typescript-eslint/types": "^8.38.0", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.72.1", + "@typescript-eslint/types": "^8.72.1", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3460,18 +3446,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", - "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.1.tgz", + "integrity": "sha512-lC/t6eMCZZQAAKZEYGL6RDVSuFehpdmMT6h+nJIjIa6oylN/PwDgDVtEIbB7O9xFfZYtZAYLoLlDNWKJhtF+uQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0" + "@typescript-eslint/types": "8.72.1", + "@typescript-eslint/visitor-keys": "8.72.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3482,9 +3468,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", - "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.1.tgz", + "integrity": "sha512-e4D5R5vpeAEPBxT2BAzsFQL3sbwyeeeo5+aczgNSRK1V734jE7pTqaGFU+fXapWEQwnZbpFaTn32+Z8DwS6OTg==", "dev": true, "license": "MIT", "engines": { @@ -3495,21 +3481,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", - "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.1.tgz", + "integrity": "sha512-iY2wlmyrXJmx4yxUGP3aYCFF3cA/6ShddOKmLU2dx7LnEykbAM8WThlxZEfd1NddqceF6eJmZUayxx9oKIYNlg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.72.1", + "@typescript-eslint/typescript-estree": "8.72.1", + "@typescript-eslint/utils": "8.72.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3519,14 +3505,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", - "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.1.tgz", + "integrity": "sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw==", "dev": true, "license": "MIT", "engines": { @@ -3538,22 +3524,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", - "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.1.tgz", + "integrity": "sha512-DAlUoUV93hIvrtIQLwCbmZQYVZwOMhiHJrOVUUIWicFZaIYjTRqlY3I/NZevfkLmSqkNHRu2qYDcq9lrn16oOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.38.0", - "@typescript-eslint/tsconfig-utils": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/project-service": "8.72.1", + "@typescript-eslint/tsconfig-utils": "8.72.1", + "@typescript-eslint/types": "8.72.1", + "@typescript-eslint/visitor-keys": "8.72.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3563,46 +3548,59 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "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": "2.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", - "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.8" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", - "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.1.tgz", + "integrity": "sha512-5v5liypurJBFHCBNqh/RjsymAD+VWcE0djuGY/BUqp5fC3Qn+luWDEksjuTtWjPn6i5zQlUtkZCRG/CYG0yCkA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.72.1", + "@typescript-eslint/types": "8.72.1", + "@typescript-eslint/typescript-estree": "8.72.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3612,19 +3610,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", - "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.1.tgz", + "integrity": "sha512-SB8xqipSzZHUePCCLNeYxqnxq83X61/qzNhjQGbTfjxGZIeOEP7tBgWYX05Tcd6CgE02WdTJnh5b8kMZJ/+bnQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.72.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3634,10 +3632,23 @@ "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/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", "license": "ISC" }, "node_modules/@vitejs/plugin-react-swc": { @@ -3655,16 +3666,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", - "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.12.tgz", + "integrity": "sha512-vFlTt+YEu9WBpNjdGayNmlMVzrWPi1+sv853/7t2FU7hpO5gAFBKHzQmkCq5Xjpr+evegF2994LQT3hF3mRlqQ==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -3673,13 +3684,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", - "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.12.tgz", + "integrity": "sha512-fKShNpKZzupWZuY0z7egydvL0sqW4INEZBEExMBMAa6izlENEVHwoXgdaTCaBZ5fwlr4xf2o1wXC83n9RpO+NA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.11", + "@vitest/spy": "4.1.12", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3700,9 +3711,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", - "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.12.tgz", + "integrity": "sha512-XW9O8+Mxx4VpCtkYdMJLZQQwsVryP9wk7cPKDxtXFfwSak6yRh5+2fep/Y0XF/ElBvJHq8bcYdi6aeuai0opZA==", "dev": true, "license": "MIT", "dependencies": { @@ -3713,13 +3724,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", - "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.12.tgz", + "integrity": "sha512-NKlVKCr5QnCe8jijdMnmkpHHU+WTqiLFR6G0pHji9uRjXK9xJl1k1nTw6F3pOOj2PDcsDt2GKQMI7wIsaT491w==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.11", + "@vitest/utils": "4.1.12", "pathe": "^2.0.3" }, "funding": { @@ -3727,14 +3738,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", - "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.12.tgz", + "integrity": "sha512-ko1y1Qgb/slzQ9mr+b89Cuqud8WG1TKtsPD8r7ZUBdvVOGt85Af2HwCqHujrhwJq95hs/9RM7fcAPg57o1vlzw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/pretty-format": "4.1.12", + "@vitest/utils": "4.1.12", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3743,9 +3754,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", - "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.12.tgz", + "integrity": "sha512-RGq9x4JNGNTZHEJxvN0oSiJjeSCExm0n2gZKKJZHY9cX5AVA6M7VJILBT3ZJ/tJ/0J9uWT7fETV9/btoi//vSg==", "dev": true, "license": "MIT", "funding": { @@ -3753,13 +3764,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", - "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.12.tgz", + "integrity": "sha512-Q3awXrwOfEV+qc3WmO5ONyE0yO7Q1gQ9/oyHxGLZ/pl7N3NO/ZztqQwKLuwMkV+CA1JYSIeO3gkHnRDIo4AVaA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", + "@vitest/pretty-format": "4.1.12", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -3776,9 +3787,9 @@ "license": "BSD-3-Clause" }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", "dev": true, "license": "MIT", "bin": { @@ -3853,21 +3864,21 @@ } }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "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" @@ -3912,9 +3923,9 @@ "license": "Python-2.0" }, "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -3951,9 +3962,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.6.2.tgz", + "integrity": "sha512-VOw9/yGTGwPPgzFcODtcv6zhEPIeIWkRSe10L2ri2f5vZ7ID7lCt6jZzRF5/ubgOZ+szYydmEF5AYsA5jxX1tA==", "dev": true, "funding": [ { @@ -3971,10 +3982,9 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", + "browserslist": "^4.28.9", + "caniuse-lite": "^1.0.30001810", + "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, @@ -4002,12 +4012,13 @@ "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.11.25", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.25.tgz", - "integrity": "sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==", + "version": "2.11.35", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.35.tgz", + "integrity": "sha512-GNk8KX52CHqeNKGk8+7tZnQab/2k1t/BgrUHPKNdijzpEhF1saPQZHVKb6m5loSAxB39gyrTYw34Qf9CQ3u1qQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4053,9 +4064,9 @@ } }, "node_modules/browserslist": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.0.tgz", - "integrity": "sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==", + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.5.tgz", + "integrity": "sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ==", "dev": true, "funding": [ { @@ -4073,11 +4084,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.11.23", - "caniuse-lite": "^1.0.30001810", - "electron-to-chromium": "^1.5.427", - "node-releases": "^2.0.55", - "update-browserslist-db": "^1.3.3" + "baseline-browser-mapping": "^2.11.33", + "caniuse-lite": "^1.0.30001819", + "electron-to-chromium": "^1.5.464", + "node-releases": "^2.0.60", + "update-browserslist-db": "^1.3.4" }, "bin": { "browserslist": "cli.js" @@ -4120,9 +4131,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", + "version": "1.0.30001820", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001820.tgz", + "integrity": "sha512-gfWD6MxqVCqAOwmODfZf7DchWvlrA+SRdNX7ceLfg3xRqe5ssjjpF7EgslC/0tiLiNTajdaNN/q8c/5u/7Gz8w==", "dev": true, "funding": [ { @@ -4151,9 +4162,9 @@ } }, "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "dev": true, "license": "MIT", "engines": { @@ -4257,6 +4268,7 @@ "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", "dependencies": { "clsx": "^2.1.1" }, @@ -4293,6 +4305,7 @@ "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" @@ -4305,6 +4318,7 @@ "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/combined-stream": { @@ -4370,6 +4384,8 @@ "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", @@ -4432,9 +4448,9 @@ "license": "MIT" }, "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.5.tgz", + "integrity": "sha512-Th8qGXoBalmWsstpkuhmBuTsBQIFqYOJtjlBvNVvBfJ8E3uYusBUwUR8HU20U0qKKQkgCvKyR1YjiozWadk5QA==", "license": "ISC", "dependencies": { "internmap": "1 - 2" @@ -4444,36 +4460,36 @@ } }, "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.1.tgz", + "integrity": "sha512-lfab8x0Bj0UO7SNsY8dZSbNIA6ipbkE3X0NG9nqjCu6CfCHZseuDnOSJY7hidKrjpP++i1M2qT+FlAdPKYRilA==", "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-B5znKqRmKROAN4oHWQ50W/qisVjA9GXh2WMsVKdFVp4DxWmcrOsweqgUOUVsv5th96kwaZlokU6SlV4J3gak1w==", "license": "BSD-3-Clause", "engines": { "node": ">=12" } }, "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.3.tgz", + "integrity": "sha512-+F+/49swqmGuQJmSKnVMIDH/QkEFV5li9QRj0xm/KhyAUBv099O5PrvpQFxBp24PYph17Mnvt9mjKQV0ii0nMA==", "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.2.tgz", + "integrity": "sha512-IRzGU62DtxhvsnSTWMQIdnoZ6gA+BCWwBon1EJI6SjoN595799b6z/QRBzXfFhE8iupUPp3042yBNo0STPqnzQ==", "license": "ISC", "dependencies": { "d3-color": "1 - 3" @@ -4483,18 +4499,18 @@ } }, "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-jsbgV8zIT38ReB9O7X7gcLndTQRONSqNNd+oGIaTBdUug4r5jFmp0N6RY9R5GWbdUDucn0qoTGyfjapT4tDhcg==", "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.3.tgz", + "integrity": "sha512-66cWobCNzcMvlfoaDHCxuIv9TBUWG1BLOWdv9kHHFuCr1JdqAWPvTmsaEYDD5NRMyWZ5+7u0GqiCDfMXMqh3hg==", "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", @@ -4508,21 +4524,21 @@ } }, "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.1.tgz", + "integrity": "sha512-dm2o+lbKdzg9tY7GEag/dB9hcbodLfwkE/DkvqbELJXaMz0yKzWWhZqhbI7CKubukA7HnRyz0avdtvi7EPxPvw==", "license": "ISC", "dependencies": { - "d3-path": "^3.1.0" + "d3-path": "^3.1.1" }, "engines": { "node": ">=12" } }, "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.1.tgz", + "integrity": "sha512-Ze7rjrhMzdeulh0/hjcfFj7XLAHOfowtEMfsoG6DU866HPynQNW7Wfen6hzXcqKTv8XzxvF6Hzr5XD6bMHr2ug==", "license": "ISC", "dependencies": { "d3-array": "2 - 3" @@ -4532,9 +4548,9 @@ } }, "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.1.tgz", + "integrity": "sha512-22XaqjyCjpqgda20erhsOjGmC3vvYwTNYniKAd45W5UWLDF43moeOuV9qYpRqobIlsnK0UhnKZjUUJm3VgORUA==", "license": "ISC", "dependencies": { "d3-time": "1 - 3" @@ -4544,9 +4560,9 @@ } }, "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-1Il1aliroVSErrv5aulRBxAY+7+DnaoLIWGd1C6SsBTWDeobWiP/V69vwb8vT6abR1kKwaNe1196pmaQ1fK90A==", "license": "ISC", "engines": { "node": ">=12" @@ -4724,16 +4740,10 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, "node_modules/electron-to-chromium": { - "version": "1.5.438", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.438.tgz", - "integrity": "sha512-AN9xMU1hJiT65LkCUPL1DZm5TCbOPb2Qsm5pYwFLEXp6/qj9SdT4yMiqs7Qqstwvkn1zF7l36SRGt+s6XcJ0FA==", + "version": "1.5.475", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.475.tgz", + "integrity": "sha512-S9tceHJbIsHH8VRwh9x+8lJO50SYwTdwVGdEjdz2FERyP59j1N6rdXOSklIusrhxt9GG/WN4V/kRgmDHl9MM5w==", "dev": true, "license": "ISC" }, @@ -4765,12 +4775,6 @@ "embla-carousel": "8.6.0" } }, - "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==", - "license": "MIT" - }, "node_modules/entities": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", @@ -4798,7 +4802,6 @@ "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" @@ -4812,9 +4815,9 @@ "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "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": { @@ -4928,26 +4931,26 @@ } }, "node_modules/eslint": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", - "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.32.0", - "@eslint/plugin-kit": "^0.3.4", + "@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", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -4966,7 +4969,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -5002,9 +5005,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.20", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", - "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", + "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -5074,9 +5077,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "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": { @@ -5146,9 +5149,9 @@ "license": "MIT" }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5169,25 +5172,25 @@ "license": "MIT" }, "node_modules/fast-equals": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", - "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.5.tgz", + "integrity": "sha512-yKEpcFuRPu/pTQL2VB8YKE2yFldrLlIsoWtJeBnAdqEhvu21OgkFT0C8njf/xYc2LSZGEr3K9JGjthHJxnVLvQ==", "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "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" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -5220,9 +5223,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -5291,22 +5294,6 @@ "dev": true, "license": "ISC" }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", @@ -5325,16 +5312,16 @@ } }, "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "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": "patreon", + "type": "github", "url": "https://github.com/sponsors/rawify" } }, @@ -5409,27 +5396,6 @@ "node": ">= 0.4" } }, - "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5442,30 +5408,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", - "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globals": { "version": "15.15.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", @@ -5492,13 +5434,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5551,9 +5486,9 @@ } }, "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.7.tgz", + "integrity": "sha512-F7DNV2NMcTxA4GqPVHnXzX+mpoPHAIY9rJAVH3CZ1FdBZOcBUEjUuvMkMpHVs/sicEtznh9tMGj5WUR9S4E2rg==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -5568,7 +5503,7 @@ "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", + "style-to-object": "^2.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" }, @@ -5719,15 +5654,15 @@ } }, "node_modules/inline-style-parser": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", - "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.9.tgz", + "integrity": "sha512-IttN8BqKLxzUrnTqHI+/hwAJQItBAUjdoHERCDv+oOuX48VP6bzW8+QjOXSfoevzq3YrYAwX1uLHp8TqO9yIeg==", "license": "MIT" }, "node_modules/input-otp": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", - "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.5.0.tgz", + "integrity": "sha512-3AcfdW1sNG0FmSA5hHMBXG7jNW5CdcdKs8ln8JOmn6S2SRkoXoJx+2UwC+ZvjflfnOdHJx0SfQ9/YjlxVYLtGQ==", "license": "MIT", "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", @@ -5780,12 +5715,12 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.18.0.tgz", + "integrity": "sha512-qyax9fgaKOEC4qK8WZn7Q4IcoZC9RC1O1fFxRcRTq/oMMkWT/uXpqpXa12kzWR409zAt1drYN9N9BO26UmBCmw==", "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.4" }, "engines": { "node": ">= 0.4" @@ -5813,15 +5748,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5876,27 +5802,13 @@ "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/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -6023,9 +5935,9 @@ } }, "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==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.4.tgz", + "integrity": "sha512-zJZyBmQhArDRefuWTypZxwDpFDIYmrj8ypSBvwGD5P13Y95s6DjzKgu4DVdGbeQa5PDEsAOCAPNk4X+QOR006w==", "license": "MIT", "engines": { "node": ">=14" @@ -6062,18 +5974,6 @@ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, - "node_modules/lodash.castarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -6103,16 +6003,11 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, "node_modules/lucide-react": { "version": "0.462.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.462.0.tgz", "integrity": "sha512-NTL7EbAao9IFtuSivSZgrAh4fZd09Lr+6MTkqIxuHaH2nnYiYIzXPo06cOxHg9wKLdj6LL8TByG4qpePqwgx/g==", + "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } @@ -6149,9 +6044,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", - "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", + "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6191,9 +6086,9 @@ } }, "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.1.tgz", + "integrity": "sha512-oXp1GIa+E9IwIs3a106+tr3Bz2MlTTBvlXjOZMoIat11kk7vjqgmBnksB9WHmWv+gZh7k3IUgpAHlwHB7DH4GQ==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -6268,9 +6163,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.2.2.tgz", + "integrity": "sha512-ELNT5jYDUdx0B/hlUSSAiAEtvqkY3Oriwkp1KEYseF1Ccu4MnKkmE5yK3oE3WGT/Pq8VTE+XwP0GLL5pafY8yA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6278,8 +6173,10 @@ "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", + "micromark-util-character": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" }, @@ -6311,9 +6208,9 @@ } }, "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", + "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", "funding": [ { "type": "GitHub Sponsors", @@ -6336,6 +6233,7 @@ "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", @@ -6346,9 +6244,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", + "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", "funding": [ { "type": "GitHub Sponsors", @@ -6365,18 +6263,19 @@ "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", + "micromark-factory-space": "^2.1.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "micromark-util-types": "^2.0.3" } }, "node_modules/micromark-factory-destination": { @@ -6423,9 +6322,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", + "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6607,6 +6506,25 @@ "micromark-util-symbol": "^2.0.0" } }, + "node_modules/micromark-util-edit-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", + "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-util-encode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", @@ -6737,9 +6655,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", "funding": [ { "type": "GitHub Sponsors", @@ -6811,15 +6729,6 @@ "node": "*" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -6838,9 +6747,9 @@ } }, "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==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", "funding": [ { "type": "github", @@ -6873,9 +6782,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.57", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", - "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", + "version": "2.0.63", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.63.tgz", + "integrity": "sha512-6li2QanLsAXpIH2R6j77MzRyvOyrvdTqlKtO4CgBdHGNvN99ZZfyxszHc5o5+IZBWD5u6Hzwg83JoGXmqZNG9Q==", "dev": true, "license": "MIT", "engines": { @@ -6891,20 +6800,10 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "version": "2.2.28", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.28.tgz", + "integrity": "sha512-IlVB7OS7qrOsVYlpnFIkETjMwT9jwvmocJmmM+GZU/PAB3uGi9Ezd7vcWhWBUnSc0ya4ppmQITOyP1ez9gg8cg==", "dev": true, "license": "MIT" }, @@ -6990,12 +6889,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7061,6 +6954,7 @@ "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" @@ -7072,22 +6966,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -7113,75 +6991,48 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/playwright": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", - "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.64.1.tgz", + "integrity": "sha512-HCrVhHr5QQuwYoswEUGTb7gGp522yflbv/ST8nF4sFWGuLjQCt17Q/EubpGGSNKYn1tsTCPZxqHhHCfVURu7UA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.58.2" + "playwright-core": "1.64.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" + "node": ">=20" } }, "node_modules/playwright-core": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", - "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.64.1.tgz", + "integrity": "sha512-BC4s8y6SEVA6Q1rSxZTto8hI1KUI3xXlHGZgvGqP4IqPdI/a6FX9H29IDNz7vKo9l21b6LfYosScPL6M3xxyDQ==", "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=18" - } - }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=20" } }, "node_modules/postcss": { - "version": "8.5.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", - "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "version": "8.5.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz", + "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==", "funding": [ { "type": "opencollective", @@ -7198,9 +7049,9 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.17", + "nanoid": "^3.3.20", "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -7224,9 +7075,19 @@ } }, "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" @@ -7234,18 +7095,14 @@ "engines": { "node": "^12 || ^14 || >= 16" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.4.21" } }, "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "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==", "funding": [ { "type": "opencollective", @@ -7258,21 +7115,28 @@ ], "license": "MIT", "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" + "lilconfig": "^3.1.1" }, "engines": { - "node": ">= 14" + "node": ">= 18" }, "peerDependencies": { + "jiti": ">=1.21.0", "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { + "jiti": { + "optional": true + }, "postcss": { "optional": true }, - "ts-node": { + "tsx": { + "optional": true + }, + "yaml": { "optional": true } } @@ -7303,9 +7167,9 @@ } }, "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==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.5.tgz", + "integrity": "sha512-TEHFzb5KRDKaOgJ4TYE+0jyJtFbjLvkdVOu0fZ2b6MTWzoqZd4Le+61aEppWkvTlYePgOX4ATL1wsAIPMLTw6Q==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -7347,17 +7211,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/pretty-format/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -7372,14 +7225,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -7398,9 +7243,9 @@ "license": "MIT" }, "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", "license": "MIT", "funding": { "type": "github", @@ -7470,9 +7315,9 @@ } }, "node_modules/react-day-picker": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", - "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.2.tgz", + "integrity": "sha512-LK68OTbHB3oJNhl9cA0qVizzp3o26w61YSjAFkYi67N86iro32wx86kSNeFU/hq+gI8m1yzWhnomMLfZ041RzQ==", "license": "MIT", "funding": { "type": "individual", @@ -7480,7 +7325,7 @@ }, "peerDependencies": { "date-fns": "^2.28.0 || ^3.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-dom": { @@ -7497,9 +7342,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.61.1", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.61.1.tgz", - "integrity": "sha512-2vbXUFDYgqEgM2RcXcAT2PwDW/80QARi+PKmHy5q2KhuKvOlG8iIYgf7eIlIANR5trW9fJbP4r5aub3a4egsew==", + "version": "7.91.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.91.0.tgz", + "integrity": "sha512-5BEBUnCBwa28AFXYTYmOaB/+CSpJ/+CWVASHEvIGUzFdHyUiPHeRhG7r5hOZ8nZi0yP7pbHdFNXO/p31EKTJFQ==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -7509,14 +7354,22 @@ "url": "https://opencollective.com/react-hook-form" }, "peerDependencies": { + "@types/react": "*", "react": "^16.8.0 || ^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/react-markdown": { "version": "10.1.0", @@ -7546,9 +7399,9 @@ } }, "node_modules/react-remove-scroll": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", - "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.7", @@ -7603,9 +7456,9 @@ } }, "node_modules/react-router": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.4.tgz", - "integrity": "sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.5.tgz", + "integrity": "sha512-dTgvcXDOrLPrlLHrcZAqWveiK1hMSqN+rGAJzegP8HtmNkfRxOoshGWBNX3ZJ0cZjOHkRdlUJtaIhZMLLyGyPw==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -7625,12 +7478,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.4.tgz", - "integrity": "sha512-yrfmJHIpDG7taCpqKjT1G5B6q3O2K+RN8/fgNf0lTjCwiPbQ0ei6vXX9ZjQR+7ld8Tr7Z5xmyMnZ8YJrphWQUw==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.5.tgz", + "integrity": "sha512-9HcfDMU6JJ/fp6gJZYGwNE6RknVGS4kBjH1HkNw959mCJi70TVwdipQWv2FEol9uGpi+SZTFtVpJPtEQfayeOw==", "license": "MIT", "dependencies": { - "react-router": "7.18.4" + "react-router": "7.18.5" }, "engines": { "node": ">=20.0.0" @@ -7694,13 +7547,10 @@ } }, "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==", - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.2.tgz", + "integrity": "sha512-/peqiBB/n07gQGLsWaHho3WfvUyRscw0gYTsEFMhrIe/nWLkYaf5SbKYjGYqtRV3aPwykJgF2VEMo1ac4bnsGA==", + "license": "MIT" }, "node_modules/readdirp": { "version": "3.6.0", @@ -7718,6 +7568,7 @@ "version": "2.15.4", "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "deprecated": "1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide", "license": "MIT", "dependencies": { "clsx": "^2.0.0", @@ -7746,6 +7597,12 @@ "decimal.js-light": "^2.4.1" } }, + "node_modules/recharts/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -7801,18 +7658,22 @@ "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.14", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.14.tgz", + "integrity": "sha512-1ZjYvR9sbkiwC5+9QHetqW5HmA2pHRMaoupD01t2HlYnV/vydC2zPwLixhsMieSWVZt0JJRg5LVIk0Ow1D/TrA==", "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.18.0", "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" } @@ -7828,9 +7689,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -7838,13 +7699,13 @@ } }, "node_modules/rollup": { - "version": "4.63.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.4.tgz", - "integrity": "sha512-4U0liVayNIoLp3GFl1FcI8561WepLnZ1rqfraGh7S9B3Ur5F9S283y8Futii7RUU2C/97tOBmBy7nYvhoiOpbQ==", + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.67.5.tgz", + "integrity": "sha512-3Ve5VH1hacCVutdpbmu/htg4kz+JCOIWgy4Q3hjHPYGHeHeIElNHJ0LcJ3rCfIsd5G7qOl5k5mwpzGMj9kdHPA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.9" + "@types/estree": "^1.0.10" }, "bin": { "rollup": "dist/bin/rollup" @@ -7854,32 +7715,32 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@rollup/rollup-android-arm-eabi": "4.63.4", - "@rollup/rollup-android-arm64": "4.63.4", - "@rollup/rollup-darwin-arm64": "4.63.4", - "@rollup/rollup-darwin-x64": "4.63.4", - "@rollup/rollup-freebsd-arm64": "4.63.4", - "@rollup/rollup-freebsd-x64": "4.63.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.63.4", - "@rollup/rollup-linux-arm-musleabihf": "4.63.4", - "@rollup/rollup-linux-arm64-gnu": "4.63.4", - "@rollup/rollup-linux-arm64-musl": "4.63.4", - "@rollup/rollup-linux-loong64-gnu": "4.63.4", - "@rollup/rollup-linux-loong64-musl": "4.63.4", - "@rollup/rollup-linux-ppc64-gnu": "4.63.4", - "@rollup/rollup-linux-ppc64-musl": "4.63.4", - "@rollup/rollup-linux-riscv64-gnu": "4.63.4", - "@rollup/rollup-linux-riscv64-musl": "4.63.4", - "@rollup/rollup-linux-s390x-gnu": "4.63.4", - "@rollup/rollup-linux-x64-gnu": "4.63.4", - "@rollup/rollup-linux-x64-musl": "4.63.4", - "@rollup/rollup-openbsd-x64": "4.63.4", - "@rollup/rollup-openharmony-arm64": "4.63.4", - "@rollup/rollup-win32-arm64-msvc": "4.63.4", - "@rollup/rollup-win32-ia32-msvc": "4.63.4", - "@rollup/rollup-win32-x64-gnu": "4.63.4", - "@rollup/rollup-win32-x64-msvc": "4.63.4", + "@rollup/rollup-android-arm-eabi": "4.67.5", + "@rollup/rollup-android-arm64": "4.67.5", + "@rollup/rollup-android-x64": "4.67.5", + "@rollup/rollup-darwin-arm64": "4.67.5", + "@rollup/rollup-darwin-x64": "4.67.5", + "@rollup/rollup-freebsd-arm64": "4.67.5", + "@rollup/rollup-freebsd-x64": "4.67.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.67.5", + "@rollup/rollup-linux-arm-musleabihf": "4.67.5", + "@rollup/rollup-linux-arm64-gnu": "4.67.5", + "@rollup/rollup-linux-arm64-musl": "4.67.5", + "@rollup/rollup-linux-loong64-gnu": "4.67.5", + "@rollup/rollup-linux-loong64-musl": "4.67.5", + "@rollup/rollup-linux-ppc64-gnu": "4.67.5", + "@rollup/rollup-linux-ppc64-musl": "4.67.5", + "@rollup/rollup-linux-riscv64-gnu": "4.67.5", + "@rollup/rollup-linux-riscv64-musl": "4.67.5", + "@rollup/rollup-linux-s390x-gnu": "4.67.5", + "@rollup/rollup-linux-x64-gnu": "4.67.5", + "@rollup/rollup-linux-x64-musl": "4.67.5", + "@rollup/rollup-openbsd-x64": "4.67.5", + "@rollup/rollup-openharmony-arm64": "4.67.5", + "@rollup/rollup-win32-arm64-msvc": "4.67.5", + "@rollup/rollup-win32-ia32-msvc": "4.67.5", + "@rollup/rollup-win32-x64-gnu": "4.67.5", + "@rollup/rollup-win32-x64-msvc": "4.67.5", "fsevents": "~2.3.2" } }, @@ -7936,9 +7797,9 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz", + "integrity": "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==", "dev": true, "license": "ISC", "bin": { @@ -7949,15 +7810,16 @@ } }, "node_modules/set-cookie-parser": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.3.tgz", + "integrity": "sha512-irZHtTqurLna57KQG/s+fzOwv/J6XSH4cs8M/vsrY3uCaQ3S6+QJguAH0WdN47SXlk82voMZ4naWMQf8fdEoIg==", "license": "MIT" }, "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" @@ -7970,6 +7832,7 @@ "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", "engines": { "node": ">=8" @@ -7982,18 +7845,6 @@ "dev": true, "license": "ISC" }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/sonner": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz", @@ -8016,9 +7867,9 @@ } }, "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==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -8042,71 +7893,12 @@ "license": "MIT" }, "node_modules/std-env": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", - "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "dev": true, "license": "MIT" }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", @@ -8121,43 +7913,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -8184,36 +7939,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-to-js": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", - "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.14" - } - }, "node_modules/style-to-object": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", - "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-2.0.2.tgz", + "integrity": "sha512-QmbXPUylqU80HAgTOJeEOdbA40W9KtxmjMhQy+tq+b8F2aoh3aQLuy82hh2jm2qsC9hR9eI0+eQidTMydKcqRA==", "license": "MIT", "dependencies": { - "inline-style-parser": "0.2.7" + "inline-style-parser": "0.2.9" } }, "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { @@ -8257,9 +8003,9 @@ "license": "MIT" }, "node_modules/tailwind-merge": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", - "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz", + "integrity": "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==", "license": "MIT", "funding": { "type": "github", @@ -8267,9 +8013,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -8280,7 +8026,7 @@ "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.6", + "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", @@ -8289,7 +8035,7 @@ "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", @@ -8357,14 +8103,13 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -8377,7 +8122,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -8395,7 +8139,6 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -8405,9 +8148,9 @@ } }, "node_modules/tinyrainbow": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", - "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.2.0.tgz", + "integrity": "sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==", "dev": true, "license": "MIT", "engines": { @@ -8476,9 +8219,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "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": { @@ -8495,9 +8238,9 @@ "license": "Apache-2.0" }, "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==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.9.1.tgz", + "integrity": "sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==", "license": "0BSD" }, "node_modules/type-check": { @@ -8514,9 +8257,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -8528,16 +8271,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz", - "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==", + "version": "8.72.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.72.1.tgz", + "integrity": "sha512-3Li9FfPmQp45nxEtFD1ZCrYFI3cYK5kpyNtmm1H7lMagm8u9sy6PTjy3ytwQZs7KNukOyKFHAZ6z6GjYFeaeXw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.38.0", - "@typescript-eslint/parser": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0" + "@typescript-eslint/eslint-plugin": "8.72.1", + "@typescript-eslint/parser": "8.72.1", + "@typescript-eslint/typescript-estree": "8.72.1", + "@typescript-eslint/utils": "8.72.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8547,8 +8290,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/undici-types": { @@ -8617,14 +8360,14 @@ } }, "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.2.0.tgz", + "integrity": "sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" + "unist-util-visit-parents": "^6.1.0" }, "funding": { "type": "opencollective", @@ -8632,9 +8375,9 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.1.0.tgz", + "integrity": "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8656,9 +8399,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", - "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", "dev": true, "funding": [ { @@ -8750,15 +8493,6 @@ } } }, - "node_modules/use-sync-external-store": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", - "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -8829,9 +8563,9 @@ } }, "node_modules/vite": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", - "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.5.tgz", + "integrity": "sha512-4enwjFfi4IwtEh0w+jPzpLVOFQiPHmmzPxcHXQOyEur47o6u0jE573DmGpjA+7irXoMLYRZD5ZaFUEneS3abPg==", "dev": true, "license": "MIT", "dependencies": { @@ -8935,19 +8669,19 @@ } }, "node_modules/vitest": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", - "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.12.tgz", + "integrity": "sha512-5eWdz2yb3ajxWF3C8C4TjkXl7FGm3n2E/VlazALrQHzK7nYMSGFnCZto0bbPNl77AwkOZVLk0YnBAejUu0NiWA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.11", - "@vitest/mocker": "4.1.11", - "@vitest/pretty-format": "4.1.11", - "@vitest/runner": "4.1.11", - "@vitest/snapshot": "4.1.11", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/expect": "4.1.12", + "@vitest/mocker": "4.1.12", + "@vitest/pretty-format": "4.1.12", + "@vitest/runner": "4.1.12", + "@vitest/snapshot": "4.1.12", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -8975,12 +8709,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.11", - "@vitest/browser-preview": "4.1.11", - "@vitest/browser-webdriverio": "4.1.11", - "@vitest/coverage-istanbul": "4.1.11", - "@vitest/coverage-v8": "4.1.11", - "@vitest/ui": "4.1.11", + "@vitest/browser-playwright": "4.1.12", + "@vitest/browser-preview": "4.1.12", + "@vitest/browser-webdriverio": "^4.1.11", + "@vitest/coverage-istanbul": "4.1.12", + "@vitest/coverage-v8": "4.1.12", + "@vitest/ui": "4.1.12", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -9102,6 +8836,7 @@ "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" @@ -9140,98 +8875,10 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/ws": { - "version": "8.21.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", - "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "version": "8.22.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.1.tgz", + "integrity": "sha512-oyL6OPYme/CmiFvNuGzeoxCJ4nOrZE2O1FwM9MWM1AsGri6nLXB2pg+lNA8aLeXMSav0J6eIVS1j6vUPzUtK9g==", "dev": true, "license": "MIT", "engines": { @@ -9267,21 +8914,6 @@ "dev": true, "license": "MIT" }, - "node_modules/yaml": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", - "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -9295,15 +8927,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 00598322..888f62a5 100644 --- a/package.json +++ b/package.json @@ -109,8 +109,7 @@ "sonner": "^1.7.4", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", - "vaul": "^0.9.9", - "zod": "^3.25.76" + "vaul": "^0.9.9" }, "devDependencies": { "@eslint/js": "^9.32.0", @@ -136,5 +135,8 @@ "typescript-eslint": "^8.38.0", "vite": "^6.4.3", "vitest": "^4.1.11" + }, + "overrides": { + "postcss-selector-parser": "6.1.5" } } diff --git a/src/pages/Settings.test.tsx b/src/pages/Settings.test.tsx index 9f754679..e61d9bce 100644 --- a/src/pages/Settings.test.tsx +++ b/src/pages/Settings.test.tsx @@ -665,7 +665,7 @@ describe("Settings AI providers", () => { expect(await screen.findByText("Connection failed")).toBeInTheDocument(); fireEvent.click(modelCombobox); - fireEvent.click(screen.getByRole("option", { name: /OpenAI: GPT-5\.2/ })); + fireEvent.click(await screen.findByRole("option", { name: /OpenAI: GPT-5\.2/ })); const testButton = screen.getByTitle("Save changes and test the current configuration"); expect(testButton).toBeEnabled(); @@ -728,7 +728,7 @@ describe("Settings AI providers", () => { fireEvent.change(screen.getByPlaceholderText("Search OpenRouter models…"), { target: { value: "gpt-5.2" }, }); - fireEvent.click(screen.getByRole("option", { name: /OpenAI: GPT-5\.2/ })); + fireEvent.click(await screen.findByRole("option", { name: /OpenAI: GPT-5\.2/ })); fireEvent.click(screen.getByRole("button", { name: "Save" })); await waitFor(() => { @@ -816,7 +816,7 @@ describe("Settings AI providers", () => { fireEvent.change(screen.getByPlaceholderText("Search OpenRouter models…"), { target: { value: "my/custom-router-model" }, }); - fireEvent.click(screen.getByRole("option", { name: /my\/custom-router-model/ })); + fireEvent.click(await screen.findByRole("option", { name: /my\/custom-router-model/ })); fireEvent.click(screen.getByRole("button", { name: "Save" })); await waitFor(() => { diff --git a/src/pages/TagDetail.test.tsx b/src/pages/TagDetail.test.tsx index 0c0f6f9f..bed80bc1 100644 --- a/src/pages/TagDetail.test.tsx +++ b/src/pages/TagDetail.test.tsx @@ -153,7 +153,7 @@ describe("TagDetail", () => { ); expect(screen.getByRole("link", { name: "Manage tags" })).toHaveAttribute("href", "/tags"); expect(screen.getByRole("button", { name: "Rename #typescript tag" })).toBeInTheDocument(); - expect(screen.getByText("Example bookmark")).toBeInTheDocument(); + expect(await screen.findByText("Example bookmark")).toBeInTheDocument(); expect(screen.getByText("1-20 of 22")).toBeInTheDocument(); expect(mockedListBookmarks).toHaveBeenCalledWith({ tag: "typescript", @@ -248,7 +248,7 @@ describe("TagDetail", () => { renderTagDetail(); expect(await screen.findByRole("heading", { name: "#typescript" })).toBeInTheDocument(); - expect(screen.getByText("No bookmarks with this tag yet")).toBeInTheDocument(); + expect(await screen.findByText("No bookmarks with this tag yet")).toBeInTheDocument(); }); it("does not request scoped bookmarks for an unknown tag", async () => { diff --git a/src/pages/Tags.tsx b/src/pages/Tags.tsx index a1768a35..50a2eb31 100644 --- a/src/pages/Tags.tsx +++ b/src/pages/Tags.tsx @@ -77,7 +77,7 @@ const Tags = () => { }); const deleteMutation = useMutation({ - mutationFn: deleteTag, + mutationFn: (id: string) => deleteTag(id), onSuccess: () => { const deletedName = deleteTarget?.name; invalidateTagAffectedQueries(); From 58004b984d2c4f486237bf46e91ab4a8dc1bc76f Mon Sep 17 00:00:00 2001 From: Robert Goniszewski <43510122+goniszewski@users.noreply.github.com> Date: Fri, 6 Nov 2026 15:49:00 +0100 Subject: [PATCH 12/14] chore(release): prepare v1.3.1 (#240) --- CHANGELOG.md | 16 ++++++++++++++++ README.md | 2 +- daemon/package.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- scripts/release-metadata.test.ts | 4 ++-- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70cc699b..e690774e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to Grimoire will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [1.3.1] - Unreleased + +### Added +- Cheaper Inference is available as an AI provider. + +### Fixed +- Theme switching works and the selected theme is remembered. +- Grimoire works behind trusted reverse proxy origins. + +### Security +- Outbound fetches resolve each hop's hostname and reject private or reserved + addresses, including NAT64, 6to4, and Teredo-embedded IPv6 and internal-only + hostnames. +- Dependencies updated to resolve audit findings, including `fast-uri` + (GHSA-58mr-gqgx-xq4g, GHSA-qw65-cvwx-89v3). + ## [1.3.0] - 2026-09-28 ### Added diff --git a/README.md b/README.md index e8daa895..dbf0f675 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@
[![Quality Gates](https://github.com/goniszewski/grimoire/actions/workflows/quality.yml/badge.svg?branch=main)](https://github.com/goniszewski/grimoire/actions/workflows/quality.yml) -![Release target](https://img.shields.io/badge/release-1.3.0-7c3aed) +![Release target](https://img.shields.io/badge/release-1.3.1-7c3aed) ![Bun 1.x](https://img.shields.io/badge/Bun-1.x-black) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) diff --git a/daemon/package.json b/daemon/package.json index 0d12ebb3..c4548806 100644 --- a/daemon/package.json +++ b/daemon/package.json @@ -1,6 +1,6 @@ { "name": "littleimpd", - "version": "1.3.0", + "version": "1.3.1", "private": true, "type": "module", "bin": { diff --git a/package-lock.json b/package-lock.json index f175dc82..12f333a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "grimoire", - "version": "1.3.0", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "grimoire", - "version": "1.3.0", + "version": "1.3.1", "license": "MIT", "dependencies": { "@dnd-kit/core": "^6.3.1", diff --git a/package.json b/package.json index 888f62a5..b54d06ff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "grimoire", "private": true, - "version": "1.3.0", + "version": "1.3.1", "license": "MIT", "author": "Robert Goniszewski", "repository": { diff --git a/scripts/release-metadata.test.ts b/scripts/release-metadata.test.ts index b9fa6391..0361919e 100644 --- a/scripts/release-metadata.test.ts +++ b/scripts/release-metadata.test.ts @@ -29,8 +29,8 @@ describe("release metadata", () => { writeFileSync(installerPath, readFileSync(installerPath, "utf8").replace(`LITTLEIMP_VERSION:-${publishedVersion}`, "LITTLEIMP_VERSION:-0.0.0")); expect(checkReleaseMetadata(root)).toContain("One-command installer default differs from published release"); const daemonPath = join(root, "daemon/package.json"); - writeFileSync(daemonPath, readFileSync(daemonPath, "utf8").replace('"version": "1.3.0"', '"version": "1.2.0"')); - expect(checkReleaseMetadata(root)).toContain("daemon/package.json version 1.2.0 differs from package.json 1.3.0"); + writeFileSync(daemonPath, readFileSync(daemonPath, "utf8").replace('"version": "1.3.1"', '"version": "1.2.0"')); + expect(checkReleaseMetadata(root)).toContain("daemon/package.json version 1.2.0 differs from package.json 1.3.1"); } finally { rmSync(root, { recursive: true, force: true }); } From 18c04ee175e1bcc9a7f18758c46e43fe42a78215 Mon Sep 17 00:00:00 2001 From: Robert Goniszewski <43510122+goniszewski@users.noreply.github.com> Date: Fri, 6 Nov 2026 16:07:11 +0100 Subject: [PATCH 13/14] test(backup): share Cheaper Inference settings fixture (#242) --- daemon/src/test/integration/backup.test.ts | 27 ++++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/daemon/src/test/integration/backup.test.ts b/daemon/src/test/integration/backup.test.ts index b05eb6da..7eea2bd1 100644 --- a/daemon/src/test/integration/backup.test.ts +++ b/daemon/src/test/integration/backup.test.ts @@ -30,6 +30,15 @@ function makeFileDb(dir: string): { db: Database; dbPath: string } { return { db, dbPath }; } +// Shared fixture for the Cheaper Inference provider block in settings payloads. +function cheaperInferenceSettings(prefix: "backup" | "current") { + return { + api_key: `${prefix}-cheaperinference-secret`, + base_url: "https://api.cheaperinference.com/v1", + model: "gpt-5.4-mini", + }; +} + const EMPTY_S3_CONFIG = { endpoint: "", bucket: "", @@ -186,11 +195,7 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, - cheaperinference: { - api_key: "backup-cheaperinference-secret", - base_url: "https://api.cheaperinference.com/v1", - model: "gpt-5.4-mini", - }, + cheaperinference: cheaperInferenceSettings("backup"), embeddings: { provider: "openai_compatible", model: "nomic-embed-text", @@ -863,11 +868,7 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, - cheaperinference: { - api_key: "backup-cheaperinference-secret", - base_url: "https://api.cheaperinference.com/v1", - model: "gpt-5.4-mini", - }, + cheaperinference: cheaperInferenceSettings("backup"), embeddings: { provider: "openai_compatible", model: "nomic-embed-text", @@ -922,11 +923,7 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-current", }, - cheaperinference: { - api_key: "current-cheaperinference-secret", - base_url: "https://api.cheaperinference.com/v1", - model: "gpt-5.4-mini", - }, + cheaperinference: cheaperInferenceSettings("current"), embeddings: { provider: "openai", model: "embed-current", From 077fd3e6e8853a90eac08823254b51715b92d780 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Mon, 9 Nov 2026 21:39:44 +0100 Subject: [PATCH 14/14] fix: remediate dependency CVEs reported by Trivy after v1.3.1 sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - lodash override ^4.18.0 (CVE-2026-4800) — upstream v1.3.1 already fixed fast-uri, proxy-addr, source-map-js and @modelcontextprotocol/sdk, so the fork overrides for those are dropped as superseded trivy fs --severity HIGH,CRITICAL --ignore-unfixed now reports 0 findings across bun.lock, daemon/bun.lock and package-lock.json. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- bun.lock | 3 ++- package-lock.json | 57 ----------------------------------------------- package.json | 1 + 3 files changed, 3 insertions(+), 58 deletions(-) diff --git a/bun.lock b/bun.lock index ce5bc189..4b7f1b8f 100644 --- a/bun.lock +++ b/bun.lock @@ -86,6 +86,7 @@ }, }, "overrides": { + "lodash": "^4.18.0", "postcss-selector-parser": "6.1.5", }, "packages": { @@ -935,7 +936,7 @@ "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], - "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + "lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="], "lodash.castarray": ["lodash.castarray@4.4.0", "", {}, "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q=="], diff --git a/package-lock.json b/package-lock.json index 12f333a5..f87aa59c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2448,9 +2448,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2465,9 +2462,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2482,9 +2476,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2499,9 +2490,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2516,9 +2504,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2533,9 +2518,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2550,9 +2532,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2567,9 +2546,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2584,9 +2560,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2601,9 +2574,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2618,9 +2588,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2635,9 +2602,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2652,9 +2616,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2852,9 +2813,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2872,9 +2830,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2892,9 +2847,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2912,9 +2864,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2932,9 +2881,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2952,9 +2898,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ diff --git a/package.json b/package.json index b54d06ff..00c8424a 100644 --- a/package.json +++ b/package.json @@ -137,6 +137,7 @@ "vitest": "^4.1.11" }, "overrides": { + "lodash": "^4.18.0", "postcss-selector-parser": "6.1.5" } }