diff --git a/eslint.config.js b/eslint.config.js index 2bb27c83e..f1c17752e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -18,6 +18,7 @@ export default tsEslint.config( "packages/babel-plugin-alloy/**/*", "packages/babel-preset-alloy/**/*", "packages/docs/**/*", + "packages/debug-ui/mock-server.js", "samples/**/*", // for some reason eslint is unhappy with some files in here "**/scripts/**/*", "**/cmd/**/*", diff --git a/package.json b/package.json index 177c75e5a..1fb71ab48 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,9 @@ "pnpm": { "patchedDependencies": { "@microsoft/tsdoc@0.15.1": "patches/@microsoft__tsdoc@0.15.1.patch" + }, + "overrides": { + "@vue/reactivity": "3.5.16" } } } diff --git a/packages/core/package.json b/packages/core/package.json index 5409f5ee8..14ca4ed29 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -25,6 +25,10 @@ "./components": { "development": "./src/components/index.ts", "import": "./dist/src/components/index.js" + }, + "./symbols": { + "development": "./src/symbols/index.ts", + "import": "./dist/src/symbols/index.js" } }, "browser": { @@ -45,16 +49,18 @@ "license": "MIT", "dependencies": { "@vue/reactivity": "catalog:", - "picocolors": "catalog:", "cli-table3": "catalog:", "pathe": "catalog:", - "prettier": "catalog:" + "picocolors": "catalog:", + "prettier": "catalog:", + "ws": "^8.18.2" }, "devDependencies": { "@alloy-js/cli": "workspace:~", "@alloy-js/rollup-plugin": "workspace:~", "@microsoft/api-extractor": "catalog:", "@rollup/plugin-typescript": "catalog:", + "@types/ws": "^8.18.1", "concurrently": "catalog:", "typescript": "catalog:", "vite": "catalog:", diff --git a/packages/core/src/components/Declaration.tsx b/packages/core/src/components/Declaration.tsx index 12f4b2430..5a46594ea 100644 --- a/packages/core/src/components/Declaration.tsx +++ b/packages/core/src/components/Declaration.tsx @@ -2,9 +2,9 @@ import { useContext } from "../context.js"; import { BinderContext } from "../context/binder.js"; import { DeclarationContext } from "../context/declaration.js"; import { onCleanup } from "../reactivity.js"; -import { Refkey } from "../refkey.js"; import type { Children } from "../runtime/component.js"; import { OutputSymbol } from "../symbols/output-symbol.js"; +import { Refkey } from "../symbols/refkey.js"; /** * Create a declaration by providing an already created symbol. The symbol is diff --git a/packages/core/src/components/MemberDeclaration.tsx b/packages/core/src/components/MemberDeclaration.tsx index 31ac72f3f..dea93e768 100644 --- a/packages/core/src/components/MemberDeclaration.tsx +++ b/packages/core/src/components/MemberDeclaration.tsx @@ -1,10 +1,10 @@ import { useContext } from "../context.js"; import { BinderContext } from "../context/binder.js"; import { MemberDeclarationContext } from "../context/member-declaration.js"; -import type { Refkey } from "../refkey.js"; import type { Children } from "../runtime/component.js"; import { OutputSymbolFlags } from "../symbols/flags.js"; import { OutputSymbol } from "../symbols/output-symbol.js"; +import type { Refkey } from "../symbols/refkey.js"; /** * Create a member declaration by providing a symbol name and optional symbol diff --git a/packages/core/src/components/Output.tsx b/packages/core/src/components/Output.tsx index 7c4c90f3a..1149ff3c4 100644 --- a/packages/core/src/components/Output.tsx +++ b/packages/core/src/components/Output.tsx @@ -1,8 +1,3 @@ -import { - createOutputBinder, - getSymbolCreator, - SymbolCreator, -} from "../binder.js"; import { BinderContext } from "../context/binder.js"; import { NamePolicyContext } from "../context/name-policy.js"; import { NamePolicy } from "../name-policy.js"; @@ -10,6 +5,11 @@ import { getContext } from "../reactivity.js"; import { PrintTreeOptions } from "../render.js"; import type { Children } from "../runtime/component.js"; import { extensionEffects } from "../slot.js"; +import { + createOutputBinder, + getSymbolCreator, + SymbolCreator, +} from "../symbols/binder.js"; import { SourceDirectory } from "./SourceDirectory.js"; // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/packages/core/src/components/ReferenceOrContent.tsx b/packages/core/src/components/ReferenceOrContent.tsx index e39ea6df0..a688bcf41 100644 --- a/packages/core/src/components/ReferenceOrContent.tsx +++ b/packages/core/src/components/ReferenceOrContent.tsx @@ -1,8 +1,8 @@ import { computed } from "@vue/reactivity"; import { useContext } from "../context.js"; import { BinderContext } from "../context/binder.js"; -import type { Refkey } from "../refkey.js"; import type { Children } from "../runtime/component.js"; +import type { Refkey } from "../symbols/refkey.js"; export interface ReferenceOrContentProps { readonly refkey: Refkey; diff --git a/packages/core/src/components/SourceFile.tsx b/packages/core/src/components/SourceFile.tsx index 137463e29..a2ae94bd7 100644 --- a/packages/core/src/components/SourceFile.tsx +++ b/packages/core/src/components/SourceFile.tsx @@ -3,9 +3,9 @@ import { useContext } from "../context.js"; import { SourceDirectoryContext } from "../context/source-directory.js"; import { SourceFileContext } from "../context/source-file.js"; import { getContext } from "../reactivity.js"; -import { Refkey } from "../refkey.js"; import { PrintTreeOptions } from "../render.js"; import type { Children, ComponentDefinition } from "../runtime/component.js"; +import { Refkey } from "../symbols/refkey.js"; import { Show } from "./Show.jsx"; export interface SourceFileProps extends PrintTreeOptions { diff --git a/packages/core/src/context/binder.ts b/packages/core/src/context/binder.ts index a94bdaf80..f755889fd 100644 --- a/packages/core/src/context/binder.ts +++ b/packages/core/src/context/binder.ts @@ -1,9 +1,9 @@ -import type { Binder } from "../binder.js"; import { type ComponentContext, createNamedContext, useContext, } from "../context.js"; +import type { Binder } from "../symbols/binder.js"; // eslint-disable-next-line @typescript-eslint/no-unused-vars import type { Output } from "../components/Output.js"; diff --git a/packages/core/src/context/source-file.ts b/packages/core/src/context/source-file.ts index 453731855..fed3bd105 100644 --- a/packages/core/src/context/source-file.ts +++ b/packages/core/src/context/source-file.ts @@ -1,6 +1,6 @@ import { ComponentContext, createNamedContext } from "../context.js"; -import type { Refkey } from "../refkey.js"; import { ComponentDefinition } from "../runtime/component.js"; +import type { Refkey } from "../symbols/refkey.js"; export interface SourceFileContext { path: string; diff --git a/packages/core/src/debug.ts b/packages/core/src/debug.ts index 8741f3a9c..d91578191 100644 --- a/packages/core/src/debug.ts +++ b/packages/core/src/debug.ts @@ -1,8 +1,209 @@ -import { isReactive } from "@vue/reactivity"; +import { isReactive, isRef, triggerRef } from "@vue/reactivity"; import Table from "cli-table3"; +import { readFile } from "fs/promises"; +import http from "http"; +import { dirname, extname, join as pathJoin } from "path"; +import { sep } from "pathe"; import pc from "picocolors"; +import { fileURLToPath } from "url"; +import { WebSocket, WebSocketServer } from "ws"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +// Serve static files from the package's dist root (two levels up from dist/src) +const uiDir = pathJoin(__dirname, ".."); + +const mimeTypes: Record = { + ".html": "text/html", + ".js": "application/javascript", + ".css": "text/css", + ".json": "application/json", + ".svg": "image/svg+xml", + ".png": "image/png", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".gif": "image/gif", + ".woff": "font/woff", + ".woff2": "font/woff2", +}; + import { contextsByKey } from "./context.js"; -import { Context, getContext } from "./reactivity.js"; +import { SourceFileContext } from "./context/source-file.js"; +import { Context, getContext, syncEffect, untrack } from "./reactivity.js"; +import { + getContextForRenderNode, + getRenderNodeForContext, + PrintHook, + printTree, + RenderedTextTree, +} from "./render.js"; +import { ComponentCreator, isComponentCreator } from "./runtime/component.js"; +import { flushJobs } from "./scheduler.js"; +import type { + OutputScope, + SerializedOutputScope, +} from "./symbols/output-scope.js"; +import type { + OutputSymbol, + SerializedOutputSymbol, +} from "./symbols/output-symbol.js"; + +// WebSocket event types +export interface WebSocketSymbolAdded { + type: "symbol_added"; + data: { + symbol: SerializedOutputSymbol; + nodeId: number | null; + }; +} + +export interface WebSocketSymbolUpdated { + type: "symbol_updated"; + data: { + symbol: SerializedOutputSymbol; + nodeId: number | null; + }; +} + +export interface WebSocketSymbolDeleted { + type: "symbol_deleted"; + data: { + symbolId: number; + }; +} + +export interface WebSocketScopeAdded { + type: "scope_added"; + data: { + scope: SerializedOutputScope; + nodeId: number | null; + }; +} + +export interface WebSocketScopeUpdated { + type: "scope_updated"; + data: { + scope: SerializedOutputScope; + nodeId: number | null; + }; +} + +export interface WebSocketScopeDeleted { + type: "scope_deleted"; + data: { + scopeId: number; + }; +} + +export interface SerializedFileInfo { + id: number; + path: string[]; + name: string; + contents: string; + nodeId: number; +} + +export interface WebSocketFileAdded { + type: "file_added"; + data: SerializedFileInfo; +} + +export interface WebSocketFileUpdated { + type: "file_updated"; + data: SerializedFileInfo; +} + +export interface SerializedNodeBase { + id: number; + kind: string; + parentId: number | null; + children: SerializedNodeContent[]; + deleted?: boolean; // Mark nodes as deleted but keep them in the tree +} + +export type SerializedNodeContent = + | string // text content + | number; // a node reference; + +export interface SerializedFragmentNode extends SerializedNodeBase { + kind: "fragment"; +} + +export interface SerializedIntrinsicElementNode extends SerializedNodeBase { + kind: "intrinsic"; + tag: string; + props: Record; +} + +interface SerializedContext { + name: string; + value: unknown; +} + +export interface SerializedComponentNode extends SerializedNodeBase { + kind: "component"; + component: string; + props: Record; + context: SerializedContext | null; +} + +export type SerializedNode = + | SerializedFragmentNode + | SerializedIntrinsicElementNode + | SerializedComponentNode; + +export type WebSocketNodeAdded = { + type: "node_added"; + data: SerializedNode; +}; + +export type WebSocketNodeUpdated = { + type: "node_updated"; + data: SerializedNode; +}; + +export type WebSocketNodeDeleted = { + type: "node_deleted"; + data: { + nodeId: number; + }; +}; + +export interface ErrorInfo { + message: string; + stack: string; + nodeId: number | null; +} + +export interface WebSocketErrorAdded { + type: "error_added"; + data: ErrorInfo; +} + +export interface WebSocketRerender { + type: "rerender"; + data: { + nodeId: number; + }; +} + +export type WebSocketMessage = + | WebSocketScopeAdded + | WebSocketScopeUpdated + | WebSocketScopeDeleted + | WebSocketSymbolAdded + | WebSocketSymbolUpdated + | WebSocketSymbolDeleted + | WebSocketFileAdded + | WebSocketFileUpdated + | WebSocketNodeAdded + | WebSocketNodeUpdated + | WebSocketNodeDeleted + | WebSocketErrorAdded + | WebSocketRerender; + +// WebSocket server and debug interface +let wss: WebSocketServer | null = null; interface DebugInterface { component: { @@ -12,24 +213,465 @@ interface DebugInterface { render(): void; context(): void; }; + // Debug interface for sending symbols and scopes + sendSymbol( + symbol: OutputSymbol, + type: "symbol_added" | "symbol_updated", + ): void; + sendScope(scope: OutputScope, type: "scope_added" | "scope_updated"): void; + sendDeletedSymbol(symbol: OutputSymbol): void; + sendDeletedScope(scope: OutputScope): void; + sendFile(file: SerializedFileInfo, type: "file_added" | "file_updated"): void; + sendComponentNode( + node: RenderedTextTree, + parent: RenderedTextTree | null, + component: ComponentCreator, + ): void; + sendFragmentNode( + node: RenderedTextTree, + parent: RenderedTextTree | PrintHook | null, + ): void; + sendIntrinsicElementNode( + printHook: PrintHook, + parent: RenderedTextTree | PrintHook | null, + tag: string, + props: Record, + ): void; + deleteNode(node: RenderedTextTree | PrintHook): void; + sendError(error: Error, context: Context | null): void; + rerenderComponent(nodeId: number): void; } +// Track symbols and scopes that we've already set up watchers for +const watchedSymbols = new WeakSet(); +const watchedScopes = new WeakSet(); + const debug: DebugInterface = { component: { stack: debugStack, tree() { + // eslint-disable-next-line no-console console.log("tree"); }, watch() { + // eslint-disable-next-line no-console console.log("watch"); }, render() { + // eslint-disable-next-line no-console console.log("render"); }, context: debugContext, }, + sendSymbol(symbol, type) { + if (!wss) return; + + const context = findRenderNodeForContext(getContext()); + + const message: WebSocketSymbolAdded | WebSocketSymbolUpdated = { + type, + data: { + symbol: untrack(() => symbol.toJSON()), + nodeId: context ? nodeId(context) : null, + }, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + + // Set up reactive effect to watch for symbol changes (only for new symbols) + if (type === "symbol_added" && !watchedSymbols.has(symbol)) { + watchedSymbols.add(symbol); + + let isFirstRun = true; + + // Watch for changes to symbol properties that would trigger an update + syncEffect(() => { + // Track all reactive properties that should trigger updates + symbol.toJSON(); + + // Send update message on subsequent runs (skip first run which is the initial setup) + if (!isFirstRun) { + debug.sendSymbol(symbol, "symbol_updated"); + } + isFirstRun = false; + }); + } + }, + sendScope(scope, type) { + if (!wss) return; + + const context = findRenderNodeForContext(getContext()); + + const message: WebSocketScopeAdded | WebSocketScopeUpdated = { + type, + data: { + scope: untrack(() => scope.toJSON()), + nodeId: context ? nodeId(context) : null, + }, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + + // Set up reactive effect to watch for scope changes (only for new scopes) + if (type === "scope_added" && !watchedScopes.has(scope)) { + watchedScopes.add(scope); + + let isFirstRun = true; + + // Watch for changes to scope properties that would trigger an update + syncEffect(() => { + // Track all reactive properties that should trigger updates + scope.toJSON(); + + // Send update message on subsequent runs (skip first run which is the initial setup) + if (!isFirstRun) { + debug.sendScope(scope, "scope_updated"); + } + isFirstRun = false; + }); + } + }, + sendFile(file, type) { + if (!wss) return; + + const message: WebSocketMessage = { + type, + data: file, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + }, + sendDeletedSymbol(symbol) { + if (!wss) return; + + const message: WebSocketSymbolDeleted = { + type: "symbol_deleted", + data: { + symbolId: symbol.id, + }, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + + // Remove from watched symbols to clean up memory + watchedSymbols.delete(symbol); + }, + sendDeletedScope(scope) { + if (!wss) return; + + const message: WebSocketScopeDeleted = { + type: "scope_deleted", + data: { + scopeId: scope.id, + }, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + + // Remove from watched scopes to clean up memory + watchedScopes.delete(scope); + }, + sendComponentNode(node, parent, creator) { + if (!wss) return; + + const serializedNode: SerializedComponentNode = { + kind: "component", + id: nodeId(node), + parentId: parent ? nodeId(parent) : null, + component: creator.component.name, + props: creator.props, + children: serializeChildren(node), + context: null, + }; + + const context = getContextForRenderNode(node); + if (context && context.context) { + const key = Object.getOwnPropertySymbols(context.context)[0]; + if (key) { + const contextDefinition = contextsByKey.get(key); + const contextName = contextDefinition?.name ?? "unknown context"; + const value = context.context[key]; + + serializedNode.context = { + name: contextName, + value, + }; + } + } + + const message: WebSocketNodeAdded = { + type: "node_added", + data: serializedNode, + }; + + syncEffect(() => { + for (const [name, value] of Object.entries(creator.props)) { + if (name === "children") continue; + + if (isRef(value)) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + value.value; // track ref + } else if ( + typeof value === "function" && + !isComponentCreator(value) && + value.length === 0 + ) { + value(); + } + } + wss!.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send( + untrack(() => + JSON.stringify(message, (key, value) => { + if (isRef(value)) { + return value.value; // serialize ref value + } + return value; // return other values as is + }), + ), + ); + } + }); + + updateFile(node); + }); + }, + + sendFragmentNode(node, parent) { + if (!wss) return; + + const serializedNode: SerializedFragmentNode = { + kind: "fragment", + id: nodeId(node), + parentId: parent ? nodeId(parent) : null, + children: serializeChildren(node), + }; + + const message: WebSocketNodeAdded = { + type: "node_added", + data: serializedNode, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(untrack(() => JSON.stringify(message))); + } + }); + + updateFile(node); + }, + + sendIntrinsicElementNode(printHook, parent, tag, props) { + untrack(() => { + if (!wss) return; + + const serializedNode: SerializedIntrinsicElementNode = { + kind: "intrinsic", + id: nodeId(printHook), + parentId: parent ? nodeId(parent) : null, + tag, + props, + children: serializeChildren(printHook.subtree), + }; + + const message: WebSocketNodeAdded = { + type: "node_added", + data: serializedNode, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + + updateFile(printHook.subtree); + }); + }, + deleteNode(node) { + if (!wss) return; + + const message: WebSocketNodeDeleted = { + type: "node_deleted", + data: { + nodeId: nodeId(node), + }, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + + updateFile(node as RenderedTextTree); + }, + sendError(error, context) { + if (!wss) return; + + let errorNode = null; + + if (context) { + // walk up to find the nearest render node since we might be in + // a memo or other kind of effect. + let currentContext: Context | null = context; + while (currentContext) { + const renderNode = getRenderNodeForContext(currentContext); + if (renderNode) { + errorNode = renderNode; + break; + } + currentContext = currentContext.owner; + } + } + + const errorInfo: ErrorInfo = { + message: error.message, + stack: error.stack || "", + nodeId: errorNode ? nodeId(errorNode) : null, + }; + + const message: WebSocketErrorAdded = { + type: "error_added", + data: errorInfo, + }; + + wss.clients.forEach((client: WebSocket) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(message)); + } + }); + }, + rerenderComponent(nodeId) { + const node = nodeIds.get(nodeId); + if (!node) { + // eslint-disable-next-line no-console + console.warn(`No node found with ID ${nodeId} for rerender.`); + return; + } + + const context = getContextForRenderNode(node as RenderedTextTree); + if (!context) { + // eslint-disable-next-line no-console + console.warn(`No context found for node with ID ${nodeId} for rerender.`); + return; + } + + if (!context.rerenderHook) { + // eslint-disable-next-line no-console + console.warn( + `No rerender hook found for node with ID ${nodeId}. Cannot rerender.`, + ); + return; + } + + triggerRef(context.rerenderHook); + flushJobs(); + }, }; +const fileContents = new Map(); +function updateFile(node: RenderedTextTree) { + let context = getContextForRenderNode(node) ?? null; + let file; + while (context) { + if (context.meta?.sourceFile) { + file = context.meta.sourceFile as SourceFileContext; + break; + } + context = context.owner; + } + + if (!file) { + return; + } + + const pathParts = file.path.split(sep); + const rootNode = getRenderNodeForContext(context!)!; + const rootComponentId = nodeId(rootNode); + + const serializedFile: SerializedFileInfo = untrack(() => { + return { + id: fileId(file), + path: pathParts.slice(0, -1), + name: pathParts.at(-1)!, + nodeId: rootComponentId, + contents: printTree(rootNode as RenderedTextTree, { + printWidth: context!.meta!.printOptions?.printWidth ?? 80, + tabWidth: context!.meta!.printOptions?.tabWidth ?? 2, + useTabs: context!.meta!.printOptions?.useTabs ?? false, + noFlush: true, + }), + }; + }); + + if (fileContents.has(serializedFile.id)) { + const currentContents = fileContents.get(serializedFile.id)!; + if (serializedFile.contents === currentContents.contents) { + return; + } + } + + fileContents.set(serializedFile.id, serializedFile); + + debug.sendFile(serializedFile, "file_added"); +} + +function serializeChildren(node: RenderedTextTree): SerializedNodeContent[] { + return node.map((child) => { + if (typeof child === "string") { + return child; + } else { + return nodeId(child); + } + }); +} + +const seenNodes = new WeakMap(); +const nodeIds = new Map(); +let nodeCount = 0; +function nodeId(node: RenderedTextTree | PrintHook) { + let id = seenNodes.get(node); + if (id === undefined) { + id = nodeCount++; + seenNodes.set(node, id); + nodeIds.set(id, node); + } + return id; +} + +const seenFiles = new WeakMap(); +let fileCount = 0; +function fileId(context: SourceFileContext) { + let id = seenFiles.get(context); + if (!id) { + id = fileCount++; + seenFiles.set(context, id); + } + return id; +} + function debugStack() { let currentContext = getContext(); let foundContexts: Context[] = []; @@ -77,10 +719,12 @@ function debugStack() { function debugContext() { let currentContext = getContext(); while (currentContext !== null) { + // eslint-disable-next-line no-console console.log(printContext(currentContext)); currentContext = currentContext.owner; } } + function printContext(context: Context, omitOwner: boolean = false) { if (!context.context) return ""; const key = Object.getOwnPropertySymbols(context.context)[0]; @@ -100,6 +744,22 @@ function printContext(context: Context, omitOwner: boolean = false) { return output; } +/** + * Return the render node that owns the given context. + */ +function findRenderNodeForContext(context: Context | null) { + let currentContext: Context | null = context; + while (currentContext) { + const renderContext = getRenderNodeForContext(currentContext); + if (renderContext) { + return renderContext; + } + currentContext = currentContext.owner; + } + + return null; +} + function findContextOwner(context: Context) { let currentContext: Context | null = context; while ( @@ -119,6 +779,69 @@ declare global { globalThis.debug = debug; +// Initialize WebSocket server when debugging is enabled +if (shouldDebug()) { + // Create HTTP server to serve debug UI files + const server = http.createServer(async (req, res) => { + let urlPath = req.url ?? "/"; + if (urlPath === "/") urlPath = "/index.html"; + const filePath = pathJoin(uiDir, urlPath); + console.log(filePath); + try { + const data = await readFile(filePath); + const ext = extname(filePath); + const mime = mimeTypes[ext] || "application/octet-stream"; + res.writeHead(200, { "Content-Type": mime }); + res.end(data); + } catch { + res.writeHead(404); + res.end("Not found"); + } + }); + + // Attach WebSocket server to HTTP server + wss = new WebSocketServer({ server }); + + // Start listening on port 8080 + server.listen(8080); + + // Wait for server to start listening + await new Promise((resolve, reject) => { + server.on("listening", () => { + // eslint-disable-next-line no-console + console.log("Debug server started at http://localhost:8080"); + // eslint-disable-next-line no-console + console.log("Waiting for debug client to connect..."); + resolve(); + }); + server.on("error", (error) => { + // eslint-disable-next-line no-console + console.error("Debug server error:", error); + reject(error); + }); + }); + + // Wait for a WebSocket client to connect + await new Promise((resolve) => { + wss!.on("connection", (ws) => { + // eslint-disable-next-line no-console + console.log("Debug client connected"); + ws.on("message", (data) => { + try { + const message = JSON.parse(data.toString()) as WebSocketMessage; + if (message.type === "rerender") { + debug.rerenderComponent(message.data.nodeId); + } + } catch (error) { + // eslint-disable-next-line no-console + console.error("Failed to parse WebSocket message:", error); + } + }); + resolve(); + }); + }); +} + const style = { value: { primitive(value: string | number | boolean | null | undefined) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c801e8766..cb4e6ba18 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -22,7 +22,6 @@ export { type ToRef, type ToRefs, } from "@vue/reactivity"; -export * from "./binder.js"; export * from "./code.js"; export * from "./components/index.js"; export * from "./context.js"; @@ -31,13 +30,14 @@ export * from "./name-policy.js"; export * from "./props-combinators.js"; export * from "./reactive-union-set.js"; export * from "./reactivity.js"; -export * from "./refkey.js"; export * from "./render.js"; export * from "./runtime/component.js"; export * from "./runtime/intrinsic.js"; export * from "./stc.js"; export * from "./sti.js"; +export * from "./symbols/binder.js"; export * from "./symbols/index.js"; +export * from "./symbols/refkey.js"; export * from "./symbols/symbol-flow.js"; export * from "./tap.js"; export * from "./utils.js"; diff --git a/packages/core/src/reactivity.ts b/packages/core/src/reactivity.ts index 0b1f012f5..5531e657c 100644 --- a/packages/core/src/reactivity.ts +++ b/packages/core/src/reactivity.ts @@ -1,6 +1,8 @@ import { + DebuggerEvent, pauseTracking, ReactiveEffectRunner, + Ref, resetTracking, ShallowReactive, shallowRef, @@ -9,7 +11,7 @@ import { } from "@vue/reactivity"; import type { RenderedTextTree } from "./render.js"; import type { Children, ComponentCreator } from "./runtime/component.js"; -import { scheduler } from "./scheduler.js"; +import { scheduler, type SchedulerJobOptions } from "./scheduler.js"; import type { OutputSymbol } from "./symbols/output-symbol.js"; import { trace, TracePhase } from "./tracer.js"; @@ -66,6 +68,11 @@ export interface Context { * The symbol that this component has taken. */ takenSymbols?: ShallowReactive>; + + /** + * A ref that, when triggered, causes the component to rerender. + */ + rerenderHook?: Ref; } let globalContext: Context | null = null; @@ -77,6 +84,11 @@ export interface RootOptions { componentOwner?: ComponentCreator; } +let lastErrorContext: Context | null = null; +export function getLastErrorContext(): Context | null { + return lastErrorContext; +} + export function root(fn: (d: Disposable) => T, options?: RootOptions): T { const context: Context = { componentOwner: options?.componentOwner, @@ -94,7 +106,7 @@ export function root(fn: (d: Disposable) => T, options?: RootOptions): T { ret = untrack(() => fn(() => { for (const d of context!.disposables) { - d(); + untrack(d); } }), ); @@ -112,18 +124,42 @@ export function untrack(fn: () => T): T { return v; } -export function memo(fn: () => T, equal?: boolean): () => T { +export interface MemoOptions extends ReactiveEffectOptions { + equal?: boolean; +} +export function memo(fn: () => T, options: MemoOptions = {}): () => T { const o = shallowRef(); - effect((prev) => { - const res = fn(); - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - (!equal || prev !== res) && (o.value = res); - return res; - }, undefined as T); + effect( + (prev) => { + const res = fn(); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + (!options.equal || prev !== res) && (o.value = res); + return res; + }, + { current: undefined as T }, + ); return () => o.value; } -export function effect(fn: (prev?: T) => T, current?: T) { +export interface ReactiveEffectOptions extends SchedulerJobOptions { + current?: T; + flush?: "sync" | "post"; + onTrack?: (event: DebuggerEvent) => void; + onTrigger?: (event: DebuggerEvent) => void; +} + +export function syncEffect( + fn: (prev?: T) => T, + options: ReactiveEffectOptions = {}, +) { + options.flush = "sync"; + return effect(fn, options); +} + +export function effect( + fn: (prev?: T) => T, + options: ReactiveEffectOptions = {}, +) { const context: Context = { context: {}, disposables: [] as (() => void)[], @@ -142,6 +178,8 @@ export function effect(fn: (prev?: T) => T, current?: T) { final && stop(runner); }; + let current = options.current; + onCleanup(() => cleanupFn(true)); const runner: ReactiveEffectRunner = vueEffect( () => { @@ -151,20 +189,28 @@ export function effect(fn: (prev?: T) => T, current?: T) { globalContext = context; try { current = fn(current); + } catch (e) { + if (lastErrorContext === null) { + lastErrorContext = context; + } + + throw e; } finally { globalContext = oldContext; } }, { - scheduler: scheduler(() => runner), + scheduler: scheduler(() => runner, options), onTrack(event) { + options.onTrack?.(event); trace(TracePhase.effect.track, () => { - return `tracking ${event.target}, ${event.key}`; + return `tracking ${event.target}, ${typeof event.key === "symbol" ? "[symbol]" : event}`; }); }, onTrigger(event) { + options.onTrigger?.(event); trace(TracePhase.effect.trigger, () => { - return `triggering ${event.target}, ${event.key}`; + return `triggering ${event.target}, ${typeof event.key === "symbol" ? "[symbol]" : event.key}`; }); }, }, diff --git a/packages/core/src/render.ts b/packages/core/src/render.ts index 88441d822..629e0082e 100644 --- a/packages/core/src/render.ts +++ b/packages/core/src/render.ts @@ -1,29 +1,29 @@ -import { isRef } from "@vue/reactivity"; +import { isRef, ref } from "@vue/reactivity"; import { Doc, doc } from "prettier"; import prettier from "prettier/doc.js"; import { useContext } from "./context.js"; import { SourceFileContext } from "./context/source-file.js"; -import { shouldDebug } from "./debug.js"; import { Context, CustomContext, effect, getContext, getElementCache, + getLastErrorContext, isCustomContext, + onCleanup, root, untrack, } from "./reactivity.js"; -import { isRefkey } from "./refkey.js"; import { Child, Children, - Component, isComponentCreator, Props, } from "./runtime/component.js"; import { IntrinsicElement, isIntrinsicElement } from "./runtime/intrinsic.js"; import { flushJobs } from "./scheduler.js"; +import { isRefkey } from "./symbols/refkey.js"; import { trace, TracePhase } from "./tracer.js"; const { @@ -140,12 +140,17 @@ export interface OutputFile { filetype: string; } -const nodesToContext = new WeakMap(); +const nodesToContext = new WeakMap(); export function getContextForRenderNode(node: RenderedTextTree) { return nodesToContext.get(node); } +const contextsToNode = new WeakMap(); +export function getRenderNodeForContext(context: Context) { + return contextsToNode.get(context); +} + export const printHookTag = Symbol(); export interface PrintHook { @@ -180,7 +185,6 @@ export function render( options?: PrintTreeOptions, ): OutputDirectory { const tree = renderTree(children); - flushJobs(); let rootDirectory: OutputDirectory | undefined = undefined; // when passing Output, the first render tree child is the Output component. @@ -271,10 +275,16 @@ export function renderTree(children: Children) { const rootElem: RenderedTextTree = []; try { root(() => { + debug.sendFragmentNode(rootElem, null); renderWorker(rootElem, children); + debug.sendFragmentNode(rootElem, null); }); - } catch (e) { - printRenderStack(); + } catch (e: any) { + // errors caught here are thrown synchronously from the render process, i.e. + // those which are the result of evaluating components or initial effect + // invocations. Errors from running reactive effects are caught by the + // scheduler. + debug.sendError(e, getLastErrorContext()); throw e; } @@ -289,10 +299,6 @@ function renderWorker(node: RenderedTextTree, children: Children) { } trace(TracePhase.render.worker, () => dumpChildren(children)); - if (Array.isArray(node)) { - nodesToContext.set(node, getContext()!); - } - if (Array.isArray(children)) { for (const child of (children as any).flat(Infinity)) { appendChild(node, child); @@ -325,8 +331,12 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { ); child.useCustomContext((children) => { const newNode: RenderedTextTree = []; + nodesToContext.set(newNode, getContext()!); + contextsToNode.set(getContext()!, newNode); renderWorker(newNode, children); + onCleanup(() => debug.deleteNode(newNode)); node.push(newNode); + debug.sendFragmentNode(newNode, node); cache.set(child, newNode); }); } else if (isIntrinsicElement(child)) { @@ -336,59 +346,94 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { ); // don't need a new context here because intrinsics are never reactive const newNode: RenderedTextTree = []; + nodesToContext.set(newNode, getContext()!); + contextsToNode.set(getContext()!, newNode); function formatHookWithChildren(command: (doc: Doc) => Doc) { - node.push( - createRenderTreeHook(newNode, { - print(tree, print) { - return command(print(tree)); - }, - }), + const printHook = createRenderTreeHook(newNode, { + print(tree, print) { + return command(print(tree)); + }, + }); + node.push(printHook); + debug.sendIntrinsicElementNode( + printHook, + node, + (child as any).name, + (child as any).props, ); + debug.sendFragmentNode(newNode, printHook); renderWorker(newNode, (child as any).props.children); + debug.sendFragmentNode(newNode, printHook); + onCleanup(() => debug.deleteNode(newNode)); } function formatHook(command: Doc) { - return node.push( - createRenderTreeHook(newNode, { - print() { - return command; - }, - }), + const printHook = createRenderTreeHook(newNode, { + print() { + return command; + }, + }); + node.push(printHook); + debug.sendIntrinsicElementNode( + printHook, + node, + (child as any).name, + (child as any).props, ); + debug.sendFragmentNode(newNode, printHook); + onCleanup(() => debug.deleteNode(newNode)); } switch (child.name) { case "indent": return formatHookWithChildren(indent); - case "indentIfBreak": - node.push( - createRenderTreeHook(newNode, { - print(tree, print) { - return indentIfBreak(print(tree), { - groupId: child.props.groupId, - negate: child.props.negate, - }); - }, - }), + case "indentIfBreak": { + const indentIfBreakHook = createRenderTreeHook(newNode, { + print(tree, print) { + return indentIfBreak(print(tree), { + groupId: child.props.groupId, + negate: child.props.negate, + }); + }, + }); + node.push(indentIfBreakHook); + debug.sendIntrinsicElementNode( + indentIfBreakHook, + node, + (child as any).name, + (child as any).props, ); + debug.sendFragmentNode(newNode, indentIfBreakHook); renderWorker(newNode, child.props.children); + debug.sendFragmentNode(newNode, indentIfBreakHook); + onCleanup(() => debug.deleteNode(newNode)); return; + } case "fill": return formatHookWithChildren(fill as any); - case "group": - node.push( - createRenderTreeHook(newNode, { - print(tree, print) { - return group(print(tree), { - id: child.props.id, - shouldBreak: child.props.shouldBreak, - }); - }, - }), + case "group": { + const groupHook = createRenderTreeHook(newNode, { + print(tree, print) { + return group(print(tree), { + id: child.props.id, + shouldBreak: child.props.shouldBreak, + }); + }, + }); + node.push(groupHook); + debug.sendIntrinsicElementNode( + groupHook, + node, + (child as any).name, + (child as any).props, ); + debug.sendFragmentNode(newNode, groupHook); renderWorker(newNode, child.props.children); + debug.sendFragmentNode(newNode, groupHook); + onCleanup(() => debug.deleteNode(newNode)); return; + } case "line": case "br": return formatHook(line); @@ -401,19 +446,28 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { case "literalline": case "lbr": return formatHook(literalline); - case "align": - node.push( - createRenderTreeHook(newNode, { - print(tree, print) { - return align( - (child.props as any).width ?? (child.props as any).string!, - print(tree), - ); - }, - }), + case "align": { + const alignHook = createRenderTreeHook(newNode, { + print(tree, print) { + return align( + (child.props as any).width ?? (child.props as any).string!, + print(tree), + ); + }, + }); + node.push(alignHook); + debug.sendIntrinsicElementNode( + alignHook, + node, + (child as any).name, + (child as any).props, ); + debug.sendFragmentNode(newNode, alignHook); renderWorker(newNode, (child as any).props.children); + debug.sendFragmentNode(newNode, alignHook); + onCleanup(() => debug.deleteNode(newNode)); return; + } case "lineSuffix": return formatHookWithChildren(lineSuffix); case "lineSuffixBoundary": @@ -426,18 +480,24 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { return formatHookWithChildren(dedentToRoot); case "markAsRoot": return formatHookWithChildren(markAsRoot); - case "ifBreak": - node.push( - createRenderTreeHook(newNode, { - print(tree, print) { - return ifBreak( - print((tree as RenderedTextTree[])[0]), - print((tree as RenderedTextTree[])[1]), - ); - }, - }), - ); + case "ifBreak": { + const ifBreakHook = createRenderTreeHook(newNode, { + print(tree, print) { + return ifBreak( + print((tree as RenderedTextTree[])[0]), + print((tree as RenderedTextTree[])[1]), + ); + }, + }); + node.push(ifBreakHook); newNode.push([], []); + debug.sendIntrinsicElementNode( + ifBreakHook, + node, + (child as any).name, + (child as any).props, + ); + debug.sendFragmentNode(newNode, ifBreakHook); renderWorker( newNode[0] as RenderedTextTree[], (child as any).props.children, @@ -446,7 +506,10 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { newNode[1] as RenderedTextTree[], (child as any).props.flatContents, ); + debug.sendFragmentNode(newNode, ifBreakHook); + onCleanup(() => debug.deleteNode(newNode)); return; + } default: throw new Error("Unknown intrinsic element"); } @@ -456,11 +519,26 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { TracePhase.render.appendChild, () => "Component: " + debugPrintChild(child), ); + const componentRoot: RenderedTextTree = []; - pushStack(child.component, child.props); - renderWorker(componentRoot, untrack(child)); - popStack(); + const context = getContext()!; + context.rerenderHook ??= ref(); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + context.rerenderHook.value; // trigger the effect + nodesToContext.set(componentRoot, context); + contextsToNode.set(context, componentRoot); + debug.sendComponentNode(componentRoot, node, child); + renderWorker( + componentRoot, + untrack(() => { + const children = child(); + debug.sendComponentNode(componentRoot, node, child); + return children; + }), + ); + onCleanup(() => debug.deleteNode(componentRoot)); node.push(componentRoot); + debug.sendComponentNode(componentRoot, node, child); cache.set(child, componentRoot); trace( TracePhase.render.appendChild, @@ -477,8 +555,14 @@ function appendChild(node: RenderedTextTree, rawChild: Child) { res = res(); } const newNodes: RenderedTextTree = []; + nodesToContext.set(newNodes, getContext()!); + contextsToNode.set(getContext()!, newNodes); + debug.sendFragmentNode(newNodes, node); renderWorker(newNodes, res); + debug.sendFragmentNode(newNodes, node); + onCleanup(() => debug.deleteNode(newNodes)); node[index] = newNodes; + debug.sendFragmentNode(newNodes, node); cache.set(child, newNodes); return newNodes; }); @@ -563,6 +647,11 @@ export interface PrintTreeOptions { * The number of spaces to use for indentation. Defaults to 2 spaces. */ tabWidth?: number; + + /** + * Whether to flush the job queue before printing. Defaults to false. + */ + noFlush?: boolean; } const defaultPrintTreeOptions: PrintTreeOptions = { @@ -578,8 +667,11 @@ export function printTree(tree: RenderedTextTree, options?: PrintTreeOptions) { ), }; - // make sure queue is empty - flushJobs(); + // make sure queue is empty unless told not to (e.g. because we are printing + // during a render pass). + if (!options.noFlush) { + flushJobs(); + } const d = printTreeWorker(tree); return doc.printer.printDocToString(d, options as doc.printer.Options) @@ -605,33 +697,6 @@ function printTreeWorker(tree: RenderedTextTree): Doc { return doc; } -// debugging utilities -const renderStack: { - component: Component; - props: Props; -}[] = []; - -export function pushStack(component: Component, props: Props) { - if (!shouldDebug()) return; - renderStack.push({ component, props }); -} - -export function popStack() { - if (!shouldDebug()) return; - renderStack.pop(); -} - -export function printRenderStack() { - if (!shouldDebug()) return; - - // eslint-disable-next-line no-console - console.error("Error rendering:"); - for (let i = renderStack.length - 1; i >= 0; i--) { - const { component, props } = renderStack[i]; - // eslint-disable-next-line no-console - console.error(` at ${component.name}(${inspectProps(props)})`); - } -} function inspectProps(props: Props) { return JSON.stringify( diff --git a/packages/core/src/runtime/component.ts b/packages/core/src/runtime/component.ts index c4727d7a2..2c1f94519 100644 --- a/packages/core/src/runtime/component.ts +++ b/packages/core/src/runtime/component.ts @@ -1,6 +1,6 @@ import { Ref } from "@vue/reactivity"; import { CustomContext } from "../reactivity.js"; -import { Refkey } from "../refkey.js"; +import { Refkey } from "../symbols/refkey.js"; import { IntrinsicElement } from "./intrinsic.js"; export type Child = diff --git a/packages/core/src/scheduler.ts b/packages/core/src/scheduler.ts index c2cc23661..78b54feeb 100644 --- a/packages/core/src/scheduler.ts +++ b/packages/core/src/scheduler.ts @@ -1,45 +1,62 @@ -import { ReactiveEffectRunner } from "@vue/reactivity"; +import { getLastErrorContext } from "./reactivity.js"; +import { trace, TracePhase } from "./tracer.js"; export interface QueueJob { (): any; } -const immediateQueue = new Set(); const queue = new Set(); +let flushing = false; +export function jobQueueSize() { + return queue.size; +} +export interface SchedulerJobOptions { + flush?: "sync" | "post"; +} export function scheduler( - jobGetter: () => ReactiveEffectRunner, - immediate = false, + jobGetter: () => QueueJob, + options: SchedulerJobOptions = {}, ) { return () => { - queueJob(jobGetter(), immediate); + queueJob(jobGetter(), options); }; } -export function queueJob(job: QueueJob, immediate = false) { - // if we have an immediate job, we don't need to queue the normal job. - // the set is serving an important purpose here in deduping the effects we run - // (which in effect coalesces multiple update effects together). - if (immediate) { - immediateQueue.add(job); +export function queueJob(job: QueueJob, options: SchedulerJobOptions = {}) { + if (options?.flush === "sync") { + trace(TracePhase.scheduler.queue, () => `Scheduling sync job`); + job(); } else { + trace(TracePhase.scheduler.queue, () => `Scheduling post job`); queue.add(job); } } export function flushJobs() { - let job; + if (flushing) { + return; + } + trace( + TracePhase.scheduler.flush, + () => `flushing jobs, queue size: ${queue.size}`, + ); + flushing = true; + let job: QueueJob | null; while ((job = takeJob()) !== null) { - job(); + try { + job(); + } catch (e: any) { + debug.sendError(e, getLastErrorContext()); + flushing = false; + throw e; + } } + + flushing = false; } function takeJob() { - if (immediateQueue.size > 0) { - // return first item in immediateQueue - const job = immediateQueue.values().next().value!; - immediateQueue.delete(job); - return job; - } if (queue.size > 0) { + trace(TracePhase.scheduler.take, () => "taking job"); // return first item in queue const job = queue.values().next().value!; queue.delete(job); diff --git a/packages/core/src/binder.ts b/packages/core/src/symbols/binder.ts similarity index 90% rename from packages/core/src/binder.ts rename to packages/core/src/symbols/binder.ts index 633934b11..7622dc9cc 100644 --- a/packages/core/src/binder.ts +++ b/packages/core/src/symbols/binder.ts @@ -1,18 +1,18 @@ import { computed, ref, Ref, ShallowRef, shallowRef } from "@vue/reactivity"; -import { useMemberScope } from "./context/member-scope.js"; -import { useScope } from "./context/scope.js"; -import { effect, untrack } from "./reactivity.js"; -import { refkey, Refkey } from "./refkey.js"; -import { OutputSymbolFlags } from "./symbols/flags.js"; -import { OutputScope } from "./symbols/output-scope.js"; -import { type OutputSymbol } from "./symbols/output-symbol.js"; +import { useMemberScope } from "../context/member-scope.js"; +import { useScope } from "../context/scope.js"; +import { effect, untrack } from "../reactivity.js"; import { formatRefkeys, formatSymbol, formatSymbolName, trace, TracePhase, -} from "./tracer.js"; +} from "../tracer.js"; +import { OutputSymbolFlags } from "./flags.js"; +import { OutputScope } from "./output-scope.js"; +import { type OutputSymbol } from "./output-symbol.js"; +import { refkey, Refkey } from "./refkey.js"; export type Metadata = object; /** @@ -106,6 +106,21 @@ export interface Binder { * Notifies the binder that a symbol has been deleted. */ notifySymbolDeleted(symbol: OutputSymbol): void; + + /** + * Notifies the binder that a scope has been deleted. + */ + notifyScopeDeleted(scope: OutputScope): void; + + /** + * The symbols that are currently being tracked by the binder. + */ + symbols: Set; + + /** + * The scopes that are currently being tracked by the binder. + */ + scopes: Set; } /** @@ -183,7 +198,10 @@ export function createOutputBinder(options: BinderOptions = {}): Binder { notifyScopeCreated, notifySymbolCreated, notifySymbolDeleted, + notifyScopeDeleted, nameConflictResolver: options.nameConflictResolver, + symbols: new Set(), + scopes: new Set(), }; binder.globalScope = new OutputScope("", { @@ -205,6 +223,8 @@ export function createOutputBinder(options: BinderOptions = {}): Binder { return binder; function notifyScopeCreated(scope: OutputScope) { + binder.scopes.add(scope); + if (globalThis.debug) globalThis.debug.sendScope(scope, "scope_added"); if (!scope.parent || !waitingScopeNames.has(scope.parent)) { return; } @@ -217,15 +237,27 @@ export function createOutputBinder(options: BinderOptions = {}): Binder { } function notifySymbolDeleted(symbol: OutputSymbol) { + binder.symbols.delete(symbol); if (!refkey) { return; } for (const refkey of symbol.refkeys) { + const knownDecl = knownDeclarations.get(refkey); + if (knownDecl && knownDecl === symbol) { + knownDeclarations.delete(refkey); + } + const resolution = waitingDeclarations.get(refkey); if (!resolution) return; resolution.value = undefined; } + if (globalThis.debug) globalThis.debug.sendDeletedSymbol(symbol); + } + + function notifyScopeDeleted(scope: OutputScope) { + binder.scopes.delete(scope); + if (globalThis.debug) globalThis.debug.sendDeletedScope(scope); } function hasTransientScope(symbol: OutputSymbol) { @@ -392,10 +424,8 @@ export function createOutputBinder(options: BinderOptions = {}): Binder { } function notifySymbolCreated(symbol: OutputSymbol): void { - if (symbol.flags & OutputSymbolFlags.Transient) { - // just ignore transient symbols. - return; - } + binder.symbols.add(symbol); + if (globalThis.debug) debug.sendSymbol(symbol, "symbol_added"); effect((oldRefkeys) => { trace( TracePhase.resolve.pending, @@ -418,6 +448,19 @@ export function createOutputBinder(options: BinderOptions = {}): Binder { } for (const refkey of symbol.refkeys) { + if (knownDeclarations.has(refkey)) { + const existingSymbol = knownDeclarations.get(refkey); + if (existingSymbol! !== symbol) { + throw new Error( + "Refkey " + + refkey.key + + " of symbol " + + symbol.name + + " has already been associated with a symbol named " + + symbol.name, + ); + } + } // notify those waiting for this refkey knownDeclarations.set(refkey, symbol); if (waitingDeclarations.has(refkey)) { @@ -572,11 +615,13 @@ export function resolve< throw new Error("Can't resolve refkey without a binder"); } - return binder.resolveDeclarationByKey( + const result = binder.resolveDeclarationByKey( scope, memberScope?.instanceMembers, refkey, - ) as any; + ); + + return result as any; } const createSymbolsSymbol: unique symbol = Symbol(); diff --git a/packages/core/src/symbols/index.ts b/packages/core/src/symbols/index.ts index 7e168c3e5..0e60fc0d2 100644 --- a/packages/core/src/symbols/index.ts +++ b/packages/core/src/symbols/index.ts @@ -1,6 +1,8 @@ +export * from "./binder.js"; export * from "./flags.js"; export * from "./output-scope.js"; export * from "./output-symbol.js"; +export * from "./refkey.js"; export * from "./symbol-flow.js"; export * from "./symbol-slot.js"; export * from "./symbol-table.js"; diff --git a/packages/core/src/symbols/output-scope.ts b/packages/core/src/symbols/output-scope.ts index 439f73a48..a9a862d77 100644 --- a/packages/core/src/symbols/output-scope.ts +++ b/packages/core/src/symbols/output-scope.ts @@ -8,11 +8,9 @@ import { TriggerOpTypes, watch, } from "@vue/reactivity"; -import type { Binder } from "../binder.js"; import { useBinder } from "../context/binder.js"; import { useScope } from "../context/scope.js"; import type { ReactiveUnionSetOptions } from "../reactive-union-set.js"; -import type { Refkey } from "../refkey.js"; import { formatScope, formatScopeName, @@ -20,8 +18,10 @@ import { traceEffect, TracePhase, } from "../tracer.js"; +import type { Binder } from "./binder.js"; import { OutputScopeFlags } from "./flags.js"; import type { OutputSymbol } from "./output-symbol.js"; +import type { Refkey } from "./refkey.js"; import { SymbolTable } from "./symbol-table.js"; let scopeCount = 0; @@ -33,6 +33,12 @@ export interface OutputScopeOptions { parent?: OutputScope; owner?: OutputSymbol; binder?: Binder; + + /** + * Unique id for this scope. If not provided a unique id is created + * automatically. + */ + id?: number; } /** @@ -164,11 +170,18 @@ export class OutputScope { return this.#binder; } - [ReactiveFlags.SKIP] = this; + #deleted = false; + get deleted() { + track(this, TrackOpTypes.GET, "deleted"); + return this.#deleted; + } + + [ReactiveFlags.SKIP] = true as const; + [ReactiveFlags.IS_SHALLOW] = true as const; constructor(name: string, options: OutputScopeOptions = {}) { this.#name = name; - this.#id = scopeCount++; + this.#id = options.id ?? scopeCount++; this.#flags = options.flags ?? OutputScopeFlags.None; this.#kind = options.kind ?? "scope"; this.#metadata = reactive(options.metadata ?? {}); @@ -293,4 +306,54 @@ export class OutputScope { return clone; } + + delete() { + // Mark as deleted to prevent further operations + this.#deleted = true; + trigger(this, TriggerOpTypes.SET, "deleted", true, false); + + // Remove this scope from its parent's children + if (this.#parent) { + this.#parent.children.delete(this); + } + + // Delete all symbols in this scope + for (const symbol of Array.from(this.#symbols)) { + symbol.delete(); + } + + // Delete all child scopes + for (const child of Array.from(this.#children)) { + child.delete(); + } + + // Notify the binder + this.#binder?.notifyScopeDeleted(this); + } + + toJSON(): SerializedOutputScope { + return { + id: this.id, + name: this.name, + kind: this.kind, + flags: this.flags, + symbols: Array.from(this.symbols).map((s) => s.id), + children: Array.from(this.children).map((c) => c.id), + parent: this.parent?.id ?? null, + owner: this.owner?.id ?? null, + metadata: this.metadata, + }; + } +} + +export interface SerializedOutputScope { + id: number; + name: string; + kind: string; + flags: OutputScopeFlags; + symbols: number[]; + children: number[]; + parent: number | null; + owner: number | null; + metadata: Record; } diff --git a/packages/core/src/symbols/output-symbol.ts b/packages/core/src/symbols/output-symbol.ts index c4cb78c6a..8f777a8ab 100644 --- a/packages/core/src/symbols/output-symbol.ts +++ b/packages/core/src/symbols/output-symbol.ts @@ -8,11 +8,9 @@ import { TriggerOpTypes, watch, } from "@vue/reactivity"; -import type { Binder } from "../binder.js"; import { useBinder } from "../context/binder.js"; import { useMemberScope } from "../context/member-scope.js"; import { useScope } from "../context/scope.js"; -import { isRefkey, refkey, type Refkey } from "../refkey.js"; import { formatScopeName, formatSymbol, @@ -21,8 +19,10 @@ import { traceEffect, TracePhase, } from "../tracer.js"; +import type { Binder } from "./binder.js"; import { OutputScopeFlags, OutputSymbolFlags } from "./flags.js"; import { OutputScope } from "./output-scope.js"; +import { isRefkey, refkey, type Refkey } from "./refkey.js"; export interface OutputSymbolOptions { binder?: Binder; @@ -243,11 +243,14 @@ export class OutputSymbol { return this.#metadata; } - /** - * Tell \@vue/reactivity that this symbol should never be wrapped in a reactive - * proxy. - */ - [ReactiveFlags.SKIP] = true; + #deleted = false; + get deleted() { + track(this, TrackOpTypes.GET, "deleted"); + return this.#deleted; + } + + [ReactiveFlags.SKIP] = true as const; + [ReactiveFlags.IS_SHALLOW] = true as const; constructor(name: string, options: OutputSymbolOptions = {}) { this.#binder = options.binder ?? useBinder(); @@ -281,11 +284,18 @@ export class OutputSymbol { } delete() { + if (this.#deleted) { + return; + } + trace(TracePhase.symbol.delete, () => `${formatSymbolName(this)}`); if (this.#scope) { this.#scope.symbols.delete(this); } + this.#deleted = true; + trigger(this, TriggerOpTypes.SET, "deleted", true, false); + this.#binder?.notifySymbolDeleted(this); } @@ -456,4 +466,32 @@ export class OutputSymbol { } } } + + toJSON(): SerializedOutputSymbol { + return { + id: this.id, + name: this.name, + originalName: this.originalName, + flags: this.flags, + scope: this.scope?.id ?? null, + refkeys: this.refkeys, + metadata: this.metadata, + instanceMemberScope: this.instanceMemberScope?.id ?? null, + staticMemberScope: this.staticMemberScope?.id ?? null, + aliasTarget: this.aliasTarget?.id ?? null, + }; + } +} + +export interface SerializedOutputSymbol { + id: number; + name: string; + originalName: string; + flags: OutputSymbolFlags; + scope: number | null; + refkeys: Refkey[]; + metadata: Record; + instanceMemberScope: number | null; + staticMemberScope: number | null; + aliasTarget: number | null; } diff --git a/packages/core/src/refkey.ts b/packages/core/src/symbols/refkey.ts similarity index 100% rename from packages/core/src/refkey.ts rename to packages/core/src/symbols/refkey.ts diff --git a/packages/core/src/symbols/symbol-table.ts b/packages/core/src/symbols/symbol-table.ts index 1ad356ec8..a9fc053e3 100644 --- a/packages/core/src/symbols/symbol-table.ts +++ b/packages/core/src/symbols/symbol-table.ts @@ -1,4 +1,3 @@ -import type { NameConflictResolver } from "../binder.js"; import { ReactiveUnionSet } from "../reactive-union-set.js"; import { queueJob } from "../scheduler.js"; import { @@ -7,6 +6,7 @@ import { trace, TracePhase, } from "../tracer.js"; +import type { NameConflictResolver } from "./binder.js"; import type { OutputScope } from "./output-scope.js"; import type { OutputSymbol } from "./output-symbol.js"; diff --git a/packages/core/src/tracer.ts b/packages/core/src/tracer.ts index d0b95f801..457fedb71 100644 --- a/packages/core/src/tracer.ts +++ b/packages/core/src/tracer.ts @@ -1,14 +1,13 @@ -import { effect, ReactiveEffectRunner } from "@vue/reactivity"; -import { untrack } from "./reactivity.js"; -import type { Refkey } from "./refkey.js"; -import { scheduler } from "./scheduler.js"; +import { syncEffect, untrack } from "./reactivity.js"; import { OutputScopeFlags, OutputSymbolFlags } from "./symbols/flags.js"; import { type OutputScope } from "./symbols/output-scope.js"; import { type OutputSymbol } from "./symbols/output-symbol.js"; +import type { Refkey } from "./symbols/refkey.js"; // enable tracing for specific phases using a comma separated list of // dotted identifiers, e.g. `scope.update,symbol.create`. -const traceEnv = process.env.ALLOY_TRACE ?? ""; + +const traceEnv = (globalThis.process && process.env.ALLOY_TRACE) ?? ""; const tracePhases = new Set( traceEnv === "" ? [] : traceEnv.split(",").map((t) => t.trim()), ); @@ -21,7 +20,8 @@ if (tracePhases.size > 0) { ); } -const debuggerIdsEnv = process.env.ALLOY_BREAK_ON_DID ?? ""; +const debuggerIdsEnv = + (globalThis.process && process.env.ALLOY_BREAK_ON_DID) ?? ""; const dids = new Set(); debuggerIdsEnv.split(",").forEach((id) => { @@ -146,6 +146,23 @@ export const TracePhase = { bg: { r: 100, g: 50, b: 0 }, }, }, + scheduler: { + queue: { + area: "scheduler", + subarea: "queue", + bg: { r: 200, g: 200, b: 200 }, + }, + take: { + area: "scheduler", + subarea: "take", + bg: { r: 150, g: 150, b: 150 }, + }, + flush: { + area: "scheduler", + subarea: "flush", + bg: { r: 100, g: 100, b: 100 }, + }, + }, } as const; interface TracePhase extends TextFormat { @@ -201,7 +218,7 @@ export function traceEffect(phase: TracePhase, cb: () => string) { let first = true; const triggerIds = new Set(); - const runner: ReactiveEffectRunner = effect( + syncEffect( () => { if (first) { // just track what we need, don't log. @@ -213,7 +230,6 @@ export function traceEffect(phase: TracePhase, cb: () => string) { triggerIds.clear(); }, { - scheduler: scheduler(() => runner, true), onTrigger(event) { const id = triggerCount++; if (dids.has(id)) { @@ -431,12 +447,12 @@ export function formatScope(scope: OutputSymbol["scope"]): string { // Show parent scope if present if (scope.parent) { - details.push(` parent: ${formatScopeName(scope.parent)}`); + details.push(` parent: ${untrack(() => formatScopeName(scope.parent!))}`); } // Show owner if present (for member scopes) if (scope.owner) { - details.push(` owner: ${formatSymbolName(scope.owner)}`); + details.push(` owner: ${untrack(() => formatSymbolName(scope.owner!))}`); } // Show child scopes if present diff --git a/packages/core/test/refkey.test.ts b/packages/core/test/refkey.test.ts index d0fe0f587..4d5f9aa92 100644 --- a/packages/core/test/refkey.test.ts +++ b/packages/core/test/refkey.test.ts @@ -1,5 +1,5 @@ import { expect, it } from "vitest"; -import { refkey } from "../src/refkey.js"; +import { refkey } from "../src/symbols/refkey.js"; it("is stable when called with same values", () => { const obj = {}; diff --git a/packages/core/test/symbols/output-scope.test.ts b/packages/core/test/symbols/output-scope.test.ts index d63572c0f..5c6d62832 100644 --- a/packages/core/test/symbols/output-scope.test.ts +++ b/packages/core/test/symbols/output-scope.test.ts @@ -1,11 +1,11 @@ import { reactive, watch } from "@vue/reactivity"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { Binder, createOutputBinder } from "../../src/binder.js"; -import { Refkey } from "../../src/refkey.js"; import { flushJobs } from "../../src/scheduler.js"; +import { Binder, createOutputBinder } from "../../src/symbols/binder.js"; import { OutputScopeFlags } from "../../src/symbols/flags.js"; import { OutputScope } from "../../src/symbols/output-scope.js"; import { OutputSymbol } from "../../src/symbols/output-symbol.js"; +import { Refkey } from "../../src/symbols/refkey.js"; import { SymbolTable } from "../../src/symbols/symbol-table.js"; let binder: Binder; diff --git a/packages/core/test/symbols/output-symbol.test.ts b/packages/core/test/symbols/output-symbol.test.ts index 622cdf714..991ca1f08 100644 --- a/packages/core/test/symbols/output-symbol.test.ts +++ b/packages/core/test/symbols/output-symbol.test.ts @@ -1,11 +1,11 @@ import { reactive, watch } from "@vue/reactivity"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { Binder, createOutputBinder } from "../../src/binder.js"; import { ComponentContext } from "../../src/context.js"; import { MemberScopeContext } from "../../src/context/member-scope.js"; import { ScopeContext } from "../../src/index.browser.js"; import { renderTree } from "../../src/render.js"; import { flushJobs } from "../../src/scheduler.js"; +import { Binder, createOutputBinder } from "../../src/symbols/binder.js"; import { OutputScopeFlags, OutputSymbolFlags, @@ -22,7 +22,6 @@ describe("OutputSymbol reactivity", () => { it("keeps symbol names up-to-date", () => { const scope = new OutputScope("scope", { binder }); const symbol = new OutputSymbol("sym", { binder, scope }); - flushJobs(); expect(scope.symbolNames.has("sym")).toBe(true); diff --git a/packages/core/test/symbols/resolution.test.ts b/packages/core/test/symbols/resolution.test.ts index f5c2f41a4..fe7918c58 100644 --- a/packages/core/test/symbols/resolution.test.ts +++ b/packages/core/test/symbols/resolution.test.ts @@ -6,7 +6,7 @@ import { OutputSymbol } from "../../src/symbols/output-symbol.js"; import { createScopeTree } from "./utils.js"; describe("Symbol name resolution", () => { - it("resolves static symbols", () => { + it.only("resolves static symbols", () => { const binder = createOutputBinder(); const { symbols: { static: staticSym }, diff --git a/packages/core/test/symbols/utils.ts b/packages/core/test/symbols/utils.ts index ec6262b5a..a2a52ca4e 100644 --- a/packages/core/test/symbols/utils.ts +++ b/packages/core/test/symbols/utils.ts @@ -1,11 +1,11 @@ import { Binder } from "../../src/index.browser.js"; -import { Refkey, refkey } from "../../src/refkey.js"; import { OutputScopeFlags, OutputSymbolFlags, } from "../../src/symbols/flags.js"; import { OutputScope } from "../../src/symbols/output-scope.js"; import { OutputSymbol } from "../../src/symbols/output-symbol.js"; +import { Refkey, refkey } from "../../src/symbols/refkey.js"; type ScopeRecords = Record; type SymbolRecords = Record; diff --git a/packages/dev-tools/dev-tools-vue/.gitattributes b/packages/dev-tools/dev-tools-vue/.gitattributes new file mode 100644 index 000000000..6313b56c5 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/packages/dev-tools/dev-tools-vue/.gitignore b/packages/dev-tools/dev-tools-vue/.gitignore new file mode 100644 index 000000000..8ee54e8d3 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo diff --git a/packages/dev-tools/dev-tools-vue/.prettierrc.json b/packages/dev-tools/dev-tools-vue/.prettierrc.json new file mode 100644 index 000000000..29a2402ef --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "semi": false, + "singleQuote": true, + "printWidth": 100 +} diff --git a/packages/dev-tools/dev-tools-vue/.vscode/extensions.json b/packages/dev-tools/dev-tools-vue/.vscode/extensions.json new file mode 100644 index 000000000..bd138dc6a --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "Vue.volar", + "vitest.explorer", + "esbenp.prettier-vscode" + ] +} diff --git a/packages/dev-tools/dev-tools-vue/README.md b/packages/dev-tools/dev-tools-vue/README.md new file mode 100644 index 000000000..757fc1da8 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/README.md @@ -0,0 +1,39 @@ +# dev-tools-vue + +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## Type Support for `.vue` Imports in TS + +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. + +## Customize configuration + +See [Vite Configuration Reference](https://vite.dev/config/). + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Type-Check, Compile and Minify for Production + +```sh +npm run build +``` + +### Run Unit Tests with [Vitest](https://vitest.dev/) + +```sh +npm run test:unit +``` diff --git a/packages/dev-tools/dev-tools-vue/components.json b/packages/dev-tools/dev-tools-vue/components.json new file mode 100644 index 000000000..3fbe9fa5e --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "new-york", + "typescript": true, + "tailwind": { + "config": "", + "css": "src/assets/base.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "composables": "@/composables", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/packages/dev-tools/dev-tools-vue/env.d.ts b/packages/dev-tools/dev-tools-vue/env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/dev-tools/dev-tools-vue/index.html b/packages/dev-tools/dev-tools-vue/index.html new file mode 100644 index 000000000..3798b3458 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/index.html @@ -0,0 +1,13 @@ + + + + + + + Alloy Dev Tools + + +
+ + + diff --git a/packages/dev-tools/dev-tools-vue/package.json b/packages/dev-tools/dev-tools-vue/package.json new file mode 100644 index 000000000..4462ff27e --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/package.json @@ -0,0 +1,47 @@ +{ + "name": "dev-tools-vue", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "run-p type-check \"build-only {@}\" --", + "preview": "vite preview", + "test:unit": "vitest", + "build-only": "vite build && cp dist/index.html ../core/dist/index.html", + "type-check": "vue-tsc --build", + "format": "prettier --write src/" + }, + "dependencies": { + "@alloy-js/core": "workspace:~", + "@tailwindcss/vite": "^4.1.8", + "@vue/reactivity": "catalog:", + "@vueuse/core": "^13.3.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-vue-next": "^0.511.0", + "reka-ui": "^2.3.0", + "tailwind-merge": "^3.3.0", + "tailwindcss": "^4.1.8", + "tw-animate-css": "^1.3.0", + "vue": "^3.5.13", + "ws": "^8.18.2" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.1", + "@types/jsdom": "^21.1.7", + "@types/node": "^22.15.24", + "@vitejs/plugin-vue": "^5.2.3", + "@vue/test-utils": "^2.4.6", + "@vue/tsconfig": "^0.7.0", + "jsdom": "^26.0.0", + "npm-run-all2": "^7.0.2", + "prettier": "3.5.3", + "typescript": "~5.8.0", + "vite": "^6.2.4", + "vite-plugin-singlefile": "^2.2.0", + "vite-plugin-vue-devtools": "^7.7.2", + "vitest": "^3.1.1", + "vue-tsc": "^2.2.8" + } +} diff --git a/packages/dev-tools/dev-tools-vue/public/favicon.ico b/packages/dev-tools/dev-tools-vue/public/favicon.ico new file mode 100644 index 000000000..df36fcfb7 Binary files /dev/null and b/packages/dev-tools/dev-tools-vue/public/favicon.ico differ diff --git a/packages/dev-tools/dev-tools-vue/scripts/mock-server.js b/packages/dev-tools/dev-tools-vue/scripts/mock-server.js new file mode 100644 index 000000000..7908e60dd --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/scripts/mock-server.js @@ -0,0 +1,384 @@ +#!/usr/bin/env node + +/** + * Mock WebSocket server for testing the symbol store + * Run with: node scripts/mock-server.js + */ + +import { WebSocketServer } from 'ws' + +const port = 8080 +const wss = new WebSocketServer({ port }) + +console.log(`Mock WebSocket server running on ws://localhost:${port}`) + +// Output symbol flags +const OutputSymbolFlags = { + None: 0, + InstanceMemberContainer: 1 << 0, + StaticMemberContainer: 1 << 1, + MemberContainer: (1 << 0) | (1 << 1), + InstanceMember: 1 << 2, + StaticMember: 1 << 3, + Transient: 1 << 4, + Alias: 1 << 5, + Member: (1 << 2) | (1 << 3), +} + +// Output scope flags +const OutputScopeFlags = { + None: 0, + StaticMemberScope: 1 << 0, + InstanceMemberScope: 1 << 1, + Transient: 1 << 2, + MemberScope: (1 << 0) | (1 << 1), +} + +let symbolId = 0 +let scopeId = 0 + +// Sample scope tree structure to send incrementally +const sampleScopeTree = { + // 1. Global scope first + globalScope: { + id: ++scopeId, + name: 'global', + kind: 'global', + flags: OutputScopeFlags.None, + symbols: [], + children: [], + parent: null, + owner: null, + metadata: { description: 'Global scope' }, + }, + + // 2. Nested scopes + moduleScope: { + id: ++scopeId, + name: 'UserModule', + kind: 'module', + flags: OutputScopeFlags.None, + symbols: [], + children: [], + parent: 1, // globalScope id + owner: null, + metadata: { description: 'User module scope' }, + }, + + classScope: { + id: ++scopeId, + name: 'UserClass', + kind: 'class', + flags: OutputScopeFlags.None, + symbols: [], + children: [], + parent: 2, // moduleScope id + owner: null, + metadata: { description: 'User class scope' }, + }, + + // Member scopes will be created for symbols that have members + instanceMemberScope: { + id: ++scopeId, + name: 'UserClass_instanceMembers', + kind: 'instanceMembers', + flags: OutputScopeFlags.InstanceMemberScope, + symbols: [], + children: [], + parent: null, + owner: null, // Will be set to UserClass symbol id + metadata: { description: 'Instance members of UserClass' }, + }, + + staticMemberScope: { + id: ++scopeId, + name: 'UserClass_staticMembers', + kind: 'staticMembers', + flags: OutputScopeFlags.StaticMemberScope, + symbols: [], + children: [], + parent: null, + owner: null, // Will be set to UserClass symbol id + metadata: { description: 'Static members of UserClass' }, + }, +} + +// Sample symbols +const sampleSymbols = { + // Regular symbol (no flags) + regularFunction: { + id: ++symbolId, + name: 'processData', + originalName: 'processData', + flags: OutputSymbolFlags.None, + scope: 2, // moduleScope + refkeys: ['processData_ref_001'], + metadata: { description: 'Regular function symbol' }, + instanceMemberScope: null, + staticMemberScope: null, + aliasTarget: null, + }, + + // Static member container symbol + utilityClass: { + id: ++symbolId, + name: 'UtilityClass', + originalName: 'UtilityClass', + flags: OutputSymbolFlags.StaticMemberContainer, + scope: 2, // moduleScope + refkeys: ['UtilityClass_ref_001'], + metadata: { description: 'Utility class with static members only' }, + instanceMemberScope: null, + staticMemberScope: ++scopeId, // Will create static member scope + aliasTarget: null, + }, + + // Instance and static member container symbol + userClass: { + id: ++symbolId, + name: 'UserClass', + originalName: 'UserClass', + flags: OutputSymbolFlags.InstanceMemberContainer | OutputSymbolFlags.StaticMemberContainer, + scope: 3, // classScope + refkeys: ['UserClass_ref_001'], + metadata: { description: 'User class with both instance and static members' }, + instanceMemberScope: 4, // instanceMemberScope + staticMemberScope: 5, // staticMemberScope + aliasTarget: null, + }, + + // Instance members + instanceMethod: { + id: ++symbolId, + name: 'getName', + originalName: 'getName', + flags: OutputSymbolFlags.InstanceMember, + scope: 4, // instanceMemberScope + refkeys: ['getName_ref_001'], + metadata: { description: 'Instance method' }, + instanceMemberScope: null, + staticMemberScope: null, + aliasTarget: null, + }, + + instanceProperty: { + id: ++symbolId, + name: 'name', + originalName: 'name', + flags: OutputSymbolFlags.InstanceMember, + scope: 4, // instanceMemberScope + refkeys: ['name_ref_001'], + metadata: { description: 'Instance property' }, + instanceMemberScope: null, + staticMemberScope: null, + aliasTarget: null, + }, + + // Static members + staticMethod: { + id: ++symbolId, + name: 'create', + originalName: 'create', + flags: OutputSymbolFlags.StaticMember, + scope: 5, // staticMemberScope + refkeys: ['create_ref_001'], + metadata: { description: 'Static factory method' }, + instanceMemberScope: null, + staticMemberScope: null, + aliasTarget: null, + }, + + staticProperty: { + id: ++symbolId, + name: 'DEFAULT_NAME', + originalName: 'DEFAULT_NAME', + flags: OutputSymbolFlags.StaticMember, + scope: 5, // staticMemberScope + refkeys: ['DEFAULT_NAME_ref_001'], + metadata: { description: 'Static constant' }, + instanceMemberScope: null, + staticMemberScope: null, + aliasTarget: null, + }, + + // Utility class static members + utilityStaticMethod: { + id: ++symbolId, + name: 'formatString', + originalName: 'formatString', + flags: OutputSymbolFlags.StaticMember, + scope: 6, // utilityClass staticMemberScope + refkeys: ['formatString_ref_001'], + metadata: { description: 'Utility static method' }, + instanceMemberScope: null, + staticMemberScope: null, + aliasTarget: null, + }, +} + +// Additional scopes for utility class +sampleScopeTree.utilityStaticMemberScope = { + id: 6, + name: 'UtilityClass_staticMembers', + kind: 'staticMembers', + flags: OutputScopeFlags.StaticMemberScope, + symbols: [8], // utilityStaticMethod + children: [], + parent: null, + owner: 2, // utilityClass symbol + metadata: { description: 'Static members of UtilityClass' }, +} + +// Update scope symbol arrays +sampleScopeTree.globalScope.children = [2] // moduleScope +sampleScopeTree.moduleScope.symbols = [1, 2] // regularFunction, utilityClass +sampleScopeTree.moduleScope.children = [3] // classScope +sampleScopeTree.classScope.symbols = [3] // userClass +sampleScopeTree.instanceMemberScope.symbols = [4, 5] // instanceMethod, instanceProperty +sampleScopeTree.instanceMemberScope.owner = 3 // userClass +sampleScopeTree.staticMemberScope.symbols = [6, 7] // staticMethod, staticProperty +sampleScopeTree.staticMemberScope.owner = 3 // userClass + +function createScopeMessage(scope) { + return { + type: 'scope_added', + data: { + scope: scope, + nodeId: Math.floor(Math.random() * 1000), // Mock nodeId + }, + } +} + +function createSymbolMessage(symbol) { + return { + type: 'symbol_added', + data: { + symbol: symbol, + nodeId: Math.floor(Math.random() * 1000), // Mock nodeId + }, + } +} + +wss.on('connection', (ws) => { + console.log('Client connected') + + ws.on('error', console.error) + + ws.on('close', () => { + console.log('Client disconnected') + }) + + // Send incremental scope tree data + let step = 0 + const sendNextStep = () => { + if (ws.readyState !== ws.OPEN) return + + switch (step) { + case 0: + // 1. Send global scope first + ws.send(JSON.stringify(createScopeMessage(sampleScopeTree.globalScope))) + console.log('Sent: Global scope') + break + + case 1: + // 2. Send module scope + ws.send(JSON.stringify(createScopeMessage(sampleScopeTree.moduleScope))) + console.log('Sent: Module scope') + break + + case 2: + // 3. Send class scope + ws.send(JSON.stringify(createScopeMessage(sampleScopeTree.classScope))) + console.log('Sent: Class scope') + break + + case 3: + // 4. Send regular function symbol (no flags) + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.regularFunction))) + console.log('Sent: Regular function symbol') + break + + case 4: + // 5. Send utility class static member scope first + ws.send(JSON.stringify(createScopeMessage(sampleScopeTree.utilityStaticMemberScope))) + console.log('Sent: Utility class static member scope') + break + + case 5: + // 6. Send utility class symbol (static member container) + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.utilityClass))) + console.log('Sent: Utility class symbol (static member container)') + break + + case 6: + // 7. Send utility static method + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.utilityStaticMethod))) + console.log('Sent: Utility static method') + break + + case 7: + // 8. Send instance member scope + ws.send(JSON.stringify(createScopeMessage(sampleScopeTree.instanceMemberScope))) + console.log('Sent: Instance member scope') + break + + case 8: + // 9. Send static member scope + ws.send(JSON.stringify(createScopeMessage(sampleScopeTree.staticMemberScope))) + console.log('Sent: Static member scope') + break + + case 9: + // 10. Send user class symbol (instance and static member container) + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.userClass))) + console.log('Sent: User class symbol (instance and static member container)') + break + + case 10: + // 11. Send instance method + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.instanceMethod))) + console.log('Sent: Instance method') + break + + case 11: + // 12. Send instance property + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.instanceProperty))) + console.log('Sent: Instance property') + break + + case 12: + // 13. Send static method + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.staticMethod))) + console.log('Sent: Static method') + break + + case 13: + // 14. Send static property + ws.send(JSON.stringify(createSymbolMessage(sampleSymbols.staticProperty))) + console.log('Sent: Static property') + console.log('Scope tree complete!') + return // Stop sending + + default: + return // Stop sending + } + + step++ + // Schedule next step + setTimeout(sendNextStep, 1500) + } + + // Start sending data after a short delay + setTimeout(sendNextStep, 1000) + + ws.on('close', () => { + console.log('Client disconnected') + }) +}) + +process.on('SIGINT', () => { + console.log('\nShutting down server...') + wss.close(() => { + process.exit(0) + }) +}) diff --git a/packages/dev-tools/dev-tools-vue/src/App.vue b/packages/dev-tools/dev-tools-vue/src/App.vue new file mode 100644 index 000000000..550572001 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/App.vue @@ -0,0 +1,49 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/assets/base.css b/packages/dev-tools/dev-tools-vue/src/assets/base.css new file mode 100644 index 000000000..a3ffe1771 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/assets/base.css @@ -0,0 +1,141 @@ +@import 'tailwindcss'; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + --animate-accordion-down: accordion-down 0.2s ease-out; + --animate-accordion-up: accordion-up 0.2s ease-out; + @keyframes accordion-down { + from { + height: 0; + } + to { + height: var(--reka-accordion-content-height); + } + } + @keyframes accordion-up { + from { + height: var(--reka-accordion-content-height); + } + to { + height: 0; + } + } +} + +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.145 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.145 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: oklch(0.269 0 0); + --input: oklch(0.269 0 0); + --ring: oklch(0.439 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(0.269 0 0); + --sidebar-ring: oklch(0.439 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/packages/dev-tools/dev-tools-vue/src/assets/logo.svg b/packages/dev-tools/dev-tools-vue/src/assets/logo.svg new file mode 100644 index 000000000..756566035 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/packages/dev-tools/dev-tools-vue/src/assets/main.css b/packages/dev-tools/dev-tools-vue/src/assets/main.css new file mode 100644 index 000000000..c39c25f48 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/assets/main.css @@ -0,0 +1,13 @@ +@import './base.css'; + +@media (min-width: 1024px) { + body { + margin: 0; + padding: 0; + } + + #app { + width: 100vw; + height: 100vh; + } +} diff --git a/packages/dev-tools/dev-tools-vue/src/components/ComponentDetails.vue b/packages/dev-tools/dev-tools-vue/src/components/ComponentDetails.vue new file mode 100644 index 000000000..c202665b0 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ComponentDetails.vue @@ -0,0 +1,314 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ComponentProps.vue b/packages/dev-tools/dev-tools-vue/src/components/ComponentProps.vue new file mode 100644 index 000000000..69273ecc1 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ComponentProps.vue @@ -0,0 +1,170 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ComponentTree.vue b/packages/dev-tools/dev-tools-vue/src/components/ComponentTree.vue new file mode 100644 index 000000000..fc9b80b41 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ComponentTree.vue @@ -0,0 +1,590 @@ + + + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ComponentTreeNode.vue b/packages/dev-tools/dev-tools-vue/src/components/ComponentTreeNode.vue new file mode 100644 index 000000000..d15c00a33 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ComponentTreeNode.vue @@ -0,0 +1,142 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ContentPane.vue b/packages/dev-tools/dev-tools-vue/src/components/ContentPane.vue new file mode 100644 index 000000000..932a9f90f --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ContentPane.vue @@ -0,0 +1,258 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ErrorDetails.vue b/packages/dev-tools/dev-tools-vue/src/components/ErrorDetails.vue new file mode 100644 index 000000000..358d1fc43 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ErrorDetails.vue @@ -0,0 +1,114 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/FileDetails.vue b/packages/dev-tools/dev-tools-vue/src/components/FileDetails.vue new file mode 100644 index 000000000..f1470770a --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/FileDetails.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/FileTree.vue b/packages/dev-tools/dev-tools-vue/src/components/FileTree.vue new file mode 100644 index 000000000..f5ed9f6fc --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/FileTree.vue @@ -0,0 +1,82 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/FileTreeNode.vue b/packages/dev-tools/dev-tools-vue/src/components/FileTreeNode.vue new file mode 100644 index 000000000..aa28e9e17 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/FileTreeNode.vue @@ -0,0 +1,118 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/MainContentArea.vue b/packages/dev-tools/dev-tools-vue/src/components/MainContentArea.vue new file mode 100644 index 000000000..5bac165fe --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/MainContentArea.vue @@ -0,0 +1,28 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/MenuPane.vue b/packages/dev-tools/dev-tools-vue/src/components/MenuPane.vue new file mode 100644 index 000000000..c6574d517 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/MenuPane.vue @@ -0,0 +1,91 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/NavigationBar.vue b/packages/dev-tools/dev-tools-vue/src/components/NavigationBar.vue new file mode 100644 index 000000000..b99055ccf --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/NavigationBar.vue @@ -0,0 +1,49 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ScopeDetails.vue b/packages/dev-tools/dev-tools-vue/src/components/ScopeDetails.vue new file mode 100644 index 000000000..018d3f78f --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ScopeDetails.vue @@ -0,0 +1,149 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/StatusBar.vue b/packages/dev-tools/dev-tools-vue/src/components/StatusBar.vue new file mode 100644 index 000000000..00b58d80b --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/StatusBar.vue @@ -0,0 +1,89 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/SymbolDetails.vue b/packages/dev-tools/dev-tools-vue/src/components/SymbolDetails.vue new file mode 100644 index 000000000..60dfc1457 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/SymbolDetails.vue @@ -0,0 +1,157 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/SymbolNode.vue b/packages/dev-tools/dev-tools-vue/src/components/SymbolNode.vue new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dev-tools/dev-tools-vue/src/components/SymbolTreeNode.vue b/packages/dev-tools/dev-tools-vue/src/components/SymbolTreeNode.vue new file mode 100644 index 000000000..d91c04413 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/SymbolTreeNode.vue @@ -0,0 +1,214 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/TreeNode.vue b/packages/dev-tools/dev-tools-vue/src/components/TreeNode.vue new file mode 100644 index 000000000..af0e69440 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/TreeNode.vue @@ -0,0 +1,128 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/Accordion.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/Accordion.vue new file mode 100644 index 000000000..b3777e520 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/Accordion.vue @@ -0,0 +1,19 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionContent.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionContent.vue new file mode 100644 index 000000000..bc5b37a4d --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionContent.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionItem.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionItem.vue new file mode 100644 index 000000000..62d4469f0 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionItem.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionTrigger.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionTrigger.vue new file mode 100644 index 000000000..f6cbea84a --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/AccordionTrigger.vue @@ -0,0 +1,37 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/index.ts b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/index.ts new file mode 100644 index 000000000..9340ac065 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/accordion/index.ts @@ -0,0 +1,4 @@ +export { default as Accordion } from './Accordion.vue' +export { default as AccordionContent } from './AccordionContent.vue' +export { default as AccordionItem } from './AccordionItem.vue' +export { default as AccordionTrigger } from './AccordionTrigger.vue' diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/button/Button.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/button/Button.vue new file mode 100644 index 000000000..ecf3fe383 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/button/Button.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/button/index.ts b/packages/dev-tools/dev-tools-vue/src/components/ui/button/index.ts new file mode 100644 index 000000000..616d1d3a2 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/button/index.ts @@ -0,0 +1,36 @@ +import { cva, type VariantProps } from 'class-variance-authority' + +export { default as Button } from './Button.vue' + +export const buttonVariants = cva( + 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=\'size-\'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive', + { + variants: { + variant: { + default: + 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90', + destructive: + 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', + outline: + 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50', + secondary: + 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', + ghost: + 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50', + link: 'text-primary underline-offset-4 hover:underline', + }, + size: { + default: 'h-9 px-4 py-2 has-[>svg]:px-3', + sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5', + lg: 'h-10 rounded-md px-6 has-[>svg]:px-4', + icon: 'size-9', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + }, +) + +export type ButtonVariants = VariantProps diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenu.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenu.vue new file mode 100644 index 000000000..f88da5f5a --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenu.vue @@ -0,0 +1,35 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuContent.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuContent.vue new file mode 100644 index 000000000..a12ab1a0f --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuContent.vue @@ -0,0 +1,32 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuIndicator.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuIndicator.vue new file mode 100644 index 000000000..5d48e8808 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuIndicator.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuItem.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuItem.vue new file mode 100644 index 000000000..03c3e5ac3 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuItem.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuLink.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuLink.vue new file mode 100644 index 000000000..7a13b241c --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuLink.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuList.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuList.vue new file mode 100644 index 000000000..f6248e680 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuList.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuTrigger.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuTrigger.vue new file mode 100644 index 000000000..32f72da71 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuTrigger.vue @@ -0,0 +1,32 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuViewport.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuViewport.vue new file mode 100644 index 000000000..5fa12106f --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/NavigationMenuViewport.vue @@ -0,0 +1,31 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/index.ts b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/index.ts new file mode 100644 index 000000000..90e0e2d6d --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/navigation-menu/index.ts @@ -0,0 +1,14 @@ +import { cva } from 'class-variance-authority' + +export { default as NavigationMenu } from './NavigationMenu.vue' +export { default as NavigationMenuContent } from './NavigationMenuContent.vue' +export { default as NavigationMenuIndicator } from './NavigationMenuIndicator.vue' +export { default as NavigationMenuItem } from './NavigationMenuItem.vue' +export { default as NavigationMenuLink } from './NavigationMenuLink.vue' +export { default as NavigationMenuList } from './NavigationMenuList.vue' +export { default as NavigationMenuTrigger } from './NavigationMenuTrigger.vue' +export { default as NavigationMenuViewport } from './NavigationMenuViewport.vue' + +export const navigationMenuTriggerStyle = cva( + 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1', +) diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizableHandle.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizableHandle.vue new file mode 100644 index 000000000..8c008b8e4 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizableHandle.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizablePanel.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizablePanel.vue new file mode 100644 index 000000000..032f92901 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizablePanel.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizablePanelGroup.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizablePanelGroup.vue new file mode 100644 index 000000000..e5545a6f7 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/ResizablePanelGroup.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/index.ts b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/index.ts new file mode 100644 index 000000000..5b3bb846b --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/resizable/index.ts @@ -0,0 +1,3 @@ +export { default as ResizableHandle } from './ResizableHandle.vue' +export { default as ResizablePanel } from './ResizablePanel.vue' +export { default as ResizablePanelGroup } from './ResizablePanelGroup.vue' diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/Tabs.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/Tabs.vue new file mode 100644 index 000000000..cdfd48c22 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/Tabs.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsContent.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsContent.vue new file mode 100644 index 000000000..a07f7a78f --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsContent.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsList.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsList.vue new file mode 100644 index 000000000..4df3287ef --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsList.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsTrigger.vue b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsTrigger.vue new file mode 100644 index 000000000..4230433a1 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/TabsTrigger.vue @@ -0,0 +1,25 @@ + + + diff --git a/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/index.ts b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/index.ts new file mode 100644 index 000000000..a5e58dc09 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/components/ui/tabs/index.ts @@ -0,0 +1,4 @@ +export { default as Tabs } from './Tabs.vue' +export { default as TabsContent } from './TabsContent.vue' +export { default as TabsList } from './TabsList.vue' +export { default as TabsTrigger } from './TabsTrigger.vue' diff --git a/packages/dev-tools/dev-tools-vue/src/composables/useContentMapping.ts b/packages/dev-tools/dev-tools-vue/src/composables/useContentMapping.ts new file mode 100644 index 000000000..f14529830 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/composables/useContentMapping.ts @@ -0,0 +1,480 @@ +import type { SerializedNode } from '@/lib/types' +import { getNode } from '@/lib/store' +import { computed } from 'vue' + +export interface ContentMapping { + nodeId: number + start: number + end: number + content: string + nodeKind?: string +} + +/** + * Maps file contents to their corresponding tree nodes. + * This function walks the tree starting from the root node and maps each node's + * content to regions in the file contents. + */ +export function useContentMapping(fileContents: string, rootNodeId: number) { + const mappings = computed(() => { + const result: ContentMapping[] = [] + + try { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Starting content mapping for file:', { + fileLength: fileContents.length, + rootNodeId, + filePreview: + JSON.stringify(fileContents.substring(0, 100)) + (fileContents.length > 100 ? '...' : ''), + }) + + // Walk the tree and map content sequentially + walkTreeForContent(rootNodeId, fileContents, 0, result) + + // eslint-disable-next-line no-console + console.log('[Content Mapping] Completed mapping:', { + totalMappings: result.length, + mappings: result.map((m) => ({ + nodeId: m.nodeId, + nodeKind: m.nodeKind, + start: m.start, + end: m.end, + content: JSON.stringify(m.content), + })), + }) + } catch (error) { + // eslint-disable-next-line no-console + console.error('[Content Mapping] Error during content mapping:', error) + } + + return result + }) + + return { + mappings, + getWrappedContent: () => wrapContentWithSpans(fileContents, mappings.value), + } +} + +function walkTreeForContent( + nodeId: number, + fileContents: string, + startPosition: number, + mappings: ContentMapping[], +): number { + const nodeRef = getNode(nodeId) + const node = nodeRef.value + + if (!node) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Node not found:', nodeId) + return startPosition + } + + // Skip deleted nodes - they shouldn't be mapped to any content + if (node.deleted) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Skipping deleted node:', { nodeId, nodeKind: node.kind }) + return startPosition + } + + // eslint-disable-next-line no-console + console.log('[Content Mapping] Processing node:', { + nodeId: node.id, + nodeKind: node.kind, + tag: (node as any).tag, + childrenCount: node.children.length, + startPosition, + }) + + let currentPosition = startPosition + + // Process children in order - this is crucial for sequential mapping + for (const child of node.children) { + if (typeof child === 'string') { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Processing text child:', { + parentNodeId: node.id, + text: JSON.stringify(child), + currentPosition, + }) + + // Text content - find this text in the file contents starting from current position + const textMatch = findTextInContent(child, fileContents, currentPosition) + if (textMatch) { + // Add mapping for this text content + mappings.push({ + nodeId: node.id, + start: textMatch.start, + end: textMatch.end, + content: child, + nodeKind: node.kind, + }) + currentPosition = textMatch.end + + // eslint-disable-next-line no-console + console.log('[Content Mapping] Mapped text content:', { + nodeId: node.id, + content: JSON.stringify(child), + start: textMatch.start, + end: textMatch.end, + newPosition: currentPosition, + actualContent: JSON.stringify(fileContents.substring(textMatch.start, textMatch.end)), + }) + } else { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Failed to map text content:', { + nodeId: node.id, + content: JSON.stringify(child), + currentPosition, + fileRemainder: JSON.stringify( + fileContents.substring(currentPosition, currentPosition + 50), + ), + searchContext: { + beforePosition: JSON.stringify( + fileContents.substring(Math.max(0, currentPosition - 10), currentPosition), + ), + atPosition: JSON.stringify( + fileContents.substring(currentPosition, currentPosition + 20), + ), + }, + }) + + // For failed text mappings, still advance position to avoid getting stuck + // This is a fallback to prevent infinite loops + if (child.length > 0) { + const fallbackIndex = fileContents.indexOf(child, currentPosition) + if (fallbackIndex !== -1) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Fallback: Found text at different position:', { + nodeId: node.id, + content: JSON.stringify(child), + expectedPosition: currentPosition, + actualPosition: fallbackIndex, + gap: fallbackIndex - currentPosition, + }) + currentPosition = fallbackIndex + child.length + } + } + } + } else if (typeof child === 'number') { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Processing node child:', { + parentNodeId: node.id, + childNodeId: child, + currentPosition, + }) + + // Node reference - recursively process the child node + // Check if the child node is deleted before processing + const childNodeRef = getNode(child) + const childNode = childNodeRef.value + + if (!childNode) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Child node not found in store:', { + parentNodeId: node.id, + childNodeId: child, + currentPosition, + }) + // Continue with current position - don't advance for missing nodes + continue + } + + if (childNode.deleted) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Skipping deleted child node:', { + childNodeId: child, + currentPosition, + }) + // Skip deleted nodes entirely + continue + } + + currentPosition = walkTreeForContent(child, fileContents, currentPosition, mappings) + } + } + + // Special handling for intrinsic elements that render without children + // These are elements like "br", "line", "hardline", etc. that render as whitespace/breaks + // but don't have text children + if (node.kind === 'intrinsic' && node.children.length === 0) { + const intrinsicNode = node as any // Cast to access tag property + const intrinsicMapping = handleIntrinsicElement(intrinsicNode, fileContents, currentPosition) + if (intrinsicMapping) { + mappings.push({ + nodeId: node.id, + start: intrinsicMapping.start, + end: intrinsicMapping.end, + content: intrinsicMapping.content, + nodeKind: node.kind, + }) + currentPosition = intrinsicMapping.end + } + } + + return currentPosition +} + +function findTextInContent( + text: string, + fileContents: string, + startPosition: number, +): { start: number; end: number } | null { + // Handle empty strings specially - they should be zero-width mappings + if (text === '') { + return { + start: startPosition, + end: startPosition, + } + } + + // Skip whitespace-only text that isn't an empty string + if (text.trim() === '' && text !== '') { + // For whitespace, try to find exact match first + const index = fileContents.indexOf(text, startPosition) + if (index !== -1) { + return { + start: index, + end: index + text.length, + } + } + return null + } + + // Find the text starting from the current position + const index = fileContents.indexOf(text, startPosition) + if (index !== -1) { + return { + start: index, + end: index + text.length, + } + } + + // If exact match not found, try to find it with flexible whitespace matching + // This is especially important for handling spaces and line breaks + if (text.trim().length > 0) { + const trimmedText = text.trim() + const trimmedIndex = fileContents.indexOf(trimmedText, startPosition) + if (trimmedIndex !== -1) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Found text with trimmed matching:', { + originalText: JSON.stringify(text), + trimmedText: JSON.stringify(trimmedText), + startPosition, + foundAt: trimmedIndex, + }) + return { + start: trimmedIndex, + end: trimmedIndex + trimmedText.length, + } + } + } + + // For single character content, look for it more broadly + if (text.length === 1) { + for (let i = startPosition; i < Math.min(fileContents.length, startPosition + 20); i++) { + if (fileContents[i] === text) { + // eslint-disable-next-line no-console + console.log('[Content Mapping] Found single character with lookahead:', { + character: JSON.stringify(text), + expectedPosition: startPosition, + actualPosition: i, + gap: i - startPosition, + }) + return { + start: i, + end: i + 1, + } + } + } + } + + return null +} + +function handleIntrinsicElement( + node: SerializedNode, + fileContents: string, + currentPosition: number, +): { start: number; end: number; content: string } | null { + if (node.kind !== 'intrinsic') { + return null + } + + const intrinsicNode = node as any // Cast to access tag property + + // Handle intrinsic elements that render as whitespace or breaks + // These elements typically don't have children and render as specific characters + switch (intrinsicNode.tag) { + case 'br': + case 'line': { + // These might render as line breaks or spaces + const match = findLineBreakOrSpace(fileContents, currentPosition) + if (match) { + return { + start: match.start, + end: match.end, + content: fileContents.substring(match.start, match.end), + } + } + break + } + case 'sbr': + case 'softline': { + // Soft breaks might render as nothing or as a line break + const match = findSoftBreak(fileContents, currentPosition) + if (match) { + return { + start: match.start, + end: match.end, + content: fileContents.substring(match.start, match.end), + } + } + break + } + case 'hardline': + case 'hbr': + case 'literalline': + case 'lbr': { + // Hard breaks should always render as line breaks + const match = findHardBreak(fileContents, currentPosition) + if (match) { + return { + start: match.start, + end: match.end, + content: fileContents.substring(match.start, match.end), + } + } + break + } + // Container elements like 'indent', 'dedent', 'group', 'align', etc. + // don't render content themselves - their children do + default: + // For other intrinsic elements, don't map specific content + break + } + + return null +} + +function findLineBreakOrSpace( + fileContents: string, + startPosition: number, +): { start: number; end: number } | null { + // Look for line break first + if (startPosition < fileContents.length && fileContents[startPosition] === '\n') { + return { start: startPosition, end: startPosition + 1 } + } + + // Look for carriage return + line feed + if ( + startPosition < fileContents.length - 1 && + fileContents.substring(startPosition, startPosition + 2) === '\r\n' + ) { + return { start: startPosition, end: startPosition + 2 } + } + + // Look for space + if (startPosition < fileContents.length && fileContents[startPosition] === ' ') { + return { start: startPosition, end: startPosition + 1 } + } + + return null +} + +function findSoftBreak( + fileContents: string, + startPosition: number, +): { start: number; end: number } | null { + // Soft breaks might be nothing (zero-width) or a line break + if (startPosition < fileContents.length && fileContents[startPosition] === '\n') { + return { start: startPosition, end: startPosition + 1 } + } + + // If no line break, soft break might be zero-width + return { start: startPosition, end: startPosition } +} + +function findHardBreak( + fileContents: string, + startPosition: number, +): { start: number; end: number } | null { + if (startPosition < fileContents.length && fileContents[startPosition] === '\n') { + return { start: startPosition, end: startPosition + 1 } + } + + if ( + startPosition < fileContents.length - 1 && + fileContents.substring(startPosition, startPosition + 2) === '\r\n' + ) { + return { start: startPosition, end: startPosition + 2 } + } + + return null +} + +function wrapContentWithSpans(fileContents: string, mappings: ContentMapping[]): string { + if (mappings.length === 0) { + return escapeHtml(fileContents) + } + + // Sort mappings by start position and handle overlaps + const sortedMappings = [...mappings] + .sort((a, b) => a.start - b.start) + .filter((mapping, index, array) => { + // Remove duplicate or overlapping mappings + if (index === 0) return true + const prev = array[index - 1] + return mapping.start >= prev.end + }) + + let result = '' + let lastEnd = 0 + + for (const mapping of sortedMappings) { + // Add any content between the last mapping and this one + if (mapping.start > lastEnd) { + const unmappedContent = fileContents.substring(lastEnd, mapping.start) + if (unmappedContent.length > 0) { + // Just add unmapped content as plain text without special styling + result += escapeHtml(unmappedContent) + } + } + + // Add the mapped content wrapped in a span with additional metadata + const content = fileContents.substring(mapping.start, mapping.end) + const nodeType = getNodeTypeFromMapping(mapping) + result += `${escapeHtml(content)}` + + lastEnd = mapping.end + } + + // Add any remaining content + if (lastEnd < fileContents.length) { + const remainingContent = fileContents.substring(lastEnd) + result += escapeHtml(remainingContent) + } + + return result +} + +function getNodeTypeFromMapping(mapping: ContentMapping): string { + // This could be enhanced to determine node type from the mapping + // For now, just return a generic type based on content + if (mapping.content.trim() === '') { + return 'whitespace' + } else if (mapping.content.includes('\n')) { + return 'multiline' + } else if (mapping.content.length === 1) { + return 'char' + } else { + return 'text' + } +} + +function escapeHtml(text: string): string { + const div = document.createElement('div') + div.textContent = text + return div.innerHTML +} diff --git a/packages/dev-tools/dev-tools-vue/src/composables/useMenuHighlight.ts b/packages/dev-tools/dev-tools-vue/src/composables/useMenuHighlight.ts new file mode 100644 index 000000000..a0b159fcd --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/composables/useMenuHighlight.ts @@ -0,0 +1,203 @@ +import { ref, computed } from 'vue' +import type { SerializedFileInfo } from '@/lib/types' +import type { SerializedOutputScope, SerializedOutputSymbol } from '@alloy-js/core/symbols' + +// State for highlighted items in the menu pane +const highlightedFile = ref(null) +const highlightedSymbol = ref(null) +const highlightedScope = ref(null) + +// State for expanded items (to reveal the highlighted item) +const expandedFilePaths = ref>(new Set()) +const expandedScopeIds = ref>(new Set()) +const expandedSymbolIds = ref>(new Set()) + +// State for manually collapsed items (user override) +const manuallyCollapsedFilePaths = ref>(new Set()) +const manuallyCollapsedScopeIds = ref>(new Set()) +const manuallyCollapsedSymbolIds = ref>(new Set()) + +export function useMenuHighlight() { + // Clear all highlights + function clearHighlight() { + highlightedFile.value = null + highlightedSymbol.value = null + highlightedScope.value = null + } + + // Highlight a file and expand its parent directories + function highlightFile(file: SerializedFileInfo) { + // Clear previous highlights but preserve manual expansion state + clearHighlight() + + // Set new highlight + highlightedFile.value = file + + // Expand all parent directories + const path = file.path + for (let i = 0; i < path.length; i++) { + const partialPath = path.slice(0, i + 1).join('/') + expandedFilePaths.value.add(partialPath) + } + } + + // Highlight a symbol and expand its parent scopes + function highlightSymbol( + symbol: SerializedOutputSymbol, + parentScopes: SerializedOutputScope[] = [], + ) { + // Clear previous highlights but preserve manual expansion state + clearHighlight() + + // Set new highlight + highlightedSymbol.value = symbol + + // Expand all parent scopes + parentScopes.forEach((scope) => { + expandedScopeIds.value.add(scope.id) + }) + + // If the symbol has member scopes, ensure they can be expanded too + if (symbol.instanceMemberScope) { + expandedSymbolIds.value.add(symbol.id) + } + if (symbol.staticMemberScope) { + expandedSymbolIds.value.add(symbol.id) + } + } + + // Highlight a scope and expand its parent scopes + function highlightScope( + scope: SerializedOutputScope, + parentScopes: SerializedOutputScope[] = [], + ) { + // Clear previous highlights but preserve manual expansion state + clearHighlight() + + // Set new highlight + highlightedScope.value = scope + + // Expand all parent scopes + parentScopes.forEach((parentScope) => { + expandedScopeIds.value.add(parentScope.id) + }) + } + + // Check if a file is highlighted + function isFileHighlighted(file: SerializedFileInfo): boolean { + return highlightedFile.value?.id === file.id + } + + // Check if a symbol is highlighted + function isSymbolHighlighted(symbol: SerializedOutputSymbol): boolean { + return highlightedSymbol.value?.id === symbol.id + } + + // Check if a scope is highlighted + function isScopeHighlighted(scope: SerializedOutputScope): boolean { + return highlightedScope.value?.id === scope.id + } + + // Check if a file path should be expanded (respecting manual overrides) + function isFilePathExpanded(path: string[]): boolean { + const pathString = path.join('/') + // If manually collapsed, don't expand even if highlight system wants it + if (manuallyCollapsedFilePaths.value.has(pathString)) { + return false + } + return expandedFilePaths.value.has(pathString) + } + + // Check if a scope should be expanded (respecting manual overrides) + function isScopeExpanded(scopeId: number): boolean { + // If manually collapsed, don't expand even if highlight system wants it + if (manuallyCollapsedScopeIds.value.has(scopeId)) { + return false + } + return expandedScopeIds.value.has(scopeId) + } + + // Check if a symbol should be expanded (respecting manual overrides) + function isSymbolExpanded(symbolId: number): boolean { + // If manually collapsed, don't expand even if highlight system wants it + if (manuallyCollapsedSymbolIds.value.has(symbolId)) { + return false + } + return expandedSymbolIds.value.has(symbolId) + } + + // Manually expand/collapse file path + function toggleFilePathExpanded(path: string[]) { + const pathString = path.join('/') + if (expandedFilePaths.value.has(pathString)) { + // If currently expanded, collapse it and mark as manually collapsed + expandedFilePaths.value.delete(pathString) + manuallyCollapsedFilePaths.value.add(pathString) + } else { + // If currently collapsed, expand it and remove from manually collapsed + expandedFilePaths.value.add(pathString) + manuallyCollapsedFilePaths.value.delete(pathString) + } + } + + // Manually expand/collapse scope + function toggleScopeExpanded(scopeId: number) { + if (expandedScopeIds.value.has(scopeId)) { + // If currently expanded, collapse it and mark as manually collapsed + expandedScopeIds.value.delete(scopeId) + manuallyCollapsedScopeIds.value.add(scopeId) + } else { + // If currently collapsed, expand it and remove from manually collapsed + expandedScopeIds.value.add(scopeId) + manuallyCollapsedScopeIds.value.delete(scopeId) + } + } + + // Manually expand/collapse symbol + function toggleSymbolExpanded(symbolId: number) { + if (expandedSymbolIds.value.has(symbolId)) { + // If currently expanded, collapse it and mark as manually collapsed + expandedSymbolIds.value.delete(symbolId) + manuallyCollapsedSymbolIds.value.add(symbolId) + } else { + // If currently collapsed, expand it and remove from manually collapsed + expandedSymbolIds.value.add(symbolId) + manuallyCollapsedSymbolIds.value.delete(symbolId) + } + } + + // Initialize expanded state for default tree expansion + function initializeExpandedState(scopeId: number) { + // Add scope to expanded set if not manually collapsed + if (!manuallyCollapsedScopeIds.value.has(scopeId)) { + expandedScopeIds.value.add(scopeId) + } + } + + return { + // State + highlightedFile: computed(() => highlightedFile.value), + highlightedSymbol: computed(() => highlightedSymbol.value), + highlightedScope: computed(() => highlightedScope.value), + + // Actions + clearHighlight, + highlightFile, + highlightSymbol, + highlightScope, + initializeExpandedState, + + // Checkers + isFileHighlighted, + isSymbolHighlighted, + isScopeHighlighted, + isFilePathExpanded, + isScopeExpanded, + isSymbolExpanded, + + // Manual toggles + toggleFilePathExpanded, + toggleScopeExpanded, + toggleSymbolExpanded, + } +} diff --git a/packages/dev-tools/dev-tools-vue/src/composables/useTabs.ts b/packages/dev-tools/dev-tools-vue/src/composables/useTabs.ts new file mode 100644 index 000000000..d1b2e67a9 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/composables/useTabs.ts @@ -0,0 +1,146 @@ +import { ref, computed } from 'vue' +import { useMenuHighlight } from './useMenuHighlight' +import { getScope, selectedNodeId } from '@/lib/store' +import type { SerializedOutputScope, SerializedOutputSymbol } from '@alloy-js/core/symbols' + +export interface Tab { + id: string + title: string + type: 'symbol' | 'scope' | 'file' | 'output' | 'error' | 'component' | 'custom' + content?: any + closable?: boolean +} + +// Global tab state +const tabs = ref([]) +const activeTabId = ref(null) + +export function useTabs() { + const { highlightFile, highlightSymbol, highlightScope, clearHighlight } = useMenuHighlight() + + const activeTab = computed(() => { + return tabs.value.find((tab) => tab.id === activeTabId.value) || null + }) + + function addTab(tab: Tab) { + // Check if tab already exists + const existingTab = tabs.value.find((t) => t.id === tab.id) + if (existingTab) { + // Update existing tab and make it active + Object.assign(existingTab, tab) + activeTabId.value = tab.id + highlightTabContent(tab) + return + } + + // Add new tab + tabs.value.push(tab) + activeTabId.value = tab.id + highlightTabContent(tab) + } + + function highlightTabContent(tab: Tab) { + // Highlight the corresponding item in the menu pane based on tab type + if (tab.type === 'file' && tab.content) { + highlightFile(tab.content) + } else if (tab.type === 'symbol' && tab.content) { + // For symbols, we need to find the parent scopes to expand them + const parentScopes = findParentScopes(tab.content) + highlightSymbol(tab.content, parentScopes) + } else if (tab.type === 'scope' && tab.content) { + // For scopes, we need to find the parent scopes to expand them + const parentScopes = findParentScopes(tab.content) + highlightScope(tab.content, parentScopes) + } else if (tab.type === 'component' && tab.content) { + // Highlight component in the tree by selecting its node + selectedNodeId.value = tab.content.id + } + } + + // Helper function to find parent scopes for a given symbol or scope + function findParentScopes( + item: SerializedOutputSymbol | SerializedOutputScope, + ): SerializedOutputScope[] { + const parentScopes: SerializedOutputScope[] = [] + + // Find the parent scope ID from the item + let parentScopeId: number | null = null + + if ('scope' in item) { + // For symbols, get their scope + parentScopeId = item.scope + } else if ('parent' in item) { + // For scopes, get their parent + parentScopeId = item.parent + } + + // Traverse up the scope hierarchy + while (parentScopeId !== null && parentScopeId !== 0) { + const parentScope = getScope(parentScopeId).value + if (parentScope) { + parentScopes.unshift(parentScope) // Add to beginning to maintain order + parentScopeId = parentScope.parent + } else { + break + } + } + + return parentScopes + } + + function setActiveTab(tabId: string) { + if (tabs.value.find((tab) => tab.id === tabId)) { + activeTabId.value = tabId + // Highlight the content when switching tabs + const tab = tabs.value.find((t) => t.id === tabId) + if (tab) { + highlightTabContent(tab) + } + } + } + + function removeTab(tabId: string) { + const index = tabs.value.findIndex((tab) => tab.id === tabId) + if (index === -1) return + const removedTab = tabs.value[index] + + tabs.value.splice(index, 1) + // If a component tab was closed, clear its highlight + if (removedTab.type === 'component') { + selectedNodeId.value = null + } + + // If the closed tab was active, switch to another tab + if (activeTabId.value === tabId) { + if (tabs.value.length > 0) { + // Switch to the next tab, or the previous one if it was the last + const newIndex = index < tabs.value.length ? index : index - 1 + activeTabId.value = tabs.value[newIndex]?.id || null + // Highlight the content of the new active tab + const newActiveTab = tabs.value[newIndex] + if (newActiveTab) { + highlightTabContent(newActiveTab) + } + } else { + activeTabId.value = null + // Clear highlights and highlight-driven expansion when no tabs are open + clearHighlight() + } + } + } + + function clearTabs() { + tabs.value = [] + activeTabId.value = null + } + + return { + tabs: computed(() => tabs.value), + activeTab, + activeTabId: computed(() => activeTabId.value), + addTab, + removeTab, + setActiveTab, + clearTabs, + } +} diff --git a/packages/dev-tools/dev-tools-vue/src/lib/composables.ts b/packages/dev-tools/dev-tools-vue/src/lib/composables.ts new file mode 100644 index 000000000..c1248ea2b --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/lib/composables.ts @@ -0,0 +1,2 @@ +import { computed } from '@vue/reactivity' +import * as store from './store' diff --git a/packages/dev-tools/dev-tools-vue/src/lib/content-mapping.ts b/packages/dev-tools/dev-tools-vue/src/lib/content-mapping.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dev-tools/dev-tools-vue/src/lib/index.ts b/packages/dev-tools/dev-tools-vue/src/lib/index.ts new file mode 100644 index 000000000..7e662b519 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/lib/index.ts @@ -0,0 +1,5 @@ +// Export all store-related functionality + +export * from './types' +export * from './store' +export * from './composables' diff --git a/packages/dev-tools/dev-tools-vue/src/lib/store.ts b/packages/dev-tools/dev-tools-vue/src/lib/store.ts new file mode 100644 index 000000000..988c98259 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/lib/store.ts @@ -0,0 +1,630 @@ +import { reactive, computed, ref, shallowRef } from '@vue/reactivity' +import type { + StoreState, + WebSocketMessage, + SerializedFileInfo, + SerializedNode, + ErrorInfo, +} from './types' +import type { SerializedOutputScope, SerializedOutputSymbol } from '@alloy-js/core/symbols' + +// Create reactive store state +const state = reactive({ + symbols: new Map(), + scopes: new Map(), + files: new Map(), + nodes: new Map(), + isConnected: false, + connectionStatus: 'disconnected', + currentError: null, // Add error state +}) as StoreState + +// Refkey-to-symbol index for efficient lookups +const refkeyToSymbolIndex = reactive(new Map()) + +// Track which node created each symbol and scope +const symbolCreatorNodes = reactive(new Map()) +const scopeCreatorNodes = reactive(new Map()) + +// Selected node state for component tree navigation +export const selectedNodeId = ref(null) + +// WebSocket connection +let websocket: WebSocket | null = null +const wsUrl = ref('ws://localhost:8080') // Default WebSocket URL +let retryTimeout: ReturnType | null = null +const RETRY_DELAY = 2000 // 2 seconds + +let initialConnectionSucceeded = false // Tracks if the first connection attempt sequence was successful +let currentConnectPromise: Promise | null = null +let resolveCurrentConnectPromise: (() => void) | null = null + +// Reactive symbol and scope refs - these update when symbols/scopes become available +const symbolRefs = new Map< + number, + ReturnType> +>() +const scopeRefs = new Map< + number, + ReturnType> +>() +const fileRefs = new Map>>() +const nodeRefs = new Map>>() + +// Computed getters for commonly used data +export const symbols = computed(() => Array.from(state.symbols.values())) +export const scopes = computed(() => Array.from(state.scopes.values())) +export const files = computed(() => Array.from(state.files.values())) +export const nodes = computed(() => Array.from(state.nodes.values())) +export const visibleNodes = computed(() => + Array.from(state.nodes.values()).filter((node) => !node.deleted), +) +export const isConnected = computed(() => state.isConnected) +export const connectionStatus = computed(() => state.connectionStatus) +export const currentError = computed(() => state.currentError) +export const hasError = computed(() => state.currentError !== null) + +// OutputSymbol operations +export function getSymbol(id: number) { + if (!symbolRefs.has(id)) { + const symbolRef = shallowRef(state.symbols.get(id)) + symbolRefs.set(id, symbolRef) + return symbolRef + } + return symbolRefs.get(id)! +} + +export function addSymbol(data: SerializedOutputSymbol, nodeId: number | null = null) { + state.symbols.set(data.id, data) + + // Track which node created this symbol + if (nodeId !== null) { + symbolCreatorNodes.set(data.id, nodeId) + } + + // Update refkey-to-symbol index + for (const refkey of data.refkeys) { + refkeyToSymbolIndex.set(refkey.key, data.id) + } + + // Update the reactive ref if it exists + const symbolRef = symbolRefs.get(data.id) + if (symbolRef) { + symbolRef.value = data + } +} + +export function updateSymbol(data: SerializedOutputSymbol, nodeId: number | null = null) { + const existingSymbol = state.symbols.get(data.id) + if (existingSymbol) { + // Clear old refkey mappings before updating + for (const refkey of existingSymbol.refkeys) { + if (refkeyToSymbolIndex.get(refkey.key) === data.id) { + refkeyToSymbolIndex.delete(refkey.key) + } + } + + // Update properties of the existing object to maintain reactivity + Object.assign(existingSymbol, data) + + // Update creator node if provided + if (nodeId !== null) { + symbolCreatorNodes.set(data.id, nodeId) + } + + // Update refkey-to-symbol index with new mappings + for (const refkey of data.refkeys) { + refkeyToSymbolIndex.set(refkey.key, data.id) + } + + // Update the reactive ref if it exists + const symbolRef = symbolRefs.get(data.id) + if (symbolRef) { + symbolRef.value = existingSymbol + } + } else { + // If symbol doesn't exist, add it + addSymbol(data, nodeId) + } +} + +export function getSymbolByRefkey(refkeyString: string) { + const symbolId = refkeyToSymbolIndex.get(refkeyString) + if (symbolId !== undefined) { + return getSymbol(symbolId) + } + return shallowRef(undefined) +} + +// OutputScope operations +export function getScope(id: number) { + if (!scopeRefs.has(id)) { + const scopeRef = shallowRef(state.scopes.get(id)) + scopeRefs.set(id, scopeRef) + return scopeRef + } + return scopeRefs.get(id)! +} + +export function addScope(data: SerializedOutputScope, nodeId: number | null = null) { + state.scopes.set(data.id, data) + + // Track which node created this scope + if (nodeId !== null) { + scopeCreatorNodes.set(data.id, nodeId) + } + + // Update the reactive ref if it exists + const scopeRef = scopeRefs.get(data.id) + if (scopeRef) { + scopeRef.value = data + } +} + +export function updateScope(data: SerializedOutputScope, nodeId: number | null = null) { + const existingScope = state.scopes.get(data.id) + if (existingScope) { + // Update properties of the existing object to maintain reactivity + Object.assign(existingScope, data) + + // Update creator node if provided + if (nodeId !== null) { + scopeCreatorNodes.set(data.id, nodeId) + } + + // Update the reactive ref if it exists + const scopeRef = scopeRefs.get(data.id) + if (scopeRef) { + scopeRef.value = existingScope + } + } else { + // If scope doesn't exist, add it + addScope(data, nodeId) + } +} + +export function removeSymbol(symbolId: number) { + const symbol = state.symbols.get(symbolId) + if (symbol) { + // Clear refkey mappings + for (const refkey of symbol.refkeys) { + if (refkeyToSymbolIndex.get(refkey.key) === symbolId) { + refkeyToSymbolIndex.delete(refkey.key) + } + } + + // Remove from state + state.symbols.delete(symbolId) + symbolCreatorNodes.delete(symbolId) + + // Update the reactive ref if it exists + const symbolRef = symbolRefs.get(symbolId) + if (symbolRef) { + symbolRef.value = undefined + } + } +} + +export function removeScope(scopeId: number) { + const scope = state.scopes.get(scopeId) + if (scope) { + // Remove from state + state.scopes.delete(scopeId) + scopeCreatorNodes.delete(scopeId) + + // Update the reactive ref if it exists + const scopeRef = scopeRefs.get(scopeId) + if (scopeRef) { + scopeRef.value = undefined + } + } +} + +// File operations +export function getFile(id: number) { + if (!fileRefs.has(id)) { + const fileRef = shallowRef(state.files.get(id)) + fileRefs.set(id, fileRef) + return fileRef + } + return fileRefs.get(id)! +} + +export function addFile(data: SerializedFileInfo) { + state.files.set(data.id, data) + + // Update the reactive ref if it exists + const fileRef = fileRefs.get(data.id) + if (fileRef) { + fileRef.value = data + } +} + +export function updateFile(data: SerializedFileInfo) { + const existingFile = state.files.get(data.id) + if (existingFile) { + // Update properties of the existing object to maintain reactivity + Object.assign(existingFile, data) + + // Update the reactive ref if it exists + const fileRef = fileRefs.get(data.id) + if (fileRef) { + fileRef.value = existingFile + } + } else { + // If file doesn't exist, add it + addFile(data) + } +} + +// Node operations for component tree +export function getNode(id: number) { + if (!nodeRefs.has(id)) { + const nodeRef = shallowRef(state.nodes.get(id)) + nodeRefs.set(id, nodeRef) + return nodeRef + } + return nodeRefs.get(id)! +} + +export function addNode(data: SerializedNode) { + state.nodes.set(data.id, data) + + // If this node has a parent, ensure the parent has this node in its children + if (data.parentId !== null) { + const parent = state.nodes.get(data.parentId) + if (parent && !parent.children.includes(data.id)) { + parent.children.push(data.id) + + // Update the parent's reactive ref if it exists + const parentRef = nodeRefs.get(data.parentId) + if (parentRef) { + parentRef.value = parent + } + } + } + + // Update the reactive ref if it exists + const nodeRef = nodeRefs.get(data.id) + if (nodeRef) { + nodeRef.value = data + } +} + +export function updateNode(data: SerializedNode) { + const existingNode = state.nodes.get(data.id) + if (existingNode) { + // Update properties of the existing object to maintain reactivity + Object.assign(existingNode, data) + + // If this node has a parent, ensure the parent has this node in its children + if (data.parentId !== null) { + const parent = state.nodes.get(data.parentId) + if (parent && !parent.children.includes(data.id)) { + parent.children.push(data.id) + + // Update the parent's reactive ref if it exists + const parentRef = nodeRefs.get(data.parentId) + if (parentRef) { + parentRef.value = parent + } + } + } + + // Update the reactive ref if it exists + const nodeRef = nodeRefs.get(data.id) + if (nodeRef) { + nodeRef.value = existingNode + } + } else { + // If node doesn't exist, add it + addNode(data) + } +} + +export function removeNode(id: number) { + // Instead of removing the node, mark it as deleted + const existingNode = state.nodes.get(id) + if (existingNode) { + existingNode.deleted = true + + // Update the reactive ref if it exists + const nodeRef = nodeRefs.get(id) + if (nodeRef) { + nodeRef.value = existingNode + } + } +} + +// Error operations +export function setError(error: ErrorInfo) { + state.currentError = error + + // Auto-open error tab when error occurs + // We need to import useTabs here, but to avoid circular dependency, + // we'll emit an event instead and handle it in the component + window.dispatchEvent(new CustomEvent('error-occurred', { detail: error })) +} + +export function clearError() { + state.currentError = null +} + +// Helper function to build component stack from a node ID +export function getComponentStack(nodeId: number | null): SerializedNode[] { + const stack: SerializedNode[] = [] + let currentNodeId: number | null = nodeId + + while (currentNodeId !== null) { + const node = state.nodes.get(currentNodeId) + if (node) { + stack.push(node) + currentNodeId = node.parentId + } else { + break + } + } + + return stack +} + +// WebSocket connection management +export function connect(url?: string): Promise { + if (url) { + wsUrl.value = url + } + + if (initialConnectionSucceeded && websocket?.readyState === WebSocket.OPEN && state.isConnected) { + return Promise.resolve() + } + + if (currentConnectPromise && !initialConnectionSucceeded) { + return currentConnectPromise + } + + initialConnectionSucceeded = false + if (retryTimeout) { + clearTimeout(retryTimeout) + retryTimeout = null + } + + currentConnectPromise = new Promise((resolve) => { + resolveCurrentConnectPromise = () => { + if (currentConnectPromise) { + resolve() + } + } + + const attemptConnection = () => { + if (initialConnectionSucceeded && state.connectionStatus === 'connected') { + if (resolveCurrentConnectPromise) { + resolveCurrentConnectPromise() + resolveCurrentConnectPromise = null + } + return + } + + state.connectionStatus = 'connecting' + websocket = new WebSocket(wsUrl.value) + + websocket.onopen = () => { + state.isConnected = true + state.connectionStatus = 'connected' + initialConnectionSucceeded = true + + // eslint-disable-next-line no-console + console.log('WebSocket connected to', wsUrl.value) + + if (retryTimeout) { + clearTimeout(retryTimeout) + retryTimeout = null + } + + if (resolveCurrentConnectPromise) { + resolveCurrentConnectPromise() + resolveCurrentConnectPromise = null + } + } + + websocket.onclose = () => { + state.isConnected = false + + if (initialConnectionSucceeded) { + state.connectionStatus = 'disconnected' + // eslint-disable-next-line no-console + console.log('WebSocket disconnected (was previously connected).') + if (retryTimeout) { + clearTimeout(retryTimeout) + retryTimeout = null + } + } else { + // state.connectionStatus remains 'connecting' (set at the start of attemptConnection) + // eslint-disable-next-line no-console + console.log( + 'WebSocket connection attempt failed or closed before initial success. Retrying...', + ) + if (retryTimeout) clearTimeout(retryTimeout) // Clear previous, if any + retryTimeout = setTimeout(attemptConnection, RETRY_DELAY) + } + } + + websocket.onerror = (error) => { + // eslint-disable-next-line no-console + console.error('WebSocket error:', error) + + if (initialConnectionSucceeded && state.connectionStatus === 'connected') { + state.connectionStatus = 'error' + } + } + + websocket.onmessage = (event) => { + try { + const message: WebSocketMessage = JSON.parse(event.data) + handleWebSocketMessage(message) + } catch (error) { + // eslint-disable-next-line no-console + console.error('Failed to parse WebSocket message:', error) + } + } + } + + attemptConnection() + }) + + return currentConnectPromise +} + +export function disconnect(): void { + if (retryTimeout) { + clearTimeout(retryTimeout) + retryTimeout = null + } + + initialConnectionSucceeded = true + + if (websocket) { + websocket.onopen = null + websocket.onclose = null + websocket.onerror = null + websocket.onmessage = null + + if (websocket.readyState === WebSocket.OPEN || websocket.readyState === WebSocket.CONNECTING) { + websocket.close() + } + websocket = null + } + + state.isConnected = false + state.connectionStatus = 'disconnected' + + currentConnectPromise = null + resolveCurrentConnectPromise = null +} + +// Send message to WebSocket server +export function sendMessage(message: WebSocketMessage): void { + if (!websocket || websocket.readyState !== WebSocket.OPEN) { + // eslint-disable-next-line no-console + console.warn('WebSocket is not connected. Cannot send message:', message) + return + } + + try { + websocket.send(JSON.stringify(message)) + } catch (error) { + // eslint-disable-next-line no-console + console.error('Failed to send WebSocket message:', error) + } +} + +// Send rerender message for a specific component +export function rerenderComponent(nodeId: number): void { + sendMessage({ + type: 'rerender', + data: { nodeId }, + }) +} + +function handleWebSocketMessage(message: WebSocketMessage): void { + switch (message.type) { + case 'symbol_added': + addSymbol(message.data.symbol, message.data.nodeId) + break + + case 'symbol_updated': + updateSymbol(message.data.symbol, message.data.nodeId) + break + + case 'scope_added': + addScope(message.data.scope, message.data.nodeId) + break + + case 'scope_updated': + updateScope(message.data.scope, message.data.nodeId) + break + + case 'symbol_deleted': + removeSymbol(message.data.symbolId) + break + + case 'scope_deleted': + removeScope(message.data.scopeId) + break + + case 'file_added': + addFile(message.data) + break + + case 'file_updated': + updateFile(message.data) + break + + case 'node_added': + addNode(message.data) + break + + case 'node_updated': + updateNode(message.data) + break + + case 'node_deleted': + removeNode(message.data.nodeId) + break + + case 'error_added': + setError(message.data) + break + + default: + // eslint-disable-next-line no-console + console.warn('Unknown message type:', (message as any).type) + } +} + +// Utility functions for debugging and testing +export function clearStore(): void { + state.symbols.clear() + state.scopes.clear() + state.files.clear() + state.nodes.clear() + symbolRefs.clear() + scopeRefs.clear() + fileRefs.clear() + nodeRefs.clear() +} + +// Export the raw state for advanced use cases +export { state as storeState } + +// Node selection functionality +export function selectNode(nodeId: number | null) { + selectedNodeId.value = nodeId +} + +// Get creator node for symbols and scopes +export function getSymbolCreatorNode(symbolId: number): number | null { + return symbolCreatorNodes.get(symbolId) || null +} + +export function getScopeCreatorNode(scopeId: number): number | null { + return scopeCreatorNodes.get(scopeId) || null +} + +// Get component name for a nodeId +export function getComponentName(nodeId: number | null): string | null { + if (nodeId === null) return null + const node = state.nodes.get(nodeId) + if (!node) return null + + if (node.kind === 'component') { + const componentNode = node as any // SerializedComponentNode + return componentNode.component + } else if (node.kind === 'intrinsic') { + const intrinsicNode = node as any // SerializedIntrinsicElementNode + return `<${intrinsicNode.tag}>` + } else if (node.kind === 'fragment') { + return 'Fragment' + } + + return null +} diff --git a/packages/dev-tools/dev-tools-vue/src/lib/tabs.ts b/packages/dev-tools/dev-tools-vue/src/lib/tabs.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dev-tools/dev-tools-vue/src/lib/types.ts b/packages/dev-tools/dev-tools-vue/src/lib/types.ts new file mode 100644 index 000000000..b4255d4d7 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/lib/types.ts @@ -0,0 +1,164 @@ +import type { SerializedOutputScope, SerializedOutputSymbol } from '@alloy-js/core/symbols' + +export interface StoreState { + symbols: Map + scopes: Map + files: Map + nodes: Map + isConnected: boolean + connectionStatus: 'disconnected' | 'connecting' | 'connected' | 'error' + currentError: ErrorInfo | null // Add error state +} + +export interface ErrorInfo { + message: string + stack: string // JavaScript error stack + nodeId: number | null // The component node where the error occurred +} + +export interface WebSocketSymbolAdded { + type: 'symbol_added' + data: { + symbol: SerializedOutputSymbol + nodeId: number | null + } +} + +export interface WebSocketSymbolUpdated { + type: 'symbol_updated' + data: { + symbol: SerializedOutputSymbol + nodeId: number | null + } +} + +export interface WebSocketSymbolDeleted { + type: 'symbol_deleted' + data: { + symbolId: number + } +} + +export interface WebSocketScopeAdded { + type: 'scope_added' + data: { + scope: SerializedOutputScope + nodeId: number | null + } +} + +export interface WebSocketScopeUpdated { + type: 'scope_updated' + data: { + scope: SerializedOutputScope + nodeId: number | null + } +} + +export interface WebSocketScopeDeleted { + type: 'scope_deleted' + data: { + scopeId: number + } +} + +export interface SerializedFileInfo { + id: number + path: string[] + name: string + contents: string + nodeId: number +} + +export interface WebSocketFileAdded { + type: 'file_added' + data: SerializedFileInfo +} + +export interface WebSocketFileUpdated { + type: 'file_updated' + data: SerializedFileInfo +} + +// Component tree node types +export interface SerializedNodeBase { + id: number + kind: string + parentId: number | null + children: SerializedNodeContent[] + deleted?: boolean // Mark nodes as deleted but keep them in the tree +} + +export type SerializedNodeContent = + | string // text content + | number // a node reference + +export interface SerializedFragmentNode extends SerializedNodeBase { + kind: 'fragment' +} + +export interface SerializedIntrinsicElementNode extends SerializedNodeBase { + kind: 'intrinsic' + tag: string + props: Record +} + +export interface SerializedComponentNode extends SerializedNodeBase { + kind: 'component' + component: string + props: Record + context: { + name: string + value: unknown + } +} + +export type SerializedNode = + | SerializedIntrinsicElementNode + | SerializedComponentNode + | SerializedFragmentNode + +export interface WebSocketNodeAdded { + type: 'node_added' + data: SerializedNode +} + +export interface WebSocketNodeUpdated { + type: 'node_updated' + data: SerializedNode +} + +export interface WebSocketNodeDeleted { + type: 'node_deleted' + data: { + nodeId: number + } +} + +// Error WebSocket message +export interface WebSocketErrorAdded { + type: 'error_added' + data: ErrorInfo +} + +export interface WebSocketRerender { + type: 'rerender' + data: { + nodeId: number + } +} + +export type WebSocketMessage = + | WebSocketScopeAdded + | WebSocketScopeUpdated + | WebSocketScopeDeleted + | WebSocketSymbolAdded + | WebSocketSymbolUpdated + | WebSocketSymbolDeleted + | WebSocketFileAdded + | WebSocketFileUpdated + | WebSocketNodeAdded + | WebSocketNodeUpdated + | WebSocketNodeDeleted + | WebSocketErrorAdded + | WebSocketRerender diff --git a/packages/dev-tools/dev-tools-vue/src/lib/utils.ts b/packages/dev-tools/dev-tools-vue/src/lib/utils.ts new file mode 100644 index 000000000..d32b0fe65 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from 'clsx' +import { twMerge } from 'tailwind-merge' + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/packages/dev-tools/dev-tools-vue/src/main.ts b/packages/dev-tools/dev-tools-vue/src/main.ts new file mode 100644 index 000000000..0ac3a5ff0 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/main.ts @@ -0,0 +1,6 @@ +import './assets/main.css' + +import { createApp } from 'vue' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/packages/dev-tools/dev-tools-vue/src/utils/formatters.ts b/packages/dev-tools/dev-tools-vue/src/utils/formatters.ts new file mode 100644 index 000000000..6529ce2c5 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/utils/formatters.ts @@ -0,0 +1,79 @@ +import { OutputSymbolFlags, OutputScopeFlags } from '@alloy-js/core/symbols' +import type { Refkey } from '@alloy-js/core' + +/** + * Format symbol flags as human-readable flag names + */ +export function formatSymbolFlags(flags: number): string[] { + const flagNames: string[] = [] + + if (flags === OutputSymbolFlags.None) { + return ['None'] + } + + if (flags & OutputSymbolFlags.InstanceMemberContainer) { + flagNames.push('InstanceMemberContainer') + } + if (flags & OutputSymbolFlags.StaticMemberContainer) { + flagNames.push('StaticMemberContainer') + } + if (flags & OutputSymbolFlags.InstanceMember) { + flagNames.push('InstanceMember') + } + if (flags & OutputSymbolFlags.StaticMember) { + flagNames.push('StaticMember') + } + if (flags & OutputSymbolFlags.Transient) { + flagNames.push('Transient') + } + if (flags & OutputSymbolFlags.Alias) { + flagNames.push('Alias') + } + + return flagNames +} + +/** + * Format scope flags as human-readable flag names + */ +export function formatScopeFlags(flags: number): string[] { + const flagNames: string[] = [] + + if (flags === OutputScopeFlags.None) { + return ['None'] + } + + if (flags & OutputScopeFlags.StaticMemberScope) { + flagNames.push('StaticMemberScope') + } + if (flags & OutputScopeFlags.InstanceMemberScope) { + flagNames.push('InstanceMemberScope') + } + if (flags & OutputScopeFlags.Transient) { + flagNames.push('Transient') + } + + return flagNames +} + +/** + * Format a single refkey for display + */ +export function formatRefkey(refkey: Refkey): string { + return `refkey[${refkey.key}]` +} + +/** + * Format refkeys as a comma-separated string for display + */ +export function formatRefkeys(refkeys: Refkey[] | Refkey | undefined): string { + if (!refkeys) { + return '' + } + + if (Array.isArray(refkeys)) { + return refkeys.map(formatRefkey).join(', ') + } + + return formatRefkey(refkeys) +} diff --git a/packages/dev-tools/dev-tools-vue/src/utils/propHelpers.ts b/packages/dev-tools/dev-tools-vue/src/utils/propHelpers.ts new file mode 100644 index 000000000..08dfe2401 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/src/utils/propHelpers.ts @@ -0,0 +1,112 @@ +import type { SerializedOutputScope, SerializedOutputSymbol } from '@alloy-js/core/symbols' + +// Check if an object is a refkey (has only a 'key' property with string value) +export const isRefkeyObject = (value: any): value is { key: string } => { + if (typeof value !== 'object' || value === null) { + return false + } + + const keys = Object.keys(value) + return keys.length === 1 && keys[0] === 'key' && typeof value.key === 'string' +} + +// Check if an object is a scope (has id, flags, symbols, and children properties) +export const isScopeObject = (value: any): value is SerializedOutputScope => { + if (typeof value !== 'object' || value === null) { + return false + } + + return ( + typeof value.id === 'number' && + typeof value.flags === 'number' && + Array.isArray(value.symbols) && + Array.isArray(value.children) + ) +} + +// Check if an object is a symbol (has id, name, originalName, and flags properties) +export const isSymbolObject = (value: any): value is SerializedOutputSymbol => { + if (typeof value !== 'object' || value === null) { + return false + } + + return ( + typeof value.id === 'number' && + typeof value.name === 'string' && + typeof value.originalName === 'string' && + typeof value.flags === 'number' + ) +} + +export interface PropValueInfo { + formattedValue: string + isRefkey: boolean + refkeyString?: string + isScope: boolean + scopeId?: number + scopeName?: string + isSymbol: boolean + symbolId?: number + symbolName?: string +} + +// Get comprehensive information about a prop value +export const getPropValueInfo = (value: any): PropValueInfo => { + // Check for refkey + if (isRefkeyObject(value)) { + return { + formattedValue: `Refkey(${value.key})`, + isRefkey: true, + refkeyString: value.key, + isScope: false, + isSymbol: false, + } + } + + // Check for scope + if (isScopeObject(value)) { + return { + formattedValue: `Scope(${value.name})`, + isRefkey: false, + isScope: true, + scopeId: value.id, + scopeName: value.name, + isSymbol: false, + } + } + + // Check for symbol + if (isSymbolObject(value)) { + return { + formattedValue: `Symbol(${value.name})`, + isRefkey: false, + isScope: false, + isSymbol: true, + symbolId: value.id, + symbolName: value.name, + } + } + + // Format regular values + let formattedValue: string + if (typeof value === 'string') { + formattedValue = JSON.stringify(value) + } else if (typeof value === 'number' || typeof value === 'boolean') { + formattedValue = String(value) + } else if (value === null) { + formattedValue = 'null' + } else if (value === undefined) { + formattedValue = 'undefined' + } else if (Array.isArray(value)) { + formattedValue = '[array]' + } else { + formattedValue = '{object}' + } + + return { + formattedValue, + isRefkey: false, + isScope: false, + isSymbol: false, + } +} diff --git a/packages/dev-tools/dev-tools-vue/tsconfig.app.json b/packages/dev-tools/dev-tools-vue/tsconfig.app.json new file mode 100644 index 000000000..6e90efc9e --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/packages/dev-tools/dev-tools-vue/tsconfig.json b/packages/dev-tools/dev-tools-vue/tsconfig.json new file mode 100644 index 000000000..1702e9dde --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/tsconfig.json @@ -0,0 +1,20 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.vitest.json" + } + ], + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/packages/dev-tools/dev-tools-vue/tsconfig.node.json b/packages/dev-tools/dev-tools-vue/tsconfig.node.json new file mode 100644 index 000000000..a83dfc9d4 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/tsconfig.node.json @@ -0,0 +1,19 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "include": [ + "vite.config.*", + "vitest.config.*", + "cypress.config.*", + "nightwatch.conf.*", + "playwright.config.*", + "eslint.config.*" + ], + "compilerOptions": { + "noEmit": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + + "module": "ESNext", + "moduleResolution": "Bundler", + "types": ["node"] + } +} diff --git a/packages/dev-tools/dev-tools-vue/tsconfig.vitest.json b/packages/dev-tools/dev-tools-vue/tsconfig.vitest.json new file mode 100644 index 000000000..7d1d8cef3 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/tsconfig.vitest.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.app.json", + "include": ["src/**/__tests__/*", "env.d.ts"], + "exclude": [], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo", + + "lib": [], + "types": ["node", "jsdom"] + } +} diff --git a/packages/dev-tools/dev-tools-vue/vite.config.ts b/packages/dev-tools/dev-tools-vue/vite.config.ts new file mode 100644 index 000000000..b0e1e0eba --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/vite.config.ts @@ -0,0 +1,17 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import vueDevTools from 'vite-plugin-vue-devtools' +import tailwindcss from '@tailwindcss/vite' +import { viteSingleFile } from 'vite-plugin-singlefile' +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue(), vueDevTools(), tailwindcss(), viteSingleFile()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + dedupe: ['@vue/reactivity'], + }, +}) diff --git a/packages/dev-tools/dev-tools-vue/vitest.config.ts b/packages/dev-tools/dev-tools-vue/vitest.config.ts new file mode 100644 index 000000000..c32871718 --- /dev/null +++ b/packages/dev-tools/dev-tools-vue/vitest.config.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url' +import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' +import viteConfig from './vite.config' + +export default mergeConfig( + viteConfig, + defineConfig({ + test: { + environment: 'jsdom', + exclude: [...configDefaults.exclude, 'e2e/**'], + root: fileURLToPath(new URL('./', import.meta.url)), + }, + }), +) diff --git a/packages/typescript/src/builtins/node.ts b/packages/typescript/src/builtins/node.ts index 44c2cec80..9aae8b870 100644 --- a/packages/typescript/src/builtins/node.ts +++ b/packages/typescript/src/builtins/node.ts @@ -70,14 +70,11 @@ export const fs = createPackage({ "openAsBlob", "opendir", "read", - "read", - "read", "readdir", "readFile", "readlink", "readv", "realpath", - "realpath", "rename", "rmdir", "rm", @@ -91,15 +88,11 @@ export const fs = createPackage({ "watch", "watchFile", "write", - "write", - "write", "writeFile", "writev", "accessSync", "appendFileSync", "chmodSync", - "chownSync", - "closeSync", "copyFileSync", "cpSync", "existsSync", @@ -124,10 +117,8 @@ export const fs = createPackage({ "readFileSync", "readlinkSync", "readSync", - "readSync", "readvSync", "realpathSync", - "realpathSync", "renameSync", "rmdirSync", "rmSync", @@ -139,9 +130,6 @@ export const fs = createPackage({ "utimesSync", "writeFileSync", "writeSync", - "writeSync", - "writeSync", - "writevSync", ], }, "./promises": { diff --git a/packages/typescript/src/components/ClassDeclaration.tsx b/packages/typescript/src/components/ClassDeclaration.tsx index 3ef6cdd5f..31a27fcd5 100644 --- a/packages/typescript/src/components/ClassDeclaration.tsx +++ b/packages/typescript/src/components/ClassDeclaration.tsx @@ -3,6 +3,7 @@ import { Children, MemberDeclaration, Name, + onCleanup, OutputSymbolFlags, Prose, Refkey, @@ -77,6 +78,10 @@ export function ClassDeclaration(props: ClassDeclarationProps) { metadata: props.metadata, }); + onCleanup(() => { + sym.delete(); + }); + return ( <> diff --git a/packages/typescript/src/components/Declaration.tsx b/packages/typescript/src/components/Declaration.tsx index 788296705..87aea5a68 100644 --- a/packages/typescript/src/components/Declaration.tsx +++ b/packages/typescript/src/components/Declaration.tsx @@ -2,6 +2,7 @@ import { Children, Declaration as CoreDeclaration, MemberScope, + onCleanup, OutputSymbolFlags, Refkey, } from "@alloy-js/core"; @@ -116,6 +117,10 @@ export function Declaration(props: DeclarationProps) { tsFlags, metadata: props.metadata, }); + + onCleanup(() => { + sym.delete(); + }); } function withMemberScope(children: Children) { diff --git a/packages/typescript/src/components/FunctionBase.tsx b/packages/typescript/src/components/FunctionBase.tsx index 7f3a3dd21..8fb5d11cf 100644 --- a/packages/typescript/src/components/FunctionBase.tsx +++ b/packages/typescript/src/components/FunctionBase.tsx @@ -191,6 +191,10 @@ function normalizeAndDeclareParameters( tsFlags: flags, }); + onCleanup(() => { + symbol.delete(); + }); + return { refkeys: symbol.refkeys, symbol }; }); } else { @@ -212,6 +216,10 @@ function normalizeAndDeclareParameters( }, ); + onCleanup(() => { + symbol.delete(); + }); + return { ...param, symbol, diff --git a/packages/typescript/src/components/MemberDeclaration.tsx b/packages/typescript/src/components/MemberDeclaration.tsx index 252b0b22c..c2b1c1bd6 100644 --- a/packages/typescript/src/components/MemberDeclaration.tsx +++ b/packages/typescript/src/components/MemberDeclaration.tsx @@ -1,6 +1,7 @@ import { MemberDeclaration as CoreMemberDeclaration, MemberDeclarationPropsWithInfo, + onCleanup, OutputSymbolFlags, } from "@alloy-js/core"; import { TypeScriptElements, useTSNamePolicy } from "../name-policy.js"; @@ -65,6 +66,10 @@ export function MemberDeclaration(props: Readonly) { tsFlags, metadata: props.metadata, }); + + onCleanup(() => { + sym.delete(); + }); } return ( diff --git a/packages/typescript/src/components/ObjectExpression.tsx b/packages/typescript/src/components/ObjectExpression.tsx index 5ce528f67..278ee0cbe 100644 --- a/packages/typescript/src/components/ObjectExpression.tsx +++ b/packages/typescript/src/components/ObjectExpression.tsx @@ -1,9 +1,7 @@ import { - AssignmentContext, Block, Children, computed, - createAssignmentContext, emitSymbol, For, Match, @@ -129,14 +127,9 @@ export function ObjectProperty(props: ObjectPropertyProps) { value = props.children; } - const assignmentContext: AssignmentContext | undefined = - sym ? createAssignmentContext(sym) : undefined; return ( <> - {name}:{" "} - - {value} - + {name}: {value} ); } diff --git a/packages/typescript/src/components/Reference.tsx b/packages/typescript/src/components/Reference.tsx index 4bcb64292..916ad251b 100644 --- a/packages/typescript/src/components/Reference.tsx +++ b/packages/typescript/src/components/Reference.tsx @@ -20,5 +20,6 @@ export function Reference({ refkey, type }: ReferenceProps) { const symbolRef = computed(() => reference()[1]); emitSymbol(symbolRef); + return <>{reference()[0]}; } diff --git a/packages/typescript/src/components/SourceFile.tsx b/packages/typescript/src/components/SourceFile.tsx index c8ccf3a21..f8c91a5cf 100644 --- a/packages/typescript/src/components/SourceFile.tsx +++ b/packages/typescript/src/components/SourceFile.tsx @@ -2,9 +2,11 @@ import { ComponentContext, SourceFile as CoreSourceFile, createNamedContext, + onCleanup, Scope, Show, SourceDirectoryContext, + untrack, useContext, type Children, } from "@alloy-js/core"; @@ -40,6 +42,10 @@ export function SourceFile(props: SourceFileProps) { const currentDir = directoryContext.path; const path: string = join(currentDir, props.path); const scope = new TSModuleScope(path); + onCleanup(() => { + // todo: this untrack shouldn't be necessary + untrack(() => scope.delete()); + }); sdData.modules.add(scope); const pkg = useContext(PackageContext); if (pkg) { diff --git a/packages/typescript/src/symbols/reference.ts b/packages/typescript/src/symbols/reference.ts index db80e0103..2c1deff79 100644 --- a/packages/typescript/src/symbols/reference.ts +++ b/packages/typescript/src/symbols/reference.ts @@ -1,5 +1,6 @@ import { memo, + onCleanup, OutputSymbolFlags, Refkey, resolve, @@ -40,6 +41,7 @@ export function ref( } const { targetDeclaration, pathDown, memberPath } = resolveResult.value; + // if we resolved a instance member, check if we should be able to access // it. if (targetDeclaration.flags & OutputSymbolFlags.InstanceMember) { @@ -58,7 +60,12 @@ export function ref( } } - validateSymbolReachable(pathDown, memberPath, currentPrivateScope); + validateSymbolReachable( + pathDown, + memberPath, + targetDeclaration, + currentPrivateScope, + ); // Where the target declaration is relative to the referencing scope. // * package: target symbol is in a different package @@ -91,6 +98,9 @@ export function ref( type: options?.type, }), ); + onCleanup(() => { + localSymbol!.delete(); + }); break; } } @@ -169,12 +179,13 @@ function buildMemberExpression(path: TSOutputSymbol[]) { function validateSymbolReachable( path: TSOutputScope[], memberPath: TSOutputSymbol[] | undefined, + targetDeclaration: TSOutputSymbol, currentPrivateScope: PrivateScopeContext | undefined, ) { for (const scope of path) { if (scope.kind === "function") { throw new Error( - "Cannot reference a symbol inside a function from outside a function", + `Cannot reference symbol named ${targetDeclaration.name} because it is bound inside a function and the current scope is outside that function.`, ); } } diff --git a/packages/typescript/test/arrow-function.test.tsx b/packages/typescript/test/arrow-function.test.tsx index f1df3b085..018446923 100644 --- a/packages/typescript/test/arrow-function.test.tsx +++ b/packages/typescript/test/arrow-function.test.tsx @@ -125,7 +125,7 @@ describe("symbols", () => { ;{innerRefkey} ); - expect(() => toSourceText(decl)).toThrow(/Cannot reference a symbol/); + expect(() => toSourceText(decl)).toThrow(/Cannot reference symbol/); }); it("creates symbols for parameters", () => { diff --git a/packages/typescript/test/class.test.tsx b/packages/typescript/test/class.test.tsx index 1a8595c7d..79541509d 100644 --- a/packages/typescript/test/class.test.tsx +++ b/packages/typescript/test/class.test.tsx @@ -363,6 +363,47 @@ describe("instance methods", () => { } `); }); + + it("with parameters", () => { + const fprk = refkey(); + const cprk = refkey(); + const frk = refkey(); + const functionParams: ts.ParameterDescriptor[] = [ + { name: "foo", type: "string", refkey: fprk }, + ]; + + const classParams: ts.ParameterDescriptor[] = [ + { name: "bar", type: "number", refkey: cprk }, + ]; + + const res = toSourceText( + + + console.log({fprk}); + + + + {cprk} + + + , + ); + + expect(res).toEqual(d` + function internalFoo(foo: string) { + console.log(foo); + } + class Foo { + two(bar: number) { + bar + } + } + `); + }); }); it("renders a class with docs for the class and its members", () => { diff --git a/packages/typescript/test/externals.test.tsx b/packages/typescript/test/externals.test.tsx index 475916493..7ab7a1ef3 100644 --- a/packages/typescript/test/externals.test.tsx +++ b/packages/typescript/test/externals.test.tsx @@ -95,49 +95,6 @@ it("can import builtins without a package", () => { }); }); -it("can import builtins without a package", () => { - const testLib = createPackage({ - name: "testLib", - version: "1.0.0", - descriptor: { - ".": { - default: "defaultExport", - named: ["foo", "bar"], - }, - "./subpath": { - named: ["nice", "cool"], - }, - }, - }); - - const res = render( - - - - - {testLib["./subpath"].nice}; - await {fs["./promises"].readFile}(); - - - - , - ); - - assertFileContents(res, { - "index.ts": ` - import { readFile } from "node:fs/promises"; - import { nice } from "testLib/subpath"; - - function foo() { - function bar() { - nice; - await readFile(); - } - } - `, - }); -}); - it("can import static members", () => { const mcpSdk = createPackage({ name: "@modelcontextprotocol/sdk", diff --git a/packages/typescript/test/function-declaration.test.tsx b/packages/typescript/test/function-declaration.test.tsx index 986398150..ee9e50272 100644 --- a/packages/typescript/test/function-declaration.test.tsx +++ b/packages/typescript/test/function-declaration.test.tsx @@ -166,7 +166,7 @@ describe("symbols", () => { ;{innerRefkey} ); - expect(() => toSourceText(decl)).toThrow(/Cannot reference a symbol/); + expect(() => toSourceText(decl)).toThrow(/Cannot reference symbol/); }); it("creates symbols for parameters", () => { diff --git a/packages/typescript/test/function-expression.test.tsx b/packages/typescript/test/function-expression.test.tsx index cd6c81fbb..01fdc202d 100644 --- a/packages/typescript/test/function-expression.test.tsx +++ b/packages/typescript/test/function-expression.test.tsx @@ -130,7 +130,7 @@ describe("symbols", () => { ;{innerRefkey} ); - expect(() => toSourceText(decl)).toThrow(/Cannot reference a symbol/); + expect(() => toSourceText(decl)).toThrow(/Cannot reference symbol/); }); it("creates symbols for parameters", () => { diff --git a/packages/typescript/test/package-external.test.tsx b/packages/typescript/test/package-external.test.tsx index fd3964fba..f264c864d 100644 --- a/packages/typescript/test/package-external.test.tsx +++ b/packages/typescript/test/package-external.test.tsx @@ -85,7 +85,7 @@ it("imports external packages", () => { `); }); -it("combines explicit dependencies with referenced dependencies", () => { +it.only("combines explicit dependencies with referenced dependencies", () => { const res = render( { `); }); - it("can reference nested members", () => { + it.only("can reference nested members", () => { const varRefkey = refkey(); const fooRefkey = refkey(); const barRefkey = refkey(); @@ -203,6 +203,7 @@ describe("symbols", () => { ); + expect(decl).toRenderTo(` const refme = { foo: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fdeffd5e8..f87d23982 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,9 +57,6 @@ catalogs: '@vitest/eslint-plugin': specifier: ^1.1.42 version: 1.1.42 - '@vue/reactivity': - specifier: ^3.5.13 - version: 3.5.13 babel-plugin-tester: specifier: ^11.0.4 version: 11.0.4 @@ -115,6 +112,9 @@ catalogs: specifier: ^3.1.1 version: 3.1.1 +overrides: + '@vue/reactivity': 3.5.16 + patchedDependencies: '@microsoft/tsdoc@0.15.1': hash: feqpbbj7jjnlaslm723zbab6bm @@ -141,22 +141,22 @@ importers: version: 1.0.1 '@typescript-eslint/utils': specifier: ^8.29.1 - version: 8.29.1(eslint@9.24.0)(typescript@5.8.3) + version: 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) '@vitest/eslint-plugin': specifier: 'catalog:' - version: 1.1.42(@typescript-eslint/utils@8.29.1(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1)) + version: 1.1.42(@typescript-eslint/utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1)) concurrently: specifier: 'catalog:' version: 9.1.2 eslint: specifier: 'catalog:' - version: 9.24.0 + version: 9.24.0(jiti@2.4.2) prettier: specifier: 'catalog:' version: 3.5.3 prettier-plugin-organize-imports: specifier: 'catalog:' - version: 4.1.0(prettier@3.5.3)(typescript@5.8.3) + version: 4.1.0(prettier@3.5.3)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3)) rimraf: specifier: 'catalog:' version: 6.0.1 @@ -168,10 +168,10 @@ importers: version: 0.28.2(typescript@5.8.3) typescript-eslint: specifier: 'catalog:' - version: 8.29.1(eslint@9.24.0)(typescript@5.8.3) + version: 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) packages/babel-plugin-alloy: dependencies: @@ -208,7 +208,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/babel-plugin-jsx-dom-expressions: dependencies: @@ -276,13 +276,13 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/core: dependencies: '@vue/reactivity': - specifier: 'catalog:' - version: 3.5.13 + specifier: 3.5.16 + version: 3.5.16 cli-table3: specifier: 'catalog:' version: 0.6.5 @@ -295,6 +295,9 @@ importers: prettier: specifier: 'catalog:' version: 3.5.3 + ws: + specifier: ^8.18.2 + version: 8.18.2 devDependencies: '@alloy-js/cli': specifier: workspace:~ @@ -304,10 +307,13 @@ importers: version: link:../rollup-plugin '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) '@rollup/plugin-typescript': specifier: 'catalog:' version: 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.3) + '@types/ws': + specifier: ^8.18.1 + version: 8.18.1 concurrently: specifier: 'catalog:' version: 9.1.2 @@ -316,10 +322,10 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/create: dependencies: @@ -362,10 +368,10 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 6.2.6(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/csharp: dependencies: @@ -387,7 +393,7 @@ importers: version: link:../rollup-plugin '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) '@rollup/plugin-typescript': specifier: 'catalog:' version: 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.3) @@ -399,7 +405,211 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + + packages/debug-ui-vibe: + dependencies: + '@alloy-js/core': + specifier: workspace:* + version: link:../core + react: + specifier: ^18.2.0 + version: 18.3.1 + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + devDependencies: + '@types/node': + specifier: ^22.15.24 + version: 22.15.24 + '@types/react': + specifier: ^18.2.66 + version: 18.3.23 + '@types/react-dom': + specifier: ^18.2.22 + version: 18.3.7(@types/react@18.3.23) + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.5.0(vite@5.4.19(@types/node@22.15.24)(lightningcss@1.30.1)) + tsx: + specifier: ^4.19.4 + version: 4.19.4 + typescript: + specifier: ^5.2.2 + version: 5.8.3 + vite: + specifier: ^5.2.0 + version: 5.4.19(@types/node@22.15.24)(lightningcss@1.30.1) + vite-plugin-singlefile: + specifier: ^2.2.0 + version: 2.2.0(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.24)(lightningcss@1.30.1)) + + packages/dev-tools: + dependencies: + '@radix-ui/react-checkbox': + specifier: ^1.3.2 + version: 1.3.2(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-separator': + specifier: ^1.1.7 + version: 1.1.7(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': + specifier: ^1.2.3 + version: 1.2.3(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-tabs': + specifier: ^1.1.12 + version: 1.1.12(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@tailwindcss/vite': + specifier: ^4.1.8 + version: 4.1.8(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + lucide-react: + specifier: ^0.511.0 + version: 0.511.0(react@19.1.0) + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + tailwind-merge: + specifier: ^3.3.0 + version: 3.3.0 + tailwindcss: + specifier: ^4.1.8 + version: 4.1.8 + devDependencies: + '@eslint/js': + specifier: ^9.25.0 + version: 9.27.0 + '@types/node': + specifier: ^22.15.24 + version: 22.15.24 + '@types/react': + specifier: ^19.1.2 + version: 19.1.6 + '@types/react-dom': + specifier: ^19.1.2 + version: 19.1.5(@types/react@19.1.6) + '@vitejs/plugin-react': + specifier: ^4.4.1 + version: 4.5.0(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + eslint: + specifier: ^9.25.0 + version: 9.27.0(jiti@2.4.2) + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.27.0(jiti@2.4.2)) + eslint-plugin-react-refresh: + specifier: ^0.4.19 + version: 0.4.20(eslint@9.27.0(jiti@2.4.2)) + globals: + specifier: ^16.0.0 + version: 16.2.0 + tw-animate-css: + specifier: ^1.3.0 + version: 1.3.0 + typescript: + specifier: ~5.8.3 + version: 5.8.3 + typescript-eslint: + specifier: ^8.30.1 + version: 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + vite: + specifier: ^6.3.5 + version: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + + packages/dev-tools-vue: + dependencies: + '@alloy-js/core': + specifier: workspace:~ + version: link:../core + '@tailwindcss/vite': + specifier: ^4.1.8 + version: 4.1.8(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + '@vue/reactivity': + specifier: 3.5.16 + version: 3.5.16 + '@vueuse/core': + specifier: ^13.3.0 + version: 13.3.0(vue@3.5.16(typescript@5.8.3)) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + lucide-vue-next: + specifier: ^0.511.0 + version: 0.511.0(vue@3.5.16(typescript@5.8.3)) + reka-ui: + specifier: ^2.3.0 + version: 2.3.0(typescript@5.8.3)(vue@3.5.16(typescript@5.8.3)) + tailwind-merge: + specifier: ^3.3.0 + version: 3.3.0 + tailwindcss: + specifier: ^4.1.8 + version: 4.1.8 + tw-animate-css: + specifier: ^1.3.0 + version: 1.3.0 + vue: + specifier: ^3.5.13 + version: 3.5.16(typescript@5.8.3) + ws: + specifier: ^8.18.2 + version: 8.18.2 + devDependencies: + '@tsconfig/node22': + specifier: ^22.0.1 + version: 22.0.2 + '@types/jsdom': + specifier: ^21.1.7 + version: 21.1.7 + '@types/node': + specifier: ^22.15.24 + version: 22.15.24 + '@vitejs/plugin-vue': + specifier: ^5.2.3 + version: 5.2.4(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))(vue@3.5.16(typescript@5.8.3)) + '@vue/test-utils': + specifier: ^2.4.6 + version: 2.4.6 + '@vue/tsconfig': + specifier: ^0.7.0 + version: 0.7.0(typescript@5.8.3)(vue@3.5.16(typescript@5.8.3)) + jsdom: + specifier: ^26.0.0 + version: 26.1.0 + npm-run-all2: + specifier: ^7.0.2 + version: 7.0.2 + prettier: + specifier: 3.5.3 + version: 3.5.3 + typescript: + specifier: ~5.8.0 + version: 5.8.3 + vite: + specifier: ^6.2.4 + version: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + vite-plugin-singlefile: + specifier: ^2.2.0 + version: 2.2.0(rollup@4.39.0)(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + vite-plugin-vue-devtools: + specifier: ^7.7.2 + version: 7.7.6(rollup@4.39.0)(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))(vue@3.5.16(typescript@5.8.3)) + vitest: + specifier: ^3.1.1 + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + vue-tsc: + specifier: ^2.2.8 + version: 2.2.10(typescript@5.8.3) packages/docs: dependencies: @@ -408,13 +618,13 @@ importers: version: 0.9.4(prettier@3.5.3)(typescript@5.8.3) '@astrojs/starlight': specifier: ^0.33.1 - version: 0.33.1(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) + version: 0.33.1(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) astro: specifier: ^5.6.1 - version: 5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) + version: 5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) astro-expressive-code: specifier: ^0.40.2 - version: 0.40.2(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) + version: 0.40.2(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) sharp: specifier: ^0.34.1 version: 0.34.1 @@ -439,10 +649,10 @@ importers: version: link:../typescript '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) '@microsoft/api-extractor-model': specifier: 'catalog:' - version: 7.30.6(@types/node@20.17.30) + version: 7.30.6(@types/node@22.15.24) '@microsoft/tsdoc': specifier: 'catalog:' version: 0.15.1(patch_hash=feqpbbj7jjnlaslm723zbab6bm) @@ -470,7 +680,7 @@ importers: version: link:../rollup-plugin '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) '@rollup/plugin-typescript': specifier: 'catalog:' version: 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.3) @@ -482,7 +692,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/json: dependencies: @@ -501,7 +711,7 @@ importers: version: link:../rollup-plugin '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) '@rollup/plugin-typescript': specifier: 'catalog:' version: 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.3) @@ -513,7 +723,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/markdown: dependencies: @@ -532,13 +742,13 @@ importers: version: link:../rollup-plugin '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) typescript: specifier: 'catalog:' version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/prettier-plugin-alloy: devDependencies: @@ -550,7 +760,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/rollup-plugin: dependencies: @@ -569,7 +779,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages/typescript: dependencies: @@ -591,7 +801,7 @@ importers: version: link:../rollup-plugin '@microsoft/api-extractor': specifier: 'catalog:' - version: 7.52.8(@types/node@20.17.30) + version: 7.52.8(@types/node@22.15.24) '@rollup/plugin-typescript': specifier: 'catalog:' version: 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.3) @@ -603,7 +813,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) samples/basic-project: dependencies: @@ -640,7 +850,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) samples/client-emitter: dependencies: @@ -674,7 +884,7 @@ importers: version: 5.8.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) packages: @@ -688,6 +898,12 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@astrojs/check@0.9.4': resolution: {integrity: sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA==} hasBin: true @@ -744,6 +960,10 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.8': resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} @@ -756,10 +976,18 @@ packages: resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.27.3': + resolution: {integrity: sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.0': resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} engines: {node: '>=6.9.0'} @@ -770,10 +998,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-member-expression-to-functions@7.25.9': resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} @@ -788,28 +1026,54 @@ packages: resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.26.5': resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + '@babel/helper-replace-supers@7.26.5': resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} engines: {node: '>=6.9.0'} + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -823,6 +1087,34 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.27.3': + resolution: {integrity: sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-proposal-decorators@7.27.1': + resolution: {integrity: sha512-DTxe4LBPrtFdsWzgpmbBKevg3e9PBy+dXRt19kSbucbZvL2uqtdqwwpluL1jfxYE0wIDTFp1nTy/q6gNLsxXrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-jsx@7.25.9': resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} @@ -841,6 +1133,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typescript@7.27.0': resolution: {integrity: sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg==} engines: {node: '>=6.9.0'} @@ -861,14 +1165,26 @@ packages: resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.27.0': resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.27.3': + resolution: {integrity: sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.27.0': resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} engines: {node: '>=6.9.0'} + '@babel/types@7.27.3': + resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} + engines: {node: '>=6.9.0'} + '@chronus/chronus@1.0.1': resolution: {integrity: sha512-w/ejdZ3VhKJS6QaPGDoO47RaZyrxJ4a65RP2koDMtuR4cy/ck1cW+FsKnypMcbUif7Cf44k+6XGeY2K1v9gfoQ==} engines: {node: '>=20.0.0'} @@ -888,6 +1204,34 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.0.10': + resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + '@ctrl/tinycolor@4.1.0': resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==} engines: {node: '>=14'} @@ -916,102 +1260,204 @@ packages: '@emnapi/runtime@1.4.0': resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.2': resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.2': resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.2': resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.2': resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.2': resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.2': resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.2': resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.2': resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.2': resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.2': resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.2': resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.2': resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.2': resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.2': resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.2': resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.2': resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.2': resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} engines: {node: '>=18'} @@ -1024,6 +1470,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.2': resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} engines: {node: '>=18'} @@ -1036,30 +1488,60 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.2': resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.2': resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.2': resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.2': resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.2': resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} engines: {node: '>=18'} @@ -1072,6 +1554,12 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -1092,6 +1580,10 @@ packages: resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1100,6 +1592,10 @@ packages: resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.27.0': + resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1108,6 +1604,10 @@ packages: resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.3.1': + resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@expressive-code/core@0.40.2': resolution: {integrity: sha512-gXY3v7jbgz6nWKvRpoDxK4AHUPkZRuJsM79vHX/5uhV9/qX6Qnctp/U/dMHog/LCVXcuOps+5nRmf1uxQVPb3w==} @@ -1124,6 +1624,18 @@ packages: resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} + '@floating-ui/core@1.7.0': + resolution: {integrity: sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==} + + '@floating-ui/dom@1.7.0': + resolution: {integrity: sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==} + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@floating-ui/vue@1.1.6': + resolution: {integrity: sha512-XFlUzGHGv12zbgHNk5FN2mUB7ROul3oG2ENdTpWdE+qMFxyNxWSRmsoyhiEnpmabNm6WnUvR1OvJfUfN4ojC1A==} + '@gerrit0/mini-shiki@3.2.2': resolution: {integrity: sha512-vaZNGhGLKMY14HbF53xxHNgFO9Wz+t5lTlGNpl2N9xFiKQ0I5oIe0vKjU9dh7Nb3Dw6lZ7wqUE0ri+zcdpnK+Q==} @@ -1362,6 +1874,12 @@ packages: cpu: [x64] os: [win32] + '@internationalized/date@3.8.1': + resolution: {integrity: sha512-PgVE6B6eIZtzf9Gu5HvJxRK3ufUFz9DhspELuhW/N0GuMGMTLvPQNRkHP2hTuP9lblOk+f+1xi96sPiPXANXAA==} + + '@internationalized/number@3.6.2': + resolution: {integrity: sha512-E5QTOlMg9wo5OrKdHD6edo1JJlIoOsylh0+mbf0evi1tHJwMZfJSaBpGtnJV9N7w3jeiioox9EG/EWRWPh82vg==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1630,6 +2148,9 @@ packages: resolution: {integrity: sha512-3PCWyFBNbW2+Ox36VAkSqlPoIb96NZiPcICRYySHZrDTM2NuNxvrjPeaQDj2egqILs9EZFObRTHVMe4XxXJV7w==} engines: {node: '>= 18'} + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} @@ -1665,54 +2186,253 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rollup/plugin-babel@6.0.4': - resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} - engines: {node: '>=14.0.0'} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@radix-ui/primitive@1.1.2': + resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + + '@radix-ui/react-checkbox@1.3.2': + resolution: {integrity: sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==} peerDependencies: - '@babel/core': ^7.0.0 - '@types/babel__core': ^7.1.9 - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - '@types/babel__core': + '@types/react': optional: true - rollup: + '@types/react-dom': optional: true - '@rollup/plugin-node-resolve@16.0.1': - resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': + optional: true + '@types/react-dom': optional: true - '@rollup/plugin-typescript@12.1.2': - resolution: {integrity: sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: - rollup: ^2.14.0||^3.0.0||^4.0.0 - tslib: '*' - typescript: '>=3.7.0' + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': optional: true - tslib: + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': optional: true - '@rollup/pluginutils@5.1.4': - resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': optional: true - '@rollup/rollup-android-arm-eabi@4.39.0': - resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} - cpu: [arm] - os: [android] + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-presence@1.1.4': + resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.10': + resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-separator@1.1.7': + resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tabs@1.1.12': + resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.9': + resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + + '@rollup/plugin-babel@6.0.4': + resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.1': + resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-typescript@12.1.2': + resolution: {integrity: sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.39.0': + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} + cpu: [arm] + os: [android] '@rollup/rollup-android-arm64@4.39.0': resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} @@ -1831,6 +2551,9 @@ packages: '@rushstack/ts-command-line@5.0.1': resolution: {integrity: sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==} + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@shikijs/core@1.29.2': resolution: {integrity: sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==} @@ -1898,6 +2621,114 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@tailwindcss/node@4.1.8': + resolution: {integrity: sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==} + + '@tailwindcss/oxide-android-arm64@4.1.8': + resolution: {integrity: sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.8': + resolution: {integrity: sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.8': + resolution: {integrity: sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.8': + resolution: {integrity: sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8': + resolution: {integrity: sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': + resolution: {integrity: sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.8': + resolution: {integrity: sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.8': + resolution: {integrity: sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.8': + resolution: {integrity: sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.8': + resolution: {integrity: sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.8': + resolution: {integrity: sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.8': + resolution: {integrity: sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.8': + resolution: {integrity: sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==} + engines: {node: '>= 10'} + + '@tailwindcss/vite@4.1.8': + resolution: {integrity: sha512-CQ+I8yxNV5/6uGaJjiuymgw0kEQiNKRinYbZXPdx1fk5WgiyReG0VaUx/Xq6aVNSUNJFzxm6o8FNKS5aMaim5A==} + peerDependencies: + vite: ^5.2.0 || ^6 + + '@tanstack/virtual-core@3.13.9': + resolution: {integrity: sha512-3jztt0jpaoJO5TARe2WIHC1UQC3VMLAFUW5mmMo0yrkwtDB2AQP0+sh10BVUpWrnvHjSLvzFizydtEGLCJKFoQ==} + + '@tanstack/vue-virtual@3.13.9': + resolution: {integrity: sha512-HsvHaOo+o52cVcPhomKDZ3CMpTF/B2qg+BhPHIQJwzn4VIqDyt/rRVqtIomG6jE83IFsE2vlr6cmx7h3dHA0SA==} + peerDependencies: + vue: ^2.7.0 || ^3.0.0 + + '@tsconfig/node22@22.0.2': + resolution: {integrity: sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA==} + '@tufjs/canonical-json@2.0.0': resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} engines: {node: ^16.14.0 || >=18.0.0} @@ -1939,6 +2770,9 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/jsdom@21.1.7': + resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1960,21 +2794,52 @@ packages: '@types/node@20.17.30': resolution: {integrity: sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==} + '@types/node@22.15.24': + resolution: {integrity: sha512-w9CZGm9RDjzTh/D+hFwlBJ3ziUaVw7oufKA3vOFSOZlzmW9AkZnfjPb+DLnrV6qtgL/LNmP0/2zBNCFHL3F0ng==} + '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + '@types/prop-types@15.7.14': + resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react-dom@19.1.5': + resolution: {integrity: sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==} + peerDependencies: + '@types/react': ^19.0.0 + + '@types/react@18.3.23': + resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} + + '@types/react@19.1.6': + resolution: {integrity: sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.29.1': resolution: {integrity: sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1983,6 +2848,14 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/eslint-plugin@8.33.0': + resolution: {integrity: sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.33.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/parser@8.29.1': resolution: {integrity: sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1990,10 +2863,31 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/parser@8.33.0': + resolution: {integrity: sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/project-service@8.33.0': + resolution: {integrity: sha512-d1hz0u9l6N+u/gcrk6s6gYdl7/+pp8yHheRTqP6X5hVDKALEaTn8WfGiit7G511yueBEL3OpOEpD+3/MBdoN+A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.29.1': resolution: {integrity: sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.33.0': + resolution: {integrity: sha512-LMi/oqrzpqxyO72ltP+dBSP6V0xiUb4saY7WLtxSfiNEBI8m321LLVFU9/QDJxjDQG9/tjSqKz/E3380TEqSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.33.0': + resolution: {integrity: sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/type-utils@8.29.1': resolution: {integrity: sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2001,16 +2895,33 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/type-utils@8.33.0': + resolution: {integrity: sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/types@8.29.1': resolution: {integrity: sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.33.0': + resolution: {integrity: sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.29.1': resolution: {integrity: sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/typescript-estree@8.33.0': + resolution: {integrity: sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.29.1': resolution: {integrity: sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2018,13 +2929,37 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.33.0': + resolution: {integrity: sha512-lPFuQaLA9aSNa7D5u2EpRiqdAUhzShwGg/nhpBlc4GR6kcTABttCuyjFs8BcEZ8VWrjCBof/bePhP3Q3fS+Yrw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/visitor-keys@8.29.1': resolution: {integrity: sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.33.0': + resolution: {integrity: sha512-7RW7CMYoskiz5OOGAWjJFxgb7c5UNjTG292gYhWeOAcFmYCtVCSqjqSBj5zMhxbXo2JOW95YYrUWJfU0zrpaGQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@vitejs/plugin-react@4.5.0': + resolution: {integrity: sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + '@vitest/eslint-plugin@1.1.42': resolution: {integrity: sha512-dTGNbh/angh+hoqp5L5A8YO/29mOXDXmDQ/1fzt/jiYzLvU6FvrMqJpGqMqh5g+Fz6MDoZi0AlxefnFUg93Q5A==} peerDependencies: @@ -2091,11 +3026,112 @@ packages: '@vscode/l10n@0.0.18': resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} - '@vue/reactivity@3.5.13': - resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + '@vue/babel-helper-vue-transform-on@1.4.0': + resolution: {integrity: sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==} + + '@vue/babel-plugin-jsx@1.4.0': + resolution: {integrity: sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.4.0': + resolution: {integrity: sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.16': + resolution: {integrity: sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==} + + '@vue/compiler-dom@3.5.16': + resolution: {integrity: sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==} + + '@vue/compiler-sfc@3.5.16': + resolution: {integrity: sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw==} + + '@vue/compiler-ssr@3.5.16': + resolution: {integrity: sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/devtools-core@7.7.6': + resolution: {integrity: sha512-ghVX3zjKPtSHu94Xs03giRIeIWlb9M+gvDRVpIZ/cRIxKHdW6HE/sm1PT3rUYS3aV92CazirT93ne+7IOvGUWg==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.7.6': + resolution: {integrity: sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==} + + '@vue/devtools-shared@7.7.6': + resolution: {integrity: sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==} + + '@vue/language-core@2.2.10': + resolution: {integrity: sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.16': + resolution: {integrity: sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA==} + + '@vue/runtime-core@3.5.16': + resolution: {integrity: sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ==} + + '@vue/runtime-dom@3.5.16': + resolution: {integrity: sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww==} + + '@vue/server-renderer@3.5.16': + resolution: {integrity: sha512-BrX0qLiv/WugguGsnQUJiYOE0Fe5mZTwi6b7X/ybGB0vfrPH9z0gD/Y6WOR1sGCgX4gc25L1RYS5eYQKDMoNIg==} + peerDependencies: + vue: 3.5.16 - '@vue/shared@3.5.13': - resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@vue/shared@3.5.16': + resolution: {integrity: sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==} + + '@vue/test-utils@2.4.6': + resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + + '@vue/tsconfig@0.7.0': + resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==} + peerDependencies: + typescript: 5.x + vue: ^3.4.0 + peerDependenciesMeta: + typescript: + optional: true + vue: + optional: true + + '@vueuse/core@12.8.2': + resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} + + '@vueuse/core@13.3.0': + resolution: {integrity: sha512-uYRz5oEfebHCoRhK4moXFM3NSCd5vu2XMLOq/Riz5FdqZMy2RvBtazdtL3gEcmDyqkztDe9ZP/zymObMIbiYSg==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/metadata@12.8.2': + resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==} + + '@vueuse/metadata@13.3.0': + resolution: {integrity: sha512-42IzJIOYCKIb0Yjv1JfaKpx8JlCiTmtCWrPxt7Ja6Wzoq0h79+YVXmBV03N966KEmDEESTbp5R/qO3AB5BDnGw==} + + '@vueuse/shared@12.8.2': + resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} + + '@vueuse/shared@13.3.0': + resolution: {integrity: sha512-L1QKsF0Eg9tiZSFXTgodYnu0Rsa2P0En2LuLrIs/jgrkyiDuJSsPZK+tx+wU0mMsYHUYEjNsuE41uqqkuR8VhA==} + peerDependencies: + vue: ^3.5.0 + + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} @@ -2143,6 +3179,9 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + alien-signals@1.0.13: + resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} + ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -2175,6 +3214,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -2231,6 +3274,9 @@ packages: before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + birpc@2.3.0: + resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2259,6 +3305,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -2328,6 +3378,9 @@ packages: resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} engines: {node: '>=8'} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} @@ -2364,6 +3417,10 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + common-ancestor-path@1.0.1: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} @@ -2375,6 +3432,9 @@ packages: engines: {node: '>=18'} hasBin: true + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -2385,6 +3445,10 @@ packages: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + core-js@3.41.0: resolution: {integrity: sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==} @@ -2403,6 +3467,20 @@ packages: engines: {node: '>=4'} hasBin: true + cssstyle@4.3.1: + resolution: {integrity: sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==} + engines: {node: '>=18'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -2412,6 +3490,9 @@ packages: supports-color: optional: true + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + decode-named-character-reference@1.1.0: resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==} @@ -2426,6 +3507,18 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} @@ -2443,6 +3536,10 @@ packages: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + deterministic-object-hash@2.0.2: resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} engines: {node: '>=18'} @@ -2471,6 +3568,11 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true + electron-to-chromium@1.5.136: resolution: {integrity: sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==} @@ -2492,6 +3594,10 @@ packages: encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -2503,6 +3609,9 @@ packages: err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + error-stack-parser-es@0.1.5: + resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} + es-module-lexer@1.6.0: resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} @@ -2512,6 +3621,11 @@ packages: esast-util-from-js@2.0.1: resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.25.2: resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} engines: {node: '>=18'} @@ -2529,6 +3643,17 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.20: + resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} + peerDependencies: + eslint: '>=8.40' + eslint-scope@8.3.0: resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2551,6 +3676,16 @@ packages: jiti: optional: true + eslint@9.27.0: + resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2598,6 +3733,10 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + execa@9.6.0: + resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} + engines: {node: ^18.19.0 || >=20.5.0} + expect-type@1.2.1: resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} @@ -2641,6 +3780,18 @@ packages: picomatch: optional: true + fdir@6.4.5: + resolution: {integrity: sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2700,6 +3851,10 @@ packages: resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} engines: {node: '>=18'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-tsconfig@4.10.0: resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} @@ -2731,6 +3886,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@16.2.0: + resolution: {integrity: sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==} + engines: {node: '>=18'} + globby@14.1.0: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} @@ -2812,10 +3971,21 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + hosted-git-info@8.0.2: resolution: {integrity: sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==} engines: {node: ^18.17.0 || >=20.5.0} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + html-entities@2.6.0: resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} @@ -2839,6 +4009,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + i18next@23.16.8: resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} @@ -2877,6 +4051,9 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ini@5.0.0: resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2943,10 +4120,21 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-unicode-supported@2.1.0: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + is-wsl@3.1.0: resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} engines: {node: '>=16'} @@ -2965,9 +4153,22 @@ packages: resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} engines: {node: 20 || >=22} + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2978,6 +4179,15 @@ packages: jsbn@1.1.0: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + jsdom@26.1.0: + resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -3032,10 +4242,77 @@ packages: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} @@ -3055,6 +4332,10 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} @@ -3072,6 +4353,16 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lucide-react@0.511.0: + resolution: {integrity: sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + lucide-vue-next@0.511.0: + resolution: {integrity: sha512-VSv0F3pHniGN7JMMzDcLFNMQbl8381+shNnHwV8hi+El7xl2ZL8qdNuzPoiBViKk8mTKK5K3ZDfmE/wEcTZVIQ==} + peerDependencies: + vue: '>=3.0.1' + lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} @@ -3153,6 +4444,10 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -3283,6 +4578,10 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -3327,6 +4626,9 @@ packages: resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} engines: {node: '>= 18'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -3352,6 +4654,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} + engines: {node: ^18 || >=20} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -3380,6 +4687,11 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + nopt@8.1.0: resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} engines: {node: ^18.17.0 || >=20.5.0} @@ -3417,9 +4729,21 @@ packages: resolution: {integrity: sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==} engines: {node: ^18.17.0 || >=20.5.0} + npm-run-all2@7.0.2: + resolution: {integrity: sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==} + engines: {node: ^18.17.0 || >=20.5.0, npm: '>= 9'} + hasBin: true + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nwsapi@2.2.20: + resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + octokit@4.1.3: resolution: {integrity: sha512-PP+EL8h4xPCE9NBo6jXq6I2/EiTXsn1cg9F0IZehHBv/qhuQpyGMFElEB17miWKciuT6vRHiFFiG9+FoXOmg6A==} engines: {node: '>= 18'} @@ -3427,6 +4751,9 @@ packages: ofetch@1.4.1: resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -3439,6 +4766,10 @@ packages: oniguruma-to-es@4.1.0: resolution: {integrity: sha512-SNwG909cSLo4vPyyPbU/VJkEc9WOXqu2ycBlfd1UCXLqk1IijcQktSBb2yRQ2UFPsDhpkaf+C1dtT3PkLK/yWA==} + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + engines: {node: '>=18'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -3492,6 +4823,10 @@ packages: parse-latin@7.0.0: resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parse5@7.2.1: resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} @@ -3506,6 +4841,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -3528,6 +4867,9 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -3539,6 +4881,11 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -3586,6 +4933,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} + engines: {node: '>=18'} + prismjs@1.30.0: resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} @@ -3608,6 +4959,9 @@ packages: property-information@7.0.0: resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} @@ -3622,6 +4976,32 @@ packages: radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + + read-package-json-fast@4.0.0: + resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==} + engines: {node: ^18.17.0 || >=20.5.0} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -3681,6 +5061,11 @@ packages: rehype@13.0.2: resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + reka-ui@2.3.0: + resolution: {integrity: sha512-HKvJej9Sc0KYEvTAbsGHgOxpEWL4FWSR70Q6Ld+bVNuaCxK6LP3jyTtyTWS+A44hHA9/aYfOBZ1Q8WkgZsGZpA==} + peerDependencies: + vue: '>= 3.2.0' + remark-directive@3.0.1: resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} @@ -3749,6 +5134,9 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rimraf@6.0.1: resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} engines: {node: 20 || >=22} @@ -3759,6 +5147,13 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3771,6 +5166,16 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -3825,6 +5230,10 @@ packages: simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -3883,6 +5292,10 @@ packages: spdx-license-ids@3.0.21: resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -3929,6 +5342,10 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -3947,6 +5364,10 @@ packages: style-to-object@1.0.8: resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} + superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3959,6 +5380,19 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tailwind-merge@3.3.0: + resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==} + + tailwindcss@4.1.8: + resolution: {integrity: sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==} + + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} + engines: {node: '>=6'} + tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} @@ -3977,6 +5411,10 @@ packages: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + engines: {node: '>=12.0.0'} + tinypool@1.0.2: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3989,6 +5427,13 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3997,6 +5442,18 @@ packages: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -4031,6 +5488,11 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tsx@4.19.4: + resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==} + engines: {node: '>=18.0.0'} + hasBin: true + tuf-js@3.0.1: resolution: {integrity: sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -4039,6 +5501,9 @@ packages: resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + tw-animate-css@1.3.0: + resolution: {integrity: sha512-jrJ0XenzS9KVuDThJDvnhalbl4IYiMQ/XvpA0a2FL8KmlK+6CSMviO7ROY/I7z1NnUs5NnDhlM6fXmF40xPxzw==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -4067,6 +5532,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + typescript-eslint@8.33.0: + resolution: {integrity: sha512-5YmNhF24ylCsvdNW2oJwMzTbaeO4bg90KeGtMjUw0AGtHksgEPLRTUil+coHwCfiu4QjVJFnjp94DmU6zV7DhQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -4092,6 +5564,9 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} @@ -4244,13 +5719,117 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-hot-client@2.0.4: + resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + vite-node@3.1.1: resolution: {integrity: sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@6.2.6: - resolution: {integrity: sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==} + vite-plugin-inspect@0.8.9: + resolution: {integrity: sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-singlefile@2.2.0: + resolution: {integrity: sha512-Ik1wXmJaGzeQtUeIV7JprDUqqy6DlLzXAY27Blei5peE4c9VJF+Kp9xWDJeuX0RJUZmFbIAuw1/RAh06A+Ql7w==} + engines: {node: '>18.0.0'} + peerDependencies: + rollup: ^4.35.0 + vite: ^5.4.11 || ^6.0.0 + + vite-plugin-vue-devtools@7.7.6: + resolution: {integrity: sha512-L7nPVM5a7lgit/Z+36iwoqHOaP3wxqVi1UvaDJwGCfblS9Y6vNqf32ILlzJVH9c47aHu90BhDXeZc+rgzHRHcw==} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 + + vite-plugin-vue-inspector@5.3.1: + resolution: {integrity: sha512-cBk172kZKTdvGpJuzCCLg8lJ909wopwsu3Ve9FsL1XsnLBiRT9U3MePcqrgGHgCX2ZgkqZmAGR8taxw+TV6s7A==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 + + vite@5.4.19: + resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vite@6.2.6: + resolution: {integrity: sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -4431,9 +6010,57 @@ packages: vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + vue-component-type-helpers@2.2.10: + resolution: {integrity: sha512-iDUO7uQK+Sab2tYuiP9D1oLujCWlhHELHMgV/cB13cuGbG4qwkLHvtfWb6FzvxrIOPDnU0oHsz2MlQjhYDeaHA==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-tsc@2.2.10: + resolution: {integrity: sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.16: + resolution: {integrity: sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + which-pm-runs@1.1.0: resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} engines: {node: '>=4'} @@ -4476,6 +6103,25 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xxhash-wasm@1.1.0: resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} @@ -4566,6 +6212,16 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 + '@antfu/utils@0.7.10': {} + + '@asamuzakjp/css-color@3.2.0': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 + '@astrojs/check@0.9.4(prettier@3.5.3)(typescript@5.8.3)': dependencies: '@astrojs/language-server': 2.15.4(prettier@3.5.3)(typescript@5.8.3) @@ -4632,12 +6288,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.2.3(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1))': + '@astrojs/mdx@4.2.3(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1))': dependencies: '@astrojs/markdown-remark': 6.3.1 '@mdx-js/mdx': 3.1.0(acorn@8.14.1) acorn: 8.14.1 - astro: 5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) es-module-lexer: 1.6.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -4661,16 +6317,16 @@ snapshots: stream-replace-string: 2.0.0 zod: 3.24.2 - '@astrojs/starlight@0.33.1(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1))': + '@astrojs/starlight@0.33.1(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1))': dependencies: - '@astrojs/mdx': 4.2.3(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) + '@astrojs/mdx': 4.2.3(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) '@astrojs/sitemap': 3.3.0 '@pagefind/default-ui': 1.3.0 '@types/hast': 3.0.4 '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 - astro: 5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) - astro-expressive-code: 0.40.2(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) + astro: 5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) + astro-expressive-code: 0.40.2(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)) bcp-47: 2.1.0 hast-util-from-html: 2.0.3 hast-util-select: 6.0.4 @@ -4714,6 +6370,12 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.26.8': {} '@babel/core@7.26.10': @@ -4744,10 +6406,22 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/generator@7.27.3': + dependencies: + '@babel/parser': 7.27.3 + '@babel/types': 7.27.3 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.25.9': dependencies: '@babel/types': 7.27.0 + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.27.3 + '@babel/helper-compilation-targets@7.27.0': dependencies: '@babel/compat-data': 7.26.8 @@ -4769,6 +6443,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.26.10) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-member-expression-to-functions@7.25.9': dependencies: '@babel/traverse': 7.27.0 @@ -4776,6 +6463,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.27.3 + '@babel/types': 7.27.3 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.27.0 @@ -4796,8 +6490,14 @@ snapshots: dependencies: '@babel/types': 7.27.0 + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.27.3 + '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -4807,6 +6507,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.3 + transitivePeerDependencies: + - supports-color + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': dependencies: '@babel/traverse': 7.27.0 @@ -4814,10 +6523,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.27.3 + '@babel/types': 7.27.3 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.25.9': {} '@babel/helpers@7.27.0': @@ -4829,6 +6549,34 @@ snapshots: dependencies: '@babel/types': 7.27.0 + '@babel/parser@7.27.3': + dependencies: + '@babel/types': 7.27.3 + + '@babel/plugin-proposal-decorators@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.26.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -4847,6 +6595,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-typescript@7.27.0(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -4879,6 +6637,12 @@ snapshots: '@babel/parser': 7.27.0 '@babel/types': 7.27.0 + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.3 + '@babel/types': 7.27.3 + '@babel/traverse@7.27.0': dependencies: '@babel/code-frame': 7.26.2 @@ -4891,11 +6655,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.27.3': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.3 + '@babel/parser': 7.27.3 + '@babel/template': 7.27.2 + '@babel/types': 7.27.3 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + '@babel/types@7.27.0': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.27.3': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@chronus/chronus@1.0.1': dependencies: cross-spawn: 7.0.6 @@ -4937,6 +6718,26 @@ snapshots: '@colors/colors@1.5.0': optional: true + '@csstools/color-helpers@5.0.2': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.0.2 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + '@ctrl/tinycolor@4.1.0': {} '@emmetio/abbreviation@2.3.3': @@ -4967,84 +6768,163 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.25.2': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.25.2': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.25.2': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.25.2': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.25.2': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.25.2': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.25.2': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.25.2': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.25.2': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.25.2': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.25.2': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.25.2': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.25.2': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.25.2': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.25.2': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.25.2': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.25.2': optional: true '@esbuild/netbsd-arm64@0.25.2': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.25.2': optional: true '@esbuild/openbsd-arm64@0.25.2': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.25.2': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.25.2': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.25.2': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.25.2': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.25.2': optional: true - '@eslint-community/eslint-utils@4.5.1(eslint@9.24.0)': + '@eslint-community/eslint-utils@4.5.1(eslint@9.24.0(jiti@2.4.2))': + dependencies: + eslint: 9.24.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.5.1(eslint@9.27.0(jiti@2.4.2))': + dependencies: + eslint: 9.27.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': dependencies: - eslint: 9.24.0 + eslint: 9.27.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -5067,6 +6947,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@0.14.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 @@ -5083,6 +6967,8 @@ snapshots: '@eslint/js@9.24.0': {} + '@eslint/js@9.27.0': {} + '@eslint/object-schema@2.1.6': {} '@eslint/plugin-kit@0.2.8': @@ -5090,6 +6976,11 @@ snapshots: '@eslint/core': 0.13.0 levn: 0.4.1 + '@eslint/plugin-kit@0.3.1': + dependencies: + '@eslint/core': 0.14.0 + levn: 0.4.1 + '@expressive-code/core@0.40.2': dependencies: '@ctrl/tinycolor': 4.1.0 @@ -5117,6 +7008,26 @@ snapshots: '@fastify/busboy@2.1.1': {} + '@floating-ui/core@1.7.0': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.7.0': + dependencies: + '@floating-ui/core': 1.7.0 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/utils@0.2.9': {} + + '@floating-ui/vue@1.1.6(vue@3.5.16(typescript@5.8.3))': + dependencies: + '@floating-ui/dom': 1.7.0 + '@floating-ui/utils': 0.2.9 + vue-demi: 0.14.10(vue@3.5.16(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + '@gerrit0/mini-shiki@3.2.2': dependencies: '@shikijs/engine-oniguruma': 3.2.2 @@ -5291,6 +7202,14 @@ snapshots: '@img/sharp-win32-x64@0.34.1': optional: true + '@internationalized/date@3.8.1': + dependencies: + '@swc/helpers': 0.5.17 + + '@internationalized/number@3.6.2': + dependencies: + '@swc/helpers': 0.5.17 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -5351,23 +7270,23 @@ snapshots: - acorn - supports-color - '@microsoft/api-extractor-model@7.30.6(@types/node@20.17.30)': + '@microsoft/api-extractor-model@7.30.6(@types/node@22.15.24)': dependencies: '@microsoft/tsdoc': 0.15.1(patch_hash=feqpbbj7jjnlaslm723zbab6bm) '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.1(@types/node@20.17.30) + '@rushstack/node-core-library': 5.13.1(@types/node@22.15.24) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.52.8(@types/node@20.17.30)': + '@microsoft/api-extractor@7.52.8(@types/node@22.15.24)': dependencies: - '@microsoft/api-extractor-model': 7.30.6(@types/node@20.17.30) + '@microsoft/api-extractor-model': 7.30.6(@types/node@22.15.24) '@microsoft/tsdoc': 0.15.1(patch_hash=feqpbbj7jjnlaslm723zbab6bm) '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.1(@types/node@20.17.30) + '@rushstack/node-core-library': 5.13.1(@types/node@22.15.24) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.3(@types/node@20.17.30) - '@rushstack/ts-command-line': 5.0.1(@types/node@20.17.30) + '@rushstack/terminal': 0.15.3(@types/node@22.15.24) + '@rushstack/ts-command-line': 5.0.1(@types/node@22.15.24) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.10 @@ -5683,6 +7602,8 @@ snapshots: '@octokit/request-error': 6.1.8 '@octokit/webhooks-methods': 5.1.1 + '@one-ini/wasm@0.1.1': {} + '@oslojs/encoding@1.1.0': {} '@pagefind/darwin-arm64@1.3.0': @@ -5696,14 +7617,181 @@ snapshots: '@pagefind/linux-arm64@1.3.0': optional: true - '@pagefind/linux-x64@1.3.0': - optional: true + '@pagefind/linux-x64@1.3.0': + optional: true + + '@pagefind/windows-x64@1.3.0': + optional: true + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.29': {} + + '@radix-ui/primitive@1.1.2': {} + + '@radix-ui/react-checkbox@1.3.2(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-context@1.1.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-direction@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-id@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-presence@1.1.4(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-slot@1.2.3(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-tabs@1.1.12(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 - '@pagefind/windows-x64@1.3.0': - optional: true + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 - '@pkgjs/parseargs@0.11.0': - optional: true + '@rolldown/pluginutils@1.0.0-beta.9': {} '@rollup/plugin-babel@6.0.4(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@4.39.0)': dependencies: @@ -5803,7 +7891,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.39.0': optional: true - '@rushstack/node-core-library@5.13.1(@types/node@20.17.30)': + '@rushstack/node-core-library@5.13.1(@types/node@22.15.24)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -5814,29 +7902,31 @@ snapshots: resolve: 1.22.10 semver: 7.5.4 optionalDependencies: - '@types/node': 20.17.30 + '@types/node': 22.15.24 '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.10 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.15.3(@types/node@20.17.30)': + '@rushstack/terminal@0.15.3(@types/node@22.15.24)': dependencies: - '@rushstack/node-core-library': 5.13.1(@types/node@20.17.30) + '@rushstack/node-core-library': 5.13.1(@types/node@22.15.24) supports-color: 8.1.1 optionalDependencies: - '@types/node': 20.17.30 + '@types/node': 22.15.24 - '@rushstack/ts-command-line@5.0.1(@types/node@20.17.30)': + '@rushstack/ts-command-line@5.0.1(@types/node@22.15.24)': dependencies: - '@rushstack/terminal': 0.15.3(@types/node@20.17.30) + '@rushstack/terminal': 0.15.3(@types/node@22.15.24) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 transitivePeerDependencies: - '@types/node' + '@sec-ant/readable-stream@0.4.1': {} + '@shikijs/core@1.29.2': dependencies: '@shikijs/engine-javascript': 1.29.2 @@ -5937,6 +8027,92 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} + '@sindresorhus/merge-streams@4.0.0': {} + + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.1.8': + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.8 + + '@tailwindcss/oxide-android-arm64@4.1.8': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.8': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.8': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.8': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.8': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.8': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.8': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.8': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.8': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.8': + optional: true + + '@tailwindcss/oxide@4.1.8': + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.8 + '@tailwindcss/oxide-darwin-arm64': 4.1.8 + '@tailwindcss/oxide-darwin-x64': 4.1.8 + '@tailwindcss/oxide-freebsd-x64': 4.1.8 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.8 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.8 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.8 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.8 + '@tailwindcss/oxide-linux-x64-musl': 4.1.8 + '@tailwindcss/oxide-wasm32-wasi': 4.1.8 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.8 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.8 + + '@tailwindcss/vite@4.1.8(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))': + dependencies: + '@tailwindcss/node': 4.1.8 + '@tailwindcss/oxide': 4.1.8 + tailwindcss: 4.1.8 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + + '@tanstack/virtual-core@3.13.9': {} + + '@tanstack/vue-virtual@3.13.9(vue@3.5.16(typescript@5.8.3))': + dependencies: + '@tanstack/virtual-core': 3.13.9 + vue: 3.5.16(typescript@5.8.3) + + '@tsconfig/node22@22.0.2': {} + '@tufjs/canonical-json@2.0.0': {} '@tufjs/models@3.0.1': @@ -5985,6 +8161,12 @@ snapshots: '@types/js-yaml@4.0.9': {} + '@types/jsdom@21.1.7': + dependencies: + '@types/node': 22.15.24 + '@types/tough-cookie': 4.0.5 + parse5: 7.2.1 + '@types/json-schema@7.0.15': {} '@types/mdast@4.0.4': @@ -6005,30 +8187,61 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/node@22.15.24': + dependencies: + undici-types: 6.21.0 + '@types/prompts@2.4.9': dependencies: - '@types/node': 20.17.30 + '@types/node': 22.15.24 kleur: 3.0.3 + '@types/prop-types@15.7.14': {} + + '@types/react-dom@18.3.7(@types/react@18.3.23)': + dependencies: + '@types/react': 18.3.23 + + '@types/react-dom@19.1.5(@types/react@19.1.6)': + dependencies: + '@types/react': 19.1.6 + + '@types/react@18.3.23': + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + + '@types/react@19.1.6': + dependencies: + csstype: 3.1.3 + '@types/resolve@1.20.2': {} '@types/sax@1.2.7': dependencies: - '@types/node': 17.0.45 + '@types/node': 22.15.24 + + '@types/tough-cookie@4.0.5': {} '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} - '@typescript-eslint/eslint-plugin@8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)': + '@types/web-bluetooth@0.0.21': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.15.24 + + '@typescript-eslint/eslint-plugin@8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.29.1(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/parser': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/scope-manager': 8.29.1 - '@typescript-eslint/type-utils': 8.29.1(eslint@9.24.0)(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.29.1 - eslint: 9.24.0 + eslint: 9.24.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -6037,29 +8250,87 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.29.1(eslint@9.24.0)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.33.0(@typescript-eslint/parser@8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.33.0 + '@typescript-eslint/type-utils': 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.33.0 + eslint: 9.27.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.3 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.29.1 '@typescript-eslint/types': 8.29.1 '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.29.1 debug: 4.4.0 - eslint: 9.24.0 + eslint: 9.24.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.33.0 + '@typescript-eslint/types': 8.33.0 + '@typescript-eslint/typescript-estree': 8.33.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.33.0 + debug: 4.4.0 + eslint: 9.27.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.33.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.33.0(typescript@5.8.3) + '@typescript-eslint/types': 8.33.0 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/scope-manager@8.29.1': dependencies: '@typescript-eslint/types': 8.29.1 '@typescript-eslint/visitor-keys': 8.29.1 - '@typescript-eslint/type-utils@8.29.1(eslint@9.24.0)(typescript@5.8.3)': + '@typescript-eslint/scope-manager@8.33.0': + dependencies: + '@typescript-eslint/types': 8.33.0 + '@typescript-eslint/visitor-keys': 8.33.0 + + '@typescript-eslint/tsconfig-utils@8.33.0(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + + '@typescript-eslint/type-utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.0 + eslint: 9.24.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.33.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.0 - eslint: 9.24.0 + eslint: 9.27.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -6067,6 +8338,8 @@ snapshots: '@typescript-eslint/types@8.29.1': {} + '@typescript-eslint/types@8.33.0': {} + '@typescript-eslint/typescript-estree@8.29.1(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 8.29.1 @@ -6081,13 +8354,40 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.29.1(eslint@9.24.0)(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.33.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.33.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.33.0(typescript@5.8.3) + '@typescript-eslint/types': 8.33.0 + '@typescript-eslint/visitor-keys': 8.33.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.29.1 '@typescript-eslint/types': 8.29.1 '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - eslint: 9.24.0 + eslint: 9.24.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.33.0 + '@typescript-eslint/types': 8.33.0 + '@typescript-eslint/typescript-estree': 8.33.0(typescript@5.8.3) + eslint: 9.27.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -6097,13 +8397,47 @@ snapshots: '@typescript-eslint/types': 8.29.1 eslint-visitor-keys: 4.2.0 + '@typescript-eslint/visitor-keys@8.33.0': + dependencies: + '@typescript-eslint/types': 8.33.0 + eslint-visitor-keys: 4.2.0 + '@ungap/structured-clone@1.3.0': {} - '@vitest/eslint-plugin@1.1.42(@typescript-eslint/utils@8.29.1(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1))': + '@vitejs/plugin-react@4.5.0(vite@5.4.19(@types/node@22.15.24)(lightningcss@1.30.1))': + dependencies: + '@babel/core': 7.26.10 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.26.10) + '@rolldown/pluginutils': 1.0.0-beta.9 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 5.4.19(@types/node@22.15.24)(lightningcss@1.30.1) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-react@4.5.0(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))': + dependencies: + '@babel/core': 7.26.10 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.26.10) + '@rolldown/pluginutils': 1.0.0-beta.9 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))(vue@3.5.16(typescript@5.8.3))': + dependencies: + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + vue: 3.5.16(typescript@5.8.3) + + '@vitest/eslint-plugin@1.1.42(@typescript-eslint/utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1))': dependencies: - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0)(typescript@5.8.3) - eslint: 9.24.0 - vitest: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.24.0(jiti@2.4.2) + vitest: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) optionalDependencies: typescript: 5.8.3 @@ -6114,13 +8448,29 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.1.1(vite@6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1))': + '@vitest/mocker@3.1.1(vite@6.2.6(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))': dependencies: '@vitest/spy': 3.1.1 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + vite: 6.2.6(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + + '@vitest/mocker@3.1.1(vite@6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1))': + dependencies: + '@vitest/spy': 3.1.1 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) + + '@vitest/mocker@3.1.1(vite@6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))': + dependencies: + '@vitest/spy': 3.1.1 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) '@vitest/pretty-format@3.1.1': dependencies: @@ -6137,71 +8487,234 @@ snapshots: magic-string: 0.30.17 pathe: 2.0.3 - '@vitest/spy@3.1.1': + '@vitest/spy@3.1.1': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@3.1.1': + dependencies: + '@vitest/pretty-format': 3.1.1 + loupe: 3.1.3 + tinyrainbow: 2.0.0 + + '@volar/kit@2.4.12(typescript@5.8.3)': + dependencies: + '@volar/language-service': 2.4.12 + '@volar/typescript': 2.4.12 + typesafe-path: 0.2.2 + typescript: 5.8.3 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + '@volar/language-core@2.4.12': + dependencies: + '@volar/source-map': 2.4.12 + + '@volar/language-server@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + '@volar/language-service': 2.4.12 + '@volar/typescript': 2.4.12 + path-browserify: 1.0.1 + request-light: 0.7.0 + vscode-languageserver: 9.0.1 + vscode-languageserver-protocol: 3.17.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + '@volar/language-service@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + vscode-languageserver-protocol: 3.17.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + '@volar/source-map@2.4.12': {} + + '@volar/typescript@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vscode/emmet-helper@2.11.0': + dependencies: + emmet: 2.4.11 + jsonc-parser: 2.3.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.1.0 + + '@vscode/l10n@0.0.18': {} + + '@vue/babel-helper-vue-transform-on@1.4.0': {} + + '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.26.10)': + dependencies: + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) + '@babel/template': 7.27.0 + '@babel/traverse': 7.27.0 + '@babel/types': 7.27.0 + '@vue/babel-helper-vue-transform-on': 1.4.0 + '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.26.10) + '@vue/shared': 3.5.16 + optionalDependencies: + '@babel/core': 7.26.10 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.26.10)': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/core': 7.26.10 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.27.0 + '@vue/compiler-sfc': 3.5.16 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.16': + dependencies: + '@babel/parser': 7.27.3 + '@vue/shared': 3.5.16 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.16': + dependencies: + '@vue/compiler-core': 3.5.16 + '@vue/shared': 3.5.16 + + '@vue/compiler-sfc@3.5.16': + dependencies: + '@babel/parser': 7.27.3 + '@vue/compiler-core': 3.5.16 + '@vue/compiler-dom': 3.5.16 + '@vue/compiler-ssr': 3.5.16 + '@vue/shared': 3.5.16 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.3 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.16': + dependencies: + '@vue/compiler-dom': 3.5.16 + '@vue/shared': 3.5.16 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))(vue@3.5.16(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.7.6 + '@vue/devtools-shared': 7.7.6 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 2.0.3 + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + vue: 3.5.16(typescript@5.8.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.7.6': dependencies: - tinyspy: 3.0.2 + '@vue/devtools-shared': 7.7.6 + birpc: 2.3.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.2 - '@vitest/utils@3.1.1': + '@vue/devtools-shared@7.7.6': dependencies: - '@vitest/pretty-format': 3.1.1 - loupe: 3.1.3 - tinyrainbow: 2.0.0 + rfdc: 1.4.1 - '@volar/kit@2.4.12(typescript@5.8.3)': + '@vue/language-core@2.2.10(typescript@5.8.3)': dependencies: - '@volar/language-service': 2.4.12 - '@volar/typescript': 2.4.12 - typesafe-path: 0.2.2 + '@volar/language-core': 2.4.12 + '@vue/compiler-dom': 3.5.16 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.16 + alien-signals: 1.0.13 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: typescript: 5.8.3 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 - '@volar/language-core@2.4.12': + '@vue/reactivity@3.5.16': dependencies: - '@volar/source-map': 2.4.12 + '@vue/shared': 3.5.16 - '@volar/language-server@2.4.12': + '@vue/runtime-core@3.5.16': dependencies: - '@volar/language-core': 2.4.12 - '@volar/language-service': 2.4.12 - '@volar/typescript': 2.4.12 - path-browserify: 1.0.1 - request-light: 0.7.0 - vscode-languageserver: 9.0.1 - vscode-languageserver-protocol: 3.17.5 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 + '@vue/reactivity': 3.5.16 + '@vue/shared': 3.5.16 - '@volar/language-service@2.4.12': + '@vue/runtime-dom@3.5.16': dependencies: - '@volar/language-core': 2.4.12 - vscode-languageserver-protocol: 3.17.5 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 + '@vue/reactivity': 3.5.16 + '@vue/runtime-core': 3.5.16 + '@vue/shared': 3.5.16 + csstype: 3.1.3 - '@volar/source-map@2.4.12': {} + '@vue/server-renderer@3.5.16(vue@3.5.16(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.5.16 + '@vue/shared': 3.5.16 + vue: 3.5.16(typescript@5.8.3) - '@volar/typescript@2.4.12': + '@vue/shared@3.5.16': {} + + '@vue/test-utils@2.4.6': dependencies: - '@volar/language-core': 2.4.12 - path-browserify: 1.0.1 - vscode-uri: 3.1.0 + js-beautify: 1.15.4 + vue-component-type-helpers: 2.2.10 - '@vscode/emmet-helper@2.11.0': + '@vue/tsconfig@0.7.0(typescript@5.8.3)(vue@3.5.16(typescript@5.8.3))': + optionalDependencies: + typescript: 5.8.3 + vue: 3.5.16(typescript@5.8.3) + + '@vueuse/core@12.8.2(typescript@5.8.3)': dependencies: - emmet: 2.4.11 - jsonc-parser: 2.3.1 - vscode-languageserver-textdocument: 1.0.12 - vscode-languageserver-types: 3.17.5 - vscode-uri: 3.1.0 + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 12.8.2 + '@vueuse/shared': 12.8.2(typescript@5.8.3) + vue: 3.5.16(typescript@5.8.3) + transitivePeerDependencies: + - typescript - '@vscode/l10n@0.0.18': {} + '@vueuse/core@13.3.0(vue@3.5.16(typescript@5.8.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 13.3.0 + '@vueuse/shared': 13.3.0(vue@3.5.16(typescript@5.8.3)) + vue: 3.5.16(typescript@5.8.3) + + '@vueuse/metadata@12.8.2': {} - '@vue/reactivity@3.5.13': + '@vueuse/metadata@13.3.0': {} + + '@vueuse/shared@12.8.2(typescript@5.8.3)': + dependencies: + vue: 3.5.16(typescript@5.8.3) + transitivePeerDependencies: + - typescript + + '@vueuse/shared@13.3.0(vue@3.5.16(typescript@5.8.3))': dependencies: - '@vue/shared': 3.5.13 + vue: 3.5.16(typescript@5.8.3) - '@vue/shared@3.5.13': {} + abbrev@2.0.0: {} abbrev@3.0.1: {} @@ -6249,6 +8762,8 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + alien-signals@1.0.13: {} + ansi-align@3.0.1: dependencies: string-width: 4.2.3 @@ -6276,6 +8791,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.3.2: {} array-iterate@2.0.1: {} @@ -6284,12 +8803,12 @@ snapshots: astring@1.9.0: {} - astro-expressive-code@0.40.2(astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)): + astro-expressive-code@0.40.2(astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1)): dependencies: - astro: 5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1) rehype-expressive-code: 0.40.2 - astro@5.6.1(@types/node@20.17.30)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1): + astro@5.6.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.39.0)(tsx@4.19.3)(typescript@5.8.3)(yaml@2.7.1): dependencies: '@astrojs/compiler': 2.11.0 '@astrojs/internal-helpers': 0.6.1 @@ -6340,8 +8859,8 @@ snapshots: unist-util-visit: 5.0.0 unstorage: 1.15.0 vfile: 6.0.3 - vite: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) - vitefu: 1.0.6(vite@6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1)) + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) + vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.1 @@ -6415,6 +8934,8 @@ snapshots: before-after-hook@3.0.2: {} + birpc@2.3.0: {} + boolbase@1.0.0: {} bottleneck@2.19.5: {} @@ -6452,6 +8973,10 @@ snapshots: buffer-from@1.1.2: {} + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + cac@6.7.14: {} cacache@19.0.1: @@ -6514,6 +9039,10 @@ snapshots: ci-info@4.2.0: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + cli-boxes@3.0.0: {} cli-table3@0.6.5: @@ -6550,6 +9079,8 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@10.0.1: {} + common-ancestor-path@1.0.1: {} concat-map@0.0.1: {} @@ -6564,12 +9095,21 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + convert-source-map@2.0.0: {} cookie-es@1.2.2: {} cookie@1.0.2: {} + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + core-js@3.41.0: {} cross-spawn@7.0.6: @@ -6586,10 +9126,26 @@ snapshots: cssesc@3.0.0: {} + cssstyle@4.3.1: + dependencies: + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 + + csstype@3.1.3: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + + de-indent@1.0.2: {} + debug@4.4.0: dependencies: ms: 2.1.3 + decimal.js@10.5.0: {} + decode-named-character-reference@1.1.0: dependencies: character-entities: 2.0.2 @@ -6600,6 +9156,15 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-lazy-prop@3.0.0: {} + defu@6.1.4: {} deprecation@2.3.1: {} @@ -6610,6 +9175,8 @@ snapshots: detect-libc@2.0.3: {} + detect-libc@2.0.4: {} + deterministic-object-hash@2.0.2: dependencies: base-64: 1.0.0 @@ -6630,6 +9197,13 @@ snapshots: eastasianwidth@0.2.0: {} + editorconfig@1.0.4: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.1 + semver: 7.7.1 + electron-to-chromium@1.5.136: {} emmet@2.4.11: @@ -6650,12 +9224,19 @@ snapshots: iconv-lite: 0.6.3 optional: true + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.2 + entities@4.5.0: {} env-paths@2.2.1: {} err-code@2.0.3: {} + error-stack-parser-es@0.1.5: {} + es-module-lexer@1.6.0: {} esast-util-from-estree@2.0.0: @@ -6672,6 +9253,32 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.2 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.2: optionalDependencies: '@esbuild/aix-ppc64': 0.25.2 @@ -6706,6 +9313,14 @@ snapshots: escape-string-regexp@5.0.0: {} + eslint-plugin-react-hooks@5.2.0(eslint@9.27.0(jiti@2.4.2)): + dependencies: + eslint: 9.27.0(jiti@2.4.2) + + eslint-plugin-react-refresh@0.4.20(eslint@9.27.0(jiti@2.4.2)): + dependencies: + eslint: 9.27.0(jiti@2.4.2) + eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 @@ -6715,9 +9330,9 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.24.0: + eslint@9.24.0(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.20.0 '@eslint/config-helpers': 0.2.1 @@ -6752,6 +9367,50 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + eslint@9.27.0(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.27.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.1 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.27.0 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + 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.4 + optionalDependencies: + jiti: 2.4.2 transitivePeerDependencies: - supports-color @@ -6810,6 +9469,21 @@ snapshots: eventemitter3@5.0.1: {} + execa@9.6.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.2.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + expect-type@1.2.1: {} exponential-backoff@3.1.2: {} @@ -6849,6 +9523,14 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fdir@6.4.5(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -6901,6 +9583,11 @@ snapshots: get-east-asian-width@1.3.0: {} + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-tsconfig@4.10.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -6937,6 +9624,8 @@ snapshots: globals@14.0.0: {} + globals@16.2.0: {} + globby@14.1.0: dependencies: '@sindresorhus/merge-streams': 2.3.0 @@ -7157,10 +9846,18 @@ snapshots: property-information: 7.0.0 space-separated-tokens: 2.0.2 + he@1.2.0: {} + + hookable@5.5.3: {} + hosted-git-info@8.0.2: dependencies: lru-cache: 10.4.3 + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + html-entities@2.6.0: {} html-escaper@3.0.3: {} @@ -7185,6 +9882,8 @@ snapshots: transitivePeerDependencies: - supports-color + human-signals@8.0.1: {} + i18next@23.16.8: dependencies: '@babel/runtime': 7.27.0 @@ -7192,7 +9891,6 @@ snapshots: iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - optional: true ignore-walk@7.0.0: dependencies: @@ -7215,6 +9913,8 @@ snapshots: indent-string@5.0.0: {} + ini@1.3.8: {} + ini@5.0.0: {} inline-style-parser@0.2.4: {} @@ -7263,8 +9963,14 @@ snapshots: is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} + + is-stream@4.0.1: {} + is-unicode-supported@2.1.0: {} + is-what@4.1.16: {} + is-wsl@3.1.0: dependencies: is-inside-container: 1.0.0 @@ -7283,8 +9989,20 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 + jiti@2.4.2: {} + jju@1.4.0: {} + js-beautify@1.15.4: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.4 + glob: 10.4.5 + js-cookie: 3.0.5 + nopt: 7.2.1 + + js-cookie@3.0.5: {} + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -7293,6 +10011,33 @@ snapshots: jsbn@1.1.0: {} + jsdom@26.1.0: + dependencies: + cssstyle: 4.3.1 + data-urls: 5.0.0 + decimal.js: 10.5.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.20 + parse5: 7.2.1 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.18.2 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -7329,11 +10074,58 @@ snapshots: klona@2.0.6: {} + kolorist@1.8.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 @@ -7350,6 +10142,10 @@ snapshots: longest-streak@3.1.0: {} + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + loupe@3.1.3: {} lru-cache@10.4.3: {} @@ -7364,6 +10160,14 @@ snapshots: dependencies: yallist: 4.0.0 + lucide-react@0.511.0(react@19.1.0): + dependencies: + react: 19.1.0 + + lucide-vue-next@0.511.0(vue@3.5.16(typescript@5.8.3)): + dependencies: + vue: 3.5.16(typescript@5.8.3) + lunr@2.3.9: {} magic-string@0.30.17: @@ -7590,6 +10394,8 @@ snapshots: mdurl@2.0.0: {} + memorystream@0.3.1: {} + merge2@1.4.1: {} micromark-core-commonmark@2.0.3: @@ -7885,6 +10691,10 @@ snapshots: dependencies: brace-expansion: 1.1.11 + minimatch@9.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -7930,6 +10740,8 @@ snapshots: dependencies: minipass: 7.1.2 + mitt@3.0.1: {} + mkdirp@1.0.4: {} mkdirp@3.0.1: {} @@ -7942,6 +10754,8 @@ snapshots: nanoid@3.3.11: {} + nanoid@5.1.5: {} + natural-compare@1.4.0: {} negotiator@1.0.0: {} @@ -7973,6 +10787,10 @@ snapshots: node-releases@2.0.19: {} + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + nopt@8.1.0: dependencies: abbrev: 3.0.1 @@ -8020,10 +10838,28 @@ snapshots: transitivePeerDependencies: - supports-color + npm-run-all2@7.0.2: + dependencies: + ansi-styles: 6.2.1 + cross-spawn: 7.0.6 + memorystream: 0.3.1 + minimatch: 9.0.5 + pidtree: 0.6.0 + read-package-json-fast: 4.0.0 + shell-quote: 1.8.2 + which: 5.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 + nwsapi@2.2.20: {} + octokit@4.1.3: dependencies: '@octokit/app': 15.1.6 @@ -8043,6 +10879,8 @@ snapshots: node-fetch-native: 1.6.6 ufo: 1.6.1 + ohash@2.0.11: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -8062,6 +10900,13 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 + open@10.1.2: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -8149,6 +10994,8 @@ snapshots: unist-util-visit-children: 3.0.0 vfile: 6.0.3 + parse-ms@4.0.0: {} + parse5@7.2.1: dependencies: entities: 4.5.0 @@ -8159,6 +11006,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -8177,12 +11026,16 @@ snapshots: pathval@2.0.0: {} + perfect-debounce@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.2: {} + pidtree@0.6.0: {} + pluralize@8.0.0: {} postcss-nested@6.2.0(postcss@8.5.3): @@ -8203,10 +11056,12 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-organize-imports@4.1.0(prettier@3.5.3)(typescript@5.8.3): + prettier-plugin-organize-imports@4.1.0(prettier@3.5.3)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3)): dependencies: prettier: 3.5.3 typescript: 5.8.3 + optionalDependencies: + vue-tsc: 2.2.10(typescript@5.8.3) prettier@2.8.7: optional: true @@ -8215,6 +11070,10 @@ snapshots: prettier@3.5.3: {} + pretty-ms@9.2.0: + dependencies: + parse-ms: 4.0.0 + prismjs@1.30.0: {} proc-log@5.0.0: {} @@ -8233,6 +11092,8 @@ snapshots: property-information@7.0.0: {} + proto-list@1.2.4: {} + punycode.js@2.3.1: {} punycode@2.3.1: {} @@ -8241,6 +11102,30 @@ snapshots: radix3@1.1.2: {} + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-refresh@0.17.0: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + react@19.1.0: {} + + read-package-json-fast@4.0.0: + dependencies: + json-parse-even-better-errors: 4.0.0 + npm-normalize-package-bin: 4.0.0 + readdirp@4.1.2: {} recma-build-jsx@1.0.0: @@ -8341,6 +11226,23 @@ snapshots: rehype-stringify: 10.0.1 unified: 11.0.5 + reka-ui@2.3.0(typescript@5.8.3)(vue@3.5.16(typescript@5.8.3)): + dependencies: + '@floating-ui/dom': 1.7.0 + '@floating-ui/vue': 1.1.6(vue@3.5.16(typescript@5.8.3)) + '@internationalized/date': 3.8.1 + '@internationalized/number': 3.6.2 + '@tanstack/vue-virtual': 3.13.9(vue@3.5.16(typescript@5.8.3)) + '@vueuse/core': 12.8.2(typescript@5.8.3) + '@vueuse/shared': 12.8.2(typescript@5.8.3) + aria-hidden: 1.2.6 + defu: 6.1.4 + ohash: 2.0.11 + vue: 3.5.16(typescript@5.8.3) + transitivePeerDependencies: + - '@vue/composition-api' + - typescript + remark-directive@3.0.1: dependencies: '@types/mdast': 4.0.4 @@ -8445,6 +11347,8 @@ snapshots: reusify@1.1.0: {} + rfdc@1.4.1: {} + rimraf@6.0.1: dependencies: glob: 11.0.1 @@ -8476,6 +11380,10 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.39.0 fsevents: 2.3.3 + rrweb-cssom@0.8.0: {} + + run-applescript@7.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -8484,11 +11392,20 @@ snapshots: dependencies: tslib: 2.8.1 - safer-buffer@2.1.2: - optional: true + safer-buffer@2.1.2: {} sax@1.4.1: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + scheduler@0.26.0: {} + semver@6.3.1: {} semver@7.5.4: @@ -8600,6 +11517,12 @@ snapshots: dependencies: is-arrayish: 0.3.2 + sirv@3.0.1: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + sisteransi@1.0.5: {} sitemap@8.0.0: @@ -8655,6 +11578,8 @@ snapshots: spdx-license-ids@3.0.21: {} + speakingurl@14.0.1: {} + sprintf-js@1.0.3: {} sprintf-js@1.1.3: {} @@ -8702,6 +11627,8 @@ snapshots: dependencies: ansi-regex: 6.1.0 + strip-final-newline@4.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -8720,6 +11647,10 @@ snapshots: dependencies: inline-style-parser: 0.2.4 + superjson@2.2.2: + dependencies: + copy-anything: 3.0.5 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -8730,6 +11661,14 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + symbol-tree@3.2.4: {} + + tailwind-merge@3.3.0: {} + + tailwindcss@4.1.8: {} + + tapable@2.2.2: {} + tar@6.2.1: dependencies: chownr: 2.0.0 @@ -8757,18 +11696,39 @@ snapshots: fdir: 6.4.3(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.5(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@1.0.2: {} tinyrainbow@2.0.0: {} tinyspy@3.0.2: {} + tldts-core@6.1.86: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toad-cache@3.7.0: {} + totalist@3.0.1: {} + + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.86 + + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -8792,6 +11752,13 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tsx@4.19.4: + dependencies: + esbuild: 0.25.2 + get-tsconfig: 4.10.0 + optionalDependencies: + fsevents: 2.3.3 + tuf-js@3.0.1: dependencies: '@tufjs/models': 3.0.1 @@ -8802,6 +11769,8 @@ snapshots: tunnel@0.0.6: {} + tw-animate-css@1.3.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -8823,12 +11792,22 @@ snapshots: dependencies: semver: 7.7.1 - typescript-eslint@8.29.1(eslint@9.24.0)(typescript@5.8.3): + typescript-eslint@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.24.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + typescript-eslint@8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3) - '@typescript-eslint/parser': 8.29.1(eslint@9.24.0)(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0)(typescript@5.8.3) - eslint: 9.24.0 + '@typescript-eslint/eslint-plugin': 8.33.0(@typescript-eslint/parser@8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.0(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.27.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -8847,6 +11826,8 @@ snapshots: undici-types@6.19.8: {} + undici-types@6.21.0: {} + undici@5.29.0: dependencies: '@fastify/busboy': 2.1.1 @@ -8972,13 +11953,59 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-node@3.1.1(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1): + vite-hot-client@2.0.4(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)): + dependencies: + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + + vite-node@3.1.1(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 2.0.3 + vite: 6.3.5(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-node@3.1.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 2.0.3 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-node@3.1.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) transitivePeerDependencies: - '@types/node' - jiti @@ -8993,25 +12020,170 @@ snapshots: - tsx - yaml - vite@6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1): + vite-plugin-inspect@0.8.9(rollup@4.39.0)(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.4(rollup@4.39.0) + debug: 4.4.0 + error-stack-parser-es: 0.1.5 + fs-extra: 11.3.0 + open: 10.1.2 + perfect-debounce: 1.0.0 + picocolors: 1.1.1 + sirv: 3.0.1 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + transitivePeerDependencies: + - rollup + - supports-color + + vite-plugin-singlefile@2.2.0(rollup@4.39.0)(vite@5.4.19(@types/node@22.15.24)(lightningcss@1.30.1)): + dependencies: + micromatch: 4.0.8 + rollup: 4.39.0 + vite: 5.4.19(@types/node@22.15.24)(lightningcss@1.30.1) + + vite-plugin-singlefile@2.2.0(rollup@4.39.0)(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)): + dependencies: + micromatch: 4.0.8 + rollup: 4.39.0 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + + vite-plugin-vue-devtools@7.7.6(rollup@4.39.0)(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))(vue@3.5.16(typescript@5.8.3)): + dependencies: + '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1))(vue@3.5.16(typescript@5.8.3)) + '@vue/devtools-kit': 7.7.6 + '@vue/devtools-shared': 7.7.6 + execa: 9.6.0 + sirv: 3.0.1 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + vite-plugin-inspect: 0.8.9(rollup@4.39.0)(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + vite-plugin-vue-inspector: 5.3.1(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + transitivePeerDependencies: + - '@nuxt/kit' + - rollup + - supports-color + - vue + + vite-plugin-vue-inspector@5.3.1(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)): + dependencies: + '@babel/core': 7.26.10 + '@babel/plugin-proposal-decorators': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.10) + '@babel/plugin-transform-typescript': 7.27.0(@babel/core@7.26.10) + '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.26.10) + '@vue/compiler-dom': 3.5.16 + kolorist: 1.8.0 + magic-string: 0.30.17 + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + transitivePeerDependencies: + - supports-color + + vite@5.4.19(@types/node@22.15.24)(lightningcss@1.30.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 22.15.24 + fsevents: 2.3.3 + lightningcss: 1.30.1 + + vite@6.2.6(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): + dependencies: + esbuild: 0.25.2 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 20.17.30 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.4 + yaml: 2.7.1 + + vite@6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1): + dependencies: + esbuild: 0.25.2 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 22.15.24 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.3 + yaml: 2.7.1 + + vite@6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): + dependencies: + esbuild: 0.25.2 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 22.15.24 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.4 + yaml: 2.7.1 + + vite@6.3.5(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): dependencies: esbuild: 0.25.2 + fdir: 6.4.5(picomatch@4.0.2) + picomatch: 4.0.2 postcss: 8.5.3 rollup: 4.39.0 + tinyglobby: 0.2.14 optionalDependencies: '@types/node': 20.17.30 fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.4 + yaml: 2.7.1 + + vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1): + dependencies: + esbuild: 0.25.2 + fdir: 6.4.5(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.3 + rollup: 4.39.0 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 22.15.24 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 tsx: 4.19.3 yaml: 2.7.1 - vitefu@1.0.6(vite@6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1)): + vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): + dependencies: + esbuild: 0.25.2 + fdir: 6.4.5(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.3 + rollup: 4.39.0 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 22.15.24 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.4 + yaml: 2.7.1 + + vitefu@1.0.6(vite@6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1)): optionalDependencies: - vite: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) - vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1): + vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): dependencies: '@vitest/expect': 3.1.1 - '@vitest/mocker': 3.1.1(vite@6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1)) + '@vitest/mocker': 3.1.1(vite@6.2.6(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) '@vitest/pretty-format': 3.1.1 '@vitest/runner': 3.1.1 '@vitest/snapshot': 3.1.1 @@ -9027,12 +12199,93 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.6(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) - vite-node: 3.1.1(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + vite: 6.2.6(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + vite-node: 3.1.1(@types/node@20.17.30)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 '@types/node': 20.17.30 + jsdom: 26.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1): + dependencies: + '@vitest/expect': 3.1.1 + '@vitest/mocker': 3.1.1(vite@6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1)) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.1.1 + '@vitest/snapshot': 3.1.1 + '@vitest/spy': 3.1.1 + '@vitest/utils': 3.1.1 + chai: 5.2.0 + debug: 4.4.0 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) + vite-node: 3.1.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.3)(yaml@2.7.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 22.15.24 + jsdom: 26.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.24)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1): + dependencies: + '@vitest/expect': 3.1.1 + '@vitest/mocker': 3.1.1(vite@6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1)) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.1.1 + '@vitest/snapshot': 3.1.1 + '@vitest/spy': 3.1.1 + '@vitest/utils': 3.1.1 + chai: 5.2.0 + debug: 4.4.0 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 6.2.6(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + vite-node: 3.1.1(@types/node@22.15.24)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.7.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 22.15.24 + jsdom: 26.1.0 transitivePeerDependencies: - jiti - less @@ -9157,8 +12410,47 @@ snapshots: vscode-uri@3.1.0: {} + vue-component-type-helpers@2.2.10: {} + + vue-demi@0.14.10(vue@3.5.16(typescript@5.8.3)): + dependencies: + vue: 3.5.16(typescript@5.8.3) + + vue-tsc@2.2.10(typescript@5.8.3): + dependencies: + '@volar/typescript': 2.4.12 + '@vue/language-core': 2.2.10(typescript@5.8.3) + typescript: 5.8.3 + + vue@3.5.16(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.5.16 + '@vue/compiler-sfc': 3.5.16 + '@vue/runtime-dom': 3.5.16 + '@vue/server-renderer': 3.5.16(vue@3.5.16(typescript@5.8.3)) + '@vue/shared': 3.5.16 + optionalDependencies: + typescript: 5.8.3 + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + web-namespaces@2.0.1: {} + webidl-conversions@7.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + which-pm-runs@1.1.0: {} which@2.0.2: @@ -9200,6 +12492,12 @@ snapshots: wrappy@1.0.2: {} + ws@8.18.2: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + xxhash-wasm@1.1.0: {} y18n@5.0.8: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0c0809100..e9e5601d7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -20,7 +20,7 @@ catalog: "@types/babel__traverse": ^7.20.7 "@types/node": ^20.14.12 "@vitest/eslint-plugin": ^1.1.42 - "@vue/reactivity": ^3.5.13 + "@vue/reactivity": ^3.5.16 babel-plugin-tester: ^11.0.4 change-case: ^5.4.4 cli-table3: ^0.6.5