diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index c7dbf545..1ec6af64 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -3,20 +3,21 @@ This repository contains a VS Code extension that provides two webview-based tools for competitive programming: **Judge** and **Stress**. - Extension backend code lives under `src/extension/**` and uses the VS Code API. `JudgeViewProvider` and `StressViewProvider` extend `BaseViewProvider`, which handles webview setup, CSP nonce generation, workspaceState storage, and message dispatch. -- Webview frontend code lives under `src/webview/**` and is built with Preact. It talks to the extension only through typed messages defined in `src/shared/*-messages.ts`. -- Shared enums, message contracts, and types live under `src/shared/**` and define the protocol between extension and webviews (including the `Status` lifecycle and testcase structures). +- Webview frontend code lives under `src/webview/**` and is built with React + `@legendapp/state` for reactive state management. It talks to the extension only through typed messages defined in `src/shared/*-messages.ts`. +- Shared enums, message contracts, and Valibot schemas live under `src/shared/**` and define the protocol between extension and webviews (including the `Status` lifecycle in `enums.ts` and testcase structures in `schemas.ts`). Build and tooling: - Use `bun install` to install dependencies. -- Use `bun run watch` during development and `bun run prod` for production builds. The build is two-stage: Tailwind CLI compiles `src/styles/global.css` to `dist/styles.css`, then Rspack bundles the extension and webviews into `dist/`. -- Run `bun run lint` and `bun run format` to apply ESLint (TypeScript + Preact) and Prettier rules. +- Use `bun run watch` during development and `bun run prod` for production builds. Rspack bundles the extension and webviews into `dist/`. Each webview has its own `index.css` stylesheet that is bundled alongside its JavaScript. +- Run `bun run lint` and `bun run format` to apply ESLint (TypeScript + React) and Prettier rules. Design and implementation guidelines: -- All extension ↔ webview communication must use the discriminated unions and enums in `src/shared/*-messages.ts`. Append to enums instead of reordering to keep numeric values and stored data stable. +- All extension ↔ webview communication must use the discriminated unions and Valibot schemas in `src/shared/*-messages.ts`. Append to enums instead of reordering to keep numeric values and stored data stable. - Use `compile()` and `Runnable` from `src/extension/utils/runtime.ts` for running code, and `resolveVariables` / `resolveCommand` from `src/extension/utils/vscode.ts` for safe, cross-platform commands. - Use `TextHandler` for streamed output; always call `.reset()` for a fresh run and `.write(data, last)` for updates. +- Use `@legendapp/state` for webview state: wrap components with `observer()`, access values via `.get()`, mutate via `.set()`, and use `` for reactive list rendering. - Keep changes minimal and consistent with existing patterns. Prefer reusing the Judge/Stress provider and webview patterns over introducing new architectures. Additional path-specific details are defined in `.github/instructions/*.instructions.md`, which Copilot uses when working in matching files. diff --git a/.github/instructions/build-and-config.instructions.md b/.github/instructions/build-and-config.instructions.md index 0376a4a9..72d8300a 100644 --- a/.github/instructions/build-and-config.instructions.md +++ b/.github/instructions/build-and-config.instructions.md @@ -1,17 +1,15 @@ --- -applyTo: "package.json,rspack.config.ts,eslint.config.ts,tailwind.config.ts,tsconfig*.json" +applyTo: "package.json,rspack.config.ts,eslint.config.ts,tsconfig*.json" --- -This repository uses Bun, Rspack, Tailwind CSS, TypeScript, and ESLint to build and lint the Fast Olympic Coding VS Code extension and its webviews. +This repository uses Bun, Rspack, TypeScript, and ESLint to build and lint the Fast Olympic Coding VS Code extension and its webviews. When working on the build, config, or tooling files matched by this pattern: - Use `bun install` to install dependencies. Prefer Bun scripts in `package.json` over ad-hoc commands. -- During development, run `bun run watch` to start Rspack and the Tailwind CLI in watch mode. For production builds, use `bun run prod` to generate minified, no-sourcemap bundles. -- The build is two-stage: - - `build:css`: Tailwind CLI reads from `src/styles/global.css` and writes `dist/styles.css`. - - `build:js`: Rspack bundles the extension backend and webview frontends into `dist/`. -- The Rspack configuration (`rspack.config.ts`) exports two configs: one targeting Node.js/CommonJS for the extension, and one targeting the web/ES modules for the webviews (TypeScript/TSX with Preact). Keep this separation intact when modifying the config. +- During development, run `bun run watch` to start Rspack in watch mode. For production builds, use `bun run prod` to generate minified, no-sourcemap bundles. +- Rspack bundles the extension backend and webview frontends into `dist/`. Each webview has its own `index.css` stylesheet that is bundled alongside its JavaScript. +- The Rspack configuration (`rspack.config.ts`) exports two configs: one targeting Node.js/CommonJS for the extension, and one targeting the web/ES modules for the webviews (TypeScript/TSX with React). Keep this separation intact when modifying the config. - Type-checking is handled by ForkTsCheckerWebpackPlugin, using `tsconfig.node.json` for the extension and `tsconfig.app.json` for the webviews. Keep these project files aligned with the respective code trees. -- For quality gates, use `bun run lint` (ESLint with TypeScript + Preact rules) and `bun run format` (Prettier). Avoid adding overlapping or conflicting linters/formatters. -- Prefer minimal, focused config changes. Avoid introducing large new toolchains or build systems; extend the existing Rspack + Tailwind + Bun setup instead. +- For quality gates, use `bun run lint` (ESLint with TypeScript + React rules) and `bun run format` (Prettier). Avoid adding overlapping or conflicting linters/formatters. +- Prefer minimal, focused config changes. Avoid introducing large new toolchains or build systems; extend the existing Rspack + Bun setup instead. diff --git a/.github/instructions/extension-backend.instructions.md b/.github/instructions/extension-backend.instructions.md index 2d201630..fa68c36c 100644 --- a/.github/instructions/extension-backend.instructions.md +++ b/.github/instructions/extension-backend.instructions.md @@ -6,11 +6,12 @@ This repository is a VS Code extension called "Fast Olympic Coding." The `src/ex When changing files under `src/extension/**`: -- Treat `JudgeViewProvider` and `StressViewProvider` as the main controllers for their respective webviews. They extend `BaseViewProvider`, which encapsulates webview setup, CSP nonce generation, message posting, and workspaceState access keyed by active file path. -- All extension ⇄ webview communication must go through the discriminated unions and enums in `src/shared/*-messages.ts`. Do not introduce ad-hoc string message types; instead, extend the shared enums and message unions. -- The `Status` enum in `src/shared/types.ts` represents the lifecycle: COMPILING → RUNNING → (AC | WA | RE | TL | CE | NA | EDITING). Preserve existing numeric values and append new states only at the end. +- Treat `JudgeViewProvider` and `StressViewProvider` as the main controllers for their respective webviews. They extend `BaseViewProvider`, which encapsulates webview setup, CSP nonce generation, message posting via Valibot-validated schemas, and workspaceState access keyed by active file path. +- Webviews rely on Codicons for icons; `BaseViewProvider` already whitelists `@vscode/codicons/dist/codicon.css` in local resource roots and injects the stylesheet. Preserve that setup (CSP, resource roots, and link tag) whenever adjusting webview HTML or resource handling so icons keep rendering. +- All extension ⇄ webview communication must go through the discriminated unions and Valibot schemas in `src/shared/*-messages.ts`. Do not introduce ad-hoc string message types; instead, extend the shared enums and message unions. +- The `Status` enum in `src/shared/enums.ts` represents the lifecycle: COMPILING → RUNNING → (AC | WA | RE | TL | CE | NA | EDITING). Preserve existing numeric values and append new states only at the end. - Persisted testcases and limits are stored in `workspaceState`, with a top-level key per view ("judge" / "stress") and an inner key per absolute file path. Treat the "default" state (no testcases and timeLimit = 0) as "no data" and delete storage entries rather than persisting defaults indefinitely. -- Use `TextHandler` (from the extension utilities) for all streamed output shown in the webviews. Always call `.reset()` before a fresh run and `.write(data, last)` to update output so truncation, batching, and whitespace handling remain correct. +- Use `TextHandler` (from the extension utilities) for all streamed output shown in the webviews. It must keep the full data for comparisons while truncating display output, normalizes CRLF to LF, and ensures a trailing newline on final writes. Always call `.reset()` before a fresh run and `.write(data, last)` to update output so truncation, batching, and whitespace handling remain correct. - For compilation and execution, use the helpers in `src/extension/utils/runtime.ts`. Specifically, use `compile()` (which caches builds by md5 of the full command) and `Runnable` (which wraps child processes with timing, timeout via `AbortSignal.timeout`, and exit/timeout information) instead of spawning processes manually. - In the Stress view logic, keep the sequential generator pattern that feeds testcases to the solution and reference solution, and ensure the loop respects both per-test (`stressTestcaseTimeLimit`) and global (`stressTimeLimit`) limits while exiting early on the first mismatch or failure for speed. - Always resolve command variables via `resolveVariables` / `resolveCommand` from `src/extension/utils/vscode.ts` before spawning external processes. Use built-in variables like `${exeExtname}`, `${path:...}`, and `${fileDirnameBasename}` for cross-platform-safe paths. diff --git a/.github/instructions/shared-contracts.instructions.md b/.github/instructions/shared-contracts.instructions.md index 4d093204..cad09366 100644 --- a/.github/instructions/shared-contracts.instructions.md +++ b/.github/instructions/shared-contracts.instructions.md @@ -2,20 +2,20 @@ applyTo: "src/shared/**/*.ts" --- -The `src/shared/**` directory contains enums, message contracts, schemas, and shared types used by both the extension backend (`src/extension/**`) and the webview frontend (`src/webview/**`). These files define the public protocol between the two halves of the extension. +The `src/shared/**` directory contains enums, Valibot schemas, message contracts, and shared types used by both the extension backend (`src/extension/**`) and the webview frontend (`src/webview/**`). These files define the public protocol between the two halves of the extension. When changing files under `src/shared/**`: -- Treat the message and enum definitions here as the single source of truth for extension ↔ webview communication. All messages should be discriminated unions with clear `type` or `kind` fields, and both sides should switch on these discriminants. +- Treat the message and enum definitions here as the single source of truth for extension ↔ webview communication. All messages use Valibot schemas (e.g., `v.object()`, `v.literal()`, `v.enum()`) with discriminated unions via `v.union([...])` and `type` fields, and both sides should switch on these discriminants. - When you add new message types or enum members, append them to the existing enums instead of reordering or renaming values. This preserves numeric enum identifiers and avoids breaking persisted data (for example, stored `Status` values). -- Keep message payloads minimal but explicit. Prefer well-typed fields over loosely structured objects to make it clear what each side should expect. +- Keep message payloads minimal but explicit. Prefer well-typed Valibot schemas over loosely structured objects to make it clear what each side should expect. - If you change a shared type, update both the extension providers (under `src/extension/providers/**`) and the corresponding webview handlers (under `src/webview/**`) in the same change to avoid protocol drift. -- The `Status` enum in `types.ts` models the run lifecycle: COMPILING → RUNNING → (AC | WA | RE | TL | CE | NA | EDITING). Preserve these semantics when adding new statuses and ensure the UI and backend continue to interpret them consistently. -- Schemas and validation helpers here should remain lightweight and focused on the Judge/Stress workflows. Avoid introducing heavy validation frameworks unless absolutely required. +- The `Status` enum in `enums.ts` models the run lifecycle: COMPILING → RUNNING → (AC | WA | RE | TL | CE | NA | EDITING). Preserve these semantics when adding new statuses and ensure the UI and backend continue to interpret them consistently. +- Use Valibot (`import * as v from "valibot"`) for all schemas. Define individual message schemas, then combine them into a union schema and export an inferred type (e.g., `type WebviewMessage = v.InferOutput`). - Because these contracts are central to the extension's behavior, keep changes focused and backwards-compatible wherever possible. When adding a new feature that requires extension ↔ webview communication: -- First, define or extend the shared contract in `src/shared/` (add a new enum member, interface, and union entry as needed). Append to existing enums rather than reordering to keep numeric values stable. +- First, define or extend the shared contract in `src/shared/` (add a new enum member, Valibot schema, and union entry). Append to existing enums rather than reordering to keep numeric values stable. - Then update the relevant Provider class under `src/extension/providers/` to mutate its internal state, call `_postMessage` with the new message type, and persist state via `writeStorage()` only after all mutations are complete. -- Finally, implement handling for the new message type on the webview side under `src/webview/**`, updating the relevant `App.tsx` and components to react to the new messages. Do not rely on message ordering beyond the established initial `INITIAL_STATE` / `SHOW` messages. +- Finally, implement handling for the new message type on the webview side under `src/webview/**`, adding a case to the `window.addEventListener("message", ...)` handler in `App.tsx`. Do not rely on message ordering beyond the established initial `INITIAL_STATE` / `SHOW` messages. diff --git a/.github/instructions/webview-frontend.instructions.md b/.github/instructions/webview-frontend.instructions.md index 493dd131..941aa353 100644 --- a/.github/instructions/webview-frontend.instructions.md +++ b/.github/instructions/webview-frontend.instructions.md @@ -2,15 +2,24 @@ applyTo: "src/webview/**/*.ts,src/webview/**/*.tsx" --- -The `src/webview/**` tree contains the Preact-based frontend code for the Judge and Stress webviews. These run in an isolated browser-like environment, not in the VS Code extension host. +The `src/webview/**` tree contains the React-based frontend code for the Judge and Stress webviews. These run in an isolated browser-like environment, not in the VS Code extension host. When changing files under `src/webview/**`: -- Do not import the `vscode` module here; webview code should communicate with the extension only via the typed message contracts defined in `src/shared/*-messages.ts`. -- Treat the `App.tsx` components under `src/webview/judge/` and `src/webview/stress/` as entry points for each view. They receive initial state and subsequent updates exclusively through message types defined in the shared message unions. -- When you need new messages or actions from the webview to the extension, first extend the shared enums and message interfaces in `src/shared/*-messages.ts`, then update both the extension providers and the webview components to handle the new types. Avoid magic string message names. -- Assume styles are provided by an external CSS file built from `src/styles/global.css` into `dist/styles.css` via Tailwind CLI. Do not import CSS directly into TypeScript/TSX; the extension side (`BaseViewProvider`) injects the stylesheet as a `` in the webview HTML. -- Prefer the existing lightweight stack (Preact + signals) for state management. Avoid introducing heavier frontend state libraries; instead, follow the current patterns used in the Judge and Stress apps. +- Do not import the `vscode` module here; webview code should communicate with the extension only via `postProviderMessage()` from each view's `message.ts` file, which wraps `vscode.postMessage()` with typed contracts from `src/shared/*-messages.ts`. +- Treat the `App.tsx` components under `src/webview/judge/` and `src/webview/stress/` as entry points for each view. They receive initial state and subsequent updates exclusively through message types defined in the shared message unions via `window.addEventListener("message", ...)`. +- Codicons are the icon set used across the webviews. The backend already exposes `@vscode/codicons/dist/codicon.css`; prefer the existing `codicon-` classes instead of adding new icon libraries or custom SVG sprite sheets unless strictly necessary. +- When you need new messages or actions from the webview to the extension, first extend the shared enums and Valibot schemas in `src/shared/*-messages.ts`, then update both the extension providers and the webview components to handle the new types. Avoid magic string message names. +- Each webview has its own `index.css` stylesheet (e.g., `src/webview/judge/index.css`, `src/webview/stress/index.css`). Import it in the webview's entry file (`index.tsx`). The CSS is bundled by Rspack alongside the webview JavaScript. +- Use `@legendapp/state` for reactive state management: + - Wrap components with `observer()` from `@legendapp/state/react` for automatic re-rendering. + - Access observable values with `.get()` and mutate with `.set(value)` or `.set(prev => newValue)`. + - Use `` for reactive list rendering; it efficiently handles additions/removals without re-rendering the entire list. + - Use `useObservable(value)` for component-local observable state. + - Collections like `Map` and `Set` have fine-grained reactivity; use `state$.map.get(key)` to get an observable for a specific entry. + - Avoid introducing additional state libraries; follow the patterns in the Judge and Stress apps. +- Shared webview utilities live in `src/webview/utils.ts` (e.g., `getStatusColor`). - Keep UI logic decoupled from process execution details. The webview should focus on rendering state and sending/receiving typed messages, not on spawning processes or resolving filesystem paths. - Maintain consistency with existing components such as `AutoresizeTextarea`, `Testcase`, and `State` in terms of props, message handling, and minimal DOM manipulation. +- Keep the file layout lean (e.g., flat component files per view) and avoid introducing extra nested directories unless there's a clear benefit; mirror the existing Judge/Stress structure when adding new pieces. - Keep changes surgical: avoid large-scale refactors or stylistic rewrites unless they are necessary for a specific task. diff --git a/.vscodeignore b/.vscodeignore index 580c539f..26b477f7 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -4,6 +4,7 @@ !LICENSE !media/icon.png !dist/judge/index.js +!dist/judge/index.css !dist/stress/index.js -!dist/extension.js -!dist/styles.css \ No newline at end of file +!dist/stress/index.css +!dist/extension.js \ No newline at end of file diff --git a/bun.lock b/bun.lock index fe5ef0e7..626c4ec8 100644 --- a/bun.lock +++ b/bun.lock @@ -5,55 +5,37 @@ "": { "name": "vscode-fastolympiccoding", "dependencies": { - "@preact/signals": "^2.5.1", - "nu-observables": "^0.0.7", - "preact": "^10.27.2", - "valibot": "^1.1.0", + "@legendapp/state": "3.0.0-beta.42", + "@vscode/codicons": "^0.0.44", + "react": "^19.2.1", + "react-dom": "^19.2.1", + "valibot": "^1.2.0", }, "devDependencies": { - "@rspack/cli": "^1.6.4", - "@tailwindcss/postcss": "^4.1.17", - "@types/node": "^22.19.1", + "@rspack/cli": "^1.6.7", + "@types/node": "^22.19.2", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@types/vscode": "^1.106.1", "@types/vscode-webview": "^1.57.5", - "@typescript-eslint/eslint-plugin": "^8.47.0", - "@typescript-eslint/parser": "^8.47.0", + "@typescript-eslint/eslint-plugin": "^8.49.0", + "@typescript-eslint/parser": "^8.49.0", "eslint": "^9.39.1", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-preact": "^0.1.0", "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "globals": "^16.5.0", - "postcss": "^8.5.6", - "postcss-load-config": "^6.0.1", - "postcss-loader": "^8.2.0", "prettier": "3.6.2", - "tailwindcss": "^4.1.17", "typescript": "^5.9.3", }, }, }, "packages": { - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - "@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="], - - "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], - - "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], - "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], - - "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], - - "@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], - - "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], - "@discoveryjs/json-ext": ["@discoveryjs/json-ext@0.5.7", "", {}, "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw=="], "@emnapi/core": ["@emnapi/core@1.7.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw=="], @@ -90,8 +72,6 @@ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], @@ -112,9 +92,9 @@ "@jsonjoy.com/util": ["@jsonjoy.com/util@1.9.0", "", { "dependencies": { "@jsonjoy.com/buffers": "^1.0.0", "@jsonjoy.com/codegen": "^1.0.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ=="], - "@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="], + "@legendapp/state": ["@legendapp/state@3.0.0-beta.42", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "expo-sqlite": "^15.0.0" }, "optionalPeers": ["expo-sqlite"] }, "sha512-KoGZrBdbHG5gMzP4NjKRsGZgTyy6pG+HBSyKrniL6NLsjG8L+hbYC21tIfdMvt1Xks1kTRAaqevatc4C7Yn/Uw=="], - "@mdn/browser-compat-data": ["@mdn/browser-compat-data@3.3.14", "", {}, "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA=="], + "@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="], "@module-federation/error-codes": ["@module-federation/error-codes@0.21.2", "", {}, "sha512-mGbPAAApgjmQUl4J7WAt20aV04a26TyS21GDEpOGXFEQG5FqmZnSJ6FqB8K19HgTKioBT1+fF/Ctl5bGGao/EA=="], @@ -132,10 +112,6 @@ "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], - "@preact/signals": ["@preact/signals@2.5.1", "", { "dependencies": { "@preact/signals-core": "^1.12.0" }, "peerDependencies": { "preact": ">= 10.25.0 || >=11.0.0-0" } }, "sha512-VPjk5YFt7i11Fi4UK0tzaEe5xLwfhUxXL3l89ocxQ5aPz7bRo8M5+N73LjBMPklyXKYKz6YsNo4Smp8n6nplng=="], - - "@preact/signals-core": ["@preact/signals-core@1.12.1", "", {}, "sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA=="], - "@rspack/binding": ["@rspack/binding@1.6.1", "", { "optionalDependencies": { "@rspack/binding-darwin-arm64": "1.6.1", "@rspack/binding-darwin-x64": "1.6.1", "@rspack/binding-linux-arm64-gnu": "1.6.1", "@rspack/binding-linux-arm64-musl": "1.6.1", "@rspack/binding-linux-x64-gnu": "1.6.1", "@rspack/binding-linux-x64-musl": "1.6.1", "@rspack/binding-wasm32-wasi": "1.6.1", "@rspack/binding-win32-arm64-msvc": "1.6.1", "@rspack/binding-win32-ia32-msvc": "1.6.1", "@rspack/binding-win32-x64-msvc": "1.6.1" } }, "sha512-6duvh3CbDA3c4HpNkzIOP9z1wn/mKY1Mrxj+AqgcNvsE0ppp1iKlMsJCDgl7SlUauus2AgtM1dIEU+0sRajmwQ=="], "@rspack/binding-darwin-arm64": ["@rspack/binding-darwin-arm64@1.6.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-am7gVsqicKY/FhDfNa/InHxrBd3wRt6rI7sFTaunKaPbPERjWSKr/sI47tB3t8uNYmLQFFhWFijomAhDyrlHMg=="], @@ -166,36 +142,6 @@ "@rspack/lite-tapable": ["@rspack/lite-tapable@1.0.1", "", {}, "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w=="], - "@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="], - - "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "postcss": "^8.4.41", "tailwindcss": "4.1.17" } }, "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], @@ -232,6 +178,10 @@ "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], + "@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="], + + "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], + "@types/retry": ["@types/retry@0.12.2", "", {}, "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow=="], "@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], @@ -250,8 +200,6 @@ "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.49.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.49.0", "@typescript-eslint/type-utils": "8.49.0", "@typescript-eslint/utils": "8.49.0", "@typescript-eslint/visitor-keys": "8.49.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.49.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-JXij0vzIaTtCwu6SxTh8qBc66kmf1xs7pI4UOiMDFVct6q86G0Zs7KRcEoJgY3Cav3x5Tq0MF5jwgpgLqgKG3A=="], - "@typescript-eslint/experimental-utils": ["@typescript-eslint/experimental-utils@2.34.0", "", { "dependencies": { "@types/json-schema": "^7.0.3", "@typescript-eslint/typescript-estree": "2.34.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, "peerDependencies": { "eslint": "*" } }, "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.49.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.49.0", "@typescript-eslint/types": "8.49.0", "@typescript-eslint/typescript-estree": "8.49.0", "@typescript-eslint/visitor-keys": "8.49.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-N9lBGA9o9aqb1hVMc9hzySbhKibHmB+N3IpoShyV6HyQYRGIhlrO5rQgttypi+yEeKsKI4idxC8Jw6gXKD4THA=="], "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.49.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.49.0", "@typescript-eslint/types": "^8.49.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g=="], @@ -270,6 +218,8 @@ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.49.0", "", { "dependencies": { "@typescript-eslint/types": "8.49.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA=="], + "@vscode/codicons": ["@vscode/codicons@0.0.44", "", {}, "sha512-F7qPRumUK3EHjNdopfICLGRf3iNPoZQt+McTHAn4AlOWPB3W2kL4H0S7uqEqbyZ6rCxaeDjpAn3MCUnwTu/VJQ=="], + "@webassemblyjs/ast": ["@webassemblyjs/ast@1.14.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ=="], "@webassemblyjs/floating-point-hex-parser": ["@webassemblyjs/floating-point-hex-parser@1.13.2", "", {}, "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA=="], @@ -344,14 +294,10 @@ "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], - "ast-metadata-inferer": ["ast-metadata-inferer@0.7.0", "", { "dependencies": { "@mdn/browser-compat-data": "^3.3.14" } }, "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q=="], - "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], - "babel-eslint": ["babel-eslint@10.1.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.7.0", "@babel/traverse": "^7.7.0", "@babel/types": "^7.7.0", "eslint-visitor-keys": "^1.0.0", "resolve": "^1.12.0" }, "peerDependencies": { "eslint": ">= 4.12.1" } }, "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg=="], - "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "baseline-browser-mapping": ["baseline-browser-mapping@2.8.25", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA=="], @@ -416,14 +362,14 @@ "cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="], - "core-js": ["core-js@3.46.0", "", {}, "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA=="], - "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], "cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], "data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="], @@ -452,8 +398,6 @@ "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], "dns-packet": ["dns-packet@5.6.1", "", { "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" } }, "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw=="], @@ -472,8 +416,6 @@ "enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], - "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], - "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], "es-abstract": ["es-abstract@1.24.0", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg=="], @@ -502,23 +444,13 @@ "eslint": ["eslint@9.39.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.1", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g=="], - "eslint-config-developit": ["eslint-config-developit@1.2.0", "", { "dependencies": { "babel-eslint": "^10.1.0", "eslint-plugin-compat": "^3.5.1", "eslint-plugin-jest": "^23.8.2", "eslint-plugin-mocha": "^6.3.0", "eslint-plugin-react": "^7.0.0" }, "peerDependencies": { "eslint": ">=5" } }, "sha512-uUXirRR5R06sqsPgOk8XlA65HRxXNSlg5vPmyLvFwksCibZZLI/RxszuAn6R2EZ6tJUIJupLrVw8fkDYX3TVsQ=="], - "eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="], - "eslint-plugin-compat": ["eslint-plugin-compat@3.13.0", "", { "dependencies": { "@mdn/browser-compat-data": "^3.3.14", "ast-metadata-inferer": "^0.7.0", "browserslist": "^4.16.8", "caniuse-lite": "^1.0.30001251", "core-js": "^3.16.2", "find-up": "^5.0.0", "lodash.memoize": "4.1.2", "semver": "7.3.5" }, "peerDependencies": { "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA=="], - - "eslint-plugin-jest": ["eslint-plugin-jest@23.20.0", "", { "dependencies": { "@typescript-eslint/experimental-utils": "^2.5.0" }, "peerDependencies": { "eslint": ">=5" } }, "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw=="], - - "eslint-plugin-mocha": ["eslint-plugin-mocha@6.3.0", "", { "dependencies": { "eslint-utils": "^2.0.0", "ramda": "^0.27.0" }, "peerDependencies": { "eslint": ">= 4.0.0" } }, "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg=="], - - "eslint-plugin-preact": ["eslint-plugin-preact@0.1.0", "", { "dependencies": { "eslint-config-developit": "^1.1.1" } }, "sha512-/ZNTjrTLhDOkZmW8cY6W91lfrGEhyF5i0KFRhjlvCAPcWENxeXlx1TKbKgzjyvGtei8c2WlvWCgxO5PdyXe0EA=="], - "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="], - "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="], - "eslint-utils": ["eslint-utils@2.1.0", "", { "dependencies": { "eslint-visitor-keys": "^1.1.0" } }, "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg=="], + "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], @@ -580,8 +512,6 @@ "fs-monkey": ["fs-monkey@1.1.0", "", {}, "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw=="], - "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -598,8 +528,6 @@ "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], - "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], - "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], "glob-to-regex.js": ["glob-to-regex.js@1.2.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ=="], @@ -656,8 +584,6 @@ "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], - "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], - "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], @@ -742,8 +668,6 @@ "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], - "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], @@ -762,50 +686,16 @@ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], - "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], - - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], - - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="], - - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="], - - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="], - - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="], - - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="], - - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="], - - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], - - "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], - "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "loader-runner": ["loader-runner@4.3.1", "", {}, "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q=="], "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], - "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], - - "lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="], - "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], - "lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], @@ -836,8 +726,6 @@ "multicast-dns": ["multicast-dns@7.2.5", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="], - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], @@ -852,8 +740,6 @@ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - "nu-observables": ["nu-observables@0.0.7", "", {}, "sha512-DeXs3xbaUT7lyTDd0UKqaZa+s5liI1mdimIOlRvkOqpZBFiihJ9aMKyAMII/Mmcx9tLTtLVQOEPDNEg91bQZ3A=="], - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], @@ -874,8 +760,6 @@ "on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="], - "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - "open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], "opener": ["opener@1.5.2", "", { "bin": { "opener": "bin/opener-bin.js" } }, "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A=="], @@ -898,8 +782,6 @@ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], - "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], - "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], @@ -914,14 +796,6 @@ "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], - "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], - - "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], - - "postcss-loader": ["postcss-loader@8.2.0", "", { "dependencies": { "cosmiconfig": "^9.0.0", "jiti": "^2.5.1", "semver": "^7.6.2" }, "peerDependencies": { "@rspack/core": "0.x || 1.x", "postcss": "^7.0.0 || ^8.0.1", "webpack": "^5.0.0" }, "optionalPeers": ["@rspack/core", "webpack"] }, "sha512-tHX+RkpsXVcc7st4dSdDGliI+r4aAQDuv+v3vFYHixb6YgjreG5AG4SEB0kDK8u2s6htqEEpKlkhSBUTvWKYnA=="], - - "preact": ["preact@10.28.0", "", {}, "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA=="], - "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="], @@ -936,14 +810,16 @@ "qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="], - "ramda": ["ramda@0.27.2", "", {}, "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA=="], - "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], "raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="], + "react": ["react@19.2.1", "", {}, "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw=="], + + "react-dom": ["react-dom@19.2.1", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.1" } }, "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg=="], + "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], @@ -976,6 +852,8 @@ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + "schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], "select-hose": ["select-hose@2.0.0", "", {}, "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg=="], @@ -1020,8 +898,6 @@ "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], "spdy": ["spdy@4.0.2", "", { "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" } }, "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA=="], @@ -1050,8 +926,6 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="], - "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], "terser": ["terser@5.44.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw=="], @@ -1076,8 +950,6 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "tsutils": ["tsutils@3.21.0", "", { "dependencies": { "tslib": "^1.8.1" }, "peerDependencies": { "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA=="], - "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], @@ -1104,6 +976,8 @@ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], @@ -1144,14 +1018,10 @@ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], - "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], - "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], @@ -1162,18 +1032,6 @@ "@rspack/dev-server/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], - - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="], - - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], - - "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@types/body-parser/@types/node": ["@types/node@22.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA=="], "@types/bonjour/@types/node": ["@types/node@22.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA=="], @@ -1196,10 +1054,6 @@ "@types/ws/@types/node": ["@types/node@22.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA=="], - "@typescript-eslint/experimental-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@2.34.0", "", { "dependencies": { "debug": "^4.1.1", "eslint-visitor-keys": "^1.1.0", "glob": "^7.1.6", "is-glob": "^4.0.1", "lodash": "^4.17.15", "semver": "^7.3.2", "tsutils": "^3.17.1" } }, "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg=="], - - "@typescript-eslint/experimental-utils/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="], - "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -1210,10 +1064,6 @@ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "babel-eslint/eslint-visitor-keys": ["eslint-visitor-keys@1.3.0", "", {}, "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="], - - "babel-eslint/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], - "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "compressible/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], @@ -1222,10 +1072,6 @@ "eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], - "eslint-plugin-compat/semver": ["semver@7.3.5", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ=="], - - "eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@1.3.0", "", {}, "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="], - "express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -1240,10 +1086,6 @@ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "postcss-loader/cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], - - "postcss-loader/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "proxy-addr/ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -1258,8 +1100,6 @@ "terser-webpack-plugin/schema-utils": ["schema-utils@4.3.3", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA=="], - "tsutils/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], - "webpack/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="], "webpack/schema-utils": ["schema-utils@4.3.3", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA=="], @@ -1280,12 +1120,6 @@ "@rspack/dev-server/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "@typescript-eslint/experimental-utils/@typescript-eslint/typescript-estree/eslint-visitor-keys": ["eslint-visitor-keys@1.3.0", "", {}, "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="], - - "@typescript-eslint/experimental-utils/@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - - "@typescript-eslint/experimental-utils/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], - "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], diff --git a/eslint.config.ts b/eslint.config.ts index 394b655e..d424003f 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -2,19 +2,14 @@ import * as js from "@eslint/js"; import * as tseslint from "@typescript-eslint/eslint-plugin"; import * as tsparser from "@typescript-eslint/parser"; import * as react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; import prettier from "eslint-config-prettier"; import * as globals from "globals"; -// eslint-plugin-preact is CommonJS without types, use require -// eslint-disable-next-line @typescript-eslint/no-require-imports -const preact = require("eslint-plugin-preact") as { - configs: { recommended: { rules: Record } }; -}; - export default [ js.configs.recommended, { - ignores: ["dist/**", "node_modules/**", "src/external/**"], + ignores: ["dist/**", "node_modules/**"], }, { files: ["src/**/*.ts", "src/**/*.tsx"], @@ -35,11 +30,11 @@ export default [ plugins: { "@typescript-eslint": tseslint, react: react, - preact: preact, + "react-hooks": reactHooks, }, rules: { ...tseslint.configs.recommended.rules, - ...preact.configs.recommended.rules, + ...reactHooks.configs.recommended.rules, // Rely on TypeScript for undefined symbols in TS files "no-undef": "off", }, diff --git a/package.json b/package.json index a6b083dd..96315f21 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,56 @@ "onStartupFinished" ], "contributes": { + "menus": { + "view/title": [ + { + "command": "fastolympiccoding.runAll", + "group": "navigation@1", + "when": "view == fastolympiccoding.judge" + }, + { + "command": "fastolympiccoding.stopAll", + "group": "navigation@2", + "when": "view == fastolympiccoding.judge" + }, + { + "command": "fastolympiccoding.deleteAll", + "group": "navigation@3", + "when": "view == fastolympiccoding.judge" + }, + { + "command": "fastolympiccoding.saveAll", + "group": "navigation@4", + "when": "view == fastolympiccoding.judge" + }, + { + "command": "fastolympiccoding.toggleJudgeSettings", + "group": "navigation@5", + "when": "view == fastolympiccoding.judge" + }, + { + "command": "fastolympiccoding.startStressTest", + "group": "navigation@1", + "when": "view == fastolympiccoding.stress" + }, + { + "command": "fastolympiccoding.stopStressTest", + "group": "navigation@2", + "when": "view == fastolympiccoding.stress" + }, + { + "command": "fastolympiccoding.clearStressTest", + "group": "navigation@3", + "when": "view == fastolympiccoding.stress" + } + ], + "commandPalette": [ + { + "command": "fastolympiccoding.toggleJudgeSettings", + "when": "false" + } + ] + }, "viewsContainers": { "activitybar": [ { @@ -207,37 +257,44 @@ { "command": "fastolympiccoding.runAll", "title": "Run All Testcases", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(run-all)" }, { "command": "fastolympiccoding.stopAll", "title": "Stop All Testcases", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(circle-slash)" }, { "command": "fastolympiccoding.deleteAll", "title": "Delete All Testcases", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(clear-all)" }, { "command": "fastolympiccoding.saveAll", "title": "Save All Testcases", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(save-all)" }, { "command": "fastolympiccoding.startStressTest", "title": "Start Stress Test", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(debug-start)" }, { "command": "fastolympiccoding.stopStressTest", "title": "Stop Stress Test", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(debug-stop)" }, { "command": "fastolympiccoding.clearStressTest", "title": "Clear Stress Test", - "category": "Fast Olympic Coding" + "category": "Fast Olympic Coding", + "icon": "$(clear-all)" }, { "command": "fastolympiccoding.clearData", @@ -258,6 +315,12 @@ "command": "fastolympiccoding.stopCompetitiveCompanion", "title": "Stop Competitive Companion", "category": "Fast Olympic Coding" + }, + { + "command": "fastolympiccoding.toggleJudgeSettings", + "title": "Toggle Judge Settings", + "category": "Fast Olympic Coding", + "icon": "$(gear)" } ], "keybindings": [ @@ -315,29 +378,27 @@ "license": "MIT", "devDependencies": { "@rspack/cli": "^1.6.7", - "@tailwindcss/postcss": "^4.1.17", "@types/node": "^22.19.2", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@types/vscode": "^1.106.1", "@types/vscode-webview": "^1.57.5", "@typescript-eslint/eslint-plugin": "^8.49.0", "@typescript-eslint/parser": "^8.49.0", "eslint": "^9.39.1", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-preact": "^0.1.0", "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "globals": "^16.5.0", - "postcss": "^8.5.6", - "postcss-load-config": "^6.0.1", - "postcss-loader": "^8.2.0", "prettier": "3.6.2", - "tailwindcss": "^4.1.17", "typescript": "^5.9.3" }, "dependencies": { - "@preact/signals": "^2.5.1", - "nu-observables": "^0.0.7", - "preact": "^10.28.0", + "@legendapp/state": "3.0.0-beta.42", + "@vscode/codicons": "^0.0.44", + "react": "^19.2.1", + "react-dom": "^19.2.1", "valibot": "^1.2.0" } } diff --git a/postcss.config.ts b/postcss.config.ts deleted file mode 100644 index 42486cec..00000000 --- a/postcss.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { Config } from "postcss-load-config"; - -const config: Config = { - plugins: { - "@tailwindcss/postcss": {}, - }, -}; - -export default config; diff --git a/rspack.config.ts b/rspack.config.ts index 95246115..fed9ae24 100644 --- a/rspack.config.ts +++ b/rspack.config.ts @@ -1,18 +1,16 @@ import { defineConfig } from "@rspack/cli"; -import { type Configuration } from "@rspack/core"; +import { type Configuration, DefinePlugin } from "@rspack/core"; import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin"; import * as path from "node:path"; const isProd = process.env.NODE_ENV === "production"; const sharedResolve: Configuration["resolve"] = { - extensions: [".ts", ".tsx"], + extensions: [".ts", ".tsx", ".js", ".jsx"], alias: { "~shared": path.resolve("./src/shared"), "~webview": path.resolve("./src/webview"), "~extension": path.resolve("./src/extension"), - "~external": path.resolve("./src/external"), - "~styles": path.resolve("./src/styles"), }, }; @@ -79,10 +77,17 @@ const webviewsConfig: Configuration = { output: { path: path.resolve("./dist"), filename: "[name].js", - cssFilename: "styles.css", }, target: ["web", "es2015"], - resolve: sharedResolve, + resolve: { + ...sharedResolve, + alias: { + ...sharedResolve.alias, + // Ensure single React instance for all imports + react: path.resolve("./node_modules/react"), + "react-dom": path.resolve("./node_modules/react-dom"), + }, + }, module: { rules: [ { @@ -93,20 +98,18 @@ const webviewsConfig: Configuration = { jsc: { parser: { syntax: "typescript", tsx: true }, transform: { - react: { runtime: "automatic", importSource: "preact" }, + react: { runtime: "automatic" }, }, }, }, }, }, - { - test: /\.css$/, - use: ["postcss-loader"], - type: "css", - }, ], }, plugins: [ + new DefinePlugin({ + "process.env.NODE_ENV": JSON.stringify(isProd ? "production" : "development"), + }), new ForkTsCheckerWebpackPlugin({ typescript: { configFile: "tsconfig.app.json", diff --git a/src/extension/index.ts b/src/extension/index.ts index 3d7270a7..48cfa74a 100644 --- a/src/extension/index.ts +++ b/src/extension/index.ts @@ -143,6 +143,12 @@ function registerCommands(context: vscode.ExtensionContext): void { ) ); + context.subscriptions.push( + vscode.commands.registerTextEditorCommand("fastolympiccoding.toggleJudgeSettings", () => + judgeViewProvider.toggleWebviewSettings() + ) + ); + context.subscriptions.push( vscode.commands.registerTextEditorCommand( "fastolympiccoding.startStressTest", diff --git a/src/extension/providers/BaseViewProvider.ts b/src/extension/providers/BaseViewProvider.ts index be044392..8aaa40c8 100644 --- a/src/extension/providers/BaseViewProvider.ts +++ b/src/extension/providers/BaseViewProvider.ts @@ -34,7 +34,10 @@ export default abstract class BaseViewProvider< this._webview = webviewView.webview; webviewView.webview.options = { enableScripts: true, - localResourceRoots: [vscode.Uri.joinPath(this._context.extensionUri, "dist")], + localResourceRoots: [ + vscode.Uri.joinPath(this._context.extensionUri, "dist"), + vscode.Uri.joinPath(this._context.extensionUri, "node_modules", "@vscode", "codicons"), + ], }; webviewView.webview.html = this._getWebviewContent(webviewView.webview); webviewView.webview.onDidReceiveMessage((message: unknown) => { @@ -78,10 +81,20 @@ export default abstract class BaseViewProvider< } private _getWebviewContent(webview: vscode.Webview): string { - const config = vscode.workspace.getConfiguration("fastolympiccoding"); - const font = config.get("font")!; const scriptUri = this._getUri(webview, ["dist", this.view, "index.js"]); - const stylesUri = this._getUri(webview, ["dist", "styles.css"]); + const stylesUri = this._getUri(webview, ["dist", this.view, "index.css"]); + const codiconsUri = webview + .asWebviewUri( + vscode.Uri.joinPath( + this._context.extensionUri, + "node_modules", + "@vscode", + "codicons", + "dist", + "codicon.css" + ) + ) + .toString(); const nonce = getNonce(); return ` @@ -90,13 +103,9 @@ export default abstract class BaseViewProvider< - + - +
diff --git a/src/extension/providers/JudgeViewProvider.ts b/src/extension/providers/JudgeViewProvider.ts index 8bce4023..aca27276 100644 --- a/src/extension/providers/JudgeViewProvider.ts +++ b/src/extension/providers/JudgeViewProvider.ts @@ -243,6 +243,10 @@ export default class extends BaseViewProvider testcase.stderr.write("", true)); testcase.process.process?.stdout.once("end", () => testcase.stdout.write("", true)); testcase.process.process?.once("error", (data: Error) => { - super._postMessage({ - type: WebviewMessageType.STDIO, - id, - stdio: Stdio.STDERR, - data: data.message, - }); + testcase.stderr.write(data.message, true); super._postMessage({ type: WebviewMessageType.SET, id, @@ -555,12 +556,19 @@ export default class extends BaseViewProvider { err += data; }); - process.process?.on("error", (data) => { + process.process?.once("error", (data) => { err += data.stack; }); @@ -140,11 +140,11 @@ export async function compile( }); errorTerminal.set(file, terminal); - // FIXME remove this hack when https://github.com/microsoft/vscode/issues/87843 is resolved - await new Promise((resolve) => setTimeout(() => resolve(), 400)); + terminal.show(true); + // Ensure the pseudoterminal is opened before writing errors + await dummy.ready; dummy.write(err); - terminal.show(true); return process.exitCode; })(); compilePromise.set(file, promise); diff --git a/src/extension/utils/vscode.ts b/src/extension/utils/vscode.ts index 0ed143cc..e226962b 100644 --- a/src/extension/utils/vscode.ts +++ b/src/extension/utils/vscode.ts @@ -10,15 +10,38 @@ export type ILanguageSettings = v.InferOutput; export class ReadonlyTerminal implements vscode.Pseudoterminal { private _writeEmitter: vscode.EventEmitter = new vscode.EventEmitter(); private _closeEmitter: vscode.EventEmitter = new vscode.EventEmitter(); + private _readyResolver: (() => void) | undefined = undefined; + private _ready: Promise; + private _buffer: string[] = []; + private _opened = false; onDidWrite: vscode.Event = this._writeEmitter.event; onDidClose: vscode.Event = this._closeEmitter.event; + get ready(): Promise { + return this._ready; + } + + constructor() { + this._ready = new Promise((resolve) => { + this._readyResolver = resolve; + }); + } - open(): void {} + open(): void { + this._opened = true; + this._readyResolver?.(); + this._buffer.forEach((text) => this._writeEmitter.fire(text)); + this._buffer = []; + } write(text: string): void { // VSCode requires \r\n for newline, but keep existing \r\n - this._writeEmitter.fire(text.replace(/\n/g, "\r\n")); + const normalized = text.replace(/\n/g, "\r\n"); + if (!this._opened) { + this._buffer.push(normalized); + return; + } + this._writeEmitter.fire(normalized); } close(): void { @@ -26,9 +49,16 @@ export class ReadonlyTerminal implements vscode.Pseudoterminal { } } -// keeps 2 versions of input: -// 1. "condensed" version which all of 2 or more consecutive whitespaces are removed -// 2. "shortened" version which respects the specified maximum boundaries from the settings (not condensed like above) +/** + * Handles text data with constraints on maximum display characters and lines. + * + * The primary purpose of this class is to truncate text for UI display limits, + * while always preserving the full data internally for any downstream usage, + * such as answer checking (e.g., comparison with accepted stdout) or other logic + * that requires the complete, untruncated output. + * + * Competitive Companion states the inputs and outputs must end with a newline! + */ export class TextHandler { private static readonly INTERVAL: number = 30; private static _maxDisplayCharacters: number = vscode.workspace @@ -37,6 +67,7 @@ export class TextHandler { private static _maxDisplayLines: number = vscode.workspace .getConfiguration("fastolympiccoding") .get("maxDisplayLines")!; + private _data = ""; private _shortDataLength = 0; private _pending = ""; @@ -45,6 +76,42 @@ export class TextHandler { private _lastWrite = Number.NEGATIVE_INFINITY; private _callback: ((data: string) => void) | undefined = undefined; + private _appendPendingCharacter(char: string) { + if ( + this._shortDataLength >= TextHandler._maxDisplayCharacters || + this._newlineCount >= TextHandler._maxDisplayLines + ) { + return; + } + this._pending += char; + this._shortDataLength++; + this._newlineCount += char === "\n" ? 1 : 0; + } + + private _sendPendingIfNeeded(last: boolean) { + if (this._shortDataLength > TextHandler._maxDisplayCharacters) { + return; + } + + const now = Date.now(); + if (now - this._lastWrite < TextHandler.INTERVAL && !last) { + return; + } + + this._lastWrite = now; + if ( + this._shortDataLength === TextHandler._maxDisplayCharacters || + this._newlineCount === TextHandler._maxDisplayLines + ) { + this._pending += "..."; + this._shortDataLength = TextHandler._maxDisplayCharacters + 1; // prevent further appends + } + if (this._callback) { + this._callback(this._pending); + } + this._pending = ""; + } + get data() { return this._data; } @@ -56,57 +123,31 @@ export class TextHandler { write(_data: string, last: boolean) { const data = _data.replace(/\r\n/g, "\n"); // just avoid \r\n entirely - // Competitive Companion removes trailing spaces for every line + // Update the "full" version for (let i = 0; i < data.length; i++) { if (data[i] === " ") { this._spacesCount++; } else if (data[i] === "\n") { + this._appendPendingCharacter("\n"); this._data += "\n"; this._spacesCount = 0; } else { + for (let j = 0; j < this._spacesCount; j++) { + this._appendPendingCharacter(" "); + } + this._appendPendingCharacter(data[i]); + this._data += " ".repeat(this._spacesCount); this._data += data[i]; this._spacesCount = 0; } } + if (last && this._data.at(-1) !== "\n") { + this._appendPendingCharacter("\n"); this._data += "\n"; } - if (this._shortDataLength > TextHandler._maxDisplayCharacters) { - return; - } - - for ( - let i = 0; - i < data.length && - this._shortDataLength < TextHandler._maxDisplayCharacters && - this._newlineCount < TextHandler._maxDisplayLines; - i++ - ) { - if (data[i] === "\n") { - this._newlineCount++; - } - this._shortDataLength++; - this._pending += data[i]; - } - - const now = Date.now(); - if (now - this._lastWrite < TextHandler.INTERVAL && !last) { - return; - } - - this._lastWrite = now; - if ( - this._shortDataLength === TextHandler._maxDisplayCharacters || - this._newlineCount === TextHandler._maxDisplayLines - ) { - this._pending += "..."; - this._shortDataLength = TextHandler._maxDisplayCharacters + 1; - } - if (this._callback) { - this._callback(this._pending); - } - this._pending = ""; + this._sendPendingIfNeeded(last); } reset() { diff --git a/src/external/observable.ts b/src/external/observable.ts deleted file mode 100644 index 5e21be70..00000000 --- a/src/external/observable.ts +++ /dev/null @@ -1,147 +0,0 @@ -// originally from https://github.com/melnikov-s/preact-observables/blob/main/src/index.ts -// modified to use @preact/signals instead - -import { signal, effect, computed, batch, Signal } from "@preact/signals"; - -import { - createGraph, - getAdministration, - getInternalNode, - getObservable, - getObservableClassInstance, - getSource, - setAdministrationType, - ObjectAdministration, -} from "nu-observables"; - -export { isObservable } from "nu-observables"; - -class PreactObjectAdministration extends ObjectAdministration { - static proxyTraps: ProxyHandler = Object.assign({}, ObjectAdministration.proxyTraps, { - get(target, prop, proxy) { - if ( - !(prop in target) && - (typeof prop === "string" || typeof prop === "number") && - String(prop)[0] === "$" - ) { - return getSignal(proxy, prop.substring(1) as keyof typeof target); - } - - return ObjectAdministration.proxyTraps.get?.apply(null, arguments as any); - }, - } as ProxyHandler); -} - -export const graph = createGraph({ - batch, - effect, - createComputed(fn, context) { - const c = computed(fn.bind(context)); - return { - node: c, - get() { - return c.value; - }, - }; - }, - createAtom() { - let value = 0; - const s = signal(value); - - return { - node: s, - reportChanged() { - s.value = ++value; - return value; - }, - reportObserved() { - return s.value; - }, - }; - }, -}); - -setAdministrationType({ object: PreactObjectAdministration }, graph); - -export type PreactObservable = T extends Function - ? T - : T extends Map - ? Map> - : T extends Array - ? Array> - : T extends Set - ? Set> - : T extends WeakSet - ? WeakSet> - : T extends WeakMap - ? WeakMap> - : { - [key in keyof T]: T[key] extends object ? PreactObservable : T[key]; - } & { - readonly [key in keyof T as T[key] extends object - ? never - : `$${string & key}`]?: Signal; - }; - -export function observable(obj: T): PreactObservable { - return getObservable(obj, graph) as any; -} - -export function source(obj: PreactObservable | T): T { - return getSource(obj) as T; -} - -export class Observable { - constructor() { - return getObservableClassInstance(this, graph); - } -} - -export function reportChanged(obj: T): T { - const adm = getAdministration(obj); - adm.reportChanged(); - - return obj; -} - -export function reportObserved(obj: T, opts?: { deep?: boolean }): T { - const adm = getAdministration(obj); - - adm.reportObserved(opts?.deep); - - return obj; -} - -const signalMap: WeakMap = new WeakMap(); - -export function getSignal(obj: T, key: keyof T): Signal { - const node = getInternalNode(obj, key); - - if (node instanceof Signal) { - let signal = signalMap.get(node); - if (!signal) { - signal = new Signal(); - Object.defineProperties(signal, { - value: { - get() { - return obj[key]; - }, - set(v) { - return (obj[key] = v); - }, - }, - peek: { - value() { - return source(obj)[key]; - }, - }, - }); - - signalMap.set(node, signal); - } - - return signal!; - } - - return node; -} diff --git a/src/shared/judge-messages.ts b/src/shared/judge-messages.ts index ceb7ae79..d3291e30 100644 --- a/src/shared/judge-messages.ts +++ b/src/shared/judge-messages.ts @@ -81,6 +81,7 @@ export enum WebviewMessageType { SAVE_ALL = 4, SHOW = 5, INITIAL_STATE = 6, + SETTINGS_TOGGLE = 7, } export const NewMessageSchema = v.object({ @@ -131,6 +132,10 @@ export const InitialStateSchema = v.object({ timeLimit: v.number(), }); +export const SettingsToggleSchema = v.object({ + type: v.literal(WebviewMessageType.SETTINGS_TOGGLE), +}); + export const WebviewMessageSchema = v.union([ NewMessageSchema, SetMessageSchema, @@ -139,6 +144,7 @@ export const WebviewMessageSchema = v.union([ SaveAllMessageSchema, ShowMessageSchema, InitialStateSchema, + SettingsToggleSchema, ]); export type WebviewMessage = v.InferOutput; diff --git a/src/shared/types.ts b/src/shared/types.ts deleted file mode 100644 index 4f8ca3aa..00000000 --- a/src/shared/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import * as v from "valibot"; - -export enum Status { - CE = 0, - RE = 1, - WA = 2, - AC = 3, - NA = 4, - TL = 5, - COMPILING = 6, - RUNNING = 7, - EDITING = 8, -} - -export enum Stdio { - STDIN = 0, - STDERR = 1, - STDOUT = 2, - ACCEPTED_STDOUT = 3, -} diff --git a/src/styles/global.css b/src/styles/global.css deleted file mode 100644 index c659dd76..00000000 --- a/src/styles/global.css +++ /dev/null @@ -1,16 +0,0 @@ -@import "tailwindcss"; - -@layer base { - input[type="number"]::-webkit-outer-spin-button, - input[type="number"]::-webkit-inner-spin-button { - appearance: none; - margin: 0; - } - input[type="number"] { - appearance: textfield; - } -} - -.fade *:not(.unfade) { - opacity: 0.5; -} diff --git a/src/webview/AutoresizeTextarea.tsx b/src/webview/AutoresizeTextarea.tsx new file mode 100644 index 00000000..0ac33126 --- /dev/null +++ b/src/webview/AutoresizeTextarea.tsx @@ -0,0 +1,157 @@ +import { type Observable } from "@legendapp/state"; +import { observer } from "@legendapp/state/react"; +import { useCallback, useLayoutEffect, useRef, useState } from "react"; + +type Variant = "default" | "stderr" | "accepted" | "active"; + +function getVariantBorderColor(variant: Variant): string { + switch (variant) { + case "stderr": + return "var(--vscode-terminal-ansiRed)"; + case "accepted": + return "var(--vscode-terminal-ansiGreen)"; + case "active": + return "var(--vscode-inputOption-activeBorder)"; + default: + return "var(--vscode-editorWidget-border)"; + } +} + +interface Props { + input$: Observable; + readonly?: boolean; + hiddenOnEmpty?: boolean; + placeholder?: string; + onKeyUp?: (event: React.KeyboardEvent) => void; + onExpand?: () => void; + variant?: Variant; +} + +const AutoresizeTextarea = observer(function AutoresizeTextarea({ + input$, + readonly, + hiddenOnEmpty, + placeholder, + onKeyUp, + onExpand, + variant = "default", +}: Props) { + const textarea = useRef(null); + const value = input$.get() ?? ""; + const [isHovered, setIsHovered] = useState(false); + + useLayoutEffect(() => { + if (textarea.current) { + textarea.current.style.height = "inherit"; + textarea.current.style.height = `${textarea.current.scrollHeight}px`; + } + }, [value]); + + const handleChange = useCallback( + (event: React.ChangeEvent) => { + input$.set(event.target.value); + }, + [input$] + ); + + const handleKeyUp = useCallback( + (event: React.KeyboardEvent) => { + onKeyUp?.(event); + }, + [onKeyUp] + ); + + const handleExpand = useCallback(() => { + onExpand?.(); + }, [onExpand]); + + const handleMouseEnter = useCallback(() => { + setIsHovered(true); + }, []); + + const handleMouseLeave = useCallback(() => { + setIsHovered(false); + }, []); + + if (hiddenOnEmpty && (value === "" || value === "\n")) { + return null; + } + + const contentStyle = { + whiteSpace: "pre-wrap" as const, + border: `1px solid ${getVariantBorderColor(variant)}`, + borderRadius: "2px" as const, + boxSizing: "border-box" as const, + background: "var(--vscode-editor-background)", + width: "100%" as const, + marginBottom: "3px" as const, + fontFamily: "var(--vscode-editor-font-family)", + fontSize: "var(--vscode-editor-font-size)", + color: "var(--vscode-foreground)", + }; + + const expandButtonStyle = { + position: "absolute" as const, + top: "2px" as const, + right: "2px" as const, + border: "none" as const, + background: "transparent" as const, + color: "var(--vscode-foreground)", + cursor: "pointer" as const, + padding: "2px" as const, + display: "flex" as const, + alignItems: "center" as const, + justifyContent: "center" as const, + opacity: isHovered ? 1 : 0, + transition: "opacity 120ms ease-in-out", + pointerEvents: isHovered ? ("auto" as const) : ("none" as const), + }; + + return ( +
+ {readonly ? ( +
+ {value || placeholder} +
+ ) : ( +