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/API.md b/API.md index ce439977..56b2a630 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 @@ -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/CHANGELOG.md b/CHANGELOG.md index 6b27ebaa..e690774e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,23 @@ 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.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 - Later / Revisit rounds present a small shuffled stack of saved bookmarks, diff --git a/Formula/grimoire.rb b/Formula/grimoire.rb index 5d271506..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" @@ -6,11 +9,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..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) @@ -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 @@ -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: @@ -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. @@ -251,6 +251,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 57aca137..66bb78eb 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,14 +32,16 @@ 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`. -- 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 +52,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 +61,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/bun.lock b/bun.lock index 04f7ad55..4b7f1b8f 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", @@ -88,7 +87,7 @@ }, "overrides": { "lodash": "^4.18.0", - "source-map-js": "^1.2.2", + "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=="], @@ -1101,7 +1100,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=="], @@ -1199,7 +1198,7 @@ "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "source-map-js": ["source-map-js@1.2.2", "", {}, "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw=="], + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], @@ -1347,8 +1346,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=="], @@ -1393,8 +1390,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=="], @@ -1413,8 +1408,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 8c9597ff..eebbfd99 100644 --- a/daemon/bun.lock +++ b/daemon/bun.lock @@ -5,67 +5,67 @@ "": { "name": "littleimpd", "dependencies": { - "@aws-sdk/client-s3": "^3.1128.0", - "@modelcontextprotocol/sdk": "^1.31.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", "proxy-addr": "2.0.8", - "qs": "6.16.0", + "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.32.1", "", { "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-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw=="], + "@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=="], @@ -89,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=="], @@ -111,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=="], @@ -165,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=="], @@ -185,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=="], @@ -193,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=="], @@ -243,7 +243,7 @@ "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=="], @@ -273,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=="], @@ -303,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 9d2dfa1b..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": { @@ -17,23 +17,23 @@ "test:performance": "bun run src/test/performance/large-library-performance.ts" }, "dependencies": { - "@aws-sdk/client-s3": "^3.1128.0", - "@modelcontextprotocol/sdk": "^1.31.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", "proxy-addr": "2.0.8", - "qs": "6.16.0" + "qs": "6.17.1" } } 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/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/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/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/server.ts b/daemon/src/server.ts index f84b93fd..d639a207 100644 --- a/daemon/src/server.ts +++ b/daemon/src/server.ts @@ -48,6 +48,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", @@ -78,9 +80,14 @@ 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; + 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; @@ -220,16 +227,16 @@ async function enforceLocalOrigin(c: Context, next: Next): Promise): 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/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/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/test/integration/backup.test.ts b/daemon/src/test/integration/backup.test.ts index d8060096..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,6 +195,7 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: cheaperInferenceSettings("backup"), embeddings: { provider: "openai_compatible", model: "nomic-embed-text", @@ -858,6 +868,7 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-v4-flash", }, + cheaperinference: cheaperInferenceSettings("backup"), embeddings: { provider: "openai_compatible", model: "nomic-embed-text", @@ -912,6 +923,7 @@ describe("Backup API", () => { base_url: "https://api.deepseek.com", model: "deepseek-current", }, + cheaperinference: cheaperInferenceSettings("current"), embeddings: { provider: "openai", model: "embed-current", diff --git a/daemon/src/test/integration/security-hardening.test.ts b/daemon/src/test/integration/security-hardening.test.ts index d481a18d..f69780b4 100644 --- a/daemon/src/test/integration/security-hardening.test.ts +++ b/daemon/src/test/integration/security-hardening.test.ts @@ -80,6 +80,7 @@ describe("Security hardening", () => { 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,16 @@ 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://normalized-path.example/admin/..", + "https://encoded-path.example/%2e", + "https://user:password@credential.example", + ]; try { const app = createApp({ db, queue, startTime: new Date(), version: "0.0.0-test", staticDir: false }); @@ -171,6 +181,38 @@ 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://normalized-path.example", + "https://encoded-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/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/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/); + }); }); 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/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/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/04-development.md b/docs/04-development.md index 1b0148ca..9d538dd1 100644 --- a/docs/04-development.md +++ b/docs/04-development.md @@ -81,8 +81,12 @@ 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: + +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 \ @@ -99,7 +103,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..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.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 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 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/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 9befb23d..ff03f654 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. | @@ -71,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. @@ -163,15 +165,35 @@ 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: + +```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 52fa1d63..4bd4a336 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,15 +68,16 @@ 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 +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/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/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/install.sh b/install.sh index e2b3d20f..a990cb56 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=() @@ -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/package-lock.json b/package-lock.json index 07ca5b37..f87aa59c 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", @@ -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,16 +2441,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2515,16 +2455,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2532,16 +2469,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2549,16 +2483,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2566,16 +2497,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2583,16 +2511,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2600,16 +2525,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2617,16 +2539,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2634,16 +2553,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2651,16 +2567,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2668,16 +2581,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2685,16 +2595,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2702,16 +2609,13 @@ ] }, "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" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2719,9 +2623,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 +2637,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 +2651,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 +2665,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 +2679,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 +2693,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 +2714,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 +2732,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 +2755,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 +2772,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 +2789,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,9 +2806,9 @@ } }, "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" ], @@ -2917,9 +2823,9 @@ } }, "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" ], @@ -2933,10 +2839,44 @@ "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, + "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, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, "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" ], @@ -2951,9 +2891,9 @@ } }, "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" ], @@ -2968,9 +2908,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 +2925,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 +2942,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 +2966,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 +2976,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 +2999,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 +3069,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 +3097,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 +3140,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 +3167,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 +3203,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 +3219,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 +3234,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 +3265,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 +3275,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 +3307,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 +3330,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 +3346,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 +3366,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 +3389,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 +3411,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 +3424,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 +3448,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 +3467,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 +3491,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 +3553,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 +3575,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 +3609,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 +3627,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 +3654,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 +3667,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 +3681,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 +3697,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 +3707,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 +3730,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 +3807,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==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "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/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 +3866,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 +3905,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 +3925,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 +3955,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 +4007,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 +4027,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 +4074,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 +4105,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 +4211,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 +4248,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 +4261,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 +4327,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 +4391,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 +4403,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 +4442,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 +4467,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 +4491,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 +4503,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 +4683,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 +4718,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 +4745,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 +4758,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 +4874,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 +4912,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 +4948,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 +5020,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 +5092,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 +5115,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 +5166,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 +5237,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 +5255,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 +5339,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 +5351,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 +5377,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 +5429,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 +5446,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 +5597,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 +5658,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 +5691,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 +5745,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 +5878,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 +5917,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 +5946,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 +5987,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 +6029,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 +6106,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 +6116,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 +6151,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 +6176,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 +6187,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 +6206,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 +6265,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 +6449,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 +6598,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 +6672,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 +6690,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 +6725,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 +6743,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 +6832,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 +6897,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 +6909,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 +6934,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 +6992,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 +7018,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 +7038,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 +7058,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 +7110,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 +7154,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 +7168,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 +7186,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 +7258,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 +7268,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 +7285,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 +7297,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 +7342,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 +7399,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 +7421,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 +7490,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 +7511,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 +7540,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 +7601,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 +7632,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 +7642,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 +7658,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 +7740,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 +7753,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 +7775,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 +7788,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", @@ -8042,71 +7836,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 +7856,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 +7882,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 +7946,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 +7956,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 +7969,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 +7978,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 +8046,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 +8065,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 +8082,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 +8091,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 +8162,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 +8181,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 +8200,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 +8214,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 +8233,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 +8303,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 +8318,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 +8342,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 +8436,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 +8506,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 +8612,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 +8652,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 +8779,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 +8818,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 +8857,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 +8870,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 088a272e..00c8424a 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": { @@ -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", @@ -139,6 +138,6 @@ }, "overrides": { "lodash": "^4.18.0", - "source-map-js": "^1.2.2" + "postcss-selector-parser": "6.1.5" } } diff --git a/scripts/api-docs-generator.test.ts b/scripts/api-docs-generator.test.ts index 84314836..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"); @@ -298,7 +299,11 @@ 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"); + const corsSection = markdown.split("## Browser Origin And CORS")[1]?.split("\n## ")[0]; + expect(corsSection).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(""); 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 5225e4d5..0361919e 100644 --- a/scripts/release-metadata.test.ts +++ b/scripts/release-metadata.test.ts @@ -24,12 +24,13 @@ 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"')); - 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 }); } @@ -50,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=("$@") 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/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.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 9a342d1c..174c8501 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -87,13 +87,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; } @@ -382,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/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) { diff --git a/src/pages/Settings.test.tsx b/src/pages/Settings.test.tsx index 90afe563..e61d9bce 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", @@ -660,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(); @@ -723,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(() => { @@ -811,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/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" && (
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();