From 0124d6efb40e41c6380f1a4a8a79d208565990c3 Mon Sep 17 00:00:00 2001 From: Tien Pham Date: Mon, 19 Jan 2026 20:38:10 +0200 Subject: [PATCH 1/3] feat(svelte): create Svelte framework integration --- crates/bindings-typescript/package.json | 11 + .../src/svelte/SpacetimeDBProvider.ts | 101 +++++ .../src/svelte/connection_state.ts | 16 + .../bindings-typescript/src/svelte/index.ts | 4 + .../src/svelte/useReducer.ts | 56 +++ .../src/svelte/useSpacetimeDB.ts | 22 + .../src/svelte/useTable.ts | 375 ++++++++++++++++++ crates/bindings-typescript/tsup.config.ts | 32 ++ .../00200-quickstarts/00160-svelte.md | 127 ++++++ pnpm-lock.yaml | 235 +++++++++++ pnpm-workspace.yaml | 1 + templates/svelte-ts/.template.json | 5 + templates/svelte-ts/LICENSE | 1 + templates/svelte-ts/index.html | 12 + templates/svelte-ts/package.json | 25 ++ templates/svelte-ts/spacetimedb/package.json | 15 + templates/svelte-ts/spacetimedb/src/index.ts | 33 ++ templates/svelte-ts/spacetimedb/tsconfig.json | 23 ++ templates/svelte-ts/src/App.svelte | 63 +++ templates/svelte-ts/src/Root.svelte | 37 ++ templates/svelte-ts/src/main.ts | 6 + .../src/module_bindings/add_reducer.ts | 15 + .../svelte-ts/src/module_bindings/add_type.ts | 15 + .../svelte-ts/src/module_bindings/index.ts | 145 +++++++ .../src/module_bindings/init_type.ts | 13 + .../src/module_bindings/on_connect_reducer.ts | 13 + .../src/module_bindings/on_connect_type.ts | 13 + .../module_bindings/on_disconnect_reducer.ts | 13 + .../src/module_bindings/on_disconnect_type.ts | 13 + .../src/module_bindings/person_table.ts | 15 + .../src/module_bindings/person_type.ts | 15 + .../src/module_bindings/say_hello_reducer.ts | 13 + .../src/module_bindings/say_hello_type.ts | 13 + templates/svelte-ts/svelte.config.js | 5 + templates/svelte-ts/tsconfig.json | 23 ++ templates/svelte-ts/vite.config.ts | 7 + templates/templates-list.json | 11 +- 37 files changed, 1541 insertions(+), 1 deletion(-) create mode 100644 crates/bindings-typescript/src/svelte/SpacetimeDBProvider.ts create mode 100644 crates/bindings-typescript/src/svelte/connection_state.ts create mode 100644 crates/bindings-typescript/src/svelte/index.ts create mode 100644 crates/bindings-typescript/src/svelte/useReducer.ts create mode 100644 crates/bindings-typescript/src/svelte/useSpacetimeDB.ts create mode 100644 crates/bindings-typescript/src/svelte/useTable.ts create mode 100644 docs/docs/00100-intro/00200-quickstarts/00160-svelte.md create mode 100644 templates/svelte-ts/.template.json create mode 120000 templates/svelte-ts/LICENSE create mode 100644 templates/svelte-ts/index.html create mode 100644 templates/svelte-ts/package.json create mode 100644 templates/svelte-ts/spacetimedb/package.json create mode 100644 templates/svelte-ts/spacetimedb/src/index.ts create mode 100644 templates/svelte-ts/spacetimedb/tsconfig.json create mode 100644 templates/svelte-ts/src/App.svelte create mode 100644 templates/svelte-ts/src/Root.svelte create mode 100644 templates/svelte-ts/src/main.ts create mode 100644 templates/svelte-ts/src/module_bindings/add_reducer.ts create mode 100644 templates/svelte-ts/src/module_bindings/add_type.ts create mode 100644 templates/svelte-ts/src/module_bindings/index.ts create mode 100644 templates/svelte-ts/src/module_bindings/init_type.ts create mode 100644 templates/svelte-ts/src/module_bindings/on_connect_reducer.ts create mode 100644 templates/svelte-ts/src/module_bindings/on_connect_type.ts create mode 100644 templates/svelte-ts/src/module_bindings/on_disconnect_reducer.ts create mode 100644 templates/svelte-ts/src/module_bindings/on_disconnect_type.ts create mode 100644 templates/svelte-ts/src/module_bindings/person_table.ts create mode 100644 templates/svelte-ts/src/module_bindings/person_type.ts create mode 100644 templates/svelte-ts/src/module_bindings/say_hello_reducer.ts create mode 100644 templates/svelte-ts/src/module_bindings/say_hello_type.ts create mode 100644 templates/svelte-ts/svelte.config.js create mode 100644 templates/svelte-ts/tsconfig.json create mode 100644 templates/svelte-ts/vite.config.ts diff --git a/crates/bindings-typescript/package.json b/crates/bindings-typescript/package.json index 7b83e8e1c4f..c50b875fa13 100644 --- a/crates/bindings-typescript/package.json +++ b/crates/bindings-typescript/package.json @@ -71,6 +71,12 @@ "import": "./dist/server/index.mjs", "require": "./dist/server/index.cjs", "default": "./dist/server/index.mjs" + }, + "./svelte": { + "types": "./dist/svelte/index.d.ts", + "import": "./dist/svelte/index.mjs", + "require": "./dist/svelte/index.cjs", + "default": "./dist/svelte/index.mjs" } }, "size-limit": [ @@ -161,18 +167,23 @@ }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0", + "svelte": "^4.0.0 || ^5.0.0", "undici": "^6.19.2" }, "peerDependenciesMeta": { "react": { "optional": true }, + "svelte": { + "optional": true + }, "undici": { "optional": true } }, "devDependencies": { "@eslint/js": "^9.17.0", + "svelte": "^5.0.0", "@size-limit/file": "^11.2.0", "@types/fast-text-encoding": "^1.0.3", "@types/react": "^19.1.13", diff --git a/crates/bindings-typescript/src/svelte/SpacetimeDBProvider.ts b/crates/bindings-typescript/src/svelte/SpacetimeDBProvider.ts new file mode 100644 index 00000000000..d4e4bd1a82a --- /dev/null +++ b/crates/bindings-typescript/src/svelte/SpacetimeDBProvider.ts @@ -0,0 +1,101 @@ +import { setContext, onDestroy } from 'svelte'; +import { writable, type Writable } from 'svelte/store'; +import { + DbConnectionBuilder, + type DbConnectionImpl, + type ErrorContextInterface, + type RemoteModuleOf, +} from '../sdk/db_connection_impl'; +import { ConnectionId } from '../lib/connection_id'; +import { + SPACETIMEDB_CONTEXT_KEY, + type ConnectionState, +} from './connection_state'; + +let connRef: DbConnectionImpl | null = null; +let cleanupTimeoutId: ReturnType | null = null; + +export function createSpacetimeDBProvider< + DbConnection extends DbConnectionImpl, +>( + connectionBuilder: DbConnectionBuilder +): Writable { + const getConnection = () => connRef as DbConnection | null; + + const store = writable({ + isActive: false, + identity: undefined, + token: undefined, + connectionId: ConnectionId.random(), + connectionError: undefined, + getConnection: getConnection as ConnectionState['getConnection'], + }); + + if (cleanupTimeoutId) { + clearTimeout(cleanupTimeoutId); + cleanupTimeoutId = null; + } + + if (!connRef) { + connRef = connectionBuilder.build(); + } + + const onConnect = (conn: DbConnection) => { + store.update(s => ({ + ...s, + isActive: conn.isActive, + identity: conn.identity, + token: conn.token, + connectionId: conn.connectionId, + })); + }; + + const onDisconnect = ( + ctx: ErrorContextInterface> + ) => { + store.update(s => ({ + ...s, + isActive: ctx.isActive, + })); + }; + + const onConnectError = ( + ctx: ErrorContextInterface>, + err: Error + ) => { + store.update(s => ({ + ...s, + isActive: ctx.isActive, + connectionError: err, + })); + }; + + connectionBuilder.onConnect(onConnect); + connectionBuilder.onDisconnect(onDisconnect); + connectionBuilder.onConnectError(onConnectError); + + const conn = connRef; + store.update(s => ({ + ...s, + isActive: conn.isActive, + identity: conn.identity, + token: conn.token, + connectionId: conn.connectionId, + })); + + setContext(SPACETIMEDB_CONTEXT_KEY, store); + + onDestroy(() => { + connRef?.removeOnConnect(onConnect as any); + connRef?.removeOnDisconnect(onDisconnect as any); + connRef?.removeOnConnectError(onConnectError as any); + + cleanupTimeoutId = setTimeout(() => { + connRef?.disconnect(); + connRef = null; + cleanupTimeoutId = null; + }, 0); + }); + + return store; +} diff --git a/crates/bindings-typescript/src/svelte/connection_state.ts b/crates/bindings-typescript/src/svelte/connection_state.ts new file mode 100644 index 00000000000..bfd2098d929 --- /dev/null +++ b/crates/bindings-typescript/src/svelte/connection_state.ts @@ -0,0 +1,16 @@ +import type { ConnectionId } from '../lib/connection_id'; +import type { Identity } from '../lib/identity'; +import type { DbConnectionImpl } from '../sdk/db_connection_impl'; + +export type ConnectionState = { + isActive: boolean; + identity?: Identity; + token?: string; + connectionId: ConnectionId; + connectionError?: Error; + getConnection< + DbConnection extends DbConnectionImpl, + >(): DbConnection | null; +}; + +export const SPACETIMEDB_CONTEXT_KEY = Symbol('spacetimedb'); diff --git a/crates/bindings-typescript/src/svelte/index.ts b/crates/bindings-typescript/src/svelte/index.ts new file mode 100644 index 00000000000..6bcf01a6a28 --- /dev/null +++ b/crates/bindings-typescript/src/svelte/index.ts @@ -0,0 +1,4 @@ +export * from './SpacetimeDBProvider.ts'; +export { useSpacetimeDB } from './useSpacetimeDB.ts'; +export { useTable, where, eq } from './useTable.ts'; +export { useReducer } from './useReducer.ts'; diff --git a/crates/bindings-typescript/src/svelte/useReducer.ts b/crates/bindings-typescript/src/svelte/useReducer.ts new file mode 100644 index 00000000000..a25c576e123 --- /dev/null +++ b/crates/bindings-typescript/src/svelte/useReducer.ts @@ -0,0 +1,56 @@ +import { onDestroy } from 'svelte'; +import { get } from 'svelte/store'; +import type { InferTypeOfRow } from '../lib/type_builders'; +import type { UntypedReducerDef } from '../sdk/reducers'; +import { useSpacetimeDB } from './useSpacetimeDB'; +import type { Prettify } from '../lib/type_util'; + +type IsEmptyObject = [keyof T] extends [never] ? true : false; +type MaybeParams = IsEmptyObject extends true ? [] : [params: T]; + +type ParamsType = MaybeParams< + Prettify> +>; + +export function useReducer( + reducerDef: ReducerDef +): (...params: ParamsType) => void { + const connectionStore = useSpacetimeDB(); + const reducerName = reducerDef.accessorName; + + // Holds calls made before the connection exists + const queueRef: ParamsType[] = []; + + // Flush when we finally have a connection + const unsubscribe = connectionStore.subscribe(state => { + const conn = state.getConnection(); + if (!conn) return; + + const fn = (conn.reducers as any)[reducerName] as ( + ...p: ParamsType + ) => void; + if (queueRef.length) { + const pending = queueRef.splice(0); + for (const params of pending) { + fn(...params); + } + } + }); + + onDestroy(() => { + unsubscribe(); + }); + + return (...params: ParamsType) => { + const state = get(connectionStore); + const conn = state.getConnection(); + if (!conn) { + queueRef.push(params); + return; + } + const fn = (conn.reducers as any)[reducerName] as ( + ...p: ParamsType + ) => void; + return fn(...params); + }; +} diff --git a/crates/bindings-typescript/src/svelte/useSpacetimeDB.ts b/crates/bindings-typescript/src/svelte/useSpacetimeDB.ts new file mode 100644 index 00000000000..899c23c4f5f --- /dev/null +++ b/crates/bindings-typescript/src/svelte/useSpacetimeDB.ts @@ -0,0 +1,22 @@ +import { getContext } from 'svelte'; +import type { Writable } from 'svelte/store'; +import { + SPACETIMEDB_CONTEXT_KEY, + type ConnectionState, +} from './connection_state'; + +// Throws an error if used outside of a SpacetimeDBProvider +export function useSpacetimeDB(): Writable { + const context = getContext | undefined>( + SPACETIMEDB_CONTEXT_KEY + ); + + if (!context) { + throw new Error( + 'useSpacetimeDB must be used within a component that called createSpacetimeDBProvider. ' + + 'Did you forget to call `createSpacetimeDBProvider` in a parent component?' + ); + } + + return context; +} diff --git a/crates/bindings-typescript/src/svelte/useTable.ts b/crates/bindings-typescript/src/svelte/useTable.ts new file mode 100644 index 00000000000..fb21cc005ba --- /dev/null +++ b/crates/bindings-typescript/src/svelte/useTable.ts @@ -0,0 +1,375 @@ +import { onDestroy } from 'svelte'; +import { writable, get, type Readable } from 'svelte/store'; +import { useSpacetimeDB } from './useSpacetimeDB'; +import type { EventContextInterface } from '../sdk/db_connection_impl'; +import type { UntypedRemoteModule } from '../sdk/spacetime_module'; +import type { RowType, UntypedTableDef } from '../lib/table'; +import type { Prettify } from '../lib/type_util'; + +export interface UseTableCallbacks { + onInsert?: (row: RowType) => void; + onDelete?: (row: RowType) => void; + onUpdate?: (oldRow: RowType, newRow: RowType) => void; +} + +export type Value = string | number | boolean; + +export type Expr = + | { type: 'eq'; key: Column; value: Value } + | { type: 'and'; children: Expr[] } + | { type: 'or'; children: Expr[] }; + +export const eq = ( + key: Column, + value: Value +): Expr => ({ type: 'eq', key, value }); + +export const and = ( + ...children: Expr[] +): Expr => { + const flat: Expr[] = []; + for (const c of children) { + if (!c) continue; + if (c.type === 'and') flat.push(...c.children); + else flat.push(c); + } + const pruned = flat.filter(Boolean); + if (pruned.length === 0) return { type: 'and', children: [] }; + if (pruned.length === 1) return pruned[0]; + return { type: 'and', children: pruned }; +}; + +export const or = ( + ...children: Expr[] +): Expr => { + const flat: Expr[] = []; + for (const c of children) { + if (!c) continue; + if (c.type === 'or') flat.push(...c.children); + else flat.push(c); + } + const pruned = flat.filter(Boolean); + if (pruned.length === 0) return { type: 'or', children: [] }; + if (pruned.length === 1) return pruned[0]; + return { type: 'or', children: pruned }; +}; + +export const isEq = ( + e: Expr +): e is Extract, { type: 'eq' }> => e.type === 'eq'; +export const isAnd = ( + e: Expr +): e is Extract, { type: 'and' }> => e.type === 'and'; +export const isOr = ( + e: Expr +): e is Extract, { type: 'or' }> => e.type === 'or'; + +export function evaluate( + expr: Expr, + row: Record +): boolean { + switch (expr.type) { + case 'eq': { + const v = row[expr.key]; + if ( + typeof v === 'string' || + typeof v === 'number' || + typeof v === 'boolean' + ) { + return v === expr.value; + } + return false; + } + case 'and': + return ( + expr.children.length === 0 || expr.children.every(c => evaluate(c, row)) + ); + case 'or': + return ( + expr.children.length !== 0 && expr.children.some(c => evaluate(c, row)) + ); + } +} + +function formatValue(v: Value): string { + switch (typeof v) { + case 'string': + return `'${v.replace(/'/g, "''")}'`; + case 'number': + return Number.isFinite(v) ? String(v) : `'${String(v)}'`; + case 'boolean': + return v ? 'TRUE' : 'FALSE'; + } +} + +function escapeIdent(id: string): string { + if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(id)) return id; + return `"${id.replace(/"/g, '""')}"`; +} + +function parenthesize(s: string): string { + if (!s.includes(' AND ') && !s.includes(' OR ')) return s; + return `(${s})`; +} + +/** + * Extracts the column names from a RowType whose values are of type Value. + * Note that this will exclude columns that are of type object, array, etc. + */ +type ColumnsFromRow = { + [K in keyof R]-?: R[K] extends Value | undefined ? K : never; +}[keyof R] & + string; + +export function toString( + tableDef: TableDef, + expr: Expr>> +): string { + switch (expr.type) { + case 'eq': { + const key = tableDef.columns[expr.key].columnMetadata.name ?? expr.key; + return `${escapeIdent(key)} = ${formatValue(expr.value)}`; + } + case 'and': + return parenthesize( + expr.children.map(expr => toString(tableDef, expr)).join(' AND ') + ); + case 'or': + return parenthesize( + expr.children.map(expr => toString(tableDef, expr)).join(' OR ') + ); + } +} + +/** + * This is just the identity function to make things look like SQL. + * @param expr + * @returns + */ +export function where(expr: Expr): Expr { + return expr; +} + +type MembershipChange = 'enter' | 'leave' | 'stayIn' | 'stayOut'; + +function classifyMembership< + Col extends string, + R extends Record, +>(where: Expr | undefined, oldRow: R, newRow: R): MembershipChange { + // No filter: everything is in, so updates are always "stayIn". + if (!where) { + return 'stayIn'; + } + + const oldIn = evaluate(where, oldRow); + const newIn = evaluate(where, newRow); + + if (oldIn && !newIn) { + return 'leave'; + } + if (!oldIn && newIn) { + return 'enter'; + } + if (oldIn && newIn) { + return 'stayIn'; + } + return 'stayOut'; +} + +export function useTable( + tableDef: TableDef, + where: Expr>>, + callbacks?: UseTableCallbacks>> +): [Readable>[]>, Readable]; + +export function useTable( + tableDef: TableDef, + callbacks?: UseTableCallbacks>> +): [Readable>[]>, Readable]; + +export function useTable( + tableDef: TableDef, + whereClauseOrCallbacks?: + | Expr>> + | UseTableCallbacks>, + callbacks?: UseTableCallbacks> +): [Readable>[]>, Readable] { + type Row = RowType; + const tableName = tableDef.name; + const accessorName = tableDef.accessorName; + + let whereClause: Expr> | undefined; + if ( + whereClauseOrCallbacks && + typeof whereClauseOrCallbacks === 'object' && + 'type' in whereClauseOrCallbacks + ) { + whereClause = whereClauseOrCallbacks as Expr>; + } else { + callbacks = whereClauseOrCallbacks as UseTableCallbacks | undefined; + } + + let connectionStore; + try { + connectionStore = useSpacetimeDB(); + } catch { + throw new Error( + 'Could not find SpacetimeDB client! Did you forget to call ' + + '`createSpacetimeDBProvider`? `useTable` must be used in a Svelte component tree ' + + 'under a component that called `createSpacetimeDBProvider`.' + ); + } + + const rows = writable[]>([]); + const isReady = writable(false); + + const query = + `SELECT * FROM ${tableName}` + + (whereClause ? ` WHERE ${toString(tableDef, whereClause)}` : ''); + + let latestTransactionEvent: any = null; + let unsubscribeFromTable: (() => void) | null = null; + let subscriptionHandle: { unsubscribe: () => void } | null = null; + + const computeFilteredRows = (): readonly Prettify[] => { + const state = get(connectionStore); + const connection = state.getConnection(); + if (!connection) return []; + + const table = connection.db[accessorName]; + if (!table) return []; + + const allRows = Array.from(table.iter()) as Row[]; + if (whereClause) { + return allRows.filter(row => + evaluate(whereClause, row as Record) + ) as Prettify[]; + } + return allRows as Prettify[]; + }; + + const setupTableListeners = () => { + const state = get(connectionStore); + const connection = state.getConnection(); + if (!connection) return; + + const table = connection.db[accessorName]; + if (!table) return; + + const onInsert = ( + eventCtx: EventContextInterface, + row: any + ) => { + if (whereClause && !evaluate(whereClause, row)) return; + callbacks?.onInsert?.(row); + + if ( + eventCtx.event !== latestTransactionEvent || + !latestTransactionEvent + ) { + latestTransactionEvent = eventCtx.event; + rows.set(computeFilteredRows()); + } + }; + + const onDelete = ( + eventCtx: EventContextInterface, + row: any + ) => { + if (whereClause && !evaluate(whereClause, row)) return; + callbacks?.onDelete?.(row); + + if ( + eventCtx.event !== latestTransactionEvent || + !latestTransactionEvent + ) { + latestTransactionEvent = eventCtx.event; + rows.set(computeFilteredRows()); + } + }; + + const onUpdate = ( + eventCtx: EventContextInterface, + oldRow: any, + newRow: any + ) => { + const change = classifyMembership(whereClause, oldRow, newRow); + + switch (change) { + case 'leave': + callbacks?.onDelete?.(oldRow); + break; + case 'enter': + callbacks?.onInsert?.(newRow); + break; + case 'stayIn': + callbacks?.onUpdate?.(oldRow, newRow); + break; + case 'stayOut': + return; + } + + if ( + eventCtx.event !== latestTransactionEvent || + !latestTransactionEvent + ) { + latestTransactionEvent = eventCtx.event; + rows.set(computeFilteredRows()); + } + }; + + table.onInsert(onInsert); + table.onDelete(onDelete); + table.onUpdate?.(onUpdate); + + return () => { + table.removeOnInsert(onInsert); + table.removeOnDelete(onDelete); + table.removeOnUpdate?.(onUpdate); + }; + }; + + const setupSubscription = () => { + const state = get(connectionStore); + const connection = state.getConnection(); + if (!connection) return; + + subscriptionHandle = connection + .subscriptionBuilder() + .onApplied(() => { + isReady.set(true); + rows.set(computeFilteredRows()); + }) + .subscribe(query); + }; + + const unsubscribeConnection = connectionStore.subscribe(state => { + // clean up existing listeners and subscriptions first + if (unsubscribeFromTable) { + unsubscribeFromTable(); + unsubscribeFromTable = null; + } + if (subscriptionHandle) { + subscriptionHandle.unsubscribe(); + subscriptionHandle = null; + } + + if (state.isActive) { + unsubscribeFromTable = setupTableListeners() || null; + setupSubscription(); + rows.set(computeFilteredRows()); + } else { + isReady.set(false); + rows.set([]); + } + }); + + onDestroy(() => { + unsubscribeConnection(); + unsubscribeFromTable?.(); + subscriptionHandle?.unsubscribe(); + latestTransactionEvent = null; + }); + + return [{ subscribe: rows.subscribe }, { subscribe: isReady.subscribe }]; +} diff --git a/crates/bindings-typescript/tsup.config.ts b/crates/bindings-typescript/tsup.config.ts index f88f703b9ec..b629b02e9bc 100644 --- a/crates/bindings-typescript/tsup.config.ts +++ b/crates/bindings-typescript/tsup.config.ts @@ -76,6 +76,38 @@ export default defineConfig([ esbuildOptions: commonEsbuildTweaks(), }, + // Svelte subpath (SSR-friendly): dist/svelte/index.{mjs,cjs} + { + entry: { index: 'src/svelte/index.ts' }, + format: ['esm', 'cjs'], + target: 'es2022', + outDir: 'dist/svelte', + dts: false, + sourcemap: true, + clean: true, + platform: 'neutral', + treeshake: 'smallest', + external: ['svelte', 'svelte/store'], + outExtension, + esbuildOptions: commonEsbuildTweaks(), + }, + + // Svelte subpath (browser ESM): dist/browser/svelte/index.mjs + { + entry: { index: 'src/svelte/index.ts' }, + format: ['esm'], + target: 'es2022', + outDir: 'dist/browser/svelte', + dts: false, + sourcemap: true, + clean: true, + platform: 'browser', + treeshake: 'smallest', + external: ['svelte', 'svelte/store'], + outExtension, + esbuildOptions: commonEsbuildTweaks(), + }, + // SDK subpath (SSR-friendly): dist/sdk/index.{mjs,cjs} { entry: { index: 'src/sdk/index.ts' }, diff --git a/docs/docs/00100-intro/00200-quickstarts/00160-svelte.md b/docs/docs/00100-intro/00200-quickstarts/00160-svelte.md new file mode 100644 index 00000000000..bc56aa552ef --- /dev/null +++ b/docs/docs/00100-intro/00200-quickstarts/00160-svelte.md @@ -0,0 +1,127 @@ +--- +title: Svelte Quickstart +sidebar_label: Svelte +slug: /quickstarts/svelte +hide_table_of_contents: true +--- + +import { InstallCardLink } from "@site/src/components/InstallCardLink"; +import { StepByStep, Step, StepText, StepCode } from "@site/src/components/Steps"; + + +Get a SpacetimeDB Svelte app running in under 5 minutes. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- [SpacetimeDB CLI](https://spacetimedb.com/install) installed + + + +--- + + + + + Run the `spacetime dev` command to create a new project with a SpacetimeDB module and Svelte client. + + This will start the local SpacetimeDB server, publish your module, generate TypeScript bindings, and start the Svelte development server. + + +```bash +spacetime dev --template svelte-ts +``` + + + + + + Navigate to [http://localhost:5173](http://localhost:5173) to see your app running. + + The template includes a basic Svelte app connected to SpacetimeDB. + + + + + + Your project contains both server and client code. + + Edit `spacetimedb/src/index.ts` to add tables and reducers. Edit `src/App.svelte` to build your UI. + + +``` +my-spacetime-app/ +├── spacetimedb/ # Your SpacetimeDB module +│ └── src/ +│ └── index.ts # Server-side logic +├── src/ # Svelte frontend +│ ├── App.svelte +│ └── module_bindings/ # Auto-generated types +└── package.json +``` + + + + + + Open `spacetimedb/src/index.ts` to see the module code. The template includes a `person` table and two reducers: `add` to insert a person, and `say_hello` to greet everyone. + + Tables store your data. Reducers are functions that modify data — they're the only way to write to the database. + + +```typescript +import { schema, table, t } from 'spacetimedb/server'; + +export const spacetimedb = schema( + table( + { name: 'person', public: true }, + { + name: t.string(), + } + ) +); + +spacetimedb.reducer('add', { name: t.string() }, (ctx, { name }) => { + ctx.db.person.insert({ name }); +}); + +spacetimedb.reducer('say_hello', (ctx) => { + for (const person of ctx.db.person.iter()) { + console.info(`Hello, ${person.name}!`); + } + console.info('Hello, World!'); +}); +``` + + + + + + Use the SpacetimeDB CLI to call reducers and query your data directly. + + +```bash +# Call the add reducer to insert a person +spacetime call add Alice + +# Query the person table +spacetime sql "SELECT * FROM person" + name +--------- + "Alice" + +# Call say_hello to greet everyone +spacetime call say_hello + +# View the module logs +spacetime logs +2025-01-13T12:00:00.000000Z INFO: Hello, Alice! +2025-01-13T12:00:00.000000Z INFO: Hello, World! +``` + + + + +## Next steps + +- Read the [TypeScript SDK Reference](/sdks/typescript) for detailed API docs diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9de64e1c10..15aa6c9d6e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,6 +108,9 @@ importers: size-limit: specifier: ^11.2.0 version: 11.2.0 + svelte: + specifier: ^5.0.0 + version: 5.46.4 ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@24.3.0)(typescript@5.9.3) @@ -369,6 +372,28 @@ importers: specifier: workspace:^ version: link:../../../crates/bindings-typescript + templates/svelte-ts: + dependencies: + spacetimedb: + specifier: workspace:* + version: link:../../crates/bindings-typescript + devDependencies: + '@sveltejs/vite-plugin-svelte': + specifier: ^5.1.1 + version: 5.1.1(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + svelte: + specifier: ^5.0.0 + version: 5.46.4 + svelte-check: + specifier: ^4.0.0 + version: 4.3.5(picomatch@4.0.3)(svelte@5.46.4)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + vite: + specifier: ^6.4.1 + version: 6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + packages: '@adobe/css-tools@4.4.4': @@ -2012,6 +2037,9 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -3061,6 +3089,26 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@sveltejs/acorn-typescript@1.0.8': + resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/vite-plugin-svelte-inspector@4.0.1': + resolution: {integrity: sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^5.0.0 + svelte: ^5.0.0 + vite: ^6.0.0 + + '@sveltejs/vite-plugin-svelte@5.1.1': + resolution: {integrity: sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22} + peerDependencies: + svelte: ^5.0.0 + vite: ^6.0.0 + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} engines: {node: '>=14'} @@ -4164,6 +4212,10 @@ packages: peerDependencies: postcss: ^8.1.0 + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + babel-loader@9.2.1: resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} engines: {node: '>= 14.15.0'} @@ -4810,6 +4862,9 @@ packages: engines: {node: '>= 4.0.0'} hasBin: true + devalue@5.6.2: + resolution: {integrity: sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -5026,6 +5081,9 @@ packages: jiti: optional: true + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5039,6 +5097,9 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} + esrap@2.2.1: + resolution: {integrity: sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -5818,6 +5879,9 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + is-regexp@1.0.0: resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} engines: {node: '>=0.10.0'} @@ -6031,6 +6095,9 @@ packages: resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} engines: {node: '>=8.9.0'} + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -6113,6 +6180,9 @@ packages: magic-string@0.30.19: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -8078,6 +8148,18 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svelte-check@4.3.5: + resolution: {integrity: sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte@5.46.4: + resolution: {integrity: sha512-VJwdXrmv9L8L7ZasJeWcCjoIuMRVbhuxbss0fpVnR8yorMmjNDwcjIH08vS6wmSzzzgAG5CADQ1JuXPS2nwt9w==} + engines: {node: '>=18'} + svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} @@ -8586,6 +8668,46 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite@6.4.1: + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} + 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@7.1.5: resolution: {integrity: sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -8626,6 +8748,14 @@ packages: yaml: optional: true + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -8867,6 +8997,9 @@ packages: zen-observable@0.8.15: resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zod@4.1.12: resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} @@ -11687,6 +11820,11 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/source-map@0.3.11': @@ -12757,6 +12895,32 @@ snapshots: '@standard-schema/spec@1.0.0': {} + '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': + dependencies: + acorn: 8.15.0 + + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)))(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': + dependencies: + '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + debug: 4.4.3 + svelte: 5.46.4 + vite: 6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)))(svelte@5.46.4)(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + debug: 4.4.3 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.21 + svelte: 5.46.4 + vite: 6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vitefu: 1.1.1(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + transitivePeerDependencies: + - supports-color + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.3)': dependencies: '@babel/core': 7.28.3 @@ -14622,6 +14786,8 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 + axobject-query@4.1.0: {} + babel-loader@9.2.1(@babel/core@7.28.3)(webpack@5.102.0): dependencies: '@babel/core': 7.28.3 @@ -15293,6 +15459,8 @@ snapshots: transitivePeerDependencies: - supports-color + devalue@5.6.2: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -15548,6 +15716,8 @@ snapshots: transitivePeerDependencies: - supports-color + esm-env@1.2.2: {} + espree@10.4.0: dependencies: acorn: 8.15.0 @@ -15560,6 +15730,10 @@ snapshots: dependencies: estraverse: 5.3.0 + esrap@2.2.1: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -16475,6 +16649,10 @@ snapshots: is-potential-custom-element-name@1.0.1: {} + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + is-regexp@1.0.0: {} is-stream@2.0.1: {} @@ -16689,6 +16867,8 @@ snapshots: emojis-list: 3.0.0 json5: 2.2.3 + locate-character@3.0.0: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -16753,6 +16933,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + magicast@0.3.5: dependencies: '@babel/parser': 7.28.3 @@ -19272,6 +19456,36 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svelte-check@4.3.5(picomatch@4.0.3)(svelte@5.46.4)(typescript@5.6.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.30 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.3) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.46.4 + typescript: 5.6.3 + transitivePeerDependencies: + - picomatch + + svelte@5.46.4: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) + '@types/estree': 1.0.8 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.2 + esm-env: 1.2.2 + esrap: 2.2.1 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.19 + zimmerframe: 1.1.4 + svg-parser@2.0.4: {} svgo@3.3.2: @@ -19814,6 +20028,21 @@ snapshots: - tsx - yaml + vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4): + dependencies: + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.50.2 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.3.0 + fsevents: 2.3.3 + jiti: 2.5.1 + terser: 5.43.1 + tsx: 4.20.4 + vite@7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4): dependencies: esbuild: 0.25.9 @@ -19844,6 +20073,10 @@ snapshots: terser: 5.43.1 tsx: 4.20.4 + vitefu@1.1.1(vite@6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)): + optionalDependencies: + vite: 6.4.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.0)(jiti@2.5.1)(jsdom@26.1.0)(terser@5.43.1)(tsx@4.20.4): dependencies: '@types/chai': 5.2.2 @@ -20185,6 +20418,8 @@ snapshots: zen-observable@0.8.15: {} + zimmerframe@1.1.4: {} + zod@4.1.12: {} zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0b6b411ea9e..e79a76ad249 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - 'crates/bindings-typescript' - 'crates/bindings-typescript/test-app' - 'templates/quickstart-chat-typescript' + - 'templates/svelte-ts' - 'templates/basic-react' - 'templates/basic-typescript' - 'modules/benchmarks-ts' diff --git a/templates/svelte-ts/.template.json b/templates/svelte-ts/.template.json new file mode 100644 index 00000000000..2f7d4081e89 --- /dev/null +++ b/templates/svelte-ts/.template.json @@ -0,0 +1,5 @@ +{ + "description": "Svelte web app with TypeScript server", + "client_lang": "typescript", + "server_lang": "typescript" +} diff --git a/templates/svelte-ts/LICENSE b/templates/svelte-ts/LICENSE new file mode 120000 index 00000000000..039e117dde2 --- /dev/null +++ b/templates/svelte-ts/LICENSE @@ -0,0 +1 @@ +../../licenses/apache2.txt \ No newline at end of file diff --git a/templates/svelte-ts/index.html b/templates/svelte-ts/index.html new file mode 100644 index 00000000000..3be04a1b6af --- /dev/null +++ b/templates/svelte-ts/index.html @@ -0,0 +1,12 @@ + + + + + + SpacetimeDB Svelte App + + +
+ + + diff --git a/templates/svelte-ts/package.json b/templates/svelte-ts/package.json new file mode 100644 index 00000000000..106ba63f522 --- /dev/null +++ b/templates/svelte-ts/package.json @@ -0,0 +1,25 @@ +{ + "name": "@clockworklabs/svelte-ts", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "generate": "pnpm --dir spacetimedb install --ignore-workspace && cargo run -p gen-bindings -- --out-dir src/module_bindings --project-path spacetimedb && prettier --write src/module_bindings", + "spacetime:generate": "spacetime generate --lang typescript --out-dir src/module_bindings --project-path spacetimedb", + "spacetime:publish:local": "spacetime publish --project-path spacetimedb --server local", + "spacetime:publish": "spacetime publish --project-path spacetimedb --server maincloud" + }, + "dependencies": { + "spacetimedb": "workspace:*" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^5.1.1", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "typescript": "~5.6.2", + "vite": "^6.4.1" + } +} diff --git a/templates/svelte-ts/spacetimedb/package.json b/templates/svelte-ts/spacetimedb/package.json new file mode 100644 index 00000000000..214ccc569bf --- /dev/null +++ b/templates/svelte-ts/spacetimedb/package.json @@ -0,0 +1,15 @@ +{ + "name": "spacetime-module", + "version": "1.0.0", + "description": "", + "scripts": { + "build": "spacetime build", + "publish": "spacetime publish" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "spacetimedb": "1.*" + } +} diff --git a/templates/svelte-ts/spacetimedb/src/index.ts b/templates/svelte-ts/spacetimedb/src/index.ts new file mode 100644 index 00000000000..900cb1bf2e9 --- /dev/null +++ b/templates/svelte-ts/spacetimedb/src/index.ts @@ -0,0 +1,33 @@ +import { schema, table, t } from 'spacetimedb/server'; + +export const spacetimedb = schema( + table( + { name: 'person', public: true }, + { + name: t.string(), + } + ) +); + +spacetimedb.init((_ctx) => { + // Called when the module is initially published +}); + +spacetimedb.clientConnected((_ctx) => { + // Called every time a new client connects +}); + +spacetimedb.clientDisconnected((_ctx) => { + // Called every time a client disconnects +}); + +spacetimedb.reducer('add', { name: t.string() }, (ctx, { name }) => { + ctx.db.person.insert({ name }); +}); + +spacetimedb.reducer('say_hello', (ctx) => { + for (const person of ctx.db.person.iter()) { + console.info(`Hello, ${person.name}!`); + } + console.info('Hello, World!'); +}); diff --git a/templates/svelte-ts/spacetimedb/tsconfig.json b/templates/svelte-ts/spacetimedb/tsconfig.json new file mode 100644 index 00000000000..b6f79b99474 --- /dev/null +++ b/templates/svelte-ts/spacetimedb/tsconfig.json @@ -0,0 +1,23 @@ +/* + * This tsconfig is used for TypeScript projects created with `spacetimedb init + * --lang typescript`. You can modify it as needed for your project, although + * some options are required by SpacetimeDB. + */ +{ + "compilerOptions": { + "strict": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "jsx": "react-jsx", + + /* The following options are required by SpacetimeDB + * and should not be modified + */ + "target": "ESNext", + "lib": ["ES2021", "dom"], + "module": "ESNext", + "isolatedModules": true, + "noEmit": true + }, + "include": ["./**/*"] +} diff --git a/templates/svelte-ts/src/App.svelte b/templates/svelte-ts/src/App.svelte new file mode 100644 index 00000000000..9e3f0d37e2c --- /dev/null +++ b/templates/svelte-ts/src/App.svelte @@ -0,0 +1,63 @@ + + +
+

SpacetimeDB Svelte App

+ +
+ Status: + + {$conn.isActive ? 'Connected' : 'Disconnected'} + +
+ +
+ + +
+ +
+

People ({$people.length})

+ {#if $people.length === 0} +

No people yet. Add someone above!

+ {:else} +
    + {#each $people as person} +
  • {person.name}
  • + {/each} +
+ {/if} +
+
diff --git a/templates/svelte-ts/src/Root.svelte b/templates/svelte-ts/src/Root.svelte new file mode 100644 index 00000000000..b3341a11285 --- /dev/null +++ b/templates/svelte-ts/src/Root.svelte @@ -0,0 +1,37 @@ + + + diff --git a/templates/svelte-ts/src/main.ts b/templates/svelte-ts/src/main.ts new file mode 100644 index 00000000000..87d1f989c60 --- /dev/null +++ b/templates/svelte-ts/src/main.ts @@ -0,0 +1,6 @@ +import { mount } from 'svelte'; +import Root from './Root.svelte'; + +mount(Root, { + target: document.getElementById('app')!, +}); diff --git a/templates/svelte-ts/src/module_bindings/add_reducer.ts b/templates/svelte-ts/src/module_bindings/add_reducer.ts new file mode 100644 index 00000000000..85081559c7d --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/add_reducer.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default { + name: __t.string(), +}; diff --git a/templates/svelte-ts/src/module_bindings/add_type.ts b/templates/svelte-ts/src/module_bindings/add_type.ts new file mode 100644 index 00000000000..638f62cea39 --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/add_type.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Add', { + name: __t.string(), +}); diff --git a/templates/svelte-ts/src/module_bindings/index.ts b/templates/svelte-ts/src/module_bindings/index.ts new file mode 100644 index 00000000000..d726335a186 --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/index.ts @@ -0,0 +1,145 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). + +/* eslint-disable */ +/* tslint:disable */ +import { + DbConnectionBuilder as __DbConnectionBuilder, + DbConnectionImpl as __DbConnectionImpl, + SubscriptionBuilderImpl as __SubscriptionBuilderImpl, + TypeBuilder as __TypeBuilder, + Uuid as __Uuid, + convertToAccessorMap as __convertToAccessorMap, + procedureSchema as __procedureSchema, + procedures as __procedures, + reducerSchema as __reducerSchema, + reducers as __reducers, + schema as __schema, + t as __t, + table as __table, + type AlgebraicTypeType as __AlgebraicTypeType, + type DbConnectionConfig as __DbConnectionConfig, + type ErrorContextInterface as __ErrorContextInterface, + type Event as __Event, + type EventContextInterface as __EventContextInterface, + type Infer as __Infer, + type ReducerEventContextInterface as __ReducerEventContextInterface, + type RemoteModule as __RemoteModule, + type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, +} from 'spacetimedb'; + +// Import and reexport all reducer arg types +import OnConnectReducer from './on_connect_reducer'; +export { OnConnectReducer }; +import OnDisconnectReducer from './on_disconnect_reducer'; +export { OnDisconnectReducer }; +import AddReducer from './add_reducer'; +export { AddReducer }; +import SayHelloReducer from './say_hello_reducer'; +export { SayHelloReducer }; + +// Import and reexport all procedure arg types + +// Import and reexport all table handle types +import PersonRow from './person_table'; +export { PersonRow }; + +// Import and reexport all types +import Add from './add_type'; +export { Add }; +import Init from './init_type'; +export { Init }; +import OnConnect from './on_connect_type'; +export { OnConnect }; +import OnDisconnect from './on_disconnect_type'; +export { OnDisconnect }; +import Person from './person_type'; +export { Person }; +import SayHello from './say_hello_type'; +export { SayHello }; + +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ +const tablesSchema = __schema( + __table( + { + name: 'person', + indexes: [], + constraints: [], + }, + PersonRow + ) +); + +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ +const reducersSchema = __reducers( + __reducerSchema('add', AddReducer), + __reducerSchema('say_hello', SayHelloReducer) +); + +/** The schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ +const proceduresSchema = __procedures(); + +/** The remote SpacetimeDB module schema, both runtime and type information. */ +const REMOTE_MODULE = { + versionInfo: { + cliVersion: '1.11.3' as const, + }, + tables: tablesSchema.schemaType.tables, + reducers: reducersSchema.reducersType.reducers, + ...proceduresSchema, +} satisfies __RemoteModule< + typeof tablesSchema.schemaType, + typeof reducersSchema.reducersType, + typeof proceduresSchema +>; + +/** The tables available in this remote SpacetimeDB module. */ +export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ +export const reducers = __convertToAccessorMap( + reducersSchema.reducersType.reducers +); + +/** The context type returned in callbacks for all possible events. */ +export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ +export type ReducerEventContext = __ReducerEventContextInterface< + typeof REMOTE_MODULE +>; +/** The context type returned in callbacks for subscription events. */ +export type SubscriptionEventContext = __SubscriptionEventContextInterface< + typeof REMOTE_MODULE +>; +/** The context type returned in callbacks for error events. */ +export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; + +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ +export class SubscriptionBuilder extends __SubscriptionBuilderImpl< + typeof REMOTE_MODULE +> {} + +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder {} + +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ +export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ + static builder = (): DbConnectionBuilder => { + return new DbConnectionBuilder( + REMOTE_MODULE, + (config: __DbConnectionConfig) => + new DbConnection(config) + ); + }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ + override subscriptionBuilder = (): SubscriptionBuilder => { + return new SubscriptionBuilder(this); + }; +} diff --git a/templates/svelte-ts/src/module_bindings/init_type.ts b/templates/svelte-ts/src/module_bindings/init_type.ts new file mode 100644 index 00000000000..52ed691ed94 --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/init_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Init', {}); diff --git a/templates/svelte-ts/src/module_bindings/on_connect_reducer.ts b/templates/svelte-ts/src/module_bindings/on_connect_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/on_connect_reducer.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default {}; diff --git a/templates/svelte-ts/src/module_bindings/on_connect_type.ts b/templates/svelte-ts/src/module_bindings/on_connect_type.ts new file mode 100644 index 00000000000..d36362515de --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/on_connect_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('OnConnect', {}); diff --git a/templates/svelte-ts/src/module_bindings/on_disconnect_reducer.ts b/templates/svelte-ts/src/module_bindings/on_disconnect_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/on_disconnect_reducer.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default {}; diff --git a/templates/svelte-ts/src/module_bindings/on_disconnect_type.ts b/templates/svelte-ts/src/module_bindings/on_disconnect_type.ts new file mode 100644 index 00000000000..efda71ebcfd --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/on_disconnect_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('OnDisconnect', {}); diff --git a/templates/svelte-ts/src/module_bindings/person_table.ts b/templates/svelte-ts/src/module_bindings/person_table.ts new file mode 100644 index 00000000000..0f70f74f617 --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/person_table.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.row({ + name: __t.string(), +}); diff --git a/templates/svelte-ts/src/module_bindings/person_type.ts b/templates/svelte-ts/src/module_bindings/person_type.ts new file mode 100644 index 00000000000..1156775a3cf --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/person_type.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Person', { + name: __t.string(), +}); diff --git a/templates/svelte-ts/src/module_bindings/say_hello_reducer.ts b/templates/svelte-ts/src/module_bindings/say_hello_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/say_hello_reducer.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default {}; diff --git a/templates/svelte-ts/src/module_bindings/say_hello_type.ts b/templates/svelte-ts/src/module_bindings/say_hello_type.ts new file mode 100644 index 00000000000..6293ca6bd09 --- /dev/null +++ b/templates/svelte-ts/src/module_bindings/say_hello_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('SayHello', {}); diff --git a/templates/svelte-ts/svelte.config.js b/templates/svelte-ts/svelte.config.js new file mode 100644 index 00000000000..4c6b24b1073 --- /dev/null +++ b/templates/svelte-ts/svelte.config.js @@ -0,0 +1,5 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +export default { + preprocess: vitePreprocess(), +}; diff --git a/templates/svelte-ts/tsconfig.json b/templates/svelte-ts/tsconfig.json new file mode 100644 index 00000000000..6406a7d1573 --- /dev/null +++ b/templates/svelte-ts/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "types": ["vite/client"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src", "vite.config.ts"] +} diff --git a/templates/svelte-ts/vite.config.ts b/templates/svelte-ts/vite.config.ts new file mode 100644 index 00000000000..5e6b0ec3055 --- /dev/null +++ b/templates/svelte-ts/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite'; +import { svelte } from '@sveltejs/vite-plugin-svelte'; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [svelte()], +}); diff --git a/templates/templates-list.json b/templates/templates-list.json index 05f8c035e5c..e83980a6f2f 100644 --- a/templates/templates-list.json +++ b/templates/templates-list.json @@ -1,6 +1,7 @@ { "highlights": [ - { "name": "React", "template_id": "basic-react" } + { "name": "React", "template_id": "basic-react" }, + { "name": "Svelte", "template_id": "svelte-ts" } ], "templates": [ { @@ -58,6 +59,14 @@ "client_source": "quickstart-chat-ts", "server_lang": "typescript", "client_lang": "typescript" + }, + { + "id": "svelte-ts", + "description": "Svelte web app with TypeScript server", + "server_source": "svelte-ts/spacetimedb", + "client_source": "svelte-ts", + "server_lang": "typescript", + "client_lang": "typescript" } ] } From 5d27ac5a872d4a5efe27757936da9cf5d9b0d63c Mon Sep 17 00:00:00 2001 From: Tien Pham Date: Tue, 27 Jan 2026 13:10:37 +0200 Subject: [PATCH 2/3] chore: consolidate utils into a shared file --- crates/bindings-typescript/src/lib/filter.ts | 184 ++++++++++++++++ .../bindings-typescript/src/react/useTable.ts | 201 ++---------------- .../src/svelte/useTable.ts | 182 ++-------------- .../bindings-typescript/src/vue/useTable.ts | 182 ++-------------- 4 files changed, 238 insertions(+), 511 deletions(-) create mode 100644 crates/bindings-typescript/src/lib/filter.ts diff --git a/crates/bindings-typescript/src/lib/filter.ts b/crates/bindings-typescript/src/lib/filter.ts new file mode 100644 index 00000000000..544801e7e98 --- /dev/null +++ b/crates/bindings-typescript/src/lib/filter.ts @@ -0,0 +1,184 @@ +import type { RowType, UntypedTableDef } from './table'; +import { Uuid } from './uuid'; + +export type Value = string | number | boolean | Uuid; + +export type Expr = + | { type: 'eq'; key: Column; value: Value } + | { type: 'and'; children: Expr[] } + | { type: 'or'; children: Expr[] }; + +export const eq = ( + key: Column, + value: Value +): Expr => ({ type: 'eq', key, value }); + +export const and = ( + ...children: Expr[] +): Expr => { + const flat: Expr[] = []; + for (const c of children) { + if (!c) continue; + if (c.type === 'and') flat.push(...c.children); + else flat.push(c); + } + const pruned = flat.filter(Boolean); + if (pruned.length === 0) return { type: 'and', children: [] }; + if (pruned.length === 1) return pruned[0]; + return { type: 'and', children: pruned }; +}; + +export const or = ( + ...children: Expr[] +): Expr => { + const flat: Expr[] = []; + for (const c of children) { + if (!c) continue; + if (c.type === 'or') flat.push(...c.children); + else flat.push(c); + } + const pruned = flat.filter(Boolean); + if (pruned.length === 0) return { type: 'or', children: [] }; + if (pruned.length === 1) return pruned[0]; + return { type: 'or', children: pruned }; +}; + +export const isEq = ( + e: Expr +): e is Extract, { type: 'eq' }> => e.type === 'eq'; +export const isAnd = ( + e: Expr +): e is Extract, { type: 'and' }> => e.type === 'and'; +export const isOr = ( + e: Expr +): e is Extract, { type: 'or' }> => e.type === 'or'; + +export function evaluate( + expr: Expr, + row: Record +): boolean { + switch (expr.type) { + case 'eq': { + // The actual value of the Column + const v = row[expr.key]; + if ( + typeof v === 'string' || + typeof v === 'number' || + typeof v === 'boolean' + ) { + return v === expr.value; + } + if (typeof v === 'object') { + // Value of the Column and passed Value are both a Uuid so do an integer comparison. + if (v instanceof Uuid && expr.value instanceof Uuid) { + return v.asBigInt() === expr.value.asBigInt(); + } + // Value of the Column is a Uuid but passed Value is a String so compare them via string. + if (v instanceof Uuid && typeof expr.value === 'string') { + return v.toString() === expr.value; + } + } + return false; + } + case 'and': + return ( + expr.children.length === 0 || expr.children.every(c => evaluate(c, row)) + ); + case 'or': + return ( + expr.children.length !== 0 && expr.children.some(c => evaluate(c, row)) + ); + } +} + +function formatValue(v: Value): string { + switch (typeof v) { + case 'string': + return `'${v.replace(/'/g, "''")}'`; + case 'number': + return Number.isFinite(v) ? String(v) : `'${String(v)}'`; + case 'boolean': + return v ? 'TRUE' : 'FALSE'; + case 'object': { + if (v instanceof Uuid) { + return `'${v.toString()}'`; + } + + return ''; + } + } +} + +function escapeIdent(id: string): string { + if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(id)) return id; + return `"${id.replace(/"/g, '""')}"`; +} + +function parenthesize(s: string): string { + if (!s.includes(' AND ') && !s.includes(' OR ')) return s; + return `(${s})`; +} + +export function toString( + tableDef: TableDef, + expr: Expr>> +): string { + switch (expr.type) { + case 'eq': { + const key = tableDef.columns[expr.key].columnMetadata.name ?? expr.key; + return `${escapeIdent(key)} = ${formatValue(expr.value)}`; + } + case 'and': + return parenthesize( + expr.children.map(expr => toString(tableDef, expr)).join(' AND ') + ); + case 'or': + return parenthesize( + expr.children.map(expr => toString(tableDef, expr)).join(' OR ') + ); + } +} + +/** + * This is just the identity function to make things look like SQL. + * @param expr + * @returns + */ +export function where(expr: Expr): Expr { + return expr; +} + +type MembershipChange = 'enter' | 'leave' | 'stayIn' | 'stayOut'; + +export function classifyMembership< + Col extends string, + R extends Record, +>(where: Expr | undefined, oldRow: R, newRow: R): MembershipChange { + // No filter: everything is in, so updates are always "stayIn". + if (!where) { + return 'stayIn'; + } + + const oldIn = evaluate(where, oldRow); + const newIn = evaluate(where, newRow); + + if (oldIn && !newIn) { + return 'leave'; + } + if (!oldIn && newIn) { + return 'enter'; + } + if (oldIn && newIn) { + return 'stayIn'; + } + return 'stayOut'; +} + +/** + * Extracts the column names from a RowType whose values are of type Value. + * Note that this will exclude columns that are of type object, array, etc. + */ +export type ColumnsFromRow = { + [K in keyof R]-?: R[K] extends Value | undefined ? K : never; +}[keyof R] & + string; diff --git a/crates/bindings-typescript/src/react/useTable.ts b/crates/bindings-typescript/src/react/useTable.ts index 569f66fb43f..5c965d621f3 100644 --- a/crates/bindings-typescript/src/react/useTable.ts +++ b/crates/bindings-typescript/src/react/useTable.ts @@ -10,8 +10,25 @@ import { type EventContextInterface } from '../sdk/db_connection_impl'; import type { ConnectionState } from './connection_state'; import type { UntypedRemoteModule } from '../sdk/spacetime_module'; import type { RowType, UntypedTableDef } from '../lib/table'; -import { Uuid } from '../lib/uuid'; import type { Prettify } from '../lib/type_util'; +import { + type Value, + type Expr, + type ColumnsFromRow, + eq, + and, + or, + isEq, + isAnd, + isOr, + evaluate, + toString, + where, + classifyMembership, +} from '../lib/filter'; + +export { eq, and, or, isEq, isAnd, isOr, where }; +export type { Value, Expr }; export interface UseTableCallbacks { onInsert?: (row: RowType) => void; @@ -19,188 +36,6 @@ export interface UseTableCallbacks { onUpdate?: (oldRow: RowType, newRow: RowType) => void; } -export type Value = string | number | boolean | Uuid; - -export type Expr = - | { type: 'eq'; key: Column; value: Value } - | { type: 'and'; children: Expr[] } - | { type: 'or'; children: Expr[] }; - -export const eq = ( - key: Column, - value: Value -): Expr => ({ type: 'eq', key, value }); - -export const and = ( - ...children: Expr[] -): Expr => { - const flat: Expr[] = []; - for (const c of children) { - if (!c) continue; - if (c.type === 'and') flat.push(...c.children); - else flat.push(c); - } - const pruned = flat.filter(Boolean); - if (pruned.length === 0) return { type: 'and', children: [] }; - if (pruned.length === 1) return pruned[0]; - return { type: 'and', children: pruned }; -}; - -export const or = ( - ...children: Expr[] -): Expr => { - const flat: Expr[] = []; - for (const c of children) { - if (!c) continue; - if (c.type === 'or') flat.push(...c.children); - else flat.push(c); - } - const pruned = flat.filter(Boolean); - if (pruned.length === 0) return { type: 'or', children: [] }; - if (pruned.length === 1) return pruned[0]; - return { type: 'or', children: pruned }; -}; - -export const isEq = ( - e: Expr -): e is Extract, { type: 'eq' }> => e.type === 'eq'; -export const isAnd = ( - e: Expr -): e is Extract, { type: 'and' }> => e.type === 'and'; -export const isOr = ( - e: Expr -): e is Extract, { type: 'or' }> => e.type === 'or'; - -export function evaluate( - expr: Expr, - row: Record -): boolean { - switch (expr.type) { - case 'eq': { - // The actual value of the Column - const v = row[expr.key]; - if ( - typeof v === 'string' || - typeof v === 'number' || - typeof v === 'boolean' - ) { - return v === expr.value; - } - if (typeof v === 'object') { - // Value of the Column and passed Value are both a Uuid so do an integer comparison. - if (v instanceof Uuid && expr.value instanceof Uuid) { - return v.asBigInt() === expr.value.asBigInt(); - } - // Value of the Column is a Uuid but passed Value is a String so compare them via string. - if (v instanceof Uuid && typeof expr.value === 'string') { - return v.toString() === expr.value; - } - } - return false; - } - case 'and': - return ( - expr.children.length === 0 || expr.children.every(c => evaluate(c, row)) - ); - case 'or': - return ( - expr.children.length !== 0 && expr.children.some(c => evaluate(c, row)) - ); - } -} - -function formatValue(v: Value): string { - switch (typeof v) { - case 'string': - return `'${v.replace(/'/g, "''")}'`; - case 'number': - return Number.isFinite(v) ? String(v) : `'${String(v)}'`; - case 'boolean': - return v ? 'TRUE' : 'FALSE'; - case 'object': { - if (v instanceof Uuid) { - return `'${v.toString()}'`; - } - - return ''; - } - } -} - -function escapeIdent(id: string): string { - if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(id)) return id; - return `"${id.replace(/"/g, '""')}"`; -} - -function parenthesize(s: string): string { - if (!s.includes(' AND ') && !s.includes(' OR ')) return s; - return `(${s})`; -} - -export function toString( - tableDef: TableDef, - expr: Expr>> -): string { - switch (expr.type) { - case 'eq': { - const key = tableDef.columns[expr.key].columnMetadata.name ?? expr.key; - return `${escapeIdent(key)} = ${formatValue(expr.value)}`; - } - case 'and': - return parenthesize( - expr.children.map(expr => toString(tableDef, expr)).join(' AND ') - ); - case 'or': - return parenthesize( - expr.children.map(expr => toString(tableDef, expr)).join(' OR ') - ); - } -} - -/** - * This is just the identity function to make things look like SQL. - * @param expr - * @returns - */ -export function where(expr: Expr): Expr { - return expr; -} - -type MembershipChange = 'enter' | 'leave' | 'stayIn' | 'stayOut'; - -function classifyMembership< - Col extends string, - R extends Record, ->(where: Expr | undefined, oldRow: R, newRow: R): MembershipChange { - // No filter: everything is in, so updates are always "stayIn". - if (!where) { - return 'stayIn'; - } - - const oldIn = evaluate(where, oldRow); - const newIn = evaluate(where, newRow); - - if (oldIn && !newIn) { - return 'leave'; - } - if (!oldIn && newIn) { - return 'enter'; - } - if (oldIn && newIn) { - return 'stayIn'; - } - return 'stayOut'; -} - -/** - * Extracts the column names from a RowType whose values are of type Value. - * Note that this will exclude columns that are of type object, array, etc. - */ -type ColumnsFromRow = { - [K in keyof R]-?: R[K] extends Value | undefined ? K : never; -}[keyof R] & - string; - /** * React hook to subscribe to a table in SpacetimeDB and receive live updates as rows are inserted, updated, or deleted. * diff --git a/crates/bindings-typescript/src/svelte/useTable.ts b/crates/bindings-typescript/src/svelte/useTable.ts index fb21cc005ba..7bd31dd20ba 100644 --- a/crates/bindings-typescript/src/svelte/useTable.ts +++ b/crates/bindings-typescript/src/svelte/useTable.ts @@ -5,6 +5,24 @@ import type { EventContextInterface } from '../sdk/db_connection_impl'; import type { UntypedRemoteModule } from '../sdk/spacetime_module'; import type { RowType, UntypedTableDef } from '../lib/table'; import type { Prettify } from '../lib/type_util'; +import { + type Value, + type Expr, + type ColumnsFromRow, + eq, + and, + or, + isEq, + isAnd, + isOr, + evaluate, + toString, + where, + classifyMembership, +} from '../lib/filter'; + +export { eq, and, or, isEq, isAnd, isOr, where }; +export type { Value, Expr }; export interface UseTableCallbacks { onInsert?: (row: RowType) => void; @@ -12,170 +30,6 @@ export interface UseTableCallbacks { onUpdate?: (oldRow: RowType, newRow: RowType) => void; } -export type Value = string | number | boolean; - -export type Expr = - | { type: 'eq'; key: Column; value: Value } - | { type: 'and'; children: Expr[] } - | { type: 'or'; children: Expr[] }; - -export const eq = ( - key: Column, - value: Value -): Expr => ({ type: 'eq', key, value }); - -export const and = ( - ...children: Expr[] -): Expr => { - const flat: Expr[] = []; - for (const c of children) { - if (!c) continue; - if (c.type === 'and') flat.push(...c.children); - else flat.push(c); - } - const pruned = flat.filter(Boolean); - if (pruned.length === 0) return { type: 'and', children: [] }; - if (pruned.length === 1) return pruned[0]; - return { type: 'and', children: pruned }; -}; - -export const or = ( - ...children: Expr[] -): Expr => { - const flat: Expr[] = []; - for (const c of children) { - if (!c) continue; - if (c.type === 'or') flat.push(...c.children); - else flat.push(c); - } - const pruned = flat.filter(Boolean); - if (pruned.length === 0) return { type: 'or', children: [] }; - if (pruned.length === 1) return pruned[0]; - return { type: 'or', children: pruned }; -}; - -export const isEq = ( - e: Expr -): e is Extract, { type: 'eq' }> => e.type === 'eq'; -export const isAnd = ( - e: Expr -): e is Extract, { type: 'and' }> => e.type === 'and'; -export const isOr = ( - e: Expr -): e is Extract, { type: 'or' }> => e.type === 'or'; - -export function evaluate( - expr: Expr, - row: Record -): boolean { - switch (expr.type) { - case 'eq': { - const v = row[expr.key]; - if ( - typeof v === 'string' || - typeof v === 'number' || - typeof v === 'boolean' - ) { - return v === expr.value; - } - return false; - } - case 'and': - return ( - expr.children.length === 0 || expr.children.every(c => evaluate(c, row)) - ); - case 'or': - return ( - expr.children.length !== 0 && expr.children.some(c => evaluate(c, row)) - ); - } -} - -function formatValue(v: Value): string { - switch (typeof v) { - case 'string': - return `'${v.replace(/'/g, "''")}'`; - case 'number': - return Number.isFinite(v) ? String(v) : `'${String(v)}'`; - case 'boolean': - return v ? 'TRUE' : 'FALSE'; - } -} - -function escapeIdent(id: string): string { - if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(id)) return id; - return `"${id.replace(/"/g, '""')}"`; -} - -function parenthesize(s: string): string { - if (!s.includes(' AND ') && !s.includes(' OR ')) return s; - return `(${s})`; -} - -/** - * Extracts the column names from a RowType whose values are of type Value. - * Note that this will exclude columns that are of type object, array, etc. - */ -type ColumnsFromRow = { - [K in keyof R]-?: R[K] extends Value | undefined ? K : never; -}[keyof R] & - string; - -export function toString( - tableDef: TableDef, - expr: Expr>> -): string { - switch (expr.type) { - case 'eq': { - const key = tableDef.columns[expr.key].columnMetadata.name ?? expr.key; - return `${escapeIdent(key)} = ${formatValue(expr.value)}`; - } - case 'and': - return parenthesize( - expr.children.map(expr => toString(tableDef, expr)).join(' AND ') - ); - case 'or': - return parenthesize( - expr.children.map(expr => toString(tableDef, expr)).join(' OR ') - ); - } -} - -/** - * This is just the identity function to make things look like SQL. - * @param expr - * @returns - */ -export function where(expr: Expr): Expr { - return expr; -} - -type MembershipChange = 'enter' | 'leave' | 'stayIn' | 'stayOut'; - -function classifyMembership< - Col extends string, - R extends Record, ->(where: Expr | undefined, oldRow: R, newRow: R): MembershipChange { - // No filter: everything is in, so updates are always "stayIn". - if (!where) { - return 'stayIn'; - } - - const oldIn = evaluate(where, oldRow); - const newIn = evaluate(where, newRow); - - if (oldIn && !newIn) { - return 'leave'; - } - if (!oldIn && newIn) { - return 'enter'; - } - if (oldIn && newIn) { - return 'stayIn'; - } - return 'stayOut'; -} - export function useTable( tableDef: TableDef, where: Expr>>, diff --git a/crates/bindings-typescript/src/vue/useTable.ts b/crates/bindings-typescript/src/vue/useTable.ts index 82e0181ec10..62fa34d4cb4 100644 --- a/crates/bindings-typescript/src/vue/useTable.ts +++ b/crates/bindings-typescript/src/vue/useTable.ts @@ -13,6 +13,24 @@ import type { EventContextInterface } from '../sdk/db_connection_impl'; import type { UntypedRemoteModule } from '../sdk/spacetime_module'; import type { RowType, UntypedTableDef } from '../lib/table'; import type { Prettify } from '../lib/type_util'; +import { + type Value, + type Expr, + type ColumnsFromRow, + eq, + and, + or, + isEq, + isAnd, + isOr, + evaluate, + toString, + where, + classifyMembership, +} from '../lib/filter'; + +export { eq, and, or, isEq, isAnd, isOr, where }; +export type { Value, Expr }; export interface UseTableCallbacks { onInsert?: (row: RowType) => void; @@ -20,170 +38,6 @@ export interface UseTableCallbacks { onUpdate?: (oldRow: RowType, newRow: RowType) => void; } -export type Value = string | number | boolean; - -export type Expr = - | { type: 'eq'; key: Column; value: Value } - | { type: 'and'; children: Expr[] } - | { type: 'or'; children: Expr[] }; - -export const eq = ( - key: Column, - value: Value -): Expr => ({ type: 'eq', key, value }); - -export const and = ( - ...children: Expr[] -): Expr => { - const flat: Expr[] = []; - for (const c of children) { - if (!c) continue; - if (c.type === 'and') flat.push(...c.children); - else flat.push(c); - } - const pruned = flat.filter(Boolean); - if (pruned.length === 0) return { type: 'and', children: [] }; - if (pruned.length === 1) return pruned[0]; - return { type: 'and', children: pruned }; -}; - -export const or = ( - ...children: Expr[] -): Expr => { - const flat: Expr[] = []; - for (const c of children) { - if (!c) continue; - if (c.type === 'or') flat.push(...c.children); - else flat.push(c); - } - const pruned = flat.filter(Boolean); - if (pruned.length === 0) return { type: 'or', children: [] }; - if (pruned.length === 1) return pruned[0]; - return { type: 'or', children: pruned }; -}; - -export const isEq = ( - e: Expr -): e is Extract, { type: 'eq' }> => e.type === 'eq'; -export const isAnd = ( - e: Expr -): e is Extract, { type: 'and' }> => e.type === 'and'; -export const isOr = ( - e: Expr -): e is Extract, { type: 'or' }> => e.type === 'or'; - -export function evaluate( - expr: Expr, - row: Record -): boolean { - switch (expr.type) { - case 'eq': { - const v = row[expr.key]; - if ( - typeof v === 'string' || - typeof v === 'number' || - typeof v === 'boolean' - ) { - return v === expr.value; - } - return false; - } - case 'and': - return ( - expr.children.length === 0 || expr.children.every(c => evaluate(c, row)) - ); - case 'or': - return ( - expr.children.length !== 0 && expr.children.some(c => evaluate(c, row)) - ); - } -} - -function formatValue(v: Value): string { - switch (typeof v) { - case 'string': - return `'${v.replace(/'/g, "''")}'`; - case 'number': - return Number.isFinite(v) ? String(v) : `'${String(v)}'`; - case 'boolean': - return v ? 'TRUE' : 'FALSE'; - } -} - -function escapeIdent(id: string): string { - if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(id)) return id; - return `"${id.replace(/"/g, '""')}"`; -} - -function parenthesize(s: string): string { - if (!s.includes(' AND ') && !s.includes(' OR ')) return s; - return `(${s})`; -} - -export function toString( - tableDef: TableDef, - expr: Expr>> -): string { - switch (expr.type) { - case 'eq': { - const key = tableDef.columns[expr.key].columnMetadata.name ?? expr.key; - return `${escapeIdent(key)} = ${formatValue(expr.value)}`; - } - case 'and': - return parenthesize( - expr.children.map(expr => toString(tableDef, expr)).join(' AND ') - ); - case 'or': - return parenthesize( - expr.children.map(expr => toString(tableDef, expr)).join(' OR ') - ); - } -} - -/** - * This is just the identity function to make things look like SQL. - * @param expr - * @returns - */ -export function where(expr: Expr): Expr { - return expr; -} - -type MembershipChange = 'enter' | 'leave' | 'stayIn' | 'stayOut'; - -function classifyMembership< - Col extends string, - R extends Record, ->(where: Expr | undefined, oldRow: R, newRow: R): MembershipChange { - // No filter: everything is in, so updates are always "stayIn". - if (!where) { - return 'stayIn'; - } - - const oldIn = evaluate(where, oldRow); - const newIn = evaluate(where, newRow); - - if (oldIn && !newIn) { - return 'leave'; - } - if (!oldIn && newIn) { - return 'enter'; - } - if (oldIn && newIn) { - return 'stayIn'; - } - return 'stayOut'; -} - -/** - * Extracts the column names from a RowType whose values are of type Value. - * Note that this will exclude columns that are of type object, array, etc. - */ -type ColumnsFromRow = { - [K in keyof R]-?: R[K] extends Value | undefined ? K : never; -}[keyof R] & - string; - export function useTable( tableDef: TableDef, where: Expr>>, From f162f853752c6da6adff865332f538d7579c00c5 Mon Sep 17 00:00:00 2001 From: Julien Lavocat Date: Mon, 26 Jan 2026 11:38:28 +0100 Subject: [PATCH 3/3] Add Angular integration and template --- crates/bindings-typescript/.editorconfig | 17 + crates/bindings-typescript/package.json | 20 +- .../bindings-typescript/src/angular/index.ts | 13 + .../src/angular/injectors/index.ts | 4 + .../src/angular/injectors/inject-reducer.ts | 50 + .../injectors/inject-spacetimedb-connected.ts | 22 + .../angular/injectors/inject-spacetimedb.ts | 9 + .../src/angular/injectors/inject-table.ts | 212 + .../src/angular/providers/index.ts | 1 + .../angular/providers/provide-spacetimedb.ts | 15 + .../bindings-typescript/src/angular/token.ts | 6 + .../src/react/useReducer.ts | 10 +- crates/bindings-typescript/src/sdk/index.ts | 1 + .../bindings-typescript/src/sdk/type_utils.ts | 10 + .../bindings-typescript/src/vue/useReducer.ts | 10 +- crates/bindings-typescript/tsup.config.ts | 32 + pnpm-lock.yaml | 444 +- templates/angular-ts/.cursor/rules/cursor.mdc | 61 + templates/angular-ts/.editorconfig | 17 + .../.github/copilot-instructions.md | 56 + templates/angular-ts/.gitignore | 44 + templates/angular-ts/.postcssrc.json | 5 + templates/angular-ts/README.md | 59 + templates/angular-ts/angular.json | 73 + templates/angular-ts/package.json | 50 + templates/angular-ts/pnpm-lock.yaml | 5670 +++++++++++++++++ templates/angular-ts/public/favicon.ico | Bin 0 -> 15086 bytes templates/angular-ts/spacetimedb/package.json | 16 + .../angular-ts/spacetimedb/pnpm-lock.yaml | 51 + templates/angular-ts/spacetimedb/src/index.ts | 36 + .../angular-ts/spacetimedb/tsconfig.json | 24 + templates/angular-ts/src/app/app.config.ts | 23 + templates/angular-ts/src/app/app.routes.ts | 9 + templates/angular-ts/src/app/app.ts | 20 + templates/angular-ts/src/app/chat/chat.html | 39 + templates/angular-ts/src/app/chat/chat.ts | 47 + templates/angular-ts/src/index.html | 13 + templates/angular-ts/src/main.ts | 6 + .../angular-ts/src/module_bindings/index.ts | 146 + .../src/module_bindings/messages_table.ts | 18 + .../src/module_bindings/messages_type.ts | 20 + .../src/module_bindings/on_connect_reducer.ts | 13 + .../src/module_bindings/on_connect_type.ts | 15 + .../module_bindings/on_disconnect_reducer.ts | 13 + .../src/module_bindings/on_disconnect_type.ts | 15 + .../src/module_bindings/online_users_table.ts | 15 + .../src/module_bindings/online_users_type.ts | 17 + .../module_bindings/send_message_reducer.ts | 15 + .../src/module_bindings/send_message_type.ts | 17 + templates/angular-ts/src/styles.css | 3 + templates/angular-ts/tsconfig.app.json | 15 + templates/angular-ts/tsconfig.json | 33 + templates/angular-ts/tsconfig.spec.json | 15 + 53 files changed, 7510 insertions(+), 55 deletions(-) create mode 100644 crates/bindings-typescript/.editorconfig create mode 100644 crates/bindings-typescript/src/angular/index.ts create mode 100644 crates/bindings-typescript/src/angular/injectors/index.ts create mode 100644 crates/bindings-typescript/src/angular/injectors/inject-reducer.ts create mode 100644 crates/bindings-typescript/src/angular/injectors/inject-spacetimedb-connected.ts create mode 100644 crates/bindings-typescript/src/angular/injectors/inject-spacetimedb.ts create mode 100644 crates/bindings-typescript/src/angular/injectors/inject-table.ts create mode 100644 crates/bindings-typescript/src/angular/providers/index.ts create mode 100644 crates/bindings-typescript/src/angular/providers/provide-spacetimedb.ts create mode 100644 crates/bindings-typescript/src/angular/token.ts create mode 100644 crates/bindings-typescript/src/sdk/type_utils.ts create mode 100644 templates/angular-ts/.cursor/rules/cursor.mdc create mode 100644 templates/angular-ts/.editorconfig create mode 100644 templates/angular-ts/.github/copilot-instructions.md create mode 100644 templates/angular-ts/.gitignore create mode 100644 templates/angular-ts/.postcssrc.json create mode 100644 templates/angular-ts/README.md create mode 100644 templates/angular-ts/angular.json create mode 100644 templates/angular-ts/package.json create mode 100644 templates/angular-ts/pnpm-lock.yaml create mode 100644 templates/angular-ts/public/favicon.ico create mode 100644 templates/angular-ts/spacetimedb/package.json create mode 100644 templates/angular-ts/spacetimedb/pnpm-lock.yaml create mode 100644 templates/angular-ts/spacetimedb/src/index.ts create mode 100644 templates/angular-ts/spacetimedb/tsconfig.json create mode 100644 templates/angular-ts/src/app/app.config.ts create mode 100644 templates/angular-ts/src/app/app.routes.ts create mode 100644 templates/angular-ts/src/app/app.ts create mode 100644 templates/angular-ts/src/app/chat/chat.html create mode 100644 templates/angular-ts/src/app/chat/chat.ts create mode 100644 templates/angular-ts/src/index.html create mode 100644 templates/angular-ts/src/main.ts create mode 100644 templates/angular-ts/src/module_bindings/index.ts create mode 100644 templates/angular-ts/src/module_bindings/messages_table.ts create mode 100644 templates/angular-ts/src/module_bindings/messages_type.ts create mode 100644 templates/angular-ts/src/module_bindings/on_connect_reducer.ts create mode 100644 templates/angular-ts/src/module_bindings/on_connect_type.ts create mode 100644 templates/angular-ts/src/module_bindings/on_disconnect_reducer.ts create mode 100644 templates/angular-ts/src/module_bindings/on_disconnect_type.ts create mode 100644 templates/angular-ts/src/module_bindings/online_users_table.ts create mode 100644 templates/angular-ts/src/module_bindings/online_users_type.ts create mode 100644 templates/angular-ts/src/module_bindings/send_message_reducer.ts create mode 100644 templates/angular-ts/src/module_bindings/send_message_type.ts create mode 100644 templates/angular-ts/src/styles.css create mode 100644 templates/angular-ts/tsconfig.app.json create mode 100644 templates/angular-ts/tsconfig.json create mode 100644 templates/angular-ts/tsconfig.spec.json diff --git a/crates/bindings-typescript/.editorconfig b/crates/bindings-typescript/.editorconfig new file mode 100644 index 00000000000..f166060da1c --- /dev/null +++ b/crates/bindings-typescript/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/crates/bindings-typescript/package.json b/crates/bindings-typescript/package.json index 65047646f67..6221feab607 100644 --- a/crates/bindings-typescript/package.json +++ b/crates/bindings-typescript/package.json @@ -83,6 +83,12 @@ "import": "./dist/svelte/index.mjs", "require": "./dist/svelte/index.cjs", "default": "./dist/svelte/index.mjs" + }, + "./angular": { + "types": "./dist/angular/index.d.ts", + "import": "./dist/angular/index.mjs", + "require": "./dist/angular/index.cjs", + "default": "./dist/angular/index.mjs" } }, "size-limit": [ @@ -172,10 +178,12 @@ "url-polyfill": "^1.1.14" }, "peerDependencies": { + "@angular/common": "^21.1.1", + "@angular/core": "^21.1.1", "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0", - "vue": "^3.3.0", "svelte": "^4.0.0 || ^5.0.0", - "undici": "^6.19.2" + "undici": "^6.19.2", + "vue": "^3.3.0" }, "peerDependenciesMeta": { "react": { @@ -189,11 +197,16 @@ }, "vue": { "optional": true + }, + "@angular/common": { + "optional": true + }, + "@angular/core": { + "optional": true } }, "devDependencies": { "@eslint/js": "^9.17.0", - "svelte": "^5.0.0", "@size-limit/file": "^11.2.0", "@types/fast-text-encoding": "^1.0.3", "@types/react": "^19.1.13", @@ -205,6 +218,7 @@ "eslint": "^9.33.0", "globals": "^15.14.0", "size-limit": "^11.2.0", + "svelte": "^5.0.0", "ts-node": "^10.9.2", "tsup": "^8.1.0", "typescript": "^5.9.3", diff --git a/crates/bindings-typescript/src/angular/index.ts b/crates/bindings-typescript/src/angular/index.ts new file mode 100644 index 00000000000..64885f4bb6e --- /dev/null +++ b/crates/bindings-typescript/src/angular/index.ts @@ -0,0 +1,13 @@ +export * from './injectors'; +export * from './providers'; +export { + type Value, + type Expr, + eq, + and, + or, + isEq, + isAnd, + isOr, + where, +} from '../lib/filter'; diff --git a/crates/bindings-typescript/src/angular/injectors/index.ts b/crates/bindings-typescript/src/angular/injectors/index.ts new file mode 100644 index 00000000000..88ef2ede18d --- /dev/null +++ b/crates/bindings-typescript/src/angular/injectors/index.ts @@ -0,0 +1,4 @@ +export { injectSpacetimeDB } from './inject-spacetimedb'; +export { injectTable, type TableRows } from './inject-table'; +export { injectSpacetimeDBConnected } from './inject-spacetimedb-connected'; +export { injectReducer } from './inject-reducer'; diff --git a/crates/bindings-typescript/src/angular/injectors/inject-reducer.ts b/crates/bindings-typescript/src/angular/injectors/inject-reducer.ts new file mode 100644 index 00000000000..8c40601cf50 --- /dev/null +++ b/crates/bindings-typescript/src/angular/injectors/inject-reducer.ts @@ -0,0 +1,50 @@ +import type { ParamsType } from '../../sdk'; +import type { UntypedReducerDef } from '../../sdk/reducers'; +import { injectSpacetimeDB } from './inject-spacetimedb'; +import { injectSpacetimeDBConnected } from './inject-spacetimedb-connected'; +import { DestroyRef, effect, inject } from '@angular/core'; + +export function injectReducer( + reducerDef: ReducerDef +) { + const conn = injectSpacetimeDB(); + const isActive = injectSpacetimeDBConnected(); + const destroyRef = inject(DestroyRef); + + const queue: ParamsType[] = []; + const reducerName = reducerDef.accessorName; + + effect(() => { + if (!isActive()) { + return; + } + + const callReducer = (conn.reducers as any)[reducerName] as ( + ...p: ParamsType + ) => void; + + if (queue.length) { + const pending = queue.splice(0); + for (const params of pending) { + callReducer(...params); + } + } + }); + + destroyRef.onDestroy(() => { + queue.splice(0); + }); + + return (...params: ParamsType) => { + if (!isActive()) { + queue.push(params); + return; + } + + const callReducer = (conn.reducers as any)[reducerName] as ( + ...p: ParamsType + ) => void; + + return callReducer(...params); + }; +} diff --git a/crates/bindings-typescript/src/angular/injectors/inject-spacetimedb-connected.ts b/crates/bindings-typescript/src/angular/injectors/inject-spacetimedb-connected.ts new file mode 100644 index 00000000000..c237afa3c23 --- /dev/null +++ b/crates/bindings-typescript/src/angular/injectors/inject-spacetimedb-connected.ts @@ -0,0 +1,22 @@ +import { effect, signal, type Signal } from '@angular/core'; +import { injectSpacetimeDB } from './inject-spacetimedb'; + +export function injectSpacetimeDBConnected(): Signal { + const conn = injectSpacetimeDB(); + + const connectedSignal = signal(conn.isActive); + + // FIXME: Bit of a dirty hack for now, we need to change injectSpacetimeDB + // to return a signal so we can react to changes in connection state properly. + effect(onCleanup => { + const interval = setInterval(() => { + connectedSignal.set(conn.isActive); + }, 100); + + onCleanup(() => { + clearInterval(interval); + }); + }); + + return connectedSignal.asReadonly(); +} diff --git a/crates/bindings-typescript/src/angular/injectors/inject-spacetimedb.ts b/crates/bindings-typescript/src/angular/injectors/inject-spacetimedb.ts new file mode 100644 index 00000000000..99e02554eb4 --- /dev/null +++ b/crates/bindings-typescript/src/angular/injectors/inject-spacetimedb.ts @@ -0,0 +1,9 @@ +import { assertInInjectionContext, inject } from '@angular/core'; +import type { DbConnectionImpl } from '../../sdk'; +import { SPACETIMEDB_TOKEN } from '../token'; + +export function injectSpacetimeDB>(): T { + assertInInjectionContext(injectSpacetimeDB); + const spacetimedb = inject(SPACETIMEDB_TOKEN); + return spacetimedb as T; +} diff --git a/crates/bindings-typescript/src/angular/injectors/inject-table.ts b/crates/bindings-typescript/src/angular/injectors/inject-table.ts new file mode 100644 index 00000000000..5927bd2dbd1 --- /dev/null +++ b/crates/bindings-typescript/src/angular/injectors/inject-table.ts @@ -0,0 +1,212 @@ +import { type Signal, signal, effect } from '@angular/core'; +import type { RowType, UntypedTableDef } from '../../lib/table'; +import type { Prettify } from '../../lib/type_util'; +import { injectSpacetimeDB } from './inject-spacetimedb'; +import { + type Expr, + type ColumnsFromRow, + evaluate, + toString, + classifyMembership, +} from '../../lib/filter'; +import type { EventContextInterface } from '../../sdk'; +import type { UntypedRemoteModule } from '../../sdk/spacetime_module'; + +export type RowTypeDef = Prettify< + RowType +>; + +export interface TableRows { + rows: readonly RowTypeDef[]; + isLoading: boolean; + error?: Error; +} + +export interface InjectTableCallbacks { + onInsert?: (row: RowType) => void; + onDelete?: (row: RowType) => void; + onUpdate?: (oldRow: RowType, newRow: RowType) => void; +} + +export interface InjectTableOptions { + where?: Expr>>; + callbacks?: InjectTableCallbacks>; +} + +/** + * Angular injection function to subscribe to a table in SpacetimeDB and receive live updates. + * + * This function returns a signal containing the table's rows, filtered by an optional `where` clause, + * and provides a loading state until the initial subscription is applied. It also allows you to specify + * callbacks for row insertions, deletions, and updates. + * + * @template TableDef The table definition type. + * + * @param tableDef - The table definition to subscribe to. + * @param options - Optional configuration including where clause and callbacks. + * + * @returns A signal containing the current rows and loading state. + * + * @example + * ```typescript + * export class UsersComponent { + * users = injectTable(User, { + * where: where(eq('isActive', true)), + * callbacks: { + * onInsert: (row) => console.log('Inserted:', row), + * onDelete: (row) => console.log('Deleted:', row), + * onUpdate: (oldRow, newRow) => console.log('Updated:', oldRow, newRow), + * } + * }); + * + * // In template: {{ users().rows.length }} users + * // Loading state: {{ users().isLoading }} + * } + * ``` + */ +export function injectTable( + tableDef: TableDef, + options?: InjectTableOptions +): Signal> { + type UseTableRowType = RowType; + + const conn = injectSpacetimeDB(); + + const tableName = tableDef.name; + const accessorName = tableDef.accessorName; + const whereClause = options?.where; + const callbacks = options?.callbacks; + + const tableSignal = signal>({ + isLoading: true, + rows: [], + }); + + let latestTransactionEvent: any = null; + let subscribeApplied = false; + + const whereKey = whereClause ? toString(tableDef, whereClause) : ''; + const query = + `SELECT * FROM ${tableName}` + (whereClause ? ` WHERE ${whereKey}` : ''); + + // Note: this code is mostly derived from the React useTable implementation + // in order to keep behavior consistent across frameworks. + + const computeSnapshot = (): readonly RowTypeDef[] => { + if (!conn.isActive) { + return []; + } + + const table = conn.db[accessorName]; + + if (whereClause) { + return Array.from(table.iter()).filter(row => + evaluate(whereClause, row as UseTableRowType) + ) as RowTypeDef[]; + } + + return Array.from(table.iter()) as RowTypeDef[]; + }; + + const updateSnapshot = () => { + tableSignal.set({ + rows: computeSnapshot(), + isLoading: !subscribeApplied, + }); + }; + + effect(onCleanup => { + if (!conn.isActive) { + return; + } + + const table = conn.db[accessorName]; + + const onInsert = ( + ctx: EventContextInterface, + row: any + ) => { + if (whereClause && !evaluate(whereClause, row)) { + return; + } + + callbacks?.onInsert?.(row); + + if (ctx.event !== latestTransactionEvent || !latestTransactionEvent) { + latestTransactionEvent = ctx.event; + updateSnapshot(); + } + }; + + const onDelete = ( + ctx: EventContextInterface, + row: any + ) => { + if (whereClause && !evaluate(whereClause, row)) { + return; + } + + callbacks?.onDelete?.(row); + + if (ctx.event !== latestTransactionEvent || !latestTransactionEvent) { + latestTransactionEvent = ctx.event; + updateSnapshot(); + } + }; + + const onUpdate = ( + ctx: EventContextInterface, + oldRow: any, + newRow: any + ) => { + const change = classifyMembership(whereClause, oldRow, newRow); + + switch (change) { + case 'leave': + callbacks?.onDelete?.(oldRow); + break; + case 'enter': + callbacks?.onInsert?.(newRow); + break; + case 'stayIn': + callbacks?.onUpdate?.(oldRow, newRow); + break; + case 'stayOut': + return; + } + + if (ctx.event !== latestTransactionEvent || !latestTransactionEvent) { + latestTransactionEvent = ctx.event; + updateSnapshot(); + } + }; + + table.onInsert(onInsert); + table.onDelete(onDelete); + table.onUpdate?.(onUpdate); + + const subscription = conn + .subscriptionBuilder() + .onApplied(() => { + subscribeApplied = true; + updateSnapshot(); + }) + .onError(err => { + tableSignal.set({ + rows: [], + isLoading: false, + error: err.event, + }); + }) + .subscribe(query); + + onCleanup(() => { + table.removeOnInsert(onInsert); + table.removeOnDelete(onDelete); + table.removeOnUpdate?.(onUpdate); + subscription.unsubscribe(); + }); + }); + + return tableSignal.asReadonly(); +} diff --git a/crates/bindings-typescript/src/angular/providers/index.ts b/crates/bindings-typescript/src/angular/providers/index.ts new file mode 100644 index 00000000000..9d3756fd203 --- /dev/null +++ b/crates/bindings-typescript/src/angular/providers/index.ts @@ -0,0 +1 @@ +export { provideSpacetimeDB } from './provide-spacetimedb'; diff --git a/crates/bindings-typescript/src/angular/providers/provide-spacetimedb.ts b/crates/bindings-typescript/src/angular/providers/provide-spacetimedb.ts new file mode 100644 index 00000000000..d28e56bdb6d --- /dev/null +++ b/crates/bindings-typescript/src/angular/providers/provide-spacetimedb.ts @@ -0,0 +1,15 @@ +import type { FactoryProvider } from '@angular/core'; +import type { DbConnectionBuilder, DbConnectionImpl } from '../../sdk'; +import { SPACETIMEDB_TOKEN } from '../token'; + +export function provideSpacetimeDB( + builder: DbConnectionBuilder> +): FactoryProvider { + return { + provide: SPACETIMEDB_TOKEN, + useFactory: () => { + const conn = builder.build(); + return conn; + }, + }; +} diff --git a/crates/bindings-typescript/src/angular/token.ts b/crates/bindings-typescript/src/angular/token.ts new file mode 100644 index 00000000000..27747ec0243 --- /dev/null +++ b/crates/bindings-typescript/src/angular/token.ts @@ -0,0 +1,6 @@ +import { InjectionToken } from '@angular/core'; +import type { DbConnectionImpl } from '../sdk'; + +export const SPACETIMEDB_TOKEN = new InjectionToken>( + 'SpacetimeDB' +); diff --git a/crates/bindings-typescript/src/react/useReducer.ts b/crates/bindings-typescript/src/react/useReducer.ts index 91634d69f9e..5ca4140b80a 100644 --- a/crates/bindings-typescript/src/react/useReducer.ts +++ b/crates/bindings-typescript/src/react/useReducer.ts @@ -1,15 +1,7 @@ import { useCallback, useEffect, useRef } from 'react'; -import type { InferTypeOfRow } from '../lib/type_builders'; import type { UntypedReducerDef } from '../sdk/reducers'; import { useSpacetimeDB } from './useSpacetimeDB'; -import type { Prettify } from '../lib/type_util'; - -type IsEmptyObject = [keyof T] extends [never] ? true : false; -type MaybeParams = IsEmptyObject extends true ? [] : [params: T]; - -type ParamsType = MaybeParams< - Prettify> ->; +import type { ParamsType } from '../sdk'; export function useReducer( reducerDef: ReducerDef diff --git a/crates/bindings-typescript/src/sdk/index.ts b/crates/bindings-typescript/src/sdk/index.ts index af3cb33668c..be5370b4a46 100644 --- a/crates/bindings-typescript/src/sdk/index.ts +++ b/crates/bindings-typescript/src/sdk/index.ts @@ -10,3 +10,4 @@ export { schema, convertToAccessorMap } from '../lib/schema.ts'; export { table } from '../lib/table.ts'; export { reducerSchema, reducers } from '../lib/reducers.ts'; export { procedureSchema, procedures } from '../lib/procedures.ts'; +export * from './type_utils.ts'; diff --git a/crates/bindings-typescript/src/sdk/type_utils.ts b/crates/bindings-typescript/src/sdk/type_utils.ts new file mode 100644 index 00000000000..2c767c73259 --- /dev/null +++ b/crates/bindings-typescript/src/sdk/type_utils.ts @@ -0,0 +1,10 @@ +import type { InferTypeOfRow } from '.'; +import type { Prettify } from '../lib/type_util'; +import type { UntypedReducerDef } from './reducers'; + +export type IsEmptyObject = [keyof T] extends [never] ? true : false; +export type MaybeParams = IsEmptyObject extends true ? [] : [params: T]; + +export type ParamsType = MaybeParams< + Prettify> +>; diff --git a/crates/bindings-typescript/src/vue/useReducer.ts b/crates/bindings-typescript/src/vue/useReducer.ts index bbcb1afb625..e3a88c161b0 100644 --- a/crates/bindings-typescript/src/vue/useReducer.ts +++ b/crates/bindings-typescript/src/vue/useReducer.ts @@ -1,15 +1,7 @@ import { shallowRef, watch, onUnmounted } from 'vue'; import { useSpacetimeDB } from './useSpacetimeDB'; -import type { InferTypeOfRow } from '../lib/type_builders'; import type { UntypedReducerDef } from '../sdk/reducers'; -import type { Prettify } from '../lib/type_util'; - -type IsEmptyObject = [keyof T] extends [never] ? true : false; -type MaybeParams = IsEmptyObject extends true ? [] : [params: T]; - -type ParamsType = MaybeParams< - Prettify> ->; +import type { ParamsType } from '../sdk'; export function useReducer( reducerDef: ReducerDef diff --git a/crates/bindings-typescript/tsup.config.ts b/crates/bindings-typescript/tsup.config.ts index 1887164824c..080ca332da8 100644 --- a/crates/bindings-typescript/tsup.config.ts +++ b/crates/bindings-typescript/tsup.config.ts @@ -140,6 +140,38 @@ export default defineConfig([ esbuildOptions: commonEsbuildTweaks(), }, + // Angular subpath (SSR-friendly): dist/angular/index.{mjs,cjs} + { + entry: { index: 'src/angular/index.ts' }, + format: ['esm', 'cjs'], + target: 'es2022', + outDir: 'dist/angular', + dts: false, + sourcemap: true, + clean: true, + platform: 'neutral', + treeshake: 'smallest', + external: ['@angular/core', '@angular/common'], + outExtension, + esbuildOptions: commonEsbuildTweaks(), + }, + + // Angular subpath (browser ESM): dist/browser/angular/index.mjs + { + entry: { index: 'src/angular/index.ts' }, + format: ['esm'], + target: 'es2022', + outDir: 'dist/browser/angular', + dts: false, + sourcemap: true, + clean: true, + platform: 'browser', + treeshake: 'smallest', + external: ['@angular/core', '@angular/common'], + outExtension, + esbuildOptions: commonEsbuildTweaks(), + }, + // SDK subpath (SSR-friendly): dist/sdk/index.{mjs,cjs} { entry: { index: 'src/sdk/index.ts' }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b677fa63f3..09e4835d93e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,12 @@ importers: crates/bindings-typescript: dependencies: + '@angular/common': + specifier: ^21.1.1 + version: 21.1.1(@angular/core@21.1.1(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': + specifier: ^21.1.1 + version: 21.1.1(rxjs@7.8.2) base64-js: specifier: ^1.5.1 version: 1.5.1 @@ -128,7 +134,7 @@ importers: version: 8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.3) vite: specifier: ^7.1.5 - version: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + version: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) vitest: specifier: ^3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(jsdom@26.1.0)(terser@5.43.1)(tsx@4.20.4) @@ -150,13 +156,13 @@ importers: version: 18.3.7(@types/react@18.3.23) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.7.0(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + version: 4.7.0(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) typescript: specifier: ^5.2.2 version: 5.9.2 vite: specifier: ^7.1.5 - version: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + version: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) docs: dependencies: @@ -168,7 +174,7 @@ importers: version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/plugin-content-docs': specifier: 3.9.2 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/preset-classic': specifier: 3.9.2 version: 3.9.2(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.6.3) @@ -275,7 +281,7 @@ importers: version: 5.6.3 vite: specifier: ^7.1.5 - version: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + version: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) templates/chat-react-ts: dependencies: @@ -309,7 +315,7 @@ importers: version: 18.3.7(@types/react@18.3.23) '@vitejs/plugin-react': specifier: ^5.0.2 - version: 5.0.2(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + version: 5.0.2(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) eslint: specifier: ^9.17.0 version: 9.33.0(jiti@2.5.1) @@ -336,7 +342,7 @@ importers: version: 8.40.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.6.3) vite: specifier: ^7.1.5 - version: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + version: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) vitest: specifier: 3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(jiti@2.5.1)(jsdom@26.1.0)(terser@5.43.1)(tsx@4.20.4) @@ -367,13 +373,13 @@ importers: version: 18.3.7(@types/react@18.3.23) '@vitejs/plugin-react': specifier: ^5.0.2 - version: 5.0.2(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + version: 5.0.2(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) typescript: specifier: ~5.6.2 version: 5.6.3 vite: specifier: ^7.1.5 - version: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + version: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) templates/svelte-ts: dependencies: @@ -527,6 +533,26 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@angular/common@21.1.1': + resolution: {integrity: sha512-Di2I6TooHdKun3SqRr45o4LbWJq/ZdwUt3fg0X3obPYaP/f6TrFQ4TMjcl03EfPufPtoQx6O+d32rcWVLhDxyw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/core': 21.1.1 + rxjs: ^6.5.3 || ^7.4.0 + + '@angular/core@21.1.1': + resolution: {integrity: sha512-KFRCEhsi02pY1EqJ5rnze4mzSaacqh14D8goDhtmARiUH0tefaHR+uKyu4bKSrWga2T/ExG0DJX52LhHRs2qSw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/compiler': 21.1.1 + rxjs: ^6.5.3 || ^7.4.0 + zone.js: ~0.15.0 || ~0.16.0 + peerDependenciesMeta: + '@angular/compiler': + optional: true + zone.js: + optional: true + '@apollo/client@3.14.0': resolution: {integrity: sha512-0YQKKRIxiMlIou+SekQqdCo0ZTHxOcES+K8vKB53cIDpwABNR0P0yRzPgsbgcj3zRJniD93S/ontsnZsCLZrxQ==} peerDependencies: @@ -1717,156 +1743,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.9': resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.9': resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.9': resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.9': resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.9': resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.9': resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.9': resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.9': resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.9': resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.9': resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.9': resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.9': resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.9': resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.9': resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.9': resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.9': resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.9': resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.9': resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.9': resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.9': resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.9': resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.9': resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.9': resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.9': resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.9': resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.7.0': resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5124,6 +5306,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -7933,6 +8120,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} @@ -8818,8 +9008,8 @@ packages: yaml: optional: true - vite@7.1.5: - resolution: {integrity: sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9278,6 +9468,17 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.30 + '@angular/common@21.1.1(@angular/core@21.1.1(rxjs@7.8.2))(rxjs@7.8.2)': + dependencies: + '@angular/core': 21.1.1(rxjs@7.8.2) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@angular/core@21.1.1(rxjs@7.8.2)': + dependencies: + rxjs: 7.8.2 + tslib: 2.8.1 + '@apollo/client@3.14.0(@types/react@18.3.23)(graphql-ws@5.16.2(graphql@16.11.0))(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) @@ -10737,7 +10938,7 @@ snapshots: '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -10774,6 +10975,46 @@ snapshots: - webpack-cli '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react-router-config': 5.0.11 + combine-promises: 1.2.0 + fs-extra: 11.3.2 + js-yaml: 4.1.0 + lodash: 4.17.21 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + schema-dts: 1.1.5 + tslib: 2.8.1 + utility-types: 3.11.0 + webpack: 5.102.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 @@ -11042,7 +11283,7 @@ snapshots: dependencies: '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) @@ -11090,7 +11331,7 @@ snapshots: '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.9.2 @@ -11130,7 +11371,7 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11154,12 +11395,36 @@ snapshots: - uglify-js - webpack-cli + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/history': 4.7.11 + '@types/react': 18.3.23 + '@types/react-router-config': 5.0.11 + clsx: 2.1.1 + parse-numeric-range: 1.3.0 + prism-react-renderer: 2.4.1(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.6.3)': dependencies: '@docsearch/react': 4.2.0(@algolia/client-search@5.39.0)(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.9.2 '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11448,81 +11713,159 @@ snapshots: '@esbuild/aix-ppc64@0.25.9': optional: true + '@esbuild/aix-ppc64@0.27.2': + optional: true + '@esbuild/android-arm64@0.25.9': optional: true + '@esbuild/android-arm64@0.27.2': + optional: true + '@esbuild/android-arm@0.25.9': optional: true + '@esbuild/android-arm@0.27.2': + optional: true + '@esbuild/android-x64@0.25.9': optional: true + '@esbuild/android-x64@0.27.2': + optional: true + '@esbuild/darwin-arm64@0.25.9': optional: true + '@esbuild/darwin-arm64@0.27.2': + optional: true + '@esbuild/darwin-x64@0.25.9': optional: true + '@esbuild/darwin-x64@0.27.2': + optional: true + '@esbuild/freebsd-arm64@0.25.9': optional: true + '@esbuild/freebsd-arm64@0.27.2': + optional: true + '@esbuild/freebsd-x64@0.25.9': optional: true + '@esbuild/freebsd-x64@0.27.2': + optional: true + '@esbuild/linux-arm64@0.25.9': optional: true + '@esbuild/linux-arm64@0.27.2': + optional: true + '@esbuild/linux-arm@0.25.9': optional: true + '@esbuild/linux-arm@0.27.2': + optional: true + '@esbuild/linux-ia32@0.25.9': optional: true + '@esbuild/linux-ia32@0.27.2': + optional: true + '@esbuild/linux-loong64@0.25.9': optional: true + '@esbuild/linux-loong64@0.27.2': + optional: true + '@esbuild/linux-mips64el@0.25.9': optional: true + '@esbuild/linux-mips64el@0.27.2': + optional: true + '@esbuild/linux-ppc64@0.25.9': optional: true + '@esbuild/linux-ppc64@0.27.2': + optional: true + '@esbuild/linux-riscv64@0.25.9': optional: true + '@esbuild/linux-riscv64@0.27.2': + optional: true + '@esbuild/linux-s390x@0.25.9': optional: true + '@esbuild/linux-s390x@0.27.2': + optional: true + '@esbuild/linux-x64@0.25.9': optional: true + '@esbuild/linux-x64@0.27.2': + optional: true + '@esbuild/netbsd-arm64@0.25.9': optional: true + '@esbuild/netbsd-arm64@0.27.2': + optional: true + '@esbuild/netbsd-x64@0.25.9': optional: true + '@esbuild/netbsd-x64@0.27.2': + optional: true + '@esbuild/openbsd-arm64@0.25.9': optional: true + '@esbuild/openbsd-arm64@0.27.2': + optional: true + '@esbuild/openbsd-x64@0.25.9': optional: true + '@esbuild/openbsd-x64@0.27.2': + optional: true + '@esbuild/openharmony-arm64@0.25.9': optional: true + '@esbuild/openharmony-arm64@0.27.2': + optional: true + '@esbuild/sunos-x64@0.25.9': optional: true + '@esbuild/sunos-x64@0.27.2': + optional: true + '@esbuild/win32-arm64@0.25.9': optional: true + '@esbuild/win32-arm64@0.27.2': + optional: true + '@esbuild/win32-ia32@0.25.9': optional: true + '@esbuild/win32-ia32@0.27.2': + optional: true + '@esbuild/win32-x64@0.25.9': optional: true + '@esbuild/win32-x64@0.27.2': + optional: true + '@eslint-community/eslint-utils@4.7.0(eslint@9.33.0(jiti@2.5.1))': dependencies: eslint: 9.33.0(jiti@2.5.1) @@ -13648,7 +13991,7 @@ snapshots: '@vercel/oidc@3.0.3': {} - '@vitejs/plugin-react@4.7.0(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': + '@vitejs/plugin-react@4.7.0(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': dependencies: '@babel/core': 7.28.3 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.3) @@ -13656,11 +13999,11 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@5.0.2(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': + '@vitejs/plugin-react@5.0.2(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': dependencies: '@babel/core': 7.28.3 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.3) @@ -13668,7 +14011,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.34 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) transitivePeerDependencies: - supports-color @@ -13704,21 +14047,21 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) - '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) '@vitest/pretty-format@3.2.4': dependencies: @@ -15879,6 +16222,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.9 '@esbuild/win32-x64': 0.25.9 + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + escalade@3.1.1: {} escalade@3.2.0: {} @@ -19316,6 +19688,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + sade@1.8.1: dependencies: mri: 1.2.0 @@ -20235,7 +20611,7 @@ snapshots: debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) transitivePeerDependencies: - '@types/node' - jiti @@ -20256,7 +20632,7 @@ snapshots: debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) transitivePeerDependencies: - '@types/node' - jiti @@ -20286,9 +20662,9 @@ snapshots: terser: 5.43.1 tsx: 4.20.4 - vite@7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4): + vite@7.3.1(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4): dependencies: - esbuild: 0.25.9 + esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -20301,9 +20677,9 @@ snapshots: terser: 5.43.1 tsx: 4.20.4 - vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4): + vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4): dependencies: - esbuild: 0.25.9 + esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -20324,7 +20700,7 @@ snapshots: dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -20342,7 +20718,7 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.5(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) vite-node: 3.2.4(@types/node@22.18.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) why-is-node-running: 2.3.0 optionalDependencies: @@ -20367,7 +20743,7 @@ snapshots: dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -20385,7 +20761,7 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) + vite: 7.3.1(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(tsx@4.20.4) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/templates/angular-ts/.cursor/rules/cursor.mdc b/templates/angular-ts/.cursor/rules/cursor.mdc new file mode 100644 index 00000000000..fa815dc5c8d --- /dev/null +++ b/templates/angular-ts/.cursor/rules/cursor.mdc @@ -0,0 +1,61 @@ +--- +context: true +priority: high +scope: project +--- + +You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices. + +## TypeScript Best Practices + +- Use strict type checking +- Prefer type inference when the type is obvious +- Avoid the `any` type; use `unknown` when type is uncertain + +## Angular Best Practices + +- Always use standalone components over NgModules +- Must NOT set `standalone: true` inside Angular decorators. It's the default in Angular v20+. +- Use signals for state management +- Implement lazy loading for feature routes +- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead +- Use `NgOptimizedImage` for all static images. + - `NgOptimizedImage` does not work for inline base64 images. + +## Accessibility Requirements + +- It MUST pass all AXE checks. +- It MUST follow all WCAG AA minimums, including focus management, color contrast, and ARIA attributes. + +### Components + +- Keep components small and focused on a single responsibility +- Use `input()` and `output()` functions instead of decorators +- Use `computed()` for derived state +- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator +- Prefer inline templates for small components +- Prefer Reactive forms instead of Template-driven ones +- Do NOT use `ngClass`, use `class` bindings instead +- Do NOT use `ngStyle`, use `style` bindings instead +- When using external templates/styles, use paths relative to the component TS file. + +## State Management + +- Use signals for local component state +- Use `computed()` for derived state +- Keep state transformations pure and predictable +- Do NOT use `mutate` on signals, use `update` or `set` instead + +## Templates + +- Keep templates simple and avoid complex logic +- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` +- Use the async pipe to handle observables +- Do not assume globals like (`new Date()`) are available. +- Do not write arrow functions in templates (they are not supported). + +## Services + +- Design services around a single responsibility +- Use the `providedIn: 'root'` option for singleton services +- Use the `inject()` function instead of constructor injection diff --git a/templates/angular-ts/.editorconfig b/templates/angular-ts/.editorconfig new file mode 100644 index 00000000000..f166060da1c --- /dev/null +++ b/templates/angular-ts/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/templates/angular-ts/.github/copilot-instructions.md b/templates/angular-ts/.github/copilot-instructions.md new file mode 100644 index 00000000000..34c3b3601dd --- /dev/null +++ b/templates/angular-ts/.github/copilot-instructions.md @@ -0,0 +1,56 @@ + +You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices. + +## TypeScript Best Practices + +- Use strict type checking +- Prefer type inference when the type is obvious +- Avoid the `any` type; use `unknown` when type is uncertain + +## Angular Best Practices + +- Always use standalone components over NgModules +- Must NOT set `standalone: true` inside Angular decorators. It's the default in Angular v20+. +- Use signals for state management +- Implement lazy loading for feature routes +- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead +- Use `NgOptimizedImage` for all static images. + - `NgOptimizedImage` does not work for inline base64 images. + +## Accessibility Requirements + +- It MUST pass all AXE checks. +- It MUST follow all WCAG AA minimums, including focus management, color contrast, and ARIA attributes. + +### Components + +- Keep components small and focused on a single responsibility +- Use `input()` and `output()` functions instead of decorators +- Use `computed()` for derived state +- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator +- Prefer inline templates for small components +- Prefer Reactive forms instead of Template-driven ones +- Do NOT use `ngClass`, use `class` bindings instead +- Do NOT use `ngStyle`, use `style` bindings instead +- When using external templates/styles, use paths relative to the component TS file. + +## State Management + +- Use signals for local component state +- Use `computed()` for derived state +- Keep state transformations pure and predictable +- Do NOT use `mutate` on signals, use `update` or `set` instead + +## Templates + +- Keep templates simple and avoid complex logic +- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` +- Use the async pipe to handle observables +- Do not assume globals like (`new Date()`) are available. +- Do not write arrow functions in templates (they are not supported). + +## Services + +- Design services around a single responsibility +- Use the `providedIn: 'root'` option for singleton services +- Use the `inject()` function instead of constructor injection diff --git a/templates/angular-ts/.gitignore b/templates/angular-ts/.gitignore new file mode 100644 index 00000000000..854acd5fc03 --- /dev/null +++ b/templates/angular-ts/.gitignore @@ -0,0 +1,44 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/mcp.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings +__screenshots__/ + +# System files +.DS_Store +Thumbs.db diff --git a/templates/angular-ts/.postcssrc.json b/templates/angular-ts/.postcssrc.json new file mode 100644 index 00000000000..72f908df1b3 --- /dev/null +++ b/templates/angular-ts/.postcssrc.json @@ -0,0 +1,5 @@ +{ + "plugins": { + "@tailwindcss/postcss": {} + } +} \ No newline at end of file diff --git a/templates/angular-ts/README.md b/templates/angular-ts/README.md new file mode 100644 index 00000000000..b53e11be788 --- /dev/null +++ b/templates/angular-ts/README.md @@ -0,0 +1,59 @@ +# AngularTs + +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.1. + +## Development server + +To start a local development server, run: + +```bash +ng serve +``` + +Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. + +## Code scaffolding + +Angular CLI includes powerful code scaffolding tools. To generate a new component, run: + +```bash +ng generate component component-name +``` + +For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: + +```bash +ng generate --help +``` + +## Building + +To build the project run: + +```bash +ng build +``` + +This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. + +## Running unit tests + +To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: + +```bash +ng test +``` + +## Running end-to-end tests + +For end-to-end (e2e) testing, run: + +```bash +ng e2e +``` + +Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. + +## Additional Resources + +For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/templates/angular-ts/angular.json b/templates/angular-ts/angular.json new file mode 100644 index 00000000000..ba229a7e143 --- /dev/null +++ b/templates/angular-ts/angular.json @@ -0,0 +1,73 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm" + }, + "newProjectRoot": "projects", + "projects": { + "angular-ts": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-ts:build:production" + }, + "development": { + "buildTarget": "angular-ts:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test" + } + } + } + } +} diff --git a/templates/angular-ts/package.json b/templates/angular-ts/package.json new file mode 100644 index 00000000000..5138b4f22f9 --- /dev/null +++ b/templates/angular-ts/package.json @@ -0,0 +1,50 @@ +{ + "name": "angular-ts", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "spacetime:generate": "spacetime generate --lang typescript --out-dir src/module_bindings --project-path spacetimedb", + "spacetime:publish:local": "spacetime publish --project-path spacetimedb --server local angular-ts -c", + "spacetime:publish": "spacetime publish --project-path spacetimedb --server maincloud angular-ts" + }, + "prettier": { + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] + }, + "private": true, + "packageManager": "pnpm@9.7.0", + "dependencies": { + "@angular/common": "21.1.1", + "@angular/compiler": "21.1.1", + "@angular/core": "21.1.1", + "@angular/forms": "21.1.1", + "@angular/platform-browser": "21.1.1", + "@angular/router": "21.1.1", + "rxjs": "~7.8.0", + "spacetimedb": "file:../../crates/bindings-typescript", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/build": "^21.1.1", + "@angular/cli": "^21.1.1", + "@angular/compiler-cli": "^21.1.0", + "@tailwindcss/postcss": "^4.1.12", + "jsdom": "^27.1.0", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.12", + "typescript": "~5.9.2", + "vitest": "^4.0.8" + } +} diff --git a/templates/angular-ts/pnpm-lock.yaml b/templates/angular-ts/pnpm-lock.yaml new file mode 100644 index 00000000000..889bd897135 --- /dev/null +++ b/templates/angular-ts/pnpm-lock.yaml @@ -0,0 +1,5670 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@angular/common': + specifier: 21.1.1 + version: 21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/compiler': + specifier: 21.1.1 + version: 21.1.1 + '@angular/core': + specifier: 21.1.1 + version: 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + '@angular/forms': + specifier: 21.1.1 + version: 21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)))(rxjs@7.8.2) + '@angular/platform-browser': + specifier: 21.1.1 + version: 21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)) + '@angular/router': + specifier: 21.1.1 + version: 21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)))(rxjs@7.8.2) + rxjs: + specifier: ~7.8.0 + version: 7.8.2 + spacetimedb: + specifier: file:../../crates/bindings-typescript + version: file:../../crates/bindings-typescript(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)) + tslib: + specifier: ^2.3.0 + version: 2.8.1 + devDependencies: + '@angular/build': + specifier: ^21.1.1 + version: 21.1.1(@angular/compiler-cli@21.1.1(@angular/compiler@21.1.1)(typescript@5.9.3))(@angular/compiler@21.1.1)(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)))(chokidar@5.0.0)(jiti@2.6.1)(lightningcss@1.30.2)(postcss@8.5.6)(tailwindcss@4.1.18)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.0.18(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.97.1)) + '@angular/cli': + specifier: ^21.1.1 + version: 21.1.1(chokidar@5.0.0)(hono@4.11.5) + '@angular/compiler-cli': + specifier: ^21.1.0 + version: 21.1.1(@angular/compiler@21.1.1)(typescript@5.9.3) + '@tailwindcss/postcss': + specifier: ^4.1.12 + version: 4.1.18 + jsdom: + specifier: ^27.1.0 + version: 27.4.0 + postcss: + specifier: ^8.5.3 + version: 8.5.6 + tailwindcss: + specifier: ^4.1.12 + version: 4.1.18 + typescript: + specifier: ~5.9.2 + version: 5.9.3 + vitest: + specifier: ^4.0.8 + version: 4.0.18(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.97.1) + +packages: + + '@acemir/cssom@0.9.31': + resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} + + '@algolia/abtesting@1.12.2': + resolution: {integrity: sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-abtesting@5.46.2': + resolution: {integrity: sha512-oRSUHbylGIuxrlzdPA8FPJuwrLLRavOhAmFGgdAvMcX47XsyM+IOGa9tc7/K5SPvBqn4nhppOCEz7BrzOPWc4A==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.46.2': + resolution: {integrity: sha512-EPBN2Oruw0maWOF4OgGPfioTvd+gmiNwx0HmD9IgmlS+l75DatcBkKOPNJN+0z3wBQWUO5oq602ATxIfmTQ8bA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.46.2': + resolution: {integrity: sha512-Hj8gswSJNKZ0oyd0wWissqyasm+wTz1oIsv5ZmLarzOZAp3vFEda8bpDQ8PUhO+DfkbiLyVnAxsPe4cGzWtqkg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.46.2': + resolution: {integrity: sha512-6dBZko2jt8FmQcHCbmNLB0kCV079Mx/DJcySTL3wirgDBUH7xhY1pOuUTLMiGkqM5D8moVZTvTdRKZUJRkrwBA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.46.2': + resolution: {integrity: sha512-1waE2Uqh/PHNeDXGn/PM/WrmYOBiUGSVxAWqiJIj73jqPqvfzZgzdakHscIVaDl6Cp+j5dwjsZ5LCgaUr6DtmA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.46.2': + resolution: {integrity: sha512-EgOzTZkyDcNL6DV0V/24+oBJ+hKo0wNgyrOX/mePBM9bc9huHxIY2352sXmoZ648JXXY2x//V1kropF/Spx83w==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.46.2': + resolution: {integrity: sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.46.2': + resolution: {integrity: sha512-1Uw2OslTWiOFDtt83y0bGiErJYy5MizadV0nHnOoHFWMoDqWW0kQoMFI65pXqRSkVvit5zjXSLik2xMiyQJDWQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.46.2': + resolution: {integrity: sha512-xk9f+DPtNcddWN6E7n1hyNNsATBCHIqAvVGG2EAGHJc4AFYL18uM/kMTiOKXE/LKDPyy1JhIerrh9oYb7RBrgw==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.46.2': + resolution: {integrity: sha512-NApbTPj9LxGzNw4dYnZmj2BoXiAc8NmbbH6qBNzQgXklGklt/xldTvu+FACN6ltFsTzoNU6j2mWNlHQTKGC5+Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.46.2': + resolution: {integrity: sha512-ekotpCwpSp033DIIrsTpYlGUCF6momkgupRV/FA3m62SreTSZUKjgK6VTNyG7TtYfq9YFm/pnh65bATP/ZWJEg==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.46.2': + resolution: {integrity: sha512-gKE+ZFi/6y7saTr34wS0SqYFDcjHW4Wminv8PDZEi0/mE99+hSrbKgJWxo2ztb5eqGirQTgIh1AMVacGGWM1iw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.46.2': + resolution: {integrity: sha512-ciPihkletp7ttweJ8Zt+GukSVLp2ANJHU+9ttiSxsJZThXc4Y2yJ8HGVWesW5jN1zrsZsezN71KrMx/iZsOYpg==} + engines: {node: '>= 14.0.0'} + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@angular-devkit/architect@0.2101.1': + resolution: {integrity: sha512-8x7hKcFs3hnpDaIj9fyzinh4X74oQaMxMsZzBf4dBL7EwokjPIf2fadQsZd8a5M+Ja4tIgTnXH9ySyaRFWGNXA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true + + '@angular-devkit/core@21.1.1': + resolution: {integrity: sha512-rCwfBUemyRoAfrO4c85b49lkPiD5WljWE+IK7vjUNIFFf4TXOS4tg4zxqopUDVE4zEjXORa5oHCEc5HCerjn1g==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^5.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/schematics@21.1.1': + resolution: {integrity: sha512-3ptEOuALghEYEPVbhRa7g8a+YmvmHqHVNqF9XqCbG22nPGWkE58qfNNbXi3tF9iQxzKSGw5Iy5gYUvSvpsdcfw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@angular/build@21.1.1': + resolution: {integrity: sha512-OqlfH7tkahw/lFT6ACU6mqt3AGgTxxT27JTqpzZOeGo1ferR9dq1O6/CT4GiNyr/Z1AMfs7rBWlQH68y1QZb2g==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + '@angular/compiler': ^21.0.0 + '@angular/compiler-cli': ^21.0.0 + '@angular/core': ^21.0.0 + '@angular/localize': ^21.0.0 + '@angular/platform-browser': ^21.0.0 + '@angular/platform-server': ^21.0.0 + '@angular/service-worker': ^21.0.0 + '@angular/ssr': ^21.1.1 + karma: ^6.4.0 + less: ^4.2.0 + ng-packagr: ^21.0.0 + postcss: ^8.4.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + tslib: ^2.3.0 + typescript: '>=5.9 <6.0' + vitest: ^4.0.8 + peerDependenciesMeta: + '@angular/core': + optional: true + '@angular/localize': + optional: true + '@angular/platform-browser': + optional: true + '@angular/platform-server': + optional: true + '@angular/service-worker': + optional: true + '@angular/ssr': + optional: true + karma: + optional: true + less: + optional: true + ng-packagr: + optional: true + postcss: + optional: true + tailwindcss: + optional: true + vitest: + optional: true + + '@angular/cli@21.1.1': + resolution: {integrity: sha512-eXhHuYvruWHBn7lX3GuAyLq29+ELwPADOW8ShzZkWRPNlIDiFDsS5pXrxkM9ez+8f86kfDHh88Twevn4UBUqQg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true + + '@angular/common@21.1.1': + resolution: {integrity: sha512-Di2I6TooHdKun3SqRr45o4LbWJq/ZdwUt3fg0X3obPYaP/f6TrFQ4TMjcl03EfPufPtoQx6O+d32rcWVLhDxyw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/core': 21.1.1 + rxjs: ^6.5.3 || ^7.4.0 + + '@angular/compiler-cli@21.1.1': + resolution: {integrity: sha512-CCB8SZS0BzqLOdOaMpPpOW256msuatYCFDRTaT+awYIY1vQp/eLXzkMTD2uqyHraQy8cReeH/P6optRP9A077Q==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@angular/compiler': 21.1.1 + typescript: '>=5.9 <6.0' + peerDependenciesMeta: + typescript: + optional: true + + '@angular/compiler@21.1.1': + resolution: {integrity: sha512-Urd3bh0zv0MQ//S7RRTanIkOMAZH/A7vSMXUDJ3aflplNs7JNbVqBwDNj8NoX1V+os+fd8JRJOReCc1EpH4ZKQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@angular/core@21.1.1': + resolution: {integrity: sha512-KFRCEhsi02pY1EqJ5rnze4mzSaacqh14D8goDhtmARiUH0tefaHR+uKyu4bKSrWga2T/ExG0DJX52LhHRs2qSw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/compiler': 21.1.1 + rxjs: ^6.5.3 || ^7.4.0 + zone.js: ~0.15.0 || ~0.16.0 + peerDependenciesMeta: + '@angular/compiler': + optional: true + zone.js: + optional: true + + '@angular/forms@21.1.1': + resolution: {integrity: sha512-NBbJOynLOeMsPo03+3dfdxE0P7SB7SXRqoFJ7WP2sOgOIxODna/huo2blmRlnZAVPTn1iQEB9Q+UeyP5c4/1+w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/common': 21.1.1 + '@angular/core': 21.1.1 + '@angular/platform-browser': 21.1.1 + rxjs: ^6.5.3 || ^7.4.0 + + '@angular/platform-browser@21.1.1': + resolution: {integrity: sha512-d6liZjPz29GUZ6dhxytFL/W2nMsYwPpc/E/vZpr5yV+u+gI2VjbnLbl8SG+jjj0/Hyq7s4aGhEKsRrCJJMXgNw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/animations': 21.1.1 + '@angular/common': 21.1.1 + '@angular/core': 21.1.1 + peerDependenciesMeta: + '@angular/animations': + optional: true + + '@angular/router@21.1.1': + resolution: {integrity: sha512-3ypbtH3KfzuVgebdEET9+bRwn1VzP//KI0tIqleCGi4rblP3WQ/HwIGa5Qhdcxmw/kbmABKLRXX2kRUvidKs/Q==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/common': 21.1.1 + '@angular/core': 21.1.1 + '@angular/platform-browser': 21.1.1 + rxjs: ^6.5.3 || ^7.4.0 + + '@asamuzakjp/css-color@4.1.1': + resolution: {integrity: sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==} + + '@asamuzakjp/dom-selector@6.7.6': + resolution: {integrity: sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + + '@babel/code-frame@7.28.6': + resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.6': + resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.6': + resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} + 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.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + 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.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.6': + resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} + engines: {node: '>=6.9.0'} + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + 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.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + 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-syntax-patches-for-csstree@1.0.26': + resolution: {integrity: sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==} + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@exodus/bytes@1.9.0': + resolution: {integrity: sha512-lagqsvnk09NKogQaN/XrtlWeUF8SRhT12odMvbTIIaVObqzwAogL6jhR4DAp0gPuKoM1AOVrKUshJpRdpMFrww==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@noble/hashes': ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + '@noble/hashes': + optional: true + + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@7.10.1': + resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@listr2/prompt-adapter-inquirer@3.0.5': + resolution: {integrity: sha512-WELs+hj6xcilkloBXYf9XXK8tYEnKsgLj01Xl5ONUJpKjmT5hGVUzNUS5tooUxs7pGMrw+jFD/41WpqW4V3LDA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@inquirer/prompts': '>= 3 < 8' + listr2: 9.0.5 + + '@lmdb/lmdb-darwin-arm64@3.4.4': + resolution: {integrity: sha512-XaKL705gDWd6XVls3ATDj13ZdML/LqSIxwgnYpG8xTzH2ifArx8fMMDdvqGE/Emd+W6R90W2fveZcJ0AyS8Y0w==} + cpu: [arm64] + os: [darwin] + + '@lmdb/lmdb-darwin-x64@3.4.4': + resolution: {integrity: sha512-GPHGEVcwJlkD01GmIr7B4kvbIcUDS2+kBadVEd7lU4can1RZaZQLDDBJRrrNfS2Kavvl0VLI/cMv7UASAXGrww==} + cpu: [x64] + os: [darwin] + + '@lmdb/lmdb-linux-arm64@3.4.4': + resolution: {integrity: sha512-mALqr7DE42HsiwVTKpQWxacjHoJk+e9p00RWIJqTACh/hpucxp/0lK/XMh5XzWnU/TDCZLukq1+vNqnNumTP/Q==} + cpu: [arm64] + os: [linux] + + '@lmdb/lmdb-linux-arm@3.4.4': + resolution: {integrity: sha512-cmev5/dZr5ACKri9f6GU6lZCXTjMhV72xujlbOhFCgFXrt4W0TxGsmY8kA1BITvH60JBKE50cSxsiulybAbrrw==} + cpu: [arm] + os: [linux] + + '@lmdb/lmdb-linux-x64@3.4.4': + resolution: {integrity: sha512-QjLs8OcmCNcraAcLoZyFlo0atzBJniQLLwhtR+ymQqS5kLYpV5RqwriL87BW+ZiR9ZiGgZx3evrz5vnWPtJ1fQ==} + cpu: [x64] + os: [linux] + + '@lmdb/lmdb-win32-arm64@3.4.4': + resolution: {integrity: sha512-tr/pwHDlZ33forLGAr0tI04cRmP4SgF93yHbb+2zvZiDEyln5yMHhbKDySxY66aUOkhvBvTuHq9q/3YmTj6ZHQ==} + cpu: [arm64] + os: [win32] + + '@lmdb/lmdb-win32-x64@3.4.4': + resolution: {integrity: sha512-KRzfocJzB/mgoTCqnMawuLSKheHRVTqWfSmouIgYpFs6Hx4zvZSvsZKSCEb5gHmICy7qsx9l06jk3MFTtiFVAQ==} + cpu: [x64] + os: [win32] + + '@modelcontextprotocol/sdk@1.25.2': + resolution: {integrity: sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + cpu: [x64] + os: [win32] + + '@napi-rs/nice-android-arm-eabi@1.1.1': + resolution: {integrity: sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@napi-rs/nice-android-arm64@1.1.1': + resolution: {integrity: sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/nice-darwin-arm64@1.1.1': + resolution: {integrity: sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/nice-darwin-x64@1.1.1': + resolution: {integrity: sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/nice-freebsd-x64@1.1.1': + resolution: {integrity: sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + resolution: {integrity: sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + resolution: {integrity: sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + resolution: {integrity: sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + resolution: {integrity: sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==} + engines: {node: '>= 10'} + cpu: [ppc64] + os: [linux] + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + resolution: {integrity: sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + resolution: {integrity: sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==} + engines: {node: '>= 10'} + cpu: [s390x] + os: [linux] + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + resolution: {integrity: sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/nice-linux-x64-musl@1.1.1': + resolution: {integrity: sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/nice-openharmony-arm64@1.1.1': + resolution: {integrity: sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [openharmony] + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + resolution: {integrity: sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + resolution: {integrity: sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + resolution: {integrity: sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/nice@1.1.1': + resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} + engines: {node: '>= 10'} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + + '@npmcli/agent@4.0.0': + resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/fs@5.0.0': + resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/git@7.0.1': + resolution: {integrity: sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/installed-package-contents@4.0.0': + resolution: {integrity: sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + '@npmcli/node-gyp@5.0.0': + resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/package-json@7.0.4': + resolution: {integrity: sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/promise-spawn@9.0.1': + resolution: {integrity: sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/redact@4.0.0': + resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@npmcli/run-script@10.0.3': + resolution: {integrity: sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@oxc-project/types@0.106.0': + resolution: {integrity: sha512-QdsH3rZq480VnOHSHgPYOhjL8O8LBdcnSjM408BpPCCUc0JYYZPG9Gafl9i3OcGk/7137o+gweb4cCv3WAUykg==} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + + '@rolldown/binding-android-arm64@1.0.0-beta.58': + resolution: {integrity: sha512-mWj5eE4Qc8TbPdGGaaLvBb9XfDPvE1EmZkJQgiGKwchkWH4oAJcRAKMTw7ZHnb1L+t7Ah41sBkAecaIsuUgsug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.58': + resolution: {integrity: sha512-wFxUymI/5R8bH8qZFYDfAxAN9CyISEIYke+95oZPiv6EWo88aa5rskjVcCpKA532R+klFmdqjbbaD56GNmTF4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.58': + resolution: {integrity: sha512-ybp3MkPj23VDV9PhtRwdU5qrGhlViWRV5BjKwO6epaSlUD5lW0WyY+roN3ZAzbma/9RrMTgZ/a/gtQq8YXOcqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.58': + resolution: {integrity: sha512-Evxj3yh7FWvyklUYZa0qTVT9N2zX9TPDqGF056hl8hlCZ9/ndQ2xMv6uw9PD1VlLpukbsqL+/C6M0qwipL0QMg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.58': + resolution: {integrity: sha512-tYeXprDOrEgVHUbPXH6MPso4cM/c6RTkmJNICMQlYdki4hGMh92aj3yU6CKs+4X5gfG0yj5kVUw/L4M685SYag==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.58': + resolution: {integrity: sha512-N78vmZzP6zG967Ohr+MasCjmKtis0geZ1SOVmxrA0/bklTQSzH5kHEjW5Qn+i1taFno6GEre1E40v0wuWsNOQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.58': + resolution: {integrity: sha512-l+p4QVtG72C7wI2SIkNQw/KQtSjuYwS3rV6AKcWrRBF62ClsFUcif5vLaZIEbPrCXu5OFRXigXFJnxYsVVZqdQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.58': + resolution: {integrity: sha512-urzJX0HrXxIh0FfxwWRjfPCMeInU9qsImLQxHBgLp5ivji1EEUnOfux8KxPPnRQthJyneBrN2LeqUix9DYrNaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.58': + resolution: {integrity: sha512-7ijfVK3GISnXIwq/1FZo+KyAUJjL3kWPJ7rViAL6MWeEBhEgRzJ0yEd9I8N9aut8Y8ab+EKFJyRNMWZuUBwQ0A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.58': + resolution: {integrity: sha512-/m7sKZCS+cUULbzyJTIlv8JbjNohxbpAOA6cM+lgWgqVzPee3U6jpwydrib328JFN/gF9A99IZEnuGYqEDJdww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.58': + resolution: {integrity: sha512-6SZk7zMgv+y3wFFQ9qE5P9NnRHcRsptL1ypmudD26PDY+PvFCvfHRkJNfclWnvacVGxjowr7JOL3a9fd1wWhUw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.58': + resolution: {integrity: sha512-sFqfYPnBZ6xBhMkadB7UD0yjEDRvs7ipR3nCggblN+N4ODCXY6qhg/bKL39+W+dgQybL7ErD4EGERVbW9DAWvg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.58': + resolution: {integrity: sha512-AnFWJdAqB8+IDPcGrATYs67Kik/6tnndNJV2jGRmwlbeNiQQ8GhRJU8ETRlINfII0pqi9k4WWLnb00p1QCxw/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.58': + resolution: {integrity: sha512-qWhDs6yFGR5xDfdrwiSa3CWGIHxD597uGE/A9xGqytBjANvh4rLCTTkq7szhMV4+Ygh+PMS90KVJ8xWG/TkX4w==} + + '@rollup/rollup-android-arm-eabi@4.56.0': + resolution: {integrity: sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.56.0': + resolution: {integrity: sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.56.0': + resolution: {integrity: sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.56.0': + resolution: {integrity: sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.56.0': + resolution: {integrity: sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.56.0': + resolution: {integrity: sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.56.0': + resolution: {integrity: sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.56.0': + resolution: {integrity: sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.56.0': + resolution: {integrity: sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.56.0': + resolution: {integrity: sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.56.0': + resolution: {integrity: sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.56.0': + resolution: {integrity: sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.56.0': + resolution: {integrity: sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.56.0': + resolution: {integrity: sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.56.0': + resolution: {integrity: sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.56.0': + resolution: {integrity: sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.56.0': + resolution: {integrity: sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.56.0': + resolution: {integrity: sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.56.0': + resolution: {integrity: sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.56.0': + resolution: {integrity: sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.56.0': + resolution: {integrity: sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.56.0': + resolution: {integrity: sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.56.0': + resolution: {integrity: sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.56.0': + resolution: {integrity: sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.56.0': + resolution: {integrity: sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==} + cpu: [x64] + os: [win32] + + '@schematics/angular@21.1.1': + resolution: {integrity: sha512-WijqITteakpFOplx7IGHIdBOdTU04Ul4qweilY1CRK3KdzQRuAf31KiKUFrJiGW076cyokmAQmBoZcngh9rCNw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@sigstore/bundle@4.0.0': + resolution: {integrity: sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@sigstore/core@3.1.0': + resolution: {integrity: sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@sigstore/protobuf-specs@0.5.0': + resolution: {integrity: sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==} + engines: {node: ^18.17.0 || >=20.5.0} + + '@sigstore/sign@4.1.0': + resolution: {integrity: sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@sigstore/tuf@4.0.1': + resolution: {integrity: sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@sigstore/verify@3.1.0': + resolution: {integrity: sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tailwindcss/node@4.1.18': + resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} + + '@tailwindcss/oxide-android-arm64@4.1.18': + resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.18': + resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} + 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.18': + resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.18': + resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.18': + resolution: {integrity: sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==} + + '@tufjs/canonical-json@2.0.0': + resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@tufjs/models@4.1.0': + resolution: {integrity: sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==} + engines: {node: ^20.17.0 || >=22.9.0} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@vitejs/plugin-basic-ssl@2.1.0': + resolution: {integrity: sha512-dOxxrhgyDIEUADhb/8OlV9JIqYLgos03YorAueTIeOUskLJSEsfwCByjbu98ctXitUN3znXKp0bYD/WHSudCeA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 + + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} + + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + algoliasearch@5.46.2: + resolution: {integrity: sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==} + engines: {node: '>= 14.0.0'} + + ansi-escapes@7.2.0: + resolution: {integrity: sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==} + engines: {node: '>=18'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.9.18: + resolution: {integrity: sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==} + hasBin: true + + beasties@0.3.5: + resolution: {integrity: sha512-NaWu+f4YrJxEttJSm16AzMIFtVldCvaJ68b1L098KpqXmxt9xOLtKoLkKxb8ekhOrLqEJAbvT6n6SEvB/sac7A==} + engines: {node: '>=14.0.0'} + + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacache@20.0.3: + resolution: {integrity: sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==} + engines: {node: ^20.17.0 || >=22.9.0} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001766: + resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@3.4.0: + resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} + engines: {node: '>=18.20'} + + cli-truncate@5.1.1: + resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} + engines: {node: '>=20'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-select@6.0.0: + resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} + + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@7.0.0: + resolution: {integrity: sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==} + engines: {node: '>= 6'} + + cssstyle@5.3.7: + resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} + engines: {node: '>=20'} + + data-urls@6.0.1: + resolution: {integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==} + engines: {node: '>=20'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.278: + resolution: {integrity: sha512-dQ0tM1svDRQOwxnXxm+twlGTjr9Upvt8UFWAgmLsxEzFQxhbti4VwxmMjsDxVC51Zo84swW7FVCXEV+VAkhuPw==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + enhanced-resolve@5.18.4: + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + + express-rate-limit@7.5.1: + resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@13.0.0: + resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} + engines: {node: 20 || >=22} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + hono@4.11.5: + resolution: {integrity: sha512-WemPi9/WfyMwZs+ZUXdiwcCh9Y+m7L+8vki9MzDw3jJ+W9Lc+12HGsd368Qc1vZi1xwW8BWMMsnK5efYKPdt4g==} + engines: {node: '>=16.9.0'} + + hosted-git-info@9.0.2: + resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} + engines: {node: ^20.17.0 || >=22.9.0} + + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore-walk@8.0.0: + resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==} + engines: {node: ^20.17.0 || >=22.9.0} + + immutable@5.1.4: + resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsdom@27.4.0: + resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@5.0.0: + resolution: {integrity: sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + engines: {node: '>= 12.0.0'} + + listr2@9.0.5: + resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} + engines: {node: '>=20.0.0'} + + lmdb@3.4.4: + resolution: {integrity: sha512-+Y2DqovevLkb6DrSQ6SXTYLEd6kvlRbhsxzgJrk7BUfOVA/mt21ak6pFDZDKxiAczHMWxrb02kXBTSTIA0O94A==} + hasBin: true + + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} + engines: {node: '>=18'} + + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-fetch-happen@15.0.3: + resolution: {integrity: sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==} + engines: {node: ^20.17.0 || >=22.9.0} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass-fetch@5.0.0: + resolution: {integrity: sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==} + engines: {node: ^20.17.0 || >=22.9.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msgpackr-extract@3.0.3: + resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + hasBin: true + + msgpackr@1.11.8: + resolution: {integrity: sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==} + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + + node-gyp@12.1.0: + resolution: {integrity: sha512-W+RYA8jBnhSr2vrTtlPYPc1K+CSjGpVDRZxcqJcERZ8ND3A1ThWPHRwctTx3qC3oW99jt726jhdz3Y6ky87J4g==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + npm-bundled@5.0.0: + resolution: {integrity: sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==} + engines: {node: ^20.17.0 || >=22.9.0} + + npm-install-checks@8.0.0: + resolution: {integrity: sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==} + engines: {node: ^20.17.0 || >=22.9.0} + + npm-normalize-package-bin@5.0.0: + resolution: {integrity: sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==} + engines: {node: ^20.17.0 || >=22.9.0} + + npm-package-arg@13.0.2: + resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==} + engines: {node: ^20.17.0 || >=22.9.0} + + npm-packlist@10.0.3: + resolution: {integrity: sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==} + engines: {node: ^20.17.0 || >=22.9.0} + + npm-pick-manifest@11.0.3: + resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + npm-registry-fetch@19.1.1: + resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==} + engines: {node: ^20.17.0 || >=22.9.0} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + ora@9.0.0: + resolution: {integrity: sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==} + engines: {node: '>=20'} + + ordered-binary@1.6.1: + resolution: {integrity: sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==} + + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + pacote@21.0.4: + resolution: {integrity: sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + parse5-html-rewriting-stream@8.0.0: + resolution: {integrity: sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==} + + parse5-sax-parser@8.0.0: + resolution: {integrity: sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==} + + parse5@8.0.0: + resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + piscina@5.1.4: + resolution: {integrity: sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==} + engines: {node: '>=20.x'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + postcss-media-query-parser@0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + proc-log@6.1.0: + resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rolldown@1.0.0-beta.58: + resolution: {integrity: sha512-v1FCjMZCan7f+xGAHBi+mqiE4MlH7I+SXEHSQSJoMOGNNB2UYtvMiejsq9YuUOiZjNeUeV/a21nSFbrUR+4ZCQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.56.0: + resolution: {integrity: sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass@1.97.1: + resolution: {integrity: sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==} + engines: {node: '>=14.0.0'} + hasBin: true + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sigstore@4.1.0: + resolution: {integrity: sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==} + engines: {node: ^20.17.0 || >=22.9.0} + + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} + engines: {node: '>=18'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + spacetimedb@file:../../crates/bindings-typescript: + resolution: {directory: ../../crates/bindings-typescript, type: directory} + peerDependencies: + '@angular/common': ^21.1.1 + '@angular/core': ^21.1.1 + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + svelte: ^4.0.0 || ^5.0.0 + undici: ^6.19.2 + vue: ^3.3.0 + peerDependenciesMeta: + '@angular/common': + optional: true + '@angular/core': + optional: true + react: + optional: true + svelte: + optional: true + undici: + optional: true + vue: + optional: true + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + + ssri@13.0.0: + resolution: {integrity: sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==} + engines: {node: ^20.17.0 || >=22.9.0} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.1.0: + resolution: {integrity: sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==} + engines: {node: '>=20'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tailwindcss@4.1.18: + resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tar@7.5.6: + resolution: {integrity: sha512-xqUeu2JAIJpXyvskvU3uvQW8PAmHrtXp2KDuMJwQqW8Sqq0CaZBAQ+dKS3RBXVhU4wC5NjAdKrmh84241gO9cA==} + engines: {node: '>=18'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + tldts-core@7.0.19: + resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} + + tldts@7.0.19: + resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} + hasBin: true + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tuf-js@4.1.0: + resolution: {integrity: sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici@7.18.2: + resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} + engines: {node: '>=20.18.1'} + + unique-filename@5.0.0: + resolution: {integrity: sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==} + engines: {node: ^20.17.0 || >=22.9.0} + + unique-slug@6.0.0: + resolution: {integrity: sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==} + engines: {node: ^20.17.0 || >=22.9.0} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + url-polyfill@1.1.14: + resolution: {integrity: sha512-p4f3TTAG6ADVF3mwbXw7hGw+QJyw5CnNGvYh5fCuQQZIiuKUswqcznyV3pGDP9j0TSmC4UvRKm8kl1QsX1diiQ==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@7.0.2: + resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} + engines: {node: ^20.17.0 || >=22.9.0} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vite@7.3.0: + resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + 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@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + 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 + + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + watchpack@2.5.0: + resolution: {integrity: sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==} + engines: {node: '>=10.13.0'} + + weak-lru-cache@1.2.2: + resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} + + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + + whatwg-url@15.1.0: + resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} + engines: {node: '>=20'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@6.0.0: + resolution: {integrity: sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + 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==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + + zod@4.3.5: + resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + +snapshots: + + '@acemir/cssom@0.9.31': {} + + '@algolia/abtesting@1.12.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/client-abtesting@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/client-analytics@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/client-common@5.46.2': {} + + '@algolia/client-insights@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/client-personalization@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/client-query-suggestions@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/client-search@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/ingestion@1.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/monitoring@1.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/recommend@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + '@algolia/requester-browser-xhr@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + + '@algolia/requester-fetch@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + + '@algolia/requester-node-http@5.46.2': + dependencies: + '@algolia/client-common': 5.46.2 + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@angular-devkit/architect@0.2101.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 21.1.1(chokidar@5.0.0) + rxjs: 7.8.2 + transitivePeerDependencies: + - chokidar + + '@angular-devkit/core@21.1.1(chokidar@5.0.0)': + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + jsonc-parser: 3.3.1 + picomatch: 4.0.3 + rxjs: 7.8.2 + source-map: 0.7.6 + optionalDependencies: + chokidar: 5.0.0 + + '@angular-devkit/schematics@21.1.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 21.1.1(chokidar@5.0.0) + jsonc-parser: 3.3.1 + magic-string: 0.30.21 + ora: 9.0.0 + rxjs: 7.8.2 + transitivePeerDependencies: + - chokidar + + '@angular/build@21.1.1(@angular/compiler-cli@21.1.1(@angular/compiler@21.1.1)(typescript@5.9.3))(@angular/compiler@21.1.1)(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)))(chokidar@5.0.0)(jiti@2.6.1)(lightningcss@1.30.2)(postcss@8.5.6)(tailwindcss@4.1.18)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.0.18(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.97.1))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.2101.1(chokidar@5.0.0) + '@angular/compiler': 21.1.1 + '@angular/compiler-cli': 21.1.1(@angular/compiler@21.1.1)(typescript@5.9.3) + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@inquirer/confirm': 5.1.21 + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.3.0(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1)) + beasties: 0.3.5 + browserslist: 4.28.1 + esbuild: 0.27.2 + https-proxy-agent: 7.0.6 + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + listr2: 9.0.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + parse5-html-rewriting-stream: 8.0.0 + picomatch: 4.0.3 + piscina: 5.1.4 + rolldown: 1.0.0-beta.58 + sass: 1.97.1 + semver: 7.7.3 + source-map-support: 0.5.21 + tinyglobby: 0.2.15 + tslib: 2.8.1 + typescript: 5.9.3 + undici: 7.18.2 + vite: 7.3.0(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1) + watchpack: 2.5.0 + optionalDependencies: + '@angular/core': 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + '@angular/platform-browser': 21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)) + lmdb: 3.4.4 + postcss: 8.5.6 + tailwindcss: 4.1.18 + vitest: 4.0.18(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.97.1) + transitivePeerDependencies: + - '@types/node' + - chokidar + - jiti + - lightningcss + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@angular/cli@21.1.1(chokidar@5.0.0)(hono@4.11.5)': + dependencies: + '@angular-devkit/architect': 0.2101.1(chokidar@5.0.0) + '@angular-devkit/core': 21.1.1(chokidar@5.0.0) + '@angular-devkit/schematics': 21.1.1(chokidar@5.0.0) + '@inquirer/prompts': 7.10.1 + '@listr2/prompt-adapter-inquirer': 3.0.5(@inquirer/prompts@7.10.1)(listr2@9.0.5) + '@modelcontextprotocol/sdk': 1.25.2(hono@4.11.5)(zod@4.3.5) + '@schematics/angular': 21.1.1(chokidar@5.0.0) + '@yarnpkg/lockfile': 1.1.0 + algoliasearch: 5.46.2 + ini: 6.0.0 + jsonc-parser: 3.3.1 + listr2: 9.0.5 + npm-package-arg: 13.0.2 + pacote: 21.0.4 + parse5-html-rewriting-stream: 8.0.0 + resolve: 1.22.11 + semver: 7.7.3 + yargs: 18.0.0 + zod: 4.3.5 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@types/node' + - chokidar + - hono + - supports-color + + '@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2)': + dependencies: + '@angular/core': 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@angular/compiler-cli@21.1.1(@angular/compiler@21.1.1)(typescript@5.9.3)': + dependencies: + '@angular/compiler': 21.1.1 + '@babel/core': 7.28.5 + '@jridgewell/sourcemap-codec': 1.5.5 + chokidar: 5.0.0 + convert-source-map: 1.9.0 + reflect-metadata: 0.2.2 + semver: 7.7.3 + tslib: 2.8.1 + yargs: 18.0.0 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@angular/compiler@21.1.1': + dependencies: + tslib: 2.8.1 + + '@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)': + dependencies: + rxjs: 7.8.2 + tslib: 2.8.1 + optionalDependencies: + '@angular/compiler': 21.1.1 + + '@angular/forms@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)))(rxjs@7.8.2)': + dependencies: + '@angular/common': 21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + '@angular/platform-browser': 21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)) + '@standard-schema/spec': 1.1.0 + rxjs: 7.8.2 + tslib: 2.8.1 + + '@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))': + dependencies: + '@angular/common': 21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + tslib: 2.8.1 + + '@angular/router@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(@angular/platform-browser@21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)))(rxjs@7.8.2)': + dependencies: + '@angular/common': 21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + '@angular/platform-browser': 21.1.1(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@asamuzakjp/css-color@4.1.1': + 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.1.0(@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: 11.2.5 + + '@asamuzakjp/dom-selector@6.7.6': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.1.0 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.2.5 + + '@asamuzakjp/nwsapi@2.3.9': {} + + '@babel/code-frame@7.28.6': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.6': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.5) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.6': + dependencies: + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.6 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.28.6 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 + + '@babel/parser@7.28.6': + dependencies: + '@babel/types': 7.28.6 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 + + '@babel/traverse@7.28.6': + dependencies: + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@csstools/color-helpers@5.1.0': {} + + '@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.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@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-syntax-patches-for-csstree@1.0.26': {} + + '@csstools/css-tokenizer@3.0.4': {} + + '@emnapi/core@1.8.1': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.27.2': + optional: true + + '@esbuild/android-arm64@0.27.2': + optional: true + + '@esbuild/android-arm@0.27.2': + optional: true + + '@esbuild/android-x64@0.27.2': + optional: true + + '@esbuild/darwin-arm64@0.27.2': + optional: true + + '@esbuild/darwin-x64@0.27.2': + optional: true + + '@esbuild/freebsd-arm64@0.27.2': + optional: true + + '@esbuild/freebsd-x64@0.27.2': + optional: true + + '@esbuild/linux-arm64@0.27.2': + optional: true + + '@esbuild/linux-arm@0.27.2': + optional: true + + '@esbuild/linux-ia32@0.27.2': + optional: true + + '@esbuild/linux-loong64@0.27.2': + optional: true + + '@esbuild/linux-mips64el@0.27.2': + optional: true + + '@esbuild/linux-ppc64@0.27.2': + optional: true + + '@esbuild/linux-riscv64@0.27.2': + optional: true + + '@esbuild/linux-s390x@0.27.2': + optional: true + + '@esbuild/linux-x64@0.27.2': + optional: true + + '@esbuild/netbsd-arm64@0.27.2': + optional: true + + '@esbuild/netbsd-x64@0.27.2': + optional: true + + '@esbuild/openbsd-arm64@0.27.2': + optional: true + + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + + '@esbuild/sunos-x64@0.27.2': + optional: true + + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + + '@exodus/bytes@1.9.0': {} + + '@hono/node-server@1.19.9(hono@4.11.5)': + dependencies: + hono: 4.11.5 + + '@inquirer/ansi@1.0.2': {} + + '@inquirer/checkbox@4.3.2': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10 + yoctocolors-cjs: 2.1.3 + + '@inquirer/confirm@5.1.21': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/type': 3.0.10 + + '@inquirer/core@10.3.2': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/editor@4.2.23': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/external-editor': 1.0.3 + '@inquirer/type': 3.0.10 + + '@inquirer/expand@4.0.23': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/type': 3.0.10 + yoctocolors-cjs: 2.1.3 + + '@inquirer/external-editor@1.0.3': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/input@4.3.1': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/type': 3.0.10 + + '@inquirer/number@3.0.23': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/type': 3.0.10 + + '@inquirer/password@4.0.23': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2 + '@inquirer/type': 3.0.10 + + '@inquirer/prompts@7.10.1': + dependencies: + '@inquirer/checkbox': 4.3.2 + '@inquirer/confirm': 5.1.21 + '@inquirer/editor': 4.2.23 + '@inquirer/expand': 4.0.23 + '@inquirer/input': 4.3.1 + '@inquirer/number': 3.0.23 + '@inquirer/password': 4.0.23 + '@inquirer/rawlist': 4.1.11 + '@inquirer/search': 3.2.2 + '@inquirer/select': 4.4.2 + + '@inquirer/rawlist@4.1.11': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/type': 3.0.10 + yoctocolors-cjs: 2.1.3 + + '@inquirer/search@3.2.2': + dependencies: + '@inquirer/core': 10.3.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10 + yoctocolors-cjs: 2.1.3 + + '@inquirer/select@4.4.2': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10 + yoctocolors-cjs: 2.1.3 + + '@inquirer/type@3.0.10': {} + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@istanbuljs/schema@0.1.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.10.1)(listr2@9.0.5)': + dependencies: + '@inquirer/prompts': 7.10.1 + '@inquirer/type': 3.0.10 + listr2: 9.0.5 + transitivePeerDependencies: + - '@types/node' + + '@lmdb/lmdb-darwin-arm64@3.4.4': + optional: true + + '@lmdb/lmdb-darwin-x64@3.4.4': + optional: true + + '@lmdb/lmdb-linux-arm64@3.4.4': + optional: true + + '@lmdb/lmdb-linux-arm@3.4.4': + optional: true + + '@lmdb/lmdb-linux-x64@3.4.4': + optional: true + + '@lmdb/lmdb-win32-arm64@3.4.4': + optional: true + + '@lmdb/lmdb-win32-x64@3.4.4': + optional: true + + '@modelcontextprotocol/sdk@1.25.2(hono@4.11.5)(zod@4.3.5)': + dependencies: + '@hono/node-server': 1.19.9(hono@4.11.5) + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 7.5.1(express@5.2.1) + jose: 6.1.3 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.5 + zod-to-json-schema: 3.25.1(zod@4.3.5) + transitivePeerDependencies: + - hono + - supports-color + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + optional: true + + '@napi-rs/nice-android-arm-eabi@1.1.1': + optional: true + + '@napi-rs/nice-android-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-x64@1.1.1': + optional: true + + '@napi-rs/nice-freebsd-x64@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + optional: true + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-musl@1.1.1': + optional: true + + '@napi-rs/nice-openharmony-arm64@1.1.1': + optional: true + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + optional: true + + '@napi-rs/nice@1.1.1': + optionalDependencies: + '@napi-rs/nice-android-arm-eabi': 1.1.1 + '@napi-rs/nice-android-arm64': 1.1.1 + '@napi-rs/nice-darwin-arm64': 1.1.1 + '@napi-rs/nice-darwin-x64': 1.1.1 + '@napi-rs/nice-freebsd-x64': 1.1.1 + '@napi-rs/nice-linux-arm-gnueabihf': 1.1.1 + '@napi-rs/nice-linux-arm64-gnu': 1.1.1 + '@napi-rs/nice-linux-arm64-musl': 1.1.1 + '@napi-rs/nice-linux-ppc64-gnu': 1.1.1 + '@napi-rs/nice-linux-riscv64-gnu': 1.1.1 + '@napi-rs/nice-linux-s390x-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-musl': 1.1.1 + '@napi-rs/nice-openharmony-arm64': 1.1.1 + '@napi-rs/nice-win32-arm64-msvc': 1.1.1 + '@napi-rs/nice-win32-ia32-msvc': 1.1.1 + '@napi-rs/nice-win32-x64-msvc': 1.1.1 + optional: true + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@npmcli/agent@4.0.0': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 11.2.5 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + '@npmcli/fs@5.0.0': + dependencies: + semver: 7.7.3 + + '@npmcli/git@7.0.1': + dependencies: + '@npmcli/promise-spawn': 9.0.1 + ini: 6.0.0 + lru-cache: 11.2.5 + npm-pick-manifest: 11.0.3 + proc-log: 6.1.0 + promise-retry: 2.0.1 + semver: 7.7.3 + which: 6.0.0 + + '@npmcli/installed-package-contents@4.0.0': + dependencies: + npm-bundled: 5.0.0 + npm-normalize-package-bin: 5.0.0 + + '@npmcli/node-gyp@5.0.0': {} + + '@npmcli/package-json@7.0.4': + dependencies: + '@npmcli/git': 7.0.1 + glob: 13.0.0 + hosted-git-info: 9.0.2 + json-parse-even-better-errors: 5.0.0 + proc-log: 6.1.0 + semver: 7.7.3 + validate-npm-package-license: 3.0.4 + + '@npmcli/promise-spawn@9.0.1': + dependencies: + which: 6.0.0 + + '@npmcli/redact@4.0.0': {} + + '@npmcli/run-script@10.0.3': + dependencies: + '@npmcli/node-gyp': 5.0.0 + '@npmcli/package-json': 7.0.4 + '@npmcli/promise-spawn': 9.0.1 + node-gyp: 12.1.0 + proc-log: 6.1.0 + which: 6.0.0 + transitivePeerDependencies: + - supports-color + + '@oxc-project/types@0.106.0': {} + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.3 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@rolldown/binding-android-arm64@1.0.0-beta.58': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.58': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.58': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.58': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.58': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.58': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.58': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.58': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.58': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.58': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.58': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.58': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.58': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.58': {} + + '@rollup/rollup-android-arm-eabi@4.56.0': + optional: true + + '@rollup/rollup-android-arm64@4.56.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.56.0': + optional: true + + '@rollup/rollup-darwin-x64@4.56.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.56.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.56.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.56.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.56.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.56.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.56.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.56.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.56.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.56.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.56.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.56.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.56.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.56.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.56.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.56.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.56.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.56.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.56.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.56.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.56.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.56.0': + optional: true + + '@schematics/angular@21.1.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 21.1.1(chokidar@5.0.0) + '@angular-devkit/schematics': 21.1.1(chokidar@5.0.0) + jsonc-parser: 3.3.1 + transitivePeerDependencies: + - chokidar + + '@sigstore/bundle@4.0.0': + dependencies: + '@sigstore/protobuf-specs': 0.5.0 + + '@sigstore/core@3.1.0': {} + + '@sigstore/protobuf-specs@0.5.0': {} + + '@sigstore/sign@4.1.0': + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.1.0 + '@sigstore/protobuf-specs': 0.5.0 + make-fetch-happen: 15.0.3 + proc-log: 6.1.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@4.0.1': + dependencies: + '@sigstore/protobuf-specs': 0.5.0 + tuf-js: 4.1.0 + transitivePeerDependencies: + - supports-color + + '@sigstore/verify@3.1.0': + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.1.0 + '@sigstore/protobuf-specs': 0.5.0 + + '@standard-schema/spec@1.1.0': {} + + '@tailwindcss/node@4.1.18': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.4 + jiti: 2.6.1 + lightningcss: 1.30.2 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.1.18 + + '@tailwindcss/oxide-android-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide@4.1.18': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-x64': 4.1.18 + '@tailwindcss/oxide-freebsd-x64': 4.1.18 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-x64-musl': 4.1.18 + '@tailwindcss/oxide-wasm32-wasi': 4.1.18 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 + + '@tailwindcss/postcss@4.1.18': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.18 + '@tailwindcss/oxide': 4.1.18 + postcss: 8.5.6 + tailwindcss: 4.1.18 + + '@tufjs/canonical-json@2.0.0': {} + + '@tufjs/models@4.1.0': + dependencies: + '@tufjs/canonical-json': 2.0.0 + minimatch: 10.1.1 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@vitejs/plugin-basic-ssl@2.1.0(vite@7.3.0(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1))': + dependencies: + vite: 7.3.0(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1) + + '@vitest/expect@4.0.18': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.18(vite@7.3.1(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1))': + dependencies: + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1) + + '@vitest/pretty-format@4.0.18': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.18': + dependencies: + '@vitest/utils': 4.0.18 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.18': {} + + '@vitest/utils@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + tinyrainbow: 3.0.3 + + '@yarnpkg/lockfile@1.1.0': {} + + abbrev@4.0.0: {} + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + agent-base@7.1.4: {} + + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algoliasearch@5.46.2: + dependencies: + '@algolia/abtesting': 1.12.2 + '@algolia/client-abtesting': 5.46.2 + '@algolia/client-analytics': 5.46.2 + '@algolia/client-common': 5.46.2 + '@algolia/client-insights': 5.46.2 + '@algolia/client-personalization': 5.46.2 + '@algolia/client-query-suggestions': 5.46.2 + '@algolia/client-search': 5.46.2 + '@algolia/ingestion': 1.46.2 + '@algolia/monitoring': 1.46.2 + '@algolia/recommend': 5.46.2 + '@algolia/requester-browser-xhr': 5.46.2 + '@algolia/requester-fetch': 5.46.2 + '@algolia/requester-node-http': 5.46.2 + + ansi-escapes@7.2.0: + dependencies: + environment: 1.1.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + assertion-error@2.0.1: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.9.18: {} + + beasties@0.3.5: + dependencies: + css-select: 6.0.0 + css-what: 7.0.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + htmlparser2: 10.1.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-media-query-parser: 0.2.3 + + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.14.1 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.18 + caniuse-lite: 1.0.30001766 + electron-to-chromium: 1.5.278 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + buffer-from@1.1.2: {} + + bytes@3.1.2: {} + + cacache@20.0.3: + dependencies: + '@npmcli/fs': 5.0.0 + fs-minipass: 3.0.3 + glob: 13.0.0 + lru-cache: 11.2.5 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 7.0.4 + ssri: 13.0.0 + unique-filename: 5.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caniuse-lite@1.0.30001766: {} + + chai@6.2.2: {} + + chalk@5.6.2: {} + + chardet@2.1.1: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + chownr@3.0.0: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@3.4.0: {} + + cli-truncate@5.1.1: + dependencies: + slice-ansi: 7.1.2 + string-width: 8.1.0 + + cli-width@4.1.0: {} + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@6.0.0: + dependencies: + boolbase: 1.0.0 + css-what: 7.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@3.1.0: + dependencies: + mdn-data: 2.12.2 + source-map-js: 1.2.1 + + css-what@7.0.0: {} + + cssstyle@5.3.7: + dependencies: + '@asamuzakjp/css-color': 4.1.1 + '@csstools/css-syntax-patches-for-csstree': 1.0.26 + css-tree: 3.1.0 + lru-cache: 11.2.5 + + data-urls@6.0.1: + dependencies: + whatwg-mimetype: 5.0.0 + whatwg-url: 15.1.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + depd@2.0.0: {} + + detect-libc@2.1.2: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.278: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + encodeurl@2.0.0: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + enhanced-resolve@5.18.4: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + entities@4.5.0: {} + + entities@6.0.1: {} + + entities@7.0.1: {} + + env-paths@2.2.1: {} + + environment@1.1.0: {} + + err-code@2.0.3: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + etag@1.8.1: {} + + eventemitter3@5.0.4: {} + + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + + expect-type@1.3.0: {} + + exponential-backoff@3.1.3: {} + + express-rate-limit@7.5.1(express@5.2.1): + dependencies: + express: 5.2.1 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.1 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-text-encoding@1.0.6: {} + + fast-uri@3.1.0: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.4.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + glob-to-regexp@0.4.1: {} + + glob@13.0.0: + dependencies: + minimatch: 10.1.1 + minipass: 7.1.2 + path-scurry: 2.0.1 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + headers-polyfill@4.0.3: {} + + hono@4.11.5: {} + + hosted-git-info@9.0.2: + dependencies: + lru-cache: 11.2.5 + + html-encoding-sniffer@6.0.0: + dependencies: + '@exodus/bytes': 1.9.0 + transitivePeerDependencies: + - '@noble/hashes' + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + http-cache-semantics@4.2.0: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore-walk@8.0.0: + dependencies: + minimatch: 10.1.1 + + immutable@5.1.4: {} + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + ini@6.0.0: {} + + ip-address@10.1.0: {} + + ipaddr.js@1.9.1: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: + optional: true + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.4.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + optional: true + + is-interactive@2.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-promise@4.0.0: {} + + is-unicode-supported@2.1.0: {} + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.28.5 + '@babel/parser': 7.28.6 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + + jiti@2.6.1: {} + + jose@6.1.3: {} + + js-tokens@4.0.0: {} + + jsdom@27.4.0: + dependencies: + '@acemir/cssom': 0.9.31 + '@asamuzakjp/dom-selector': 6.7.6 + '@exodus/bytes': 1.9.0 + cssstyle: 5.3.7 + data-urls: 6.0.1 + decimal.js: 10.6.0 + html-encoding-sniffer: 6.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + parse5: 8.0.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 15.1.0 + ws: 8.19.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - '@noble/hashes' + - bufferutil + - supports-color + - utf-8-validate + + jsesc@3.1.0: {} + + json-parse-even-better-errors@5.0.0: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + jsonparse@1.3.1: {} + + lightningcss-android-arm64@1.30.2: + optional: true + + lightningcss-darwin-arm64@1.30.2: + optional: true + + lightningcss-darwin-x64@1.30.2: + optional: true + + lightningcss-freebsd-x64@1.30.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.2: + optional: true + + lightningcss-linux-arm64-gnu@1.30.2: + optional: true + + lightningcss-linux-arm64-musl@1.30.2: + optional: true + + lightningcss-linux-x64-gnu@1.30.2: + optional: true + + lightningcss-linux-x64-musl@1.30.2: + optional: true + + lightningcss-win32-arm64-msvc@1.30.2: + optional: true + + lightningcss-win32-x64-msvc@1.30.2: + optional: true + + lightningcss@1.30.2: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 + + listr2@9.0.5: + dependencies: + cli-truncate: 5.1.1 + colorette: 2.0.20 + eventemitter3: 5.0.4 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.2 + + lmdb@3.4.4: + dependencies: + msgpackr: 1.11.8 + node-addon-api: 6.1.0 + node-gyp-build-optional-packages: 5.2.2 + ordered-binary: 1.6.1 + weak-lru-cache: 1.2.2 + optionalDependencies: + '@lmdb/lmdb-darwin-arm64': 3.4.4 + '@lmdb/lmdb-darwin-x64': 3.4.4 + '@lmdb/lmdb-linux-arm': 3.4.4 + '@lmdb/lmdb-linux-arm64': 3.4.4 + '@lmdb/lmdb-linux-x64': 3.4.4 + '@lmdb/lmdb-win32-arm64': 3.4.4 + '@lmdb/lmdb-win32-x64': 3.4.4 + optional: true + + log-symbols@7.0.1: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 + + log-update@6.1.0: + dependencies: + ansi-escapes: 7.2.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 + + lru-cache@11.2.5: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-fetch-happen@15.0.3: + dependencies: + '@npmcli/agent': 4.0.0 + cacache: 20.0.3 + http-cache-semantics: 4.2.0 + minipass: 7.1.2 + minipass-fetch: 5.0.0 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 1.0.0 + proc-log: 6.1.0 + promise-retry: 2.0.1 + ssri: 13.0.0 + transitivePeerDependencies: + - supports-color + + math-intrinsics@1.1.0: {} + + mdn-data@2.12.2: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mimic-function@5.0.1: {} + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + + minipass-fetch@5.0.0: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 3.1.0 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@7.1.2: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + msgpackr-extract@3.0.3: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + optional: true + + msgpackr@1.11.8: + optionalDependencies: + msgpackr-extract: 3.0.3 + optional: true + + mute-stream@2.0.0: {} + + nanoid@3.3.11: {} + + negotiator@1.0.0: {} + + node-addon-api@6.1.0: + optional: true + + node-addon-api@7.1.1: + optional: true + + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.1.2 + optional: true + + node-gyp@12.1.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + graceful-fs: 4.2.11 + make-fetch-happen: 15.0.3 + nopt: 9.0.0 + proc-log: 6.1.0 + semver: 7.7.3 + tar: 7.5.6 + tinyglobby: 0.2.15 + which: 6.0.0 + transitivePeerDependencies: + - supports-color + + node-releases@2.0.27: {} + + nopt@9.0.0: + dependencies: + abbrev: 4.0.0 + + npm-bundled@5.0.0: + dependencies: + npm-normalize-package-bin: 5.0.0 + + npm-install-checks@8.0.0: + dependencies: + semver: 7.7.3 + + npm-normalize-package-bin@5.0.0: {} + + npm-package-arg@13.0.2: + dependencies: + hosted-git-info: 9.0.2 + proc-log: 6.1.0 + semver: 7.7.3 + validate-npm-package-name: 7.0.2 + + npm-packlist@10.0.3: + dependencies: + ignore-walk: 8.0.0 + proc-log: 6.1.0 + + npm-pick-manifest@11.0.3: + dependencies: + npm-install-checks: 8.0.0 + npm-normalize-package-bin: 5.0.0 + npm-package-arg: 13.0.2 + semver: 7.7.3 + + npm-registry-fetch@19.1.1: + dependencies: + '@npmcli/redact': 4.0.0 + jsonparse: 1.3.1 + make-fetch-happen: 15.0.3 + minipass: 7.1.2 + minipass-fetch: 5.0.0 + minizlib: 3.1.0 + npm-package-arg: 13.0.2 + proc-log: 6.1.0 + transitivePeerDependencies: + - supports-color + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obug@2.1.1: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + ora@9.0.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 3.4.0 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 7.0.1 + stdin-discarder: 0.2.2 + string-width: 8.1.0 + strip-ansi: 7.1.2 + + ordered-binary@1.6.1: + optional: true + + p-map@7.0.4: {} + + pacote@21.0.4: + dependencies: + '@npmcli/git': 7.0.1 + '@npmcli/installed-package-contents': 4.0.0 + '@npmcli/package-json': 7.0.4 + '@npmcli/promise-spawn': 9.0.1 + '@npmcli/run-script': 10.0.3 + cacache: 20.0.3 + fs-minipass: 3.0.3 + minipass: 7.1.2 + npm-package-arg: 13.0.2 + npm-packlist: 10.0.3 + npm-pick-manifest: 11.0.3 + npm-registry-fetch: 19.1.1 + proc-log: 6.1.0 + promise-retry: 2.0.1 + sigstore: 4.1.0 + ssri: 13.0.0 + tar: 7.5.6 + transitivePeerDependencies: + - supports-color + + parse5-html-rewriting-stream@8.0.0: + dependencies: + entities: 6.0.1 + parse5: 8.0.0 + parse5-sax-parser: 8.0.0 + + parse5-sax-parser@8.0.0: + dependencies: + parse5: 8.0.0 + + parse5@8.0.0: + dependencies: + entities: 6.0.1 + + parseurl@1.3.3: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.5 + minipass: 7.1.2 + + path-to-regexp@8.3.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + piscina@5.1.4: + optionalDependencies: + '@napi-rs/nice': 1.1.1 + + pkce-challenge@5.0.1: {} + + postcss-media-query-parser@0.2.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.8.1: {} + + proc-log@6.1.0: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + qs@6.14.1: + dependencies: + side-channel: 1.1.0 + + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + + readdirp@4.1.2: {} + + readdirp@5.0.0: {} + + reflect-metadata@0.2.2: {} + + require-from-string@2.0.2: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + retry@0.12.0: {} + + rfdc@1.4.1: {} + + rolldown@1.0.0-beta.58: + dependencies: + '@oxc-project/types': 0.106.0 + '@rolldown/pluginutils': 1.0.0-beta.58 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.58 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.58 + '@rolldown/binding-darwin-x64': 1.0.0-beta.58 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.58 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.58 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.58 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.58 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.58 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.58 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.58 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.58 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.58 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.58 + + rollup@4.56.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.56.0 + '@rollup/rollup-android-arm64': 4.56.0 + '@rollup/rollup-darwin-arm64': 4.56.0 + '@rollup/rollup-darwin-x64': 4.56.0 + '@rollup/rollup-freebsd-arm64': 4.56.0 + '@rollup/rollup-freebsd-x64': 4.56.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.56.0 + '@rollup/rollup-linux-arm-musleabihf': 4.56.0 + '@rollup/rollup-linux-arm64-gnu': 4.56.0 + '@rollup/rollup-linux-arm64-musl': 4.56.0 + '@rollup/rollup-linux-loong64-gnu': 4.56.0 + '@rollup/rollup-linux-loong64-musl': 4.56.0 + '@rollup/rollup-linux-ppc64-gnu': 4.56.0 + '@rollup/rollup-linux-ppc64-musl': 4.56.0 + '@rollup/rollup-linux-riscv64-gnu': 4.56.0 + '@rollup/rollup-linux-riscv64-musl': 4.56.0 + '@rollup/rollup-linux-s390x-gnu': 4.56.0 + '@rollup/rollup-linux-x64-gnu': 4.56.0 + '@rollup/rollup-linux-x64-musl': 4.56.0 + '@rollup/rollup-openbsd-x64': 4.56.0 + '@rollup/rollup-openharmony-arm64': 4.56.0 + '@rollup/rollup-win32-arm64-msvc': 4.56.0 + '@rollup/rollup-win32-ia32-msvc': 4.56.0 + '@rollup/rollup-win32-x64-gnu': 4.56.0 + '@rollup/rollup-win32-x64-msvc': 4.56.0 + fsevents: 2.3.3 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safer-buffer@2.1.2: {} + + sass@1.97.1: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.4 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + semver@6.3.1: {} + + semver@7.7.3: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + sigstore@4.1.0: + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.1.0 + '@sigstore/protobuf-specs': 0.5.0 + '@sigstore/sign': 4.1.0 + '@sigstore/tuf': 4.0.1 + '@sigstore/verify': 3.1.0 + transitivePeerDependencies: + - supports-color + + slice-ansi@7.1.2: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks@2.8.7: + dependencies: + ip-address: 10.1.0 + smart-buffer: 4.2.0 + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + spacetimedb@file:../../crates/bindings-typescript(@angular/common@21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2)): + dependencies: + base64-js: 1.5.1 + fast-text-encoding: 1.0.6 + headers-polyfill: 4.0.3 + prettier: 3.8.1 + statuses: 2.0.2 + url-polyfill: 1.1.14 + optionalDependencies: + '@angular/common': 21.1.1(@angular/core@21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 21.1.1(@angular/compiler@21.1.1)(rxjs@7.8.2) + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.22 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.22 + + spdx-license-ids@3.0.22: {} + + ssri@13.0.0: + dependencies: + minipass: 7.1.2 + + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + stdin-discarder@0.2.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + string-width@8.1.0: + dependencies: + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-tree@3.2.4: {} + + tailwindcss@4.1.18: {} + + tapable@2.3.0: {} + + tar@7.5.6: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.0.3: {} + + tldts-core@7.0.19: {} + + tldts@7.0.19: + dependencies: + tldts-core: 7.0.19 + + toidentifier@1.0.1: {} + + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.19 + + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + + tslib@2.8.1: {} + + tuf-js@4.1.0: + dependencies: + '@tufjs/models': 4.1.0 + debug: 4.4.3 + make-fetch-happen: 15.0.3 + transitivePeerDependencies: + - supports-color + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + typescript@5.9.3: {} + + undici@7.18.2: {} + + unique-filename@5.0.0: + dependencies: + unique-slug: 6.0.0 + + unique-slug@6.0.0: + dependencies: + imurmurhash: 0.1.4 + + unpipe@1.0.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + url-polyfill@1.1.14: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@7.0.2: {} + + vary@1.1.2: {} + + vite@7.3.0(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1): + dependencies: + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.56.0 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.2 + sass: 1.97.1 + + vite@7.3.1(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1): + dependencies: + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.56.0 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.2 + sass: 1.97.1 + + vitest@4.0.18(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.97.1): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.1(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.1) + why-is-node-running: 2.3.0 + optionalDependencies: + jsdom: 27.4.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + watchpack@2.5.0: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + weak-lru-cache@1.2.2: + optional: true + + webidl-conversions@8.0.1: {} + + whatwg-mimetype@4.0.0: {} + + whatwg-mimetype@5.0.0: {} + + whatwg-url@15.1.0: + dependencies: + tr46: 6.0.0 + webidl-conversions: 8.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@6.0.0: + dependencies: + isexe: 3.1.1 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + wrappy@1.0.2: {} + + ws@8.19.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yargs-parser@22.0.0: {} + + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + yoctocolors-cjs@2.1.3: {} + + yoctocolors@2.1.2: {} + + zod-to-json-schema@3.25.1(zod@4.3.5): + dependencies: + zod: 4.3.5 + + zod@4.3.5: {} diff --git a/templates/angular-ts/public/favicon.ico b/templates/angular-ts/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 zcmd^G33O9Omi+`8$@{|M-I6TH3wzF-p5CV8o}7f~KxR60LK+ApEFB<$bcciv%@SmA zV{n>g85YMFFeU*Uvl=i4v)C*qgnb;$GQ=3XTe9{Y%c`mO%su)noNCCQ*@t1WXn|B(hQ7i~ zrUK8|pUkD6#lNo!bt$6)jR!&C?`P5G(`e((P($RaLeq+o0Vd~f11;qB05kdbAOm?r zXv~GYr_sibQO9NGTCdT;+G(!{4Xs@4fPak8#L8PjgJwcs-Mm#nR_Z0s&u?nDX5^~@ z+A6?}g0|=4e_LoE69pPFO`yCD@BCjgKpzMH0O4Xs{Ahc?K3HC5;l=f zg>}alhBXX&);z$E-wai+9TTRtBX-bWYY@cl$@YN#gMd~tM_5lj6W%8ah4;uZ;jP@Q zVbuel1rPA?2@x9Y+u?e`l{Z4ngfG5q5BLH5QsEu4GVpt{KIp1?U)=3+KQ;%7ec8l* zdV=zZgN5>O3G(3L2fqj3;oBbZZw$Ij@`Juz@?+yy#OPw)>#wsTewVgTK9BGt5AbZ&?K&B3GVF&yu?@(Xj3fR3n+ZP0%+wo)D9_xp>Z$`A4 zfV>}NWjO#3lqumR0`gvnffd9Ka}JJMuHS&|55-*mCD#8e^anA<+sFZVaJe7{=p*oX zE_Uv?1>e~ga=seYzh{9P+n5<+7&9}&(kwqSaz;1aD|YM3HBiy<))4~QJSIryyqp| z8nGc(8>3(_nEI4n)n7j(&d4idW1tVLjZ7QbNLXg;LB ziHsS5pXHEjGJZb59KcvS~wv;uZR-+4qEqow`;JCfB*+b^UL^3!?;-^F%yt=VjU|v z39SSqKcRu_NVvz!zJzL0CceJaS6%!(eMshPv_0U5G`~!a#I$qI5Ic(>IONej@aH=f z)($TAT#1I{iCS4f{D2+ApS=$3E7}5=+y(rA9mM#;Cky%b*Gi0KfFA`ofKTzu`AV-9 znW|y@19rrZ*!N2AvDi<_ZeR3O2R{#dh1#3-d%$k${Rx42h+i&GZo5!C^dSL34*AKp z27mTd>k>?V&X;Nl%GZ(>0s`1UN~Hfyj>KPjtnc|)xM@{H_B9rNr~LuH`Gr5_am&Ep zTjZA8hljNj5H1Ipm-uD9rC}U{-vR!eay5&6x6FkfupdpT*84MVwGpdd(}ib)zZ3Ky z7C$pnjc82(W_y_F{PhYj?o!@3__UUvpX)v69aBSzYj3 zdi}YQkKs^SyXyFG2LTRz9{(w}y~!`{EuAaUr6G1M{*%c+kP1olW9z23dSH!G4_HSK zzae-DF$OGR{ofP*!$a(r^5Go>I3SObVI6FLY)N@o<*gl0&kLo-OT{Tl*7nCz>Iq=? zcigIDHtj|H;6sR?or8Wd_a4996GI*CXGU}o;D9`^FM!AT1pBY~?|4h^61BY#_yIfO zKO?E0 zJ{Pc`9rVEI&$xxXu`<5E)&+m(7zX^v0rqofLs&bnQT(1baQkAr^kEsk)15vlzAZ-l z@OO9RF<+IiJ*O@HE256gCt!bF=NM*vh|WVWmjVawcNoksRTMvR03H{p@cjwKh(CL4 z7_PB(dM=kO)!s4fW!1p0f93YN@?ZSG` z$B!JaAJCtW$B97}HNO9(x-t30&E}Mo1UPi@Av%uHj~?T|!4JLwV;KCx8xO#b9IlUW zI6+{a@Wj|<2Y=U;a@vXbxqZNngH8^}LleE_4*0&O7#3iGxfJ%Id>+sb;7{L=aIic8 z|EW|{{S)J-wr@;3PmlxRXU8!e2gm_%s|ReH!reFcY8%$Hl4M5>;6^UDUUae?kOy#h zk~6Ee_@ZAn48Bab__^bNmQ~+k=02jz)e0d9Z3>G?RGG!65?d1>9}7iG17?P*=GUV-#SbLRw)Hu{zx*azHxWkGNTWl@HeWjA?39Ia|sCi{e;!^`1Oec zb>Z|b65OM*;eC=ZLSy?_fg$&^2xI>qSLA2G*$nA3GEnp3$N-)46`|36m*sc#4%C|h zBN<2U;7k>&G_wL4=Ve5z`ubVD&*Hxi)r@{4RCDw7U_D`lbC(9&pG5C*z#W>8>HU)h z!h3g?2UL&sS!oY5$3?VlA0Me9W5e~V;2jds*fz^updz#AJ%G8w2V}AEE?E^=MK%Xt z__Bx1cr7+DQmuHmzn*|hh%~eEc9@m05@clWfpEFcr+06%0&dZJH&@8^&@*$qR@}o3 z@Tuuh2FsLz^zH+dN&T&?0G3I?MpmYJ;GP$J!EzjeM#YLJ!W$}MVNb0^HfOA>5Fe~UNn%Zk(PT@~9}1dt)1UQ zU*B5K?Dl#G74qmg|2>^>0WtLX#Jz{lO4NT`NYB*(L#D|5IpXr9v&7a@YsGp3vLR7L zHYGHZg7{ie6n~2p$6Yz>=^cEg7tEgk-1YRl%-s7^cbqFb(U7&Dp78+&ut5!Tn(hER z|Gp4Ed@CnOPeAe|N>U(dB;SZ?NU^AzoD^UAH_vamp6Ws}{|mSq`^+VP1g~2B{%N-!mWz<`)G)>V-<`9`L4?3dM%Qh6<@kba+m`JS{Ya@9Fq*m6$$ zA1%Ogc~VRH33|S9l%CNb4zM%k^EIpqY}@h{w(aBcJ9c05oiZx#SK9t->5lSI`=&l~ z+-Ic)a{FbBhXV$Xt!WRd`R#Jk-$+_Z52rS>?Vpt2IK<84|E-SBEoIw>cs=a{BlQ7O z-?{Fy_M&84&9|KM5wt~)*!~i~E=(6m8(uCO)I=)M?)&sRbzH$9Rovzd?ZEY}GqX+~ zFbEbLz`BZ49=2Yh-|<`waK-_4!7`ro@zlC|r&I4fc4oyb+m=|c8)8%tZ-z5FwhzDt zL5kB@u53`d@%nHl0Sp)Dw`(QU&>vujEn?GPEXUW!Wi<+4e%BORl&BIH+SwRcbS}X@ z01Pk|vA%OdJKAs17zSXtO55k!;%m9>1eW9LnyAX4uj7@${O6cfii`49qTNItzny5J zH&Gj`e}o}?xjQ}r?LrI%FjUd@xflT3|7LA|ka%Q3i}a8gVm<`HIWoJGH=$EGClX^C0lysQJ>UO(q&;`T#8txuoQ_{l^kEV9CAdXuU1Ghg8 zN_6hHFuy&1x24q5-(Z7;!poYdt*`UTdrQOIQ!2O7_+AHV2hgXaEz7)>$LEdG z<8vE^Tw$|YwZHZDPM!SNOAWG$?J)MdmEk{U!!$M#fp7*Wo}jJ$Q(=8>R`Ats?e|VU?Zt7Cdh%AdnfyN3MBWw{ z$OnREvPf7%z6`#2##_7id|H%Y{vV^vWXb?5d5?a_y&t3@p9t$ncHj-NBdo&X{wrfJ zamN)VMYROYh_SvjJ=Xd!Ga?PY_$;*L=SxFte!4O6%0HEh%iZ4=gvns7IWIyJHa|hT z2;1+e)`TvbNb3-0z&DD_)Jomsg-7p_Uh`wjGnU1urmv1_oVqRg#=C?e?!7DgtqojU zWoAB($&53;TsXu^@2;8M`#z{=rPy?JqgYM0CDf4v@z=ZD|ItJ&8%_7A#K?S{wjxgd z?xA6JdJojrWpB7fr2p_MSsU4(R7=XGS0+Eg#xR=j>`H@R9{XjwBmqAiOxOL` zt?XK-iTEOWV}f>Pz3H-s*>W z4~8C&Xq25UQ^xH6H9kY_RM1$ch+%YLF72AA7^b{~VNTG}Tj#qZltz5Q=qxR`&oIlW Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/templates/angular-ts/spacetimedb/package.json b/templates/angular-ts/spacetimedb/package.json new file mode 100644 index 00000000000..3f67799626d --- /dev/null +++ b/templates/angular-ts/spacetimedb/package.json @@ -0,0 +1,16 @@ +{ + "name": "spacetime-module", + "version": "1.0.0", + "description": "", + "scripts": { + "build": "spacetime build", + "publish": "spacetime publish" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "spacetimedb": "1.*" + } +} + diff --git a/templates/angular-ts/spacetimedb/pnpm-lock.yaml b/templates/angular-ts/spacetimedb/pnpm-lock.yaml new file mode 100644 index 00000000000..b8b7739cda8 --- /dev/null +++ b/templates/angular-ts/spacetimedb/pnpm-lock.yaml @@ -0,0 +1,51 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + spacetimedb: + specifier: 1.* + version: 1.9.0 + +packages: + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + spacetimedb@1.9.0: + resolution: {integrity: sha512-cl/HeO50A1z6JgUZpA7pJcTspBE4IfH1SJJU8f1DpZ4hYHvQesbbYFHPPIC181s8zexdVAj5NnvFOPwQnSrcXg==} + peerDependencies: + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + undici: ^6.19.2 + peerDependenciesMeta: + react: + optional: true + undici: + optional: true + +snapshots: + + base64-js@1.5.1: {} + + fast-text-encoding@1.0.6: {} + + prettier@3.6.2: {} + + spacetimedb@1.9.0: + dependencies: + base64-js: 1.5.1 + fast-text-encoding: 1.0.6 + prettier: 3.6.2 diff --git a/templates/angular-ts/spacetimedb/src/index.ts b/templates/angular-ts/spacetimedb/src/index.ts new file mode 100644 index 00000000000..ba15f9783a7 --- /dev/null +++ b/templates/angular-ts/spacetimedb/src/index.ts @@ -0,0 +1,36 @@ +import { schema, table, t } from 'spacetimedb/server'; + +export const spacetimedb = schema( + table( + { name: 'onlineUsers', public: true }, + { + identity: t.identity().primaryKey(), + }, + ), + table( + { name: 'messages', public: true }, + { + id: t.u64().primaryKey().autoInc(), + sender_identity: t.identity(), + content: t.string(), + timestamp: t.timestamp(), + }, + ), +); + +spacetimedb.clientConnected((ctx) => { + ctx.db.onlineUsers.insert({ identity: ctx.sender }); +}); + +spacetimedb.clientDisconnected((ctx) => { + ctx.db.onlineUsers.identity.delete(ctx.sender); +}); + +spacetimedb.reducer('send_message', { content: t.string() }, (ctx, { content }) => { + ctx.db.messages.insert({ + id: 0n, + sender_identity: ctx.sender, + timestamp: ctx.timestamp, + content, + }); +}); diff --git a/templates/angular-ts/spacetimedb/tsconfig.json b/templates/angular-ts/spacetimedb/tsconfig.json new file mode 100644 index 00000000000..77c6124cb16 --- /dev/null +++ b/templates/angular-ts/spacetimedb/tsconfig.json @@ -0,0 +1,24 @@ + +/* + * This tsconfig is used for TypeScript projects created with `spacetimedb init + * --lang typescript`. You can modify it as needed for your project, although + * some options are required by SpacetimeDB. + */ +{ + "compilerOptions": { + "strict": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "jsx": "react-jsx", + + /* The following options are required by SpacetimeDB + * and should not be modified + */ + "target": "ESNext", + "lib": ["ES2021", "dom"], + "module": "ESNext", + "isolatedModules": true, + "noEmit": true + }, + "include": ["./**/*"] +} \ No newline at end of file diff --git a/templates/angular-ts/src/app/app.config.ts b/templates/angular-ts/src/app/app.config.ts new file mode 100644 index 00000000000..dbd5270cad7 --- /dev/null +++ b/templates/angular-ts/src/app/app.config.ts @@ -0,0 +1,23 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; +import { provideRouter } from '@angular/router'; + +import { routes } from './app.routes'; +import { provideSpacetimeDB } from 'spacetimedb/angular'; +import { DbConnection } from '../module_bindings'; + +const builder = DbConnection.builder() + .withUri('http://localhost:4000') + .withModuleName('angular-ts') + .onConnect((_, identity, token) => + console.log('Connected to SpacetimeDB as ' + identity + ' with token ' + token), + ) + .onConnectError((_, err) => console.error('Connection error', err)) + .onDisconnect((_, err) => console.error('Disconnected from SpacetimeDB ' + err)); + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideRouter(routes), + provideSpacetimeDB(builder), + ], +}; diff --git a/templates/angular-ts/src/app/app.routes.ts b/templates/angular-ts/src/app/app.routes.ts new file mode 100644 index 00000000000..2c064a4333e --- /dev/null +++ b/templates/angular-ts/src/app/app.routes.ts @@ -0,0 +1,9 @@ +import { Routes } from '@angular/router'; +import { Chat } from './chat/chat'; + +export const routes: Routes = [ + { + path: '', + component: Chat, + }, +]; diff --git a/templates/angular-ts/src/app/app.ts b/templates/angular-ts/src/app/app.ts new file mode 100644 index 00000000000..dbe5230906e --- /dev/null +++ b/templates/angular-ts/src/app/app.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; +import { injectSpacetimeDBConnected } from 'spacetimedb/angular'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + template: ` + @if (isConnected()) { + + } @else { +
+

Connecting to SpacetimeDB...

+
+ } + `, +}) +export class App { + protected isConnected = injectSpacetimeDBConnected(); +} diff --git a/templates/angular-ts/src/app/chat/chat.html b/templates/angular-ts/src/app/chat/chat.html new file mode 100644 index 00000000000..706628826e5 --- /dev/null +++ b/templates/angular-ts/src/app/chat/chat.html @@ -0,0 +1,39 @@ +
+
+
+
+
+ @for (message of messages().rows; track message.id) { +
{{ message.senderIdentity.toHexString().slice(-8) }}:
+
{{ message.content }}
+
+ {{ message.timestamp.toDate() | date: 'short' }} +
+ } +
+
+
+ + +
+
+
+

Online users: {{ onlineUsersCount() }}

+
    + @for (user of onlineUsers().rows; track user.identity) { +
  • {{ user.identity.toHexString().slice(-8) }}
  • + } +
+
+
+
diff --git a/templates/angular-ts/src/app/chat/chat.ts b/templates/angular-ts/src/app/chat/chat.ts new file mode 100644 index 00000000000..e8379a2c35a --- /dev/null +++ b/templates/angular-ts/src/app/chat/chat.ts @@ -0,0 +1,47 @@ +import { CommonModule } from '@angular/common'; +import { Component, computed, effect, ElementRef, ViewChild } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { injectReducer, injectTable } from 'spacetimedb/angular'; +import { reducers, tables } from '../../module_bindings'; + +@Component({ + selector: 'app-chat', + imports: [CommonModule, FormsModule], + templateUrl: './chat.html', +}) +export class Chat { + onlineUsers = injectTable(tables.onlineUsers); + onlineUsersCount = computed(() => this.onlineUsers().rows.length); + messages = injectTable(tables.messages); + + private sendMessage = injectReducer(reducers.sendMessage); + + @ViewChild('messagesContainer') messagesContainer?: ElementRef; + + protected messageContent = ''; + + constructor() { + effect(() => { + this.messages(); // Track messages changes + queueMicrotask(() => this.scrollToBottom()); + }); + } + + protected onSendMessage() { + const content = this.messageContent.trim(); + if (content === '') { + return; + } + + this.sendMessage({ content }); + this.messageContent = ''; + } + + private scrollToBottom() { + if (this.messagesContainer) { + const container = this.messagesContainer.nativeElement; + console.log('Scrolling to bottom of messages container'); + container.scrollTop = container.scrollHeight; + } + } +} diff --git a/templates/angular-ts/src/index.html b/templates/angular-ts/src/index.html new file mode 100644 index 00000000000..2a0d8ca0905 --- /dev/null +++ b/templates/angular-ts/src/index.html @@ -0,0 +1,13 @@ + + + + + Angular Quickstart + + + + + + + + diff --git a/templates/angular-ts/src/main.ts b/templates/angular-ts/src/main.ts new file mode 100644 index 00000000000..5df75f9c838 --- /dev/null +++ b/templates/angular-ts/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/templates/angular-ts/src/module_bindings/index.ts b/templates/angular-ts/src/module_bindings/index.ts new file mode 100644 index 00000000000..cfe616350af --- /dev/null +++ b/templates/angular-ts/src/module_bindings/index.ts @@ -0,0 +1,146 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). + +/* eslint-disable */ +/* tslint:disable */ +import { + DbConnectionBuilder as __DbConnectionBuilder, + DbConnectionImpl as __DbConnectionImpl, + SubscriptionBuilderImpl as __SubscriptionBuilderImpl, + TypeBuilder as __TypeBuilder, + Uuid as __Uuid, + convertToAccessorMap as __convertToAccessorMap, + procedureSchema as __procedureSchema, + procedures as __procedures, + reducerSchema as __reducerSchema, + reducers as __reducers, + schema as __schema, + t as __t, + table as __table, + type AlgebraicTypeType as __AlgebraicTypeType, + type DbConnectionConfig as __DbConnectionConfig, + type ErrorContextInterface as __ErrorContextInterface, + type Event as __Event, + type EventContextInterface as __EventContextInterface, + type Infer as __Infer, + type ReducerEventContextInterface as __ReducerEventContextInterface, + type RemoteModule as __RemoteModule, + type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, +} from "spacetimedb"; + +// Import and reexport all reducer arg types +import OnConnectReducer from "./on_connect_reducer"; +export { OnConnectReducer }; +import OnDisconnectReducer from "./on_disconnect_reducer"; +export { OnDisconnectReducer }; +import SendMessageReducer from "./send_message_reducer"; +export { SendMessageReducer }; + +// Import and reexport all procedure arg types + +// Import and reexport all table handle types +import MessagesRow from "./messages_table"; +export { MessagesRow }; +import OnlineUsersRow from "./online_users_table"; +export { OnlineUsersRow }; + +// Import and reexport all types +import Messages from "./messages_type"; +export { Messages }; +import OnConnect from "./on_connect_type"; +export { OnConnect }; +import OnDisconnect from "./on_disconnect_type"; +export { OnDisconnect }; +import OnlineUsers from "./online_users_type"; +export { OnlineUsers }; +import SendMessage from "./send_message_type"; +export { SendMessage }; + +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ +const tablesSchema = __schema( + __table({ + name: 'messages', + indexes: [ + { name: 'id', algorithm: 'btree', columns: [ + 'id', + ] }, + ], + constraints: [ + { name: 'messages_id_key', constraint: 'unique', columns: ['id'] }, + ], + }, MessagesRow), + __table({ + name: 'onlineUsers', + indexes: [ + { name: 'identity', algorithm: 'btree', columns: [ + 'identity', + ] }, + ], + constraints: [ + { name: 'onlineUsers_identity_key', constraint: 'unique', columns: ['identity'] }, + ], + }, OnlineUsersRow), +); + +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ +const reducersSchema = __reducers( + __reducerSchema("send_message", SendMessageReducer), +); + +/** The schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ +const proceduresSchema = __procedures( +); + +/** The remote SpacetimeDB module schema, both runtime and type information. */ +const REMOTE_MODULE = { + versionInfo: { + cliVersion: "1.11.3" as const, + }, + tables: tablesSchema.schemaType.tables, + reducers: reducersSchema.reducersType.reducers, + ...proceduresSchema, +} satisfies __RemoteModule< + typeof tablesSchema.schemaType, + typeof reducersSchema.reducersType, + typeof proceduresSchema +>; + +/** The tables available in this remote SpacetimeDB module. */ +export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ +export const reducers = __convertToAccessorMap(reducersSchema.reducersType.reducers); + +/** The context type returned in callbacks for all possible events. */ +export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ +export type ReducerEventContext = __ReducerEventContextInterface; +/** The context type returned in callbacks for subscription events. */ +export type SubscriptionEventContext = __SubscriptionEventContextInterface; +/** The context type returned in callbacks for error events. */ +export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; + +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ +export class SubscriptionBuilder extends __SubscriptionBuilderImpl {} + +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder {} + +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ +export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ + static builder = (): DbConnectionBuilder => { + return new DbConnectionBuilder(REMOTE_MODULE, (config: __DbConnectionConfig) => new DbConnection(config)); + }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ + override subscriptionBuilder = (): SubscriptionBuilder => { + return new SubscriptionBuilder(this); + }; +} + diff --git a/templates/angular-ts/src/module_bindings/messages_table.ts b/templates/angular-ts/src/module_bindings/messages_table.ts new file mode 100644 index 00000000000..1c533690e1b --- /dev/null +++ b/templates/angular-ts/src/module_bindings/messages_table.ts @@ -0,0 +1,18 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.row({ + id: __t.u64().primaryKey(), + senderIdentity: __t.identity().name("sender_identity"), + content: __t.string(), + timestamp: __t.timestamp(), +}); diff --git a/templates/angular-ts/src/module_bindings/messages_type.ts b/templates/angular-ts/src/module_bindings/messages_type.ts new file mode 100644 index 00000000000..9b538733737 --- /dev/null +++ b/templates/angular-ts/src/module_bindings/messages_type.ts @@ -0,0 +1,20 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.object("Messages", { + id: __t.u64(), + senderIdentity: __t.identity(), + content: __t.string(), + timestamp: __t.timestamp(), +}); + + diff --git a/templates/angular-ts/src/module_bindings/on_connect_reducer.ts b/templates/angular-ts/src/module_bindings/on_connect_reducer.ts new file mode 100644 index 00000000000..e18fbc0a086 --- /dev/null +++ b/templates/angular-ts/src/module_bindings/on_connect_reducer.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default {}; diff --git a/templates/angular-ts/src/module_bindings/on_connect_type.ts b/templates/angular-ts/src/module_bindings/on_connect_type.ts new file mode 100644 index 00000000000..d95ba1fa6e2 --- /dev/null +++ b/templates/angular-ts/src/module_bindings/on_connect_type.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.object("OnConnect", {}); + + diff --git a/templates/angular-ts/src/module_bindings/on_disconnect_reducer.ts b/templates/angular-ts/src/module_bindings/on_disconnect_reducer.ts new file mode 100644 index 00000000000..e18fbc0a086 --- /dev/null +++ b/templates/angular-ts/src/module_bindings/on_disconnect_reducer.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default {}; diff --git a/templates/angular-ts/src/module_bindings/on_disconnect_type.ts b/templates/angular-ts/src/module_bindings/on_disconnect_type.ts new file mode 100644 index 00000000000..3d29234b70e --- /dev/null +++ b/templates/angular-ts/src/module_bindings/on_disconnect_type.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.object("OnDisconnect", {}); + + diff --git a/templates/angular-ts/src/module_bindings/online_users_table.ts b/templates/angular-ts/src/module_bindings/online_users_table.ts new file mode 100644 index 00000000000..481e061e729 --- /dev/null +++ b/templates/angular-ts/src/module_bindings/online_users_table.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.row({ + identity: __t.identity().primaryKey(), +}); diff --git a/templates/angular-ts/src/module_bindings/online_users_type.ts b/templates/angular-ts/src/module_bindings/online_users_type.ts new file mode 100644 index 00000000000..1e20231fa1e --- /dev/null +++ b/templates/angular-ts/src/module_bindings/online_users_type.ts @@ -0,0 +1,17 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.object("OnlineUsers", { + identity: __t.identity(), +}); + + diff --git a/templates/angular-ts/src/module_bindings/send_message_reducer.ts b/templates/angular-ts/src/module_bindings/send_message_reducer.ts new file mode 100644 index 00000000000..4d7afb9bb6d --- /dev/null +++ b/templates/angular-ts/src/module_bindings/send_message_reducer.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default { + content: __t.string(), +}; diff --git a/templates/angular-ts/src/module_bindings/send_message_type.ts b/templates/angular-ts/src/module_bindings/send_message_type.ts new file mode 100644 index 00000000000..d47eb9dac82 --- /dev/null +++ b/templates/angular-ts/src/module_bindings/send_message_type.ts @@ -0,0 +1,17 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from "spacetimedb"; + +export default __t.object("SendMessage", { + content: __t.string(), +}); + + diff --git a/templates/angular-ts/src/styles.css b/templates/angular-ts/src/styles.css new file mode 100644 index 00000000000..35eb9c28bdb --- /dev/null +++ b/templates/angular-ts/src/styles.css @@ -0,0 +1,3 @@ +/* You can add global styles to this file, and also import other style files */ + +@import "tailwindcss"; diff --git a/templates/angular-ts/tsconfig.app.json b/templates/angular-ts/tsconfig.app.json new file mode 100644 index 00000000000..264f459bf87 --- /dev/null +++ b/templates/angular-ts/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/templates/angular-ts/tsconfig.json b/templates/angular-ts/tsconfig.json new file mode 100644 index 00000000000..2ab7442758f --- /dev/null +++ b/templates/angular-ts/tsconfig.json @@ -0,0 +1,33 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/templates/angular-ts/tsconfig.spec.json b/templates/angular-ts/tsconfig.spec.json new file mode 100644 index 00000000000..d38370633f6 --- /dev/null +++ b/templates/angular-ts/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "vitest/globals" + ] + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] +}