11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/preact/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/examples/plain/scripts/vite.ts:
--------------------------------------------------------------------------------
1 | import { pluginDeno } from "@deno-plc/vite-plugin-deno";
2 | import type { InlineConfig } from "vite";
3 |
4 | export const config: InlineConfig = {
5 | configFile: false, // configuration is inlined here
6 | server: {
7 | port: 8000,
8 | },
9 | plugins: [
10 | pluginDeno({
11 | // see configuration docs
12 | }),
13 | ],
14 | };
15 |
--------------------------------------------------------------------------------
/examples/plain/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": {
3 | "dev": "deno run -A scripts/dev.ts",
4 | "release": "deno run -A scripts/release.ts"
5 | },
6 | "nodeModulesDir": "auto",
7 | "compilerOptions": {
8 | "lib": [
9 | "deno.window",
10 | "deno.ns",
11 | "ESNext",
12 | "DOM",
13 | "DOM.Iterable",
14 | "DOM.AsyncIterable",
15 | "webworker"
16 | ]
17 | },
18 | "importMap": "../../deno.json"
19 | }
20 |
--------------------------------------------------------------------------------
/examples/preact/src/app.css:
--------------------------------------------------------------------------------
1 | #app {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | width: 6em;
11 | padding: 1.5em;
12 | display: inline-block;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.preact:hover {
18 | filter: drop-shadow(0 0 2em #673ab8aa);
19 | }
20 |
21 | .card {
22 | padding: 2em;
23 | }
24 |
25 | .read-the-docs {
26 | color: #888;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/preact/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Preact + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.github/workflows/jsr.yml:
--------------------------------------------------------------------------------
1 | name: JSR Publish
2 | on:
3 | push:
4 | branches: main
5 |
6 | jobs:
7 | publish:
8 | name: Publish
9 | runs-on: ubuntu-latest
10 |
11 | permissions:
12 | contents: read
13 | id-token: write
14 |
15 | steps:
16 | - name: Clone repository
17 | uses: actions/checkout@v3
18 |
19 | - name: Install Deno
20 | uses: denoland/setup-deno@v1
21 | with:
22 | deno-version: v2.x
23 |
24 | - name: Test
25 | run: deno task check-ci
26 |
27 | - name: Publish package to JSR
28 | run: deno publish
29 |
--------------------------------------------------------------------------------
/src/ray.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | export class Ray {
25 | constructor(readonly id: string, readonly referrer: string) {
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | export const supported_extensions = [
25 | "js",
26 | "jsx",
27 | "ts",
28 | "tsx",
29 | "mjs",
30 | "cjs",
31 | "json",
32 | ];
33 |
--------------------------------------------------------------------------------
/src/specifier.test.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { assertEquals } from "@std/assert";
25 | import { parseModuleSpecifier } from "./specifier.ts";
26 |
27 | Deno.test("parseModuleSpecifier", () => {
28 | assertEquals(parseModuleSpecifier(`npm:foo`).href, `npm:foo`);
29 | assertEquals(parseModuleSpecifier(`npm:/foo`).href, `npm:foo`);
30 | });
31 |
--------------------------------------------------------------------------------
/src/options.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import type { Logger } from "@logtape/logtape";
25 |
26 | export interface Opt {
27 | deno_json?: string;
28 | deno_lock?: string;
29 | extra_import_map: Map>;
30 | environment: "deno" | "browser";
31 | exclude: RegExp[];
32 | legacy_npm: string[];
33 | logger: Logger;
34 | }
35 |
--------------------------------------------------------------------------------
/examples/preact/src/app.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "preact/hooks";
2 |
3 | export function App() {
4 | const [count, setCount] = useState(0);
5 |
6 | const viteLogo = new URL("/vite.svg", import.meta.url).href;
7 | const preactLogo = new URL("./assets/preact.svg", import.meta.url).href;
8 | const denoLogo = new URL("/Deno.svg", import.meta.url).href;
9 |
10 | return (
11 | <>
12 |
32 | >
33 | );
34 | }
35 |
--------------------------------------------------------------------------------
/examples/preact/scripts/vite.ts:
--------------------------------------------------------------------------------
1 | import { pluginDeno } from "@deno-plc/vite-plugin-deno";
2 | import prefresh from "@prefresh/vite";
3 | import type { InlineConfig, Plugin } from "vite";
4 |
5 | export const config: InlineConfig = {
6 | configFile: false, // configuration is inlined here
7 | server: {
8 | port: 8000,
9 | },
10 | plugins: [
11 | pluginDeno({
12 | exclude: [/style-import\.js/],
13 | env: "browser",
14 | undeclared_npm_imports: [
15 | // injected by JSX transform
16 | "preact/jsx-runtime",
17 | "preact/jsx-dev-runtime",
18 | // injected by HMR
19 | "@prefresh/core",
20 | "@prefresh/utils",
21 | // injected by react compat
22 | "@preact/compat",
23 | ],
24 | extra_import_map: new Map([
25 | // react compat
26 | ["react", "@preact/compat"],
27 | ["react-dom", "@preact/compat"],
28 | ]),
29 | }) as Plugin,
30 | // HMR Plugin
31 | prefresh({
32 | // `node_modules` is excluded internally, lets do the same
33 | exclude: [/^npm/, /registry.npmjs.org/, /^jsr/, /^https?/],
34 | }) as Plugin,
35 | ],
36 | esbuild: {
37 | jsx: "automatic",
38 | jsxImportSource: "preact",
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/examples/preact/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/preact/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | a {
17 | font-weight: 500;
18 | color: #646cff;
19 | text-decoration: inherit;
20 | }
21 | a:hover {
22 | color: #535bf2;
23 | }
24 |
25 | body {
26 | margin: 0;
27 | display: flex;
28 | place-items: center;
29 | min-width: 320px;
30 | min-height: 100vh;
31 | }
32 |
33 | h1 {
34 | font-size: 3.2em;
35 | line-height: 1.1;
36 | }
37 |
38 | button {
39 | border-radius: 8px;
40 | border: 1px solid transparent;
41 | padding: 0.6em 1.2em;
42 | font-size: 1em;
43 | font-weight: 500;
44 | font-family: inherit;
45 | background-color: #1a1a1a;
46 | cursor: pointer;
47 | transition: border-color 0.25s;
48 | }
49 | button:hover {
50 | border-color: #646cff;
51 | }
52 | button:focus,
53 | button:focus-visible {
54 | outline: 4px auto -webkit-focus-ring-color;
55 | }
56 |
57 | @media (prefers-color-scheme: light) {
58 | :root {
59 | color: #213547;
60 | background-color: #ffffff;
61 | }
62 | a:hover {
63 | color: #747bff;
64 | }
65 | button {
66 | background-color: #f9f9f9;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/examples/preact/src/assets/preact.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/preact/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": {
3 | "dev": "deno run -A scripts/dev.ts",
4 | "release": "deno run -A scripts/release.ts"
5 | },
6 | "nodeModulesDir": "auto",
7 | "compilerOptions": {
8 | "lib": [
9 | "deno.window",
10 | "deno.ns",
11 | "ESNext",
12 | "DOM",
13 | "DOM.Iterable",
14 | "DOM.AsyncIterable",
15 | "webworker"
16 | ],
17 | "jsx": "react-jsx",
18 | "jsxImportSource": "preact"
19 | },
20 | "imports": {
21 | "preact": "npm:preact@^10.24.3",
22 | "@preact/compat": "npm:@preact/compat@^18.3.1",
23 | "@prefresh/core": "npm:@prefresh/core@^1.5.2",
24 | "@prefresh/utils": "npm:@prefresh/utils@^1.2.0",
25 | "@prefresh/vite": "npm:@prefresh/vite@^2.4.6",
26 | "@deno-plc/vite-plugin-deno": "../../mod.ts",
27 | "@coderspirit/nominal": "npm:@coderspirit/nominal@^4.1.1",
28 | "@logtape/logtape": "jsr:@logtape/logtape@^0.8.2",
29 | "@std/assert": "jsr:@std/assert@^0.223.0",
30 | "@std/encoding": "jsr:@std/encoding@^0.223.0",
31 | "@std/fs": "jsr:@std/fs@^0.223.0",
32 | "@std/path": "jsr:@std/path@^0.225.1",
33 | "@std/semver": "jsr:@std/semver@^1.0.2",
34 | "acorn": "npm:acorn@^8.12.1",
35 | "acorn-walk": "npm:acorn-walk@^8.3.3",
36 | "lebab": "npm:lebab@^3.2.4",
37 | "resolve.exports": "npm:resolve.exports@^2.0.2",
38 | "validate-npm-package-name": "npm:validate-npm-package-name@^5.0.1",
39 | "vite": "npm:vite@^6.1.1",
40 | "zod": "npm:zod@^3.22.5"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/exclude.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import type { Opt } from "./options.ts";
25 |
26 | function is_excluded_inner(spec: string, o: Opt) {
27 | for (const exclude of o.exclude) {
28 | if (exclude.test(spec)) {
29 | return true;
30 | }
31 | }
32 | return false;
33 | }
34 |
35 | const cache = new Map();
36 |
37 | export function is_excluded(spec: string, o: Opt): boolean {
38 | return cache.get(spec) ?? (() => {
39 | const excl = is_excluded_inner(spec, o);
40 | cache.set(spec, excl);
41 | return excl;
42 | })();
43 | }
44 |
45 | // function* cache_info() {
46 | // for (const [id, excl] of cache) {
47 | // yield `${excl ? "-" : "+"} ${id}`;
48 | // }
49 | // }
50 |
--------------------------------------------------------------------------------
/src/undeclared_npm.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { z } from "zod";
25 | import { parseModuleSpecifier } from "./specifier.ts";
26 | import type { ModuleGraph } from "./graph.ts";
27 |
28 | const Schema = z.object({
29 | redirects: z.record(z.string().transform(parseModuleSpecifier)),
30 | });
31 |
32 | export function resolve_undeclared_npm(
33 | packages: string[],
34 | graph: ModuleGraph,
35 | extra_import_map: Map>,
36 | ) {
37 | for (const pkg of packages) {
38 | extra_import_map.set(
39 | pkg,
40 | graph
41 | .call_deno(`npm:${pkg}`)
42 | .then(Schema.parse)
43 | .then(({ redirects }) => `${redirects[`npm:${pkg}`].href}#standalone`),
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@deno-plc/vite-plugin-deno",
3 | "version": "2.3.4",
4 | "exports": "./mod.ts",
5 | "compilerOptions": {
6 | "lib": [
7 | "deno.window",
8 | "deno.ns",
9 | "ESNext",
10 | "webworker"
11 | ]
12 | },
13 | "fmt": {
14 | "indentWidth": 4,
15 | "lineWidth": 120,
16 | "exclude": [
17 | "examples/**/dist/**"
18 | ]
19 | },
20 | "tasks": {
21 | "check": "deno fmt && deno lint && deno publish --dry-run --allow-dirty && deno test -A --parallel",
22 | "check-ci": "deno fmt --check && deno lint && deno publish --dry-run && deno test -A --parallel"
23 | },
24 | "lint": {
25 | "rules": {
26 | "exclude": [
27 | "no-misused-new"
28 | ]
29 | },
30 | "exclude": [
31 | "examples/**/dist/**"
32 | ]
33 | },
34 | "imports": {
35 | "@deno-plc/vite-plugin-deno": "./mod.ts",
36 | "@coderspirit/nominal": "npm:@coderspirit/nominal@^4.1.1",
37 | "@logtape/logtape": "jsr:@logtape/logtape@^0.8.2",
38 | "@std/assert": "jsr:@std/assert@^0.223.0",
39 | "@std/encoding": "jsr:@std/encoding@^0.223.0",
40 | "@std/fs": "jsr:@std/fs@^0.223.0",
41 | "@std/path": "jsr:@std/path@^0.225.1",
42 | "@std/semver": "jsr:@std/semver@^1.0.2",
43 | "acorn": "npm:acorn@^8.12.1",
44 | "acorn-walk": "npm:acorn-walk@^8.3.3",
45 | "lebab": "npm:lebab@^3.2.4",
46 | "resolve.exports": "npm:resolve.exports@^2.0.2",
47 | "validate-npm-package-name": "npm:validate-npm-package-name@^5.0.1",
48 | "vite": "npm:vite@^6.1.1",
49 | "zod": "npm:zod@^3.22.5"
50 | },
51 | "publish": {
52 | "exclude": [
53 | "examples"
54 | ]
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/ast-ops.test.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { assert } from "@std/assert";
25 | import { has_default_export } from "./ast-ops.ts";
26 | import type { Opt } from "./options.ts";
27 | import { getLogger } from "@logtape/logtape";
28 |
29 | const o: Opt = {
30 | deno_json: "",
31 | deno_lock: "",
32 | extra_import_map: new Map(),
33 | environment: "deno",
34 | exclude: [],
35 | legacy_npm: [],
36 | logger: getLogger("vite-plugin-deno/test"),
37 | };
38 |
39 | Deno.test("has default export", async () => {
40 | assert(await has_default_export(o, `export default function foo(){}`) === true);
41 | assert(await has_default_export(o, `function foo(){}\n export {foo as default};`) === true);
42 | assert(await has_default_export(o, `// export default`) === false);
43 | assert(await has_default_export(o, `/*\nexport default\n*/`) === false);
44 | assert(await has_default_export(o, `// export {foo as default}`) === false);
45 | });
46 |
--------------------------------------------------------------------------------
/src/ast-ops.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { WorkerPool } from "./ast-pool.ts";
25 | import type { Opt } from "./options.ts";
26 |
27 | const pool = new WorkerPool(navigator.hardwareConcurrency ?? 4);
28 |
29 | export async function toESM(o: Opt, raw_code: string, id: string) {
30 | if (raw_code.includes("require") || raw_code.includes("module")) {
31 | return (await pool.run(o, {
32 | task_id: pool.get_task_id(),
33 | kind: "cjs-to-esm",
34 | id,
35 | raw_code,
36 | })).code!;
37 | } else {
38 | return raw_code;
39 | }
40 | }
41 |
42 | const default_export_cache = new Map | boolean>();
43 |
44 | export async function has_default_export(o: Opt, code: string, id: string = code): Promise {
45 | if (default_export_cache.has(id)) {
46 | return default_export_cache.get(id)!;
47 | }
48 | if (!code.includes("default")) {
49 | default_export_cache.set(id, false);
50 | return false;
51 | }
52 |
53 | const pr = (async () =>
54 | (await pool.run(o, {
55 | task_id: pool.get_task_id(),
56 | kind: "default-exports",
57 | id,
58 | raw_code: code,
59 | })).has_default_export!)();
60 |
61 | default_export_cache.set(id, pr);
62 | const has_default_export = await pr;
63 | default_export_cache.set(id, has_default_export);
64 | return has_default_export;
65 | }
66 |
--------------------------------------------------------------------------------
/src/ast-pool.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import type { AstResult, AstTask } from "./ast-worker.ts";
25 | import { assert } from "@std/assert/assert";
26 | import type { Opt } from "./options.ts";
27 |
28 | export class WorkerPool {
29 | constructor(readonly concurrency: number) {
30 | assert(concurrency > 0);
31 | assert(concurrency % 1 === 0); // int
32 | for (let i = 0; i < concurrency; i++) {
33 | this.#pool.push(this.#spawn_worker());
34 | }
35 | }
36 | #spawn_worker() {
37 | const worker = new Worker(new URL("./ast-worker.ts", import.meta.url), {
38 | type: "module",
39 | name: `ast-worker-${this.#pool.length}`,
40 | });
41 | worker.addEventListener("message", (ev) => {
42 | const result = ev.data as AstResult;
43 | const listener = this.#listener.get(result.task_id);
44 | listener?.(result);
45 | this.#listener.delete(result.task_id);
46 |
47 | const waiting = this.#waiting.shift();
48 | if (waiting) {
49 | waiting(worker);
50 | } else {
51 | this.#free_pool.push(worker);
52 | }
53 | });
54 | this.#free_pool.push(worker);
55 | return worker;
56 | }
57 | #pool: Worker[] = [];
58 | #free_pool: Worker[] = [];
59 | #waiting: ((worker: Worker) => void)[] = [];
60 | #listener = new Map void>();
61 | #run_task(o: Opt, task: AstTask, worker: Worker): Promise {
62 | o.logger.debug(`running AST operation {kind} {id}`, { ...task });
63 | return new Promise((resolve) => {
64 | this.#listener.set(task.task_id, resolve);
65 | worker.postMessage(task);
66 | });
67 | }
68 | public run(o: Opt, task: AstTask): Promise {
69 | const worker = this.#free_pool.shift();
70 | if (worker) {
71 | return this.#run_task(o, task, worker);
72 | } else {
73 | return new Promise((resolve) => {
74 | this.#waiting.push((worker) => {
75 | this.#run_task(o, task, worker).then(resolve);
76 | });
77 | });
78 | }
79 | }
80 | #task_id = 0;
81 | public get_task_id(): number {
82 | return this.#task_id++;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/ast-worker.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { transform } from "lebab";
25 | import { parse } from "acorn";
26 | import { simple as walk_simple } from "acorn-walk";
27 |
28 | export interface AstTask {
29 | task_id: number;
30 | kind: "cjs-to-esm" | "default-exports";
31 | id: string;
32 | raw_code: string;
33 | }
34 |
35 | export interface AstResult {
36 | task_id: number;
37 | code?: string;
38 | has_default_export?: boolean;
39 | }
40 |
41 | function run_task(task: AstTask): Omit {
42 | try {
43 | if (task.kind === "cjs-to-esm") {
44 | const { code, warnings } = transform(
45 | task.raw_code,
46 | ["commonjs"],
47 | );
48 | for (const $ of warnings) {
49 | if ($.msg === "export can only be at root level") {
50 | throw new Error(`Failed to transform to ESM: ${task.id} does UGLY things with Cjs exports.`);
51 | } else {
52 | console.warn(task.id, $);
53 | }
54 | }
55 |
56 | return {
57 | code,
58 | };
59 | } else {
60 | const ast = parse(task.raw_code, {
61 | ecmaVersion: 2023,
62 | sourceType: "module",
63 | });
64 |
65 | let has_default_export = false;
66 |
67 | walk_simple(ast, {
68 | ExportDefaultDeclaration(_node) {
69 | has_default_export = true;
70 | },
71 | ExportNamedDeclaration(node) {
72 | if (node.specifiers) {
73 | for (const specifier of node.specifiers) {
74 | // @ts-ignore missing typedef
75 | if (specifier.type === "ExportSpecifier" && specifier.exported?.name === "default") {
76 | has_default_export = true;
77 | }
78 | }
79 | }
80 | },
81 | });
82 |
83 | return {
84 | has_default_export,
85 | };
86 | }
87 | } catch (err) {
88 | if (err instanceof Error) {
89 | throw new Error(`Failed to run task ${task.id}: ${err.message}`);
90 | } else {
91 | throw new Error(`Failed to run task ${task.id}: ${err}`);
92 | }
93 | }
94 | }
95 |
96 | self.onmessage = (e) => {
97 | const task = e.data as AstTask;
98 |
99 | const res: AstResult = {
100 | task_id: task.task_id,
101 | ...run_task(task),
102 | };
103 |
104 | self.postMessage(res);
105 | };
106 |
--------------------------------------------------------------------------------
/src/specifier.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { parse, type SemVer } from "@std/semver";
25 | import validate from "validate-npm-package-name";
26 | import type { FastBrand } from "@coderspirit/nominal";
27 |
28 | export type ModuleSpecifier = FastBrand;
29 |
30 | export function parseModuleSpecifier(inp: string | URL): ModuleSpecifier {
31 | const url = new URL(inp);
32 | if (url.href.includes("\\")) {
33 | return parseModuleSpecifier(url.href.replaceAll("\\", "/"));
34 | }
35 | if (url.protocol === "https:") {
36 | return url as ModuleSpecifier;
37 | } else if (url.protocol === "file:") {
38 | if (!url.href.startsWith("file:///")) {
39 | return new URL(url.href.replace("file://", "file:///")) as ModuleSpecifier;
40 | }
41 | return url as ModuleSpecifier;
42 | } else if (url.pathname.startsWith("/")) {
43 | return new URL(url.href.replace(url.pathname, url.pathname.substring(1))) as ModuleSpecifier;
44 | } else {
45 | return url as ModuleSpecifier;
46 | }
47 | }
48 |
49 | export interface NPMExact {
50 | name: string;
51 | version: SemVer;
52 | path: string;
53 | }
54 |
55 | export function parseNPMExact(spec: string): NPMExact | null {
56 | spec = spec.trim();
57 | if (spec.startsWith("npm:")) {
58 | spec = spec.substring(4);
59 | }
60 | let marker = 0;
61 | marker = spec.indexOf("/");
62 | if (spec[0] === "@") {
63 | // @scope/package contains one more slash
64 | marker = spec.indexOf("/", marker + 1);
65 | }
66 | if (marker === -1) {
67 | marker = Infinity;
68 | }
69 | // exclude trailing @
70 | const version_marker = spec.indexOf("@", 2);
71 |
72 | if (version_marker > marker) {
73 | return null;
74 | }
75 |
76 | let version: SemVer | null = null;
77 | let name = spec.substring(0, marker);
78 |
79 | if (version_marker !== -1) {
80 | version = parse(spec.substring(version_marker + 1, marker));
81 | name = spec.substring(0, version_marker);
82 | } else {
83 | return null;
84 | }
85 |
86 | const path = spec.substring(marker + 1);
87 |
88 | if (!validate(name)) {
89 | return null;
90 | }
91 |
92 | return {
93 | version,
94 | name,
95 | path,
96 | };
97 | }
98 |
99 | export interface NPMImport {
100 | name: string;
101 | path: string;
102 | }
103 |
104 | export function parseNPMImport(spec: string): NPMImport | null {
105 | spec = spec.trim();
106 | if (spec.startsWith("npm:")) {
107 | spec = spec.substring(4);
108 | }
109 | let marker = 0;
110 | marker = spec.indexOf("/");
111 | if (spec[0] === "@") {
112 | // @scope/package contains one more slash
113 | marker = spec.indexOf("/", marker + 1);
114 | }
115 | if (marker === -1) {
116 | marker = Infinity;
117 | }
118 |
119 | const name = spec.substring(0, marker);
120 |
121 | const path = spec.substring(marker + 1);
122 |
123 | if (!validate(name)) {
124 | return null;
125 | }
126 |
127 | return {
128 | name,
129 | path,
130 | };
131 | }
132 |
--------------------------------------------------------------------------------
/src/resolve.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { fromFileUrl, isAbsolute, join, normalize, toFileUrl } from "@std/path";
25 | import type { ModuleGraph } from "./graph.ts";
26 | import { type ModuleSpecifier, parseModuleSpecifier, parseNPMImport } from "./specifier.ts";
27 | import type { Opt } from "./options.ts";
28 | import type { Ray } from "./ray.ts";
29 |
30 | async function exists(path: string): Promise {
31 | try {
32 | await Deno.stat(path);
33 | return true;
34 | } catch (_) {
35 | return false;
36 | }
37 | }
38 |
39 | export async function resolve(
40 | o: Opt,
41 | ray: Ray,
42 | graph: ModuleGraph,
43 | id: string,
44 | referrer?: string,
45 | may_fetch: boolean = true,
46 | ): Promise {
47 | // console.log(`%c[RESOLVE] ${id}`, "color:#ff0");
48 | // console.log(`%c[REFERRER] ${referrer} (${isAbsolute(referrer || "") ? "" : "!"}abs)`, "color: gray");
49 | if (o.extra_import_map.has(id)) {
50 | return await resolve(o, ray, graph, await o.extra_import_map.get(id)!, referrer, may_fetch);
51 | }
52 |
53 | if (referrer === undefined) {
54 | // local entrypoint
55 | id = join(Deno.cwd(), id);
56 | }
57 |
58 | const fast_forward = graph.get_resolved(id);
59 |
60 | if (fast_forward) {
61 | return fast_forward.specifier;
62 | }
63 |
64 | let referrer_mod = referrer ? graph.get_resolved(referrer) : null;
65 |
66 | if (
67 | referrer && !referrer_mod && isAbsolute(referrer) && !referrer.includes(`registry.npmjs.org`) &&
68 | await exists(referrer)
69 | ) {
70 | referrer_mod = await graph.get_module(toFileUrl(referrer) as ModuleSpecifier);
71 | }
72 |
73 | if (id.endsWith("#standalone")) {
74 | const mod = await graph.get_module(parseModuleSpecifier(id.substring(0, id.length - "#standalone".length)));
75 | if (mod) {
76 | return mod.specifier;
77 | }
78 | }
79 |
80 | if (referrer_mod) {
81 | // console.log(`%c[REFERRER] ${referrer_mod.specifier.href}`, "color: green");
82 | const ref = await referrer_mod.resolve_import(id);
83 | if (ref) {
84 | return ref.specifier;
85 | } else {
86 | if (!id.startsWith("npm")) {
87 | if (may_fetch) {
88 | await graph.update_info(referrer_mod.specifier);
89 | return await resolve(o, ray, graph, id, referrer, false);
90 | } else {
91 | throw new Error(`cannot resolve '${id}' from ${referrer_mod.specifier.href}`);
92 | }
93 | }
94 | }
95 | }
96 |
97 | if (isAbsolute(id)) {
98 | if (await exists(id)) {
99 | const mod = await graph.get_module(toFileUrl(id) as ModuleSpecifier);
100 |
101 | if (mod) {
102 | // console.log(`%c[RESOLVED ABS] ${mod.specifier.href}`, "color:blue");
103 |
104 | return mod.specifier;
105 | }
106 | } else {
107 | const project_abs = join(Deno.cwd(), id);
108 | if (await exists(project_abs)) {
109 | const mod = await graph.get_module(toFileUrl(project_abs) as ModuleSpecifier);
110 |
111 | if (mod) {
112 | // console.log(`%c[RESOLVED ABS] ${mod.specifier.href}`, "color:blue");
113 |
114 | return mod.specifier;
115 | }
116 | }
117 | }
118 | }
119 | if (URL.canParse(id)) {
120 | const mod = await graph.get_module(parseModuleSpecifier(id));
121 | if (mod) {
122 | return mod.specifier;
123 | }
124 | }
125 |
126 | const npm = parseNPMImport(id);
127 | if (npm) {
128 | if (graph.npm_package_versions.has(npm.name)) {
129 | const versions = graph.npm_package_versions.get(npm.name)!;
130 | throw new Error(`cannot resolve ${id} from ${referrer}
131 | ${npm.name} has been recognized as an NPM package, if it is an injected import you may want to add "${npm.name}" to undeclared_npm_imports or one of the following entries to extra_import_map:
132 | ${
133 | [...versions.values()].map((version) =>
134 | `"${id}" => "npm:${npm.name}@${version}${npm.path ? `/${npm.path}` : ""}"`
135 | ).join("\n")
136 | }`);
137 | }
138 | }
139 | if (referrer?.endsWith(".html")) {
140 | return null;
141 | }
142 | throw new Error(`cannot resolve ${id} from ${referrer}`);
143 | }
144 |
145 | const fs_remap = new Map();
146 |
147 | export function encodeSpec(spec: ModuleSpecifier) {
148 | if (spec.protocol === "file:") {
149 | const path = fromFileUrl(spec.href);
150 | fs_remap.set(path, spec);
151 | return path;
152 | }
153 | return `${encodeURIComponent(spec.href)}`;
154 | }
155 |
156 | export function decodeSpec(spec: string) {
157 | const normalized = normalize(spec);
158 | if (fs_remap.has(normalized)) {
159 | return fs_remap.get(normalized)!.href;
160 | }
161 | return decodeURIComponent(spec);
162 | }
163 |
--------------------------------------------------------------------------------
/examples/preact/public/Deno.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
94 |
--------------------------------------------------------------------------------
/src/npm.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { format, type SemVer } from "@std/semver";
25 | import { fromFileUrl, join, toFileUrl } from "@std/path";
26 | import { z } from "zod";
27 | import type { ModuleGraph, NPMImportInfo } from "./graph.ts";
28 | import * as npmResolver from "resolve.exports";
29 | import { assert } from "jsr:@std/assert@^0.225.2/assert";
30 | import { type ModuleSpecifier, parseModuleSpecifier, parseNPMExact } from "./specifier.ts";
31 | import { has_default_export, toESM } from "./ast-ops.ts";
32 | import type { Opt } from "./options.ts";
33 |
34 | export const PackageJSON = z.object({
35 | name: z.string(),
36 | version: z.string(),
37 | main: z.unknown().optional(),
38 | browser: z.unknown().optional(),
39 | exports: z.unknown().optional(),
40 | });
41 | export type PackageJSON = z.infer;
42 |
43 | const cacheDir = (async () =>
44 | z
45 | .object({
46 | npmCache: z.string().transform(toFileUrl),
47 | })
48 | .parse(
49 | JSON.parse(
50 | new TextDecoder().decode(
51 | (await new Deno.Command(Deno.execPath(), {
52 | args: ["info", "--json"],
53 | stdout: "piped",
54 | }).output())
55 | .stdout,
56 | ),
57 | ),
58 | )
59 | .npmCache)();
60 |
61 | const pending = new Map>();
62 |
63 | export async function getNPMPath(name: string, version: SemVer) {
64 | return join(fromFileUrl(await cacheDir), `registry.npmjs.org/${name}/${format(version)}`);
65 | }
66 |
67 | export async function getPackageMetadata(name: string, version: SemVer): Promise {
68 | const id = `${name}@${format(version)}`;
69 | if (pending.has(id)) {
70 | return await pending.get(id)!;
71 | } else {
72 | const pr = (async () => {
73 | const path = join(await getNPMPath(name, version), "package.json");
74 | const content = await Deno.readTextFile(path).catch(() => {
75 | return null;
76 | });
77 | if (content) {
78 | const data = JSON.parse(content);
79 | const parsed = PackageJSON.safeParse(data);
80 | if (parsed.success) {
81 | return parsed.data;
82 | } else {
83 | console.error(`Failed to parse package.json for ${id}`);
84 | throw {
85 | zod: parsed.error,
86 | message: `Failed to parse package.json for ${id}`,
87 | package: data,
88 | };
89 | }
90 | } else {
91 | return null;
92 | }
93 | })();
94 | pending.set(id, pr);
95 | return await pr;
96 | }
97 | }
98 |
99 | export class NPMPackage {
100 | constructor(
101 | readonly name: string,
102 | readonly version: SemVer,
103 | readonly raw_dependencies: string[],
104 | readonly graph: ModuleGraph,
105 | ) {
106 | this.metadata = getPackageMetadata(name, version);
107 | this.dependencies.set(this.name, this);
108 | }
109 | readonly metadata;
110 | readonly dependencies = new Map();
111 | async fetch_metadata() {
112 | await this.metadata;
113 | }
114 |
115 | link() {
116 | for (const dep of this.raw_dependencies) {
117 | const pkg = this.graph.npm_packages.get(dep);
118 | assert(pkg, `failed to link dependency ${dep} of ${this.name}@${format(this.version)}`);
119 | this.dependencies.set(pkg.name, pkg);
120 | }
121 | }
122 |
123 | public async resolve_import(path: string): Promise {
124 | const metadata = await this.metadata;
125 | const resolved = npmResolver.exports(metadata, path, {
126 | browser: this.graph.o.environment === "browser",
127 | });
128 |
129 | if (resolved) {
130 | for (const path of resolved) {
131 | const realPath = join(await getNPMPath(this.name, this.version), path);
132 |
133 | if ((await stat(realPath))?.isFile) {
134 | return parseModuleSpecifier(`npm-data:${this.name}@${format(this.version)}/${path.substring(2)}`);
135 | }
136 | }
137 | throw new Error(`export ${path} from ${this.name}@${format(this.version)} could not be resolved`);
138 | } else if (path) {
139 | return parseModuleSpecifier(join(`npm-probe:${this.name}@${format(this.version)}/`, path));
140 | } else {
141 | const res = npmResolver.legacy(metadata, {
142 | browser: this.graph.o.environment === "browser",
143 | });
144 | assert(typeof res === "string", `legacy resolution failed for ${this.name}@${format(this.version)}`);
145 | return parseModuleSpecifier(join(`npm-probe:${this.name}@${format(this.version)}/`, res));
146 | }
147 | }
148 | }
149 |
150 | const npm_data_transform_cache = new Map>();
151 |
152 | export async function getNPMData(o: Opt, specifier: ModuleSpecifier) {
153 | if (npm_data_transform_cache.has(specifier.href)) {
154 | return npm_data_transform_cache.get(specifier.href)!;
155 | }
156 |
157 | const pr = getNPMDataInner(o, specifier);
158 | npm_data_transform_cache.set(specifier.href, pr);
159 | const code = await pr;
160 | npm_data_transform_cache.set(specifier.href, code);
161 | return code;
162 | }
163 |
164 | async function getNPMDataInner(o: Opt, specifier: ModuleSpecifier) {
165 | const id = parseNPMExact(specifier.pathname);
166 | assert(id);
167 | const raw_code = await Deno.readTextFile(join(await getNPMPath(id.name, id.version), id.path));
168 | let code = await toESM(o, raw_code, specifier.href);
169 | code = code.replace(/\/\/# sourceMappingURL.+/, ""); // TODO resolve source map url
170 | return code;
171 | }
172 |
173 | export async function get_npm_import_link(o: Opt, info: NPMImportInfo): Promise {
174 | const importedCode = await getNPMData(o, info.module);
175 |
176 | if (await has_default_export(o, importedCode, info.specifier.href)) {
177 | return `
178 | // npm:${info.package.name}@${format(info.package.version)}
179 |
180 | export * from "${info.module.href}";
181 | import d from "${info.module.href}";
182 | export default d;`;
183 | } else {
184 | return `
185 | // npm:${info.package.name}@${format(info.package.version)}
186 |
187 | export * from "${info.module.href}";`;
188 | }
189 | }
190 |
191 | function stat(path: string | URL) {
192 | return Deno.stat(path).catch(() => null);
193 | }
194 |
195 | export async function importProbe(path: string, virtualPath: string = path) {
196 | const direct = await stat(path);
197 | if (direct?.isFile) {
198 | return virtualPath;
199 | } else if (direct?.isDirectory) {
200 | return await importProbe(`${path}/index`, `${virtualPath}/index`);
201 | } else {
202 | for (const ext of ["js", "mjs", "cjs"]) {
203 | if (await stat(`${path}.${ext}`)) {
204 | return `${virtualPath}.${ext}`;
205 | }
206 | }
207 | }
208 | return null;
209 | }
210 |
--------------------------------------------------------------------------------
/mod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import type { HmrContext, PluginOption } from "vite";
25 | import type { Opt } from "./src/options.ts";
26 | import { ModuleGraph } from "./src/graph.ts";
27 | import { decodeSpec, encodeSpec, resolve } from "./src/resolve.ts";
28 | import { resolve_undeclared_npm } from "./src/undeclared_npm.ts";
29 | import { is_excluded } from "./src/exclude.ts";
30 | import { getLogger } from "@logtape/logtape";
31 | import { Ray } from "./src/ray.ts";
32 |
33 | /**
34 | * Plugin configuration
35 | */
36 | export interface PluginDenoOptions {
37 | /**
38 | * override path to deno.json
39 | */
40 | deno_json?: string;
41 |
42 | /**
43 | * override path to deno.lock
44 | */
45 | deno_lock?: string;
46 |
47 | /**
48 | * bundling context
49 | * 1. Controls the Node module resolution conditions (when set to `"browser"` the package.json
50 | * `browser` entry is preferred over `main`)
51 | * 2. `node:` imports are only allowed when set to `"deno"`
52 | */
53 | env?: "deno" | "browser";
54 |
55 | /**
56 | * Those NPM packages will always be allowed even if they are not included in Deno's module graph.
57 | *
58 | * This can be used to resolve packages that are imported by injected code like HMR.
59 | */
60 | undeclared_npm_imports?: string[];
61 |
62 | /**
63 | * Those npm dependencies are left over to vite for resolution. This requires a `node_nodules` folder (like the symlinked one deno generates)
64 | */
65 | legacy_npm?: string[];
66 |
67 | /**
68 | * import map that is only applied to build module resolution.
69 | *
70 | * Useful for polyfilling `node:` and handling injected imports (JSX runtime, HMR, ...)
71 | *
72 | * Sometimes it might be required to add `#standalone` to the replaced import, otherwise
73 | * you will get errors because the replaced import is (of course) not reported by deno info.
74 | * The `#standalone` instructs the plugin to treat the import like an independent entrypoint.
75 | */
76 | extra_import_map?: [string, string][] | Map>;
77 |
78 | /**
79 | * All specifiers that are equal to this or match the RegExp are ignored, deferring
80 | * resolution to other plugins and Vite.
81 | *
82 | * Using strings is deprecated (strings are converted to RegExps anyway)
83 | *
84 | * Note that the specifiers passed to this might be in different formats (even for the
85 | * same one) depending on the circumstances where it is checked: It might be absolute
86 | * or relative, as path or `file:` URL and with or without `npm:` prefix, semver version
87 | * or version range.
88 | *
89 | * The RegExps should not be too expensive to check
90 | */
91 | exclude?: (string | RegExp)[];
92 |
93 | /**
94 | * @logtape/logtape logger id
95 | * @default "vite-plugin-deno"
96 | */
97 | log_id?: string;
98 |
99 | /**
100 | * Minimum time in milliseconds between hot updates, see Issue #5
101 | * @default 0
102 | */
103 | hot_update_min_time?: number;
104 | }
105 |
106 | /**
107 | * see {@link PluginDenoOptions}
108 | */
109 | export function pluginDeno(options: PluginDenoOptions): PluginOption {
110 | const extra_import_map = new Map(options.extra_import_map);
111 | const o: Opt = {
112 | logger: getLogger(options.log_id ?? "vite-plugin-deno"),
113 | deno_json: options.deno_json,
114 | deno_lock: options.deno_lock,
115 | extra_import_map,
116 | environment: options.env ?? "browser",
117 | exclude: [
118 | ...options.exclude?.map((excl) => {
119 | if (excl instanceof RegExp) {
120 | return excl;
121 | } else {
122 | // transform to regexp
123 | return new RegExp(`^${excl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`);
124 | }
125 | }) ?? [],
126 | ],
127 | legacy_npm: options.legacy_npm ?? [],
128 | };
129 |
130 | const legacy_npm_regex = new RegExp(`"npm:(${o.legacy_npm.join("|")})(@.+)"`, "g");
131 |
132 | if (o.environment === "deno") {
133 | o.exclude.push(/^node:/);
134 | }
135 | o.exclude.push(/\/@(fs|id)/);
136 | o.exclude.push(/\/?(@|\.)vite\//);
137 | o.exclude.push(/\/node_modules\//);
138 | o.exclude.push(/^$/);
139 |
140 | const graph = new ModuleGraph(o);
141 |
142 | resolve_undeclared_npm(options.undeclared_npm_imports ?? [], graph, extra_import_map);
143 |
144 | return {
145 | // @ts-ignore some of the Plugin type definitions do not include name
146 | name: "vite-plugin-deno",
147 | enforce: "pre",
148 | config() {
149 | if (o.environment === "deno") {
150 | return {
151 | build: {
152 | rollupOptions: {
153 | external: [/^node:/],
154 | },
155 | },
156 | };
157 | }
158 | },
159 | resolveId: {
160 | order: "pre",
161 | async handler(raw_id: string, raw_referrer: string | undefined) {
162 | const start = performance.now();
163 | const id = decodeSpec(raw_id);
164 | const referrer = raw_referrer && decodeSpec(raw_referrer);
165 |
166 | o.logger.debug(
167 | `Resolve module {id}${id !== raw_id ? `({raw_id})` : ""} from {referrer}${
168 | referrer !== raw_referrer ? `({raw_referrer})` : ""
169 | }`,
170 | {
171 | id,
172 | raw_id,
173 | referrer,
174 | raw_referrer,
175 | },
176 | );
177 |
178 | const ray = new Ray(id, referrer ?? "");
179 |
180 | if (id.endsWith(".html")) {
181 | return null;
182 | }
183 |
184 | if (is_excluded(id, o)) {
185 | o.logger.debug(`skipping (excluded specifier) {id}`, { ...ray });
186 | return null;
187 | }
188 |
189 | if (referrer && is_excluded(referrer, o)) {
190 | o.logger.debug(`skipping (excluded referrer) {id} from {referrer}`, { ...ray });
191 | return null;
192 | }
193 |
194 | if (o.legacy_npm.includes(id)) {
195 | o.logger.info(`skipping (legacy npm) {id}`, { ...ray });
196 | return null;
197 | }
198 |
199 | const resolved = await resolve(o, ray, graph, id, referrer);
200 |
201 | if (resolved) {
202 | o.logger.debug(`resolved {id} from {referrer} to {resolved} ({duration}ms)`, {
203 | ...ray,
204 | resolved: resolved.href,
205 | duration: performance.now() - start,
206 | });
207 | const encoded = encodeSpec(resolved);
208 |
209 | /**
210 | * Does not work with workspaces, because workspace imports would be skipped
211 | */
212 | // if (resolved.protocol === "file:" && referrer?.startsWith("file://")) {
213 | // o.logger.debug(`resolved file specifier {id} from {referrer} to {resolved} ({duration}ms)`, {
214 | // ...ray,
215 | // resolved: resolved.href,
216 | // duration: performance.now() - start,
217 | // });
218 | // return null;
219 | // }
220 |
221 | return encoded;
222 | } else {
223 | return null;
224 | }
225 | },
226 | },
227 | async load(raw_id: string) {
228 | const id = decodeSpec(raw_id);
229 | // const id = decodeURIComponent(raw_id);
230 | o.logger.debug(`Loading module {id}({raw_id})`, { id, raw_id });
231 |
232 | const mod = graph.get_resolved(id);
233 |
234 | if (!mod) {
235 | o.logger.warn(`[loader] failed to resolve {id}`, { id });
236 | return;
237 | }
238 |
239 | let result = await mod.load();
240 |
241 | result = result.replaceAll(legacy_npm_regex, (_, package_name) => `"${package_name}"`);
242 |
243 | if (id.startsWith("http")) {
244 | result = result.replace(/\/\/# sourceMappingURL.+/, "");
245 | }
246 |
247 | if (id.endsWith(".tsx")) {
248 | result = result.replaceAll(/\/\*\* \@jsx.+\*\//g, "");
249 | }
250 |
251 | o.logger.debug(`loaded {id}`, { id });
252 |
253 | return result;
254 | },
255 | handleHotUpdate(ctx: HmrContext) {
256 | // console.log({ ...ctx, server: undefined, read: undefined, modules: undefined });
257 | const last_file_update = last_update.get(ctx.file);
258 | last_update.set(ctx.file, ctx.timestamp);
259 |
260 | if (last_file_update && (ctx.timestamp - last_file_update) < (options.hot_update_min_time ?? 0)) {
261 | o.logger.error(`skipping HMR update for {file}, too early (d={diff})`, {
262 | file: ctx.file,
263 | last_update: last_file_update,
264 | timestamp: ctx.timestamp,
265 | hot_update_min_time: options.hot_update_min_time,
266 | diff: ctx.timestamp - last_file_update,
267 | });
268 | return [];
269 | }
270 | },
271 | };
272 | }
273 |
274 | const last_update = new Map();
275 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [@Deno-PLC](https://github.com/deno-plc) / [vite-plugin-deno](https://jsr.io/@deno-plc/vite-plugin-deno)
2 |
3 | Native Vite support for Deno imports (jsr:, npm:, https://).
4 |
5 | Use Deno for the frontend and enjoy development without the hassle of `node_modules` and package managers!
6 |
7 | ## Overview
8 |
9 | 1. Enable Deno for the whole workspace
10 |
11 | 2. Adjust your Vite config to use this plugin
12 |
13 | 3. Enjoy development without `node_modules` and package managers
14 |
15 | ## Project status
16 |
17 | `vite-plugin-deno` can be considered 'ready' for standard setups, however in more complex setups or when using NPM
18 | dependencies that do hacky things, builds might fail.
19 |
20 | In this case good knowledge of module resolution is required to troubleshoot these problems. Of course I will assist you
21 | in this process, feel free to contact [me](https://github.com/hansSchall) via GitHub or Matrix. Please always open an
22 | Github Issue to help others in the same situation.
23 |
24 | _**Short: Nothing fow newbies...**_
25 |
26 | Please read the [FAQ / Known limitations](#faq--known-limitations) section first and make sure you are not using
27 | anything that is described as incompatible there.
28 |
29 | I use the plugin on my own for a quite large codebase that includes SSR, multiple frontend builds, server code bundling,
30 | WebAssembly and a number of commonly used dependencies. This is used as a reference project for testing. While this can
31 | never be a replacement for unit tests, a real world project is a pretty good testing playground for this kind of
32 | software and ensures the plugin always works with the latest Deno versions (failing builds are very likely to be noticed
33 | on my biggest project...).
34 |
35 | ## How does this work?
36 |
37 | This plugin injects a custom rollup resolver at the earliest stage possible (even before the builtin fs loader) which
38 | catches nearly every import.
39 |
40 | Instead of letting Vite resolve the imports the plugin consults the Deno CLI (`deno info --json`). This ensures that all
41 | imports link to exactly the same files Deno would use (including import mapping).
42 |
43 | Additionally the plugin contains a Node.js/NPM compatible resolver (including probing and package.json exports), because
44 | `deno info` only outputs the resolved npm package versions, not the exact files.
45 |
46 | A custom loader is able to locate the source code for all those new specifier schemes (for example in the global deno
47 | cache). `file:` URLs are mapped back to ordinary paths to make HMR work (Vite has no clue about `file:` URLs). The
48 | source code of `npm:` imports is transformed from CJS to ESM if necessary.
49 |
50 | ## Supported imports
51 |
52 | ### Provided by Deno
53 |
54 | - `./foo.ts`: relative imports
55 | - `https://deno.land/x/foo@1.2.3/mod.ts`: HTTPS imports
56 | - `jsr:@scope/foo`: JSR
57 | - `npm:foo@^1.0.0`: NPM with version range
58 | - `foo`: Mapped imports (`deno.json`>`imports`)
59 |
60 | ... and maybe imports that are not even invented yet, none of the imports above is explicitly handled by the plugin,
61 | `deno info` tells us everything that is needed to get the module source code.
62 |
63 | ### Provided by the Plugin
64 |
65 | - `npm:foo@1.2.3`: resolved NPM imports (including subpath imports)
66 |
67 | The following imports are only used internally, but you may get in contact with them in the DevTools. You cannot use
68 | them in your source code because Deno wont be able to resolve them, but you may specify them in
69 | [`extra_import_map`](https://jsr.io/@deno-plc/vite-plugin-deno/doc/~/PluginDenoOptions.extra_import_map)
70 |
71 | - `npm-data:foo@1.2.3/bar.js`: This references an internal file of the package tarball (remember, not all files in an
72 | NPM package can be imported from the outside)
73 | - `npm-probe:foo@1.2.3/bar`: Same as above, but with probing. Will be resolved to a `npm-data:` URL
74 |
75 | ## Usage
76 |
77 | Currently only build script configurations are supported because `vite.config.ts` will always be run with Node :-(. It
78 | is not that complicated as it sounds, you just have to use the JS API of Vite.
79 |
80 | ### `scripts/vite.ts`
81 |
82 | ```ts
83 | import { pluginDeno } from "@deno-plc/vite-plugin-deno";
84 | import type { InlineConfig } from "vite";
85 |
86 | export const config: InlineConfig = {
87 | configFile: false, // configuration is inlined here
88 | server: {
89 | port: 80,
90 | },
91 | plugins: [
92 | pluginDeno({
93 | // see configuration docs
94 | }),
95 | ],
96 | };
97 | ```
98 |
99 | ### `scripts/dev.ts`:
100 |
101 | ```ts
102 | import { createServer } from "vite";
103 | import { config } from "./vite.ts";
104 |
105 | const server = await createServer(config);
106 | await server.listen();
107 | server.printUrls();
108 | ```
109 |
110 | ### `scripts/release.ts`
111 |
112 | ```ts
113 | import { build } from "vite";
114 | import { config } from "./vite.ts";
115 |
116 | await build(config);
117 | ```
118 |
119 | ### `Deno.json`
120 |
121 | Include the DOM in the TS compiler options and define the build tasks
122 |
123 | ```json
124 | {
125 | "tasks": {
126 | "dev": "deno run -A scripts/dev.ts",
127 | "release": "deno run -A scripts/release.ts"
128 | },
129 | "compilerOptions": {
130 | "lib": [
131 | "deno.window",
132 | "deno.ns",
133 | "ESNext",
134 | "DOM",
135 | "DOM.Iterable",
136 | "DOM.AsyncIterable",
137 | "webworker"
138 | ]
139 | }
140 | }
141 | ```
142 |
143 | For an example/template see [examples/plain](examples/plain/README.md)
144 |
145 | ## Configuration options (Overview)
146 |
147 | [> for a full version visit the JSR Docs](https://jsr.io/@deno-plc/vite-plugin-deno/doc/~/PluginDenoOptions)
148 |
149 | ### `deno_json` and `deno_lock`
150 |
151 | Override the locations of `deno.json` and `deno.lock`. Passed to `deno --config ...` and `deno --lock ...`
152 |
153 | ### `env`: `"deno"` or `"browser"`(default)
154 |
155 | Set to `"deno"` if you are bundling for Deno. This enables `node:` imports.
156 |
157 | Set to `"browser"` (default) if you are bundling for Browsers. This prefers NPM `browser` exports.
158 |
159 | ### `undeclared_npm_imports`: `string[]`
160 |
161 | Those packages can always be imported, even when they don't show up in the deno module graph. This can be used to
162 | resolve packages that are imported by injected code like HMR.
163 |
164 | ### `extra_import_map`: `string` => `string`
165 |
166 | This can be a anything the `Map` constructor supports. (yes, we use a Map for the import map)
167 |
168 | This import map can be used to polyfill `node:` (for details see [here](#polyfilling-node)) or do the same as
169 | `undeclared_npm_imports` on a more granular level.
170 |
171 | Sometimes it might be required to add `#standalone` to the replaced import, otherwise you will get errors because the
172 | replaced import is (of course) not reported by `deno info`. The `#standalone` instructs the plugin to treat the import
173 | like an independent entrypoint.
174 |
175 | ### `exclude`: `(string | RegExp)[]`
176 |
177 | Those imports wont be touched. RegExps are preferred (strings are converted to RegExps anyway). Note: Deno still checks
178 | these imports so make sure they are valid anyway.
179 |
180 | ### `legacy_npm`: `string[]`
181 |
182 | These npm packages are left over to Vite
183 |
184 | ## `node_modules`
185 |
186 | This plugin works without `node_modules` most of the time, but in some cases this directory is required to make things
187 | work.
188 |
189 | There are various reasons why a dependency has to reside in `node_modules`. Some dependencies like `@xterm/xterm` do
190 | ugly things with their exports (like exporting inside if-blocks), so it is impossible for this plugin to transform them
191 | to ESM. In this case we let Vite do it using plain old `node_modules` instead.
192 |
193 | There are good news: Deno supports `node_modules` natively! (= you don't even need Node.js and NPM) Just set
194 | `"nodeModulesDir": "auto",` in your `deno.json` and add the respective dependency to the `legacy_npm` option of this
195 | plugin.
196 |
197 | Don't worry about the `node_modules` folder, it only contains symlinks to the global cache!
198 | [Read more](https://deno.com/blog/your-new-js-package-manager)
199 |
200 | ## Polyfilling `node:`
201 |
202 | This plugin does not automatically polyfill `node:` in browsers, but you can easily do so by setting `extra_import_map`.
203 |
204 | Unfortunately most polyfill packages do crazy things with exports (I tested `buffer` and `util`, both didn't worked out
205 | of the box for different reasons). This is why it is not as straightforward as mapping `node:buffer` to `npm:buffer`
206 |
207 | 1. Select an appropriate polyfill package (likely on NPM)
208 | 2. Look up its most recent version
209 | 3. link it in `extra_import_map`: `"node:buffer", "https://cdn.jsdelivr.net/npm/buffer@6.0.3/+esm#standalone"`
210 |
211 | We use a https:// import to get rid of CommonJS issues, but in the end it is just a Deno remote import (=Deno downloads
212 | the file, no CDN import)
213 |
214 | Make sure to add [`#standalone`](#extra_import_map-string--string) to the replaced import.
215 |
216 | In case you don't want to polyfill a module and instead let the import fail, redirect it to `virtual:node:null` (this
217 | time without `#standalone`). This makes Vite happy but any attempt to load the module will fail with an error (It
218 | resolves to a file that just contains a `throw` statement). This is useful if a package does feature detection: It tries
219 | to dynamically import `node:fs` (or any other module), if it succeeds it uses the filesystem and if it fails it simply
220 | doesn't do anything filesystem-related. This mechanism is used by many packages that use the filesystem when used with
221 | Node/Deno, but work in browsers, too.
222 |
223 | ## Usage with React
224 |
225 | Currently React is unsupported.
226 |
227 | 1. The Deno LSP has problems with React. It is about missing JSXRuntime types...
228 | 2. `react-dom` does some extremely ugly things with cjs exports (like exporting inside an if statement ...). For this
229 | reason it cannot be transformed to ESM correctly. At the same time it needs to be linked by JSX which makes it
230 | extremely difficult to use it via the `node_modules` fallback.
231 |
232 | I personally only use Preact, so this is not top priority.
233 |
234 | Until this is supported out of the box you could use the [Preact configuration](#usage-with-preact). If you are doing
235 | this, all react imports are redirected to preact and the whole application is run with the react compatibility layer...
236 | (this works without any problems 🤯) Read more: https://preactjs.com/guide/v10/switching-to-preact. You do not need to
237 | care about the bundler setup shown there, the setup [below](#usage-with-preact) already configures everything.
238 |
239 | If you really need React, please file an issue. This should be a very rare case because the `preact/compat` layer covers
240 | nearly the whole React API. By the way, Preact is a bit faster than React...
241 |
242 | ## Usage with Preact
243 |
244 | For an example/template see [examples/preact](examples/preact/README.md)
245 |
246 | Although `@preact/preset-vite` works when the respective Babel plugins are linked via `node_modules`, I do recommend
247 | _**against**_ using it.
248 |
249 | With a only few lines of configuration you can do exactly the same. By the way: this speeds up the development server a
250 | lot, because it uses ESBuild instead of Babel
251 |
252 | Just update your Vite config to set up prefresh (the Preact HMR Engine) and ESBuild for JSX transformation:
253 |
254 | ```typescript
255 | import { pluginDeno } from "@deno-plc/vite-plugin-deno";
256 | import prefresh from "@prefresh/vite"; // HMR
257 | import type { InlineConfig, Plugin } from "vite";
258 |
259 | export const config: InlineConfig = {
260 | plugins: [
261 | pluginDeno({
262 | env: "browser",
263 | undeclared_npm_imports: [
264 | // injected by JSX transform
265 | "preact/jsx-runtime",
266 | "preact/jsx-dev-runtime",
267 | // injected by HMR
268 | "@prefresh/core",
269 | "@prefresh/utils",
270 | // injected by react compat
271 | "@preact/compat",
272 | ],
273 | extra_import_map: new Map([
274 | // react compat
275 | ["react", "@preact/compat"],
276 | ["react-dom", "@preact/compat"],
277 | ]),
278 | }),
279 | // HMR Plugin
280 | prefresh({
281 | // `node_modules` is excluded internally, lets do the same
282 | exclude: [/^npm/, /registry.npmjs.org/, /^jsr/, /^https?/],
283 | }) as Plugin,
284 | ],
285 | // JSX transform
286 | esbuild: {
287 | jsx: "automatic",
288 | jsxImportSource: "preact",
289 | },
290 | };
291 | ```
292 |
293 | And your `deno.json`:
294 |
295 | ```json
296 | "compilerOptions": {
297 | "jsx": "react-jsx",
298 | "jsxImportSource": "preact",
299 | }
300 | ```
301 |
302 | If you want to use the Preact DevTools, follow the instructions there: https://preactjs.github.io/preact-devtools/ (it's
303 | one import)
304 |
305 | We need the prefresh exclude rule to replicate the internal exclude of all paths containing `node_modules`. Otherwise
306 | prefresh would inject HMR helpers into libraries and the code that powers HMR, which causes very strange errors.
307 |
308 | If you are on Windows, a [little workaround](#denostat-workaround-needed-windows-only) is required.
309 |
310 | ## Usage with Deno (Code bundling)
311 |
312 | Just set the `env` option to `deno`, everything should work out of the box! (even with `node:` imports)
313 |
314 | This can replace `deno bundle`.
315 |
316 | If you want a lightweight solution, check out
317 | [esbuild_deno_loader](https://github.com/lucacasonato/esbuild_deno_loader), which is exactly the same for esbuild.
318 |
319 | ## FAQ / Known limitations
320 |
321 | ### Asset imports
322 |
323 | Importing assets like `import imgUrl from './img.png'` will throw errors, because Deno simply cannot handle such
324 | imports. Currently it is not even possible to exclude these files :-(
325 |
326 | Instead of asset imports you should use `const imgUrl = new URL("/img.png", import.meta.url).href` which provides
327 | exactly the same functionality while being compatible with Deno.
328 |
329 | ### CSS imports
330 |
331 | Similar to asset imports, CSS imports are vite-only, so Deno complains about them...
332 |
333 | **Solution 1:** Import your CSS directly from the HTML
334 |
335 | **Solution 2:** Import your CSS fom a JS file that is imported from the HTML, excluded from this plugin and not imported
336 | from the rest of the JS/TS code (like this one:
337 | [examples/preact/src/style-import.js](examples/preact/src/style-import.js))
338 |
339 | ### Fullstack Frameworks
340 |
341 | Fullstack frameworks are most likely incompatible with this / Deno. They are unhappy with swapping out internal parts in
342 | general, especially when it affects a fundamental thing like module resolution. Additionally most of them use React.
343 |
344 | ### React does not work (and maybe more packages that do ugly things with exports)
345 |
346 | See [Usage with React](#usage-with-react)
347 |
348 | For other packages it might be possible to use the [`node_modules` fallback](#node_modules)
349 |
350 | ### Build scripts
351 |
352 | The classic `vite.config.ts` file would be executed using Node.js instead of Deno. Just use scripts as shown above.
353 |
354 | ### Dependency optimization
355 |
356 | Unsupported because dependency optimization relies on `node_modules`. If you really need it (lodash), see
357 | [`node_modules` section](#node_modules)
358 |
359 | ### Babel/PostCSS
360 |
361 | Some other plugins require Babel or PostCSS or one of their plugins. Their plugin loaders depend on `node_modules`, see
362 | [`node_modules` section](#node_modules).
363 |
364 | In order to get the best DX possible, you should avoid Babel based plugins. For most setups Babel isn't really needed,
365 | see [Usage wit Preact](#usage-with-preact). Using builtin esbuild is usually many times faster.
366 |
367 | ### TailwindCSS
368 |
369 | The `tailwindcss` PostCSS plugin currently needs to be installed in `node_modules`, see
370 | [`node_modules` section](#node_modules)
371 |
372 | The recommended way is to use [Tailwind Play CDN](https://tailwindcss.com/docs/installation/play-cdn) during development
373 | and the [Tailwind CLI](https://tailwindcss.com/docs/installation) for release build.
374 |
375 | ### `Deno.stat` workaround is not needed anymore
376 |
377 | The issue has been fixed by Deno. In case you use an old Deno version (1.x and early 2.x) read about it
378 | [here](https://github.com/deno-plc/vite-plugin-deno/tree/c917814f5b4cf0fdcbfcd9a09772fe6644e24cb0?tab=readme-ov-file#denostat-workaround-needed-windows-only)
379 |
380 | ### Deno 2.x
381 |
382 | Versions older than 2.1.7 do not support Deno 2.0.
383 |
384 | ## Acknowledgements
385 |
386 | [esbuild_deno_loader](https://github.com/lucacasonato/esbuild_deno_loader) does exactly the same for esbuild. The basic
387 | principle of operation is the same.
388 |
389 | [resolve.exports](https://github.com/lukeed/resolve.exports) helped a lot, it handles all the `package.json` fields.
390 |
391 | ## License (LGPL-2.1-or-later)
392 |
393 | Copyright (C) 2024 Hans Schallmoser
394 |
395 | This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
396 | License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later
397 | version.
398 |
399 | This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
400 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
401 | details.
402 |
403 | You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the
404 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see
405 | https://www.gnu.org/licenses/
406 |
--------------------------------------------------------------------------------
/src/graph.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @license LGPL-2.1-or-later
3 | *
4 | * vite-plugin-deno
5 | *
6 | * Copyright (C) 2024 - 2025 Hans Schallmoser
7 | *
8 | * This library is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU Lesser General Public
10 | * License as published by the Free Software Foundation; either
11 | * version 2.1 of the License, or (at your option) any later version.
12 | *
13 | * This library is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | * Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public
19 | * License along with this library; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 | * USA or see .
22 | */
23 |
24 | import { join, toFileUrl } from "@std/path";
25 | import { z } from "zod";
26 | import type { Opt } from "./options.ts";
27 | import { format, parse } from "@std/semver";
28 | import { get_npm_import_link, getNPMData, getNPMPath, importProbe, NPMPackage } from "./npm.ts";
29 | import { type ModuleSpecifier, parseModuleSpecifier, parseNPMExact, parseNPMImport } from "./specifier.ts";
30 | import { assert } from "jsr:@std/assert@^0.225.2/assert";
31 | import { is_excluded } from "./exclude.ts";
32 | import { supported_extensions } from "./constants.ts";
33 |
34 | const DenoInfoPosition = z.object({
35 | line: z.number().int().nonnegative(),
36 | character: z.number().int().nonnegative(),
37 | });
38 |
39 | const DenoInfoImport = z.object({
40 | specifier: z.string(),
41 | span: z.object({
42 | start: DenoInfoPosition,
43 | end: DenoInfoPosition,
44 | }),
45 | });
46 |
47 | const DenoInfoModule = z.union([
48 | z.object({
49 | kind: z.literal("esm"),
50 | specifier: z.string().transform(parseModuleSpecifier),
51 | mediaType: z.enum(["TypeScript", "JavaScript", "TSX", "Dts"]),
52 | dependencies: z.object({
53 | specifier: z.string(),
54 | type: DenoInfoImport.optional(),
55 | code: DenoInfoImport.optional(),
56 | }).array().default([]),
57 | local: z.string().transform(toFileUrl),
58 | size: z.number().int().nonnegative(),
59 | }),
60 | z.object({
61 | kind: z.literal("asserted"),
62 | specifier: z.string().transform(parseModuleSpecifier),
63 | mediaType: z.enum(["Json"]),
64 | local: z.string().transform(toFileUrl),
65 | size: z.number().int().nonnegative(),
66 | }),
67 | z.object({
68 | kind: z.literal("node"),
69 | specifier: z.string().transform(parseModuleSpecifier),
70 | moduleName: z.string(),
71 | }),
72 | z.object({
73 | kind: z.literal("npm"),
74 | specifier: z.string().transform(parseModuleSpecifier),
75 | npmPackage: z.string(),
76 | }),
77 | ]);
78 | type DenoInfoModule = z.infer;
79 |
80 | const DenoInfoNPMPackage = z.object({
81 | name: z.string(),
82 | version: z.string().transform((version) => parse(version)),
83 | dependencies: z.string().array(),
84 | });
85 |
86 | const DenoInfoOutput = z.object({
87 | roots: z.string().array(),
88 | modules: DenoInfoModule.array(),
89 | redirects: z.record(z.string().transform(parseModuleSpecifier)),
90 | packages: z.record(z.string()),
91 | npmPackages: z.record(DenoInfoNPMPackage),
92 | });
93 |
94 | export const npmImportKind = Symbol();
95 | export const npmDataKind = Symbol();
96 | export const virtualImportKind = Symbol();
97 |
98 | export interface NPMImportInfo {
99 | kind: typeof npmImportKind;
100 | specifier: ModuleSpecifier;
101 | package: NPMPackage;
102 | module: ModuleSpecifier;
103 | }
104 |
105 | export interface NPMDataInfo {
106 | kind: typeof npmDataKind;
107 | specifier: ModuleSpecifier;
108 | package: NPMPackage;
109 | }
110 |
111 | export interface VirtualInfo {
112 | kind: typeof virtualImportKind;
113 | specifier: ModuleSpecifier;
114 | code: () => Promise;
115 | }
116 |
117 | export class GraphModule {
118 | readonly specifier: ModuleSpecifier;
119 | readonly esm_dependencies = new Map();
120 | private constructor(
121 | readonly def: DenoInfoModule | NPMImportInfo | NPMDataInfo | VirtualInfo,
122 | readonly graph: ModuleGraph,
123 | ) {
124 | this.specifier = def.specifier;
125 |
126 | graph.modules.set(this.specifier.href, this);
127 |
128 | // this.load();
129 | }
130 |
131 | public static new(
132 | def: DenoInfoModule | NPMImportInfo | NPMDataInfo | VirtualInfo,
133 | graph: ModuleGraph,
134 | ): GraphModule {
135 | const spec = def.specifier.href;
136 | const mod = graph.modules.get(spec) || new GraphModule(def, graph);
137 |
138 | if (def.kind === "esm") {
139 | for (const dep of def.dependencies) {
140 | if (dep.code) {
141 | graph.get_module(parseModuleSpecifier(dep.code.specifier), false).then((dep_mod) => {
142 | if (dep_mod) {
143 | mod.esm_dependencies.set(dep.specifier, dep_mod);
144 | }
145 | });
146 | }
147 | }
148 | }
149 |
150 | return mod;
151 | }
152 |
153 | private code: string | Promise | null = null;
154 |
155 | async #load() {
156 | if (this.def.kind === "esm") {
157 | return await Deno.readTextFile(this.def.local);
158 | } else if (this.def.kind === npmImportKind) {
159 | return await get_npm_import_link(this.graph.o, this.def);
160 | } else if (this.def.kind === npmDataKind) {
161 | return await getNPMData(this.graph.o, this.def.specifier);
162 | } else if (this.def.kind === virtualImportKind) {
163 | return await this.def.code();
164 | }
165 | throw new Error(`module type ${this.def.kind} unsupported`);
166 | }
167 |
168 | async load(): Promise {
169 | if (this.code) {
170 | return this.code;
171 | } else {
172 | const pr = this.#load();
173 | this.code = pr;
174 | const code = await pr;
175 | if (this.specifier.protocol === "file:") {
176 | this.code = null;
177 | } else {
178 | this.code = code;
179 | }
180 | return code;
181 | }
182 | }
183 |
184 | async resolve_import(spec: string): Promise {
185 | if (this.def.kind === npmDataKind) {
186 | if (spec.startsWith(".")) {
187 | return await this.graph.get_module(
188 | parseModuleSpecifier(`npm-probe:${join(this.specifier.pathname, "../", spec)}`),
189 | );
190 | } else {
191 | const imp = parseNPMImport(spec);
192 | assert(imp);
193 | const pkg = this.def.package.dependencies.get(imp.name);
194 | assert(pkg, `cannot find dependency ${imp.name}(${spec}) on ${this.def.package.name}`);
195 | return await this.graph.get_module(await pkg.resolve_import(imp.path));
196 | }
197 | } else if (this.def.kind === "esm") {
198 | return this.esm_dependencies.get(spec) || null;
199 | }
200 | return null;
201 | }
202 | }
203 |
204 | export class ModuleGraph {
205 | constructor(readonly o: Opt) {
206 | GraphModule.new({
207 | kind: virtualImportKind,
208 | specifier: parseModuleSpecifier("virtual:node:null"),
209 | code() {
210 | return Promise.resolve(`throw new Error("");`);
211 | },
212 | }, this);
213 | }
214 |
215 | #pending: Promise | null = null;
216 | readonly modules = new Map();
217 | readonly #redirects = new Map();
218 | readonly #npm_extended_id = new Map();
219 | readonly npm_packages = new Map();
220 | readonly npm_package_versions = new Map>();
221 |
222 | async call_deno(root: string) {
223 | const args = ["info", "--json"];
224 | if (this.o.deno_json) {
225 | args.push("--config", this.o.deno_json);
226 | }
227 | if (this.o.deno_lock) {
228 | args.push("--lock", this.o.deno_lock);
229 | }
230 | args.push(root);
231 | const start = performance.now();
232 | const info = new Deno.Command(Deno.execPath(), {
233 | args,
234 | env: { DENO_NO_PACKAGE_JSON: "true" },
235 | stdout: "piped",
236 | stderr: "inherit",
237 | });
238 |
239 | const output = await info.output();
240 | const duration = performance.now() - start;
241 | this.o.logger.info(`deno info {root} took {duration}ms`, {
242 | root,
243 | duration,
244 | });
245 | const data = JSON.parse(new TextDecoder().decode(output.stdout));
246 | return data;
247 | }
248 |
249 | private async get_deno_info(root: string) {
250 | const deno_info = await this.call_deno(root);
251 | const parsed = DenoInfoOutput.safeParse(deno_info);
252 |
253 | if (!parsed.success) {
254 | const partial_parse = z.object({
255 | modules: z.object({
256 | error: z.string().optional(),
257 | specifier: z.string().transform(parseModuleSpecifier),
258 | }).array(),
259 | }).safeParse(deno_info);
260 | if (partial_parse.success) {
261 | const { modules } = partial_parse.data;
262 | const errors: string[] = [];
263 | for (const { specifier, error } of modules) {
264 | if (error) {
265 | errors.push(`${specifier}: ${error}`);
266 | }
267 | }
268 | if (errors.length > 0) {
269 | throw new Error(`failed to look up module graph of ${root}:\n${errors.join("\n")}`);
270 | }
271 | }
272 | throw new Error(`failed to look up module graph of ${root}: Invalid Output:\n ${parsed.error}`);
273 | }
274 |
275 | const { modules, redirects, npmPackages, roots } = parsed.data;
276 |
277 | assert(roots.length === 1);
278 |
279 | const waitNPM: Promise[] = [];
280 |
281 | for (const extended_id in npmPackages) {
282 | const { name, version, dependencies } = npmPackages[extended_id];
283 |
284 | if (this.npm_package_versions.has(name)) {
285 | this.npm_package_versions.get(name)!.add(format(version));
286 | } else {
287 | this.npm_package_versions.set(name, new Set([format(version)]));
288 | }
289 |
290 | const npm_name = `${name}@${format(version)}`;
291 |
292 | // {
293 | // if (this.#npm_extended_id.has(npm_name)) {
294 | // if (this.#npm_extended_id.get(npm_name) !== extended_id) {
295 | // throw new Error(
296 | // `Expectation failed: underscore version extension differs while processing package '${name}'@'${
297 | // format(version)
298 | // }' processing '${extended_id}' hit '${
299 | // this.#npm_extended_id.get(npm_name)
300 | // }'. Please file an issue: https://github.com/deno-plc/vite-plugin-deno/issues/new`,
301 | // );
302 | // }
303 | // } else {
304 | // this.#npm_extended_id.set(npm_name, extended_id);
305 | // }
306 | // }
307 |
308 | const specifier = parseModuleSpecifier(`npm:${npm_name}`);
309 | if (npm_name !== extended_id) {
310 | this.#redirects.set(parseModuleSpecifier(`npm:${extended_id}`).href, specifier);
311 | }
312 |
313 | if (this.npm_packages.has(npm_name)) {
314 | if (!this.npm_packages.has(extended_id)) {
315 | this.npm_packages.set(extended_id, this.npm_packages.get(npm_name)!);
316 | }
317 | continue;
318 | }
319 |
320 | const pkg = new NPMPackage(name, version, dependencies, this);
321 |
322 | this.npm_packages.set(npm_name, pkg);
323 | this.npm_packages.set(extended_id, pkg);
324 |
325 | waitNPM.push(pkg.fetch_metadata());
326 | }
327 |
328 | for (const redirect in redirects) {
329 | this.#redirects.set(parseModuleSpecifier(redirect).href, redirects[redirect]);
330 | }
331 |
332 | // remove self-redirects
333 | for (const [k, v] of this.#redirects) {
334 | if (k === v.href) {
335 | this.#redirects.delete(k);
336 | }
337 | }
338 |
339 | Promise.all(waitNPM).then(() => {
340 | for (const [_id, pkg] of this.npm_packages) {
341 | pkg.link();
342 | }
343 | });
344 |
345 | for (const mod of modules) {
346 | if (mod.kind === "esm") {
347 | GraphModule.new(mod, this);
348 | }
349 | }
350 | }
351 |
352 | async update_info(specifier: ModuleSpecifier) {
353 | const pr = this.get_deno_info(specifier.href);
354 | this.#pending = pr;
355 | await pr;
356 | this.#pending = null;
357 | }
358 |
359 | async get_module(specifier: ModuleSpecifier, may_fetch: boolean = true): Promise {
360 | if (is_excluded(specifier.href, this.o)) {
361 | return null;
362 | }
363 | const spec_ext = specifier.pathname.split(".").pop();
364 | if (spec_ext && /^[a-zA-Z]{1,20}$/.test(spec_ext) && !supported_extensions.includes(spec_ext)) {
365 | return null;
366 | }
367 | if (this.#redirects.has(specifier.href)) {
368 | // console.log(`redirecting ${specifier}`);
369 | return await this.get_module(this.#redirects.get(specifier.href)!, may_fetch);
370 | }
371 | if (this.o.extra_import_map.has(specifier.href)) {
372 | return await this.get_module(
373 | parseModuleSpecifier(await this.o.extra_import_map.get(specifier.href)!),
374 | may_fetch,
375 | );
376 | }
377 | if (this.modules.has(specifier.href)) {
378 | return this.modules.get(specifier.href)!;
379 | }
380 | if (this.#pending) {
381 | await this.#pending;
382 | return await this.get_module(specifier, may_fetch);
383 | }
384 | if (specifier.protocol === "npm:") {
385 | const id = parseNPMExact(specifier.pathname);
386 | if (id) {
387 | const pkg = this.npm_packages.get(`${id.name}@${format(id.version)}`);
388 | if (pkg) {
389 | const spec = await pkg.resolve_import(id.path);
390 | const mod = GraphModule.new({
391 | kind: npmImportKind,
392 | package: pkg,
393 | specifier,
394 | module: spec,
395 | }, this);
396 | // free-running prefetch
397 | this.get_module(spec, false);
398 | return mod;
399 | }
400 | }
401 | }
402 | if (specifier.protocol === "npm-probe:") {
403 | // console.log(`%c[PROBING] ${specifier}`, "color:#f00");
404 | const id = parseNPMExact(specifier.pathname);
405 | if (id) {
406 | const pkg = this.npm_packages.get(`${id.name}@${format(id.version)}`);
407 | if (pkg) {
408 | const probe_res = await importProbe(
409 | join(await getNPMPath(pkg.name, pkg.version), id.path),
410 | id.path,
411 | );
412 | if (probe_res) {
413 | const spec = parseModuleSpecifier(`npm-data:${pkg.name}@${format(pkg.version)}/${probe_res}`);
414 | const mod = GraphModule.new({
415 | kind: npmDataKind,
416 | specifier: spec,
417 | package: pkg,
418 | }, this);
419 | return mod;
420 | }
421 | }
422 | }
423 | throw new Error(`Failed to probe ${specifier}`);
424 | }
425 | if (specifier.protocol === "npm-data:") {
426 | const id = parseNPMExact(specifier.pathname);
427 | if (id) {
428 | const pkg = this.npm_packages.get(`${id.name}@${format(id.version)}`);
429 | if (pkg) {
430 | const mod = GraphModule.new({
431 | kind: npmDataKind,
432 | specifier,
433 | package: pkg,
434 | }, this);
435 | return mod;
436 | }
437 | }
438 | throw new Error(`Failed to parse as npm-data: ${specifier}`);
439 | }
440 | if (may_fetch) {
441 | await this.update_info(specifier);
442 | return await this.get_module(specifier, false);
443 | } else {
444 | // console.log(`Specifier ${specifier} could not be resolved`);
445 | // throw new Error(`Specifier ${specifier} could not be resolved`);
446 |
447 | return null;
448 | }
449 | }
450 |
451 | get_resolved(specifier: string): GraphModule | null {
452 | if (this.#redirects.has(specifier)) {
453 | return this.get_resolved(this.#redirects.get(specifier)!.href);
454 | } else if (this.modules.has(specifier)) {
455 | return this.modules.get(specifier)!;
456 | } else {
457 | return null;
458 | }
459 | }
460 | }
461 |
--------------------------------------------------------------------------------
/examples/plain/deno.lock:
--------------------------------------------------------------------------------
1 | {
2 | "version": "4",
3 | "specifiers": {
4 | "jsr:@std/assert@0.223": "0.223.0",
5 | "jsr:@std/assert@0.226": "0.226.0",
6 | "jsr:@std/assert@~0.225.2": "0.225.3",
7 | "jsr:@std/path@~0.225.1": "0.225.2",
8 | "jsr:@std/semver@^1.0.2": "1.0.3",
9 | "npm:acorn-walk@^8.3.3": "8.3.4",
10 | "npm:acorn@^8.12.1": "8.13.0",
11 | "npm:lebab@^3.2.4": "3.2.4",
12 | "npm:resolve.exports@^2.0.2": "2.0.2",
13 | "npm:validate-npm-package-name@^5.0.1": "5.0.1",
14 | "npm:vite@^5.2.12": "5.4.9",
15 | "npm:zod@^3.22.5": "3.23.8"
16 | },
17 | "jsr": {
18 | "@std/assert@0.223.0": {
19 | "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24"
20 | },
21 | "@std/assert@0.225.3": {
22 | "integrity": "b3c2847aecf6955b50644cdb9cf072004ea3d1998dd7579fc0acb99dbb23bd4f"
23 | },
24 | "@std/assert@0.226.0": {
25 | "integrity": "0dfb5f7c7723c18cec118e080fec76ce15b4c31154b15ad2bd74822603ef75b3"
26 | },
27 | "@std/path@0.225.2": {
28 | "integrity": "0f2db41d36b50ef048dcb0399aac720a5348638dd3cb5bf80685bf2a745aa506",
29 | "dependencies": [
30 | "jsr:@std/assert@0.226"
31 | ]
32 | },
33 | "@std/semver@1.0.3": {
34 | "integrity": "7c139c6076a080eeaa4252c78b95ca5302818d7eafab0470d34cafd9930c13c8"
35 | }
36 | },
37 | "npm": {
38 | "@esbuild/aix-ppc64@0.21.5": {
39 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="
40 | },
41 | "@esbuild/android-arm64@0.21.5": {
42 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="
43 | },
44 | "@esbuild/android-arm@0.21.5": {
45 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="
46 | },
47 | "@esbuild/android-x64@0.21.5": {
48 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="
49 | },
50 | "@esbuild/darwin-arm64@0.21.5": {
51 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="
52 | },
53 | "@esbuild/darwin-x64@0.21.5": {
54 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="
55 | },
56 | "@esbuild/freebsd-arm64@0.21.5": {
57 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="
58 | },
59 | "@esbuild/freebsd-x64@0.21.5": {
60 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="
61 | },
62 | "@esbuild/linux-arm64@0.21.5": {
63 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="
64 | },
65 | "@esbuild/linux-arm@0.21.5": {
66 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="
67 | },
68 | "@esbuild/linux-ia32@0.21.5": {
69 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="
70 | },
71 | "@esbuild/linux-loong64@0.21.5": {
72 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="
73 | },
74 | "@esbuild/linux-mips64el@0.21.5": {
75 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="
76 | },
77 | "@esbuild/linux-ppc64@0.21.5": {
78 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="
79 | },
80 | "@esbuild/linux-riscv64@0.21.5": {
81 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="
82 | },
83 | "@esbuild/linux-s390x@0.21.5": {
84 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="
85 | },
86 | "@esbuild/linux-x64@0.21.5": {
87 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="
88 | },
89 | "@esbuild/netbsd-x64@0.21.5": {
90 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="
91 | },
92 | "@esbuild/openbsd-x64@0.21.5": {
93 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="
94 | },
95 | "@esbuild/sunos-x64@0.21.5": {
96 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="
97 | },
98 | "@esbuild/win32-arm64@0.21.5": {
99 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="
100 | },
101 | "@esbuild/win32-ia32@0.21.5": {
102 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="
103 | },
104 | "@esbuild/win32-x64@0.21.5": {
105 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="
106 | },
107 | "@isaacs/cliui@8.0.2": {
108 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
109 | "dependencies": [
110 | "string-width@5.1.2",
111 | "string-width-cjs@npm:string-width@4.2.3",
112 | "strip-ansi@7.1.0",
113 | "strip-ansi-cjs@npm:strip-ansi@6.0.1",
114 | "wrap-ansi@8.1.0",
115 | "wrap-ansi-cjs@npm:wrap-ansi@7.0.0"
116 | ]
117 | },
118 | "@pkgjs/parseargs@0.11.0": {
119 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="
120 | },
121 | "@rollup/rollup-android-arm-eabi@4.24.0": {
122 | "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA=="
123 | },
124 | "@rollup/rollup-android-arm64@4.24.0": {
125 | "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA=="
126 | },
127 | "@rollup/rollup-darwin-arm64@4.24.0": {
128 | "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA=="
129 | },
130 | "@rollup/rollup-darwin-x64@4.24.0": {
131 | "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ=="
132 | },
133 | "@rollup/rollup-linux-arm-gnueabihf@4.24.0": {
134 | "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA=="
135 | },
136 | "@rollup/rollup-linux-arm-musleabihf@4.24.0": {
137 | "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw=="
138 | },
139 | "@rollup/rollup-linux-arm64-gnu@4.24.0": {
140 | "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA=="
141 | },
142 | "@rollup/rollup-linux-arm64-musl@4.24.0": {
143 | "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw=="
144 | },
145 | "@rollup/rollup-linux-powerpc64le-gnu@4.24.0": {
146 | "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw=="
147 | },
148 | "@rollup/rollup-linux-riscv64-gnu@4.24.0": {
149 | "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg=="
150 | },
151 | "@rollup/rollup-linux-s390x-gnu@4.24.0": {
152 | "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g=="
153 | },
154 | "@rollup/rollup-linux-x64-gnu@4.24.0": {
155 | "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A=="
156 | },
157 | "@rollup/rollup-linux-x64-musl@4.24.0": {
158 | "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ=="
159 | },
160 | "@rollup/rollup-win32-arm64-msvc@4.24.0": {
161 | "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ=="
162 | },
163 | "@rollup/rollup-win32-ia32-msvc@4.24.0": {
164 | "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ=="
165 | },
166 | "@rollup/rollup-win32-x64-msvc@4.24.0": {
167 | "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw=="
168 | },
169 | "@types/estree@1.0.6": {
170 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
171 | },
172 | "acorn-jsx@5.3.2_acorn@8.13.0": {
173 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
174 | "dependencies": [
175 | "acorn"
176 | ]
177 | },
178 | "acorn-walk@8.3.4": {
179 | "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
180 | "dependencies": [
181 | "acorn"
182 | ]
183 | },
184 | "acorn@8.13.0": {
185 | "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w=="
186 | },
187 | "ansi-regex@5.0.1": {
188 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
189 | },
190 | "ansi-regex@6.1.0": {
191 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="
192 | },
193 | "ansi-styles@4.3.0": {
194 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
195 | "dependencies": [
196 | "color-convert"
197 | ]
198 | },
199 | "ansi-styles@6.2.1": {
200 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
201 | },
202 | "ast-types@0.16.1": {
203 | "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
204 | "dependencies": [
205 | "tslib"
206 | ]
207 | },
208 | "balanced-match@1.0.2": {
209 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
210 | },
211 | "brace-expansion@2.0.1": {
212 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
213 | "dependencies": [
214 | "balanced-match"
215 | ]
216 | },
217 | "color-convert@2.0.1": {
218 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
219 | "dependencies": [
220 | "color-name"
221 | ]
222 | },
223 | "color-name@1.1.4": {
224 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
225 | },
226 | "commander@11.1.0": {
227 | "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="
228 | },
229 | "cross-spawn@7.0.3": {
230 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
231 | "dependencies": [
232 | "path-key",
233 | "shebang-command",
234 | "which"
235 | ]
236 | },
237 | "eastasianwidth@0.2.0": {
238 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
239 | },
240 | "emoji-regex@8.0.0": {
241 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
242 | },
243 | "emoji-regex@9.2.2": {
244 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
245 | },
246 | "esbuild@0.21.5": {
247 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
248 | "dependencies": [
249 | "@esbuild/aix-ppc64",
250 | "@esbuild/android-arm",
251 | "@esbuild/android-arm64",
252 | "@esbuild/android-x64",
253 | "@esbuild/darwin-arm64",
254 | "@esbuild/darwin-x64",
255 | "@esbuild/freebsd-arm64",
256 | "@esbuild/freebsd-x64",
257 | "@esbuild/linux-arm",
258 | "@esbuild/linux-arm64",
259 | "@esbuild/linux-ia32",
260 | "@esbuild/linux-loong64",
261 | "@esbuild/linux-mips64el",
262 | "@esbuild/linux-ppc64",
263 | "@esbuild/linux-riscv64",
264 | "@esbuild/linux-s390x",
265 | "@esbuild/linux-x64",
266 | "@esbuild/netbsd-x64",
267 | "@esbuild/openbsd-x64",
268 | "@esbuild/sunos-x64",
269 | "@esbuild/win32-arm64",
270 | "@esbuild/win32-ia32",
271 | "@esbuild/win32-x64"
272 | ]
273 | },
274 | "escope@4.0.0": {
275 | "integrity": "sha512-E36qlD/r6RJHVpPKArgMoMlNJzoRJFH8z/cAZlI9lbc45zB3+S7i9k6e/MNb+7bZQzNEa6r8WKN3BovpeIBwgA==",
276 | "dependencies": [
277 | "esrecurse",
278 | "estraverse@4.3.0"
279 | ]
280 | },
281 | "eslint-visitor-keys@3.4.3": {
282 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="
283 | },
284 | "espree@9.6.1_acorn@8.13.0": {
285 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
286 | "dependencies": [
287 | "acorn",
288 | "acorn-jsx",
289 | "eslint-visitor-keys"
290 | ]
291 | },
292 | "esprima@4.0.1": {
293 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
294 | },
295 | "esrecurse@4.3.0": {
296 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
297 | "dependencies": [
298 | "estraverse@5.3.0"
299 | ]
300 | },
301 | "estraverse@4.3.0": {
302 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
303 | },
304 | "estraverse@5.3.0": {
305 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
306 | },
307 | "f-matches@1.1.0": {
308 | "integrity": "sha512-8NALQS5oB1+9hkEwiRjsRroTAQ7zKmXjxe0ZcMHDRrFIR54PhSJp7Rm+Q5+tgJ7eO5ejCgbUPNXeiflX18Rt0Q==",
309 | "dependencies": [
310 | "lodash"
311 | ]
312 | },
313 | "foreground-child@3.3.0": {
314 | "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
315 | "dependencies": [
316 | "cross-spawn",
317 | "signal-exit"
318 | ]
319 | },
320 | "fsevents@2.3.3": {
321 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="
322 | },
323 | "glob@10.4.5": {
324 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
325 | "dependencies": [
326 | "foreground-child",
327 | "jackspeak",
328 | "minimatch",
329 | "minipass",
330 | "package-json-from-dist",
331 | "path-scurry"
332 | ]
333 | },
334 | "is-fullwidth-code-point@3.0.0": {
335 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
336 | },
337 | "isexe@2.0.0": {
338 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
339 | },
340 | "jackspeak@3.4.3": {
341 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
342 | "dependencies": [
343 | "@isaacs/cliui",
344 | "@pkgjs/parseargs"
345 | ]
346 | },
347 | "lebab@3.2.4": {
348 | "integrity": "sha512-rtffzCSZ3LFG92Mqd05i2HcaMq73HfXtZWvP3AkvS3DdvfLAEr2pAcgpeQ7r/6DVoNBiFmMyK5Ho4t6AIkQU1w==",
349 | "dependencies": [
350 | "commander",
351 | "escope",
352 | "espree",
353 | "estraverse@5.3.0",
354 | "f-matches",
355 | "glob",
356 | "lodash",
357 | "recast"
358 | ]
359 | },
360 | "lodash@4.17.21": {
361 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
362 | },
363 | "lru-cache@10.4.3": {
364 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
365 | },
366 | "minimatch@9.0.5": {
367 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
368 | "dependencies": [
369 | "brace-expansion"
370 | ]
371 | },
372 | "minipass@7.1.2": {
373 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
374 | },
375 | "nanoid@3.3.7": {
376 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
377 | },
378 | "package-json-from-dist@1.0.1": {
379 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
380 | },
381 | "path-key@3.1.1": {
382 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
383 | },
384 | "path-scurry@1.11.1": {
385 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
386 | "dependencies": [
387 | "lru-cache",
388 | "minipass"
389 | ]
390 | },
391 | "picocolors@1.1.1": {
392 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
393 | },
394 | "postcss@8.4.47": {
395 | "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
396 | "dependencies": [
397 | "nanoid",
398 | "picocolors",
399 | "source-map-js"
400 | ]
401 | },
402 | "recast@0.23.9": {
403 | "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==",
404 | "dependencies": [
405 | "ast-types",
406 | "esprima",
407 | "source-map",
408 | "tiny-invariant",
409 | "tslib"
410 | ]
411 | },
412 | "resolve.exports@2.0.2": {
413 | "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg=="
414 | },
415 | "rollup@4.24.0": {
416 | "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==",
417 | "dependencies": [
418 | "@rollup/rollup-android-arm-eabi",
419 | "@rollup/rollup-android-arm64",
420 | "@rollup/rollup-darwin-arm64",
421 | "@rollup/rollup-darwin-x64",
422 | "@rollup/rollup-linux-arm-gnueabihf",
423 | "@rollup/rollup-linux-arm-musleabihf",
424 | "@rollup/rollup-linux-arm64-gnu",
425 | "@rollup/rollup-linux-arm64-musl",
426 | "@rollup/rollup-linux-powerpc64le-gnu",
427 | "@rollup/rollup-linux-riscv64-gnu",
428 | "@rollup/rollup-linux-s390x-gnu",
429 | "@rollup/rollup-linux-x64-gnu",
430 | "@rollup/rollup-linux-x64-musl",
431 | "@rollup/rollup-win32-arm64-msvc",
432 | "@rollup/rollup-win32-ia32-msvc",
433 | "@rollup/rollup-win32-x64-msvc",
434 | "@types/estree",
435 | "fsevents"
436 | ]
437 | },
438 | "shebang-command@2.0.0": {
439 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
440 | "dependencies": [
441 | "shebang-regex"
442 | ]
443 | },
444 | "shebang-regex@3.0.0": {
445 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
446 | },
447 | "signal-exit@4.1.0": {
448 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
449 | },
450 | "source-map-js@1.2.1": {
451 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
452 | },
453 | "source-map@0.6.1": {
454 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
455 | },
456 | "string-width@4.2.3": {
457 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
458 | "dependencies": [
459 | "emoji-regex@8.0.0",
460 | "is-fullwidth-code-point",
461 | "strip-ansi@6.0.1"
462 | ]
463 | },
464 | "string-width@5.1.2": {
465 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
466 | "dependencies": [
467 | "eastasianwidth",
468 | "emoji-regex@9.2.2",
469 | "strip-ansi@7.1.0"
470 | ]
471 | },
472 | "strip-ansi@6.0.1": {
473 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
474 | "dependencies": [
475 | "ansi-regex@5.0.1"
476 | ]
477 | },
478 | "strip-ansi@7.1.0": {
479 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
480 | "dependencies": [
481 | "ansi-regex@6.1.0"
482 | ]
483 | },
484 | "tiny-invariant@1.3.3": {
485 | "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
486 | },
487 | "tslib@2.8.0": {
488 | "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA=="
489 | },
490 | "validate-npm-package-name@5.0.1": {
491 | "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="
492 | },
493 | "vite@5.4.9": {
494 | "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==",
495 | "dependencies": [
496 | "esbuild",
497 | "fsevents",
498 | "postcss",
499 | "rollup"
500 | ]
501 | },
502 | "which@2.0.2": {
503 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
504 | "dependencies": [
505 | "isexe"
506 | ]
507 | },
508 | "wrap-ansi@7.0.0": {
509 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
510 | "dependencies": [
511 | "ansi-styles@4.3.0",
512 | "string-width@4.2.3",
513 | "strip-ansi@6.0.1"
514 | ]
515 | },
516 | "wrap-ansi@8.1.0": {
517 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
518 | "dependencies": [
519 | "ansi-styles@6.2.1",
520 | "string-width@5.1.2",
521 | "strip-ansi@7.1.0"
522 | ]
523 | },
524 | "zod@3.23.8": {
525 | "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
526 | }
527 | }
528 | }
529 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5 | Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
6 |
7 | [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public
8 | License, version 2, hence the version number 2.1.]
9 |
10 | Preamble
11 |
12 | The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU
13 | General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the
14 | software is free for all its users.
15 |
16 | This license, the Lesser General Public License, applies to some specially designated software packages--typically
17 | libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest
18 | you first think carefully about whether this license or the ordinary General Public License is the better strategy to
19 | use in any particular case, based on the explanations below.
20 |
21 | When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed
22 | to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish);
23 | that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new
24 | free programs; and that you are informed that you can do these things.
25 |
26 | To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to
27 | surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the
28 | library or if you modify it.
29 |
30 | For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the
31 | rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code
32 | with the library, you must provide complete object files to the recipients, so that they can relink them with the
33 | library after making changes to the library and recompiling it. And you must show them these terms so they know their
34 | rights.
35 |
36 | We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which
37 | gives you legal permission to copy, distribute and/or modify the library.
38 |
39 | To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the
40 | library is modified by someone else and passed on, the recipients should know that what they have is not the original
41 | version, so that the original author's reputation will not be affected by problems that might be introduced by others.
42 |
43 | Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a
44 | company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder.
45 | Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full
46 | freedom of use specified in this license.
47 |
48 | Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the
49 | GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary
50 | General Public License. We use this license for certain libraries in order to permit linking those libraries into
51 | non-free programs.
52 |
53 | When a program is linked with a library, whether statically or using a shared library, the combination of the two is
54 | legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore
55 | permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License
56 | permits more lax criteria for linking other code with the library.
57 |
58 | We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the
59 | ordinary General Public License. It also provides other free software developers Less of an advantage over competing
60 | non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries.
61 | However, the Lesser license provides advantages in certain special circumstances.
62 |
63 | For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library,
64 | so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more
65 | frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little
66 | to gain by limiting the free library to free software only, so we use the Lesser General Public License.
67 |
68 | In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a
69 | large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more
70 | people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
71 |
72 | Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a
73 | program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version
74 | of the Library.
75 |
76 | The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the
77 | difference between a "work based on the library" and a "work that uses the library". The former contains code derived
78 | from the library, whereas the latter must be combined with the library in order to run.
79 |
80 | GNU LESSER GENERAL PUBLIC LICENSE
81 |
82 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
83 |
84 | 0. This License Agreement applies to any software library or other program which contains a notice placed by the
85 | copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public
86 | License (also called "this License"). Each licensee is addressed as "you".
87 |
88 | A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with
89 | application programs (which use some of those functions and data) to form executables.
90 |
91 | The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work
92 | based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work
93 | containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly
94 | into another language. (Hereinafter, translation is included without limitation in the term "modification".)
95 |
96 | "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete
97 | source code means all the source code for all modules it contains, plus any associated interface definition files, plus
98 | the scripts used to control compilation and installation of the library.
99 |
100 | Activities other than copying, distribution and modification are not covered by this License; they are outside its
101 | scope. The act of running a program using the Library is not restricted, and output from such a program is covered only
102 | if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it).
103 | Whether that is true depends on what the Library does and what the program that uses the Library does.
104 |
105 | 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium,
106 | provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer
107 | of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and
108 | distribute a copy of this License along with the Library.
109 |
110 | You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection
111 | in exchange for a fee.
112 |
113 | 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and
114 | copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of
115 | these conditions:
116 |
117 | a) The modified work must itself be a software library.
118 |
119 | b) You must cause the files modified to carry prominent notices
120 | stating that you changed the files and the date of any change.
121 |
122 | c) You must cause the whole of the work to be licensed at no
123 | charge to all third parties under the terms of this License.
124 |
125 | d) If a facility in the modified Library refers to a function or a
126 | table of data to be supplied by an application program that uses
127 | the facility, other than as an argument passed when the facility
128 | is invoked, then you must make a good faith effort to ensure that,
129 | in the event an application does not supply such function or
130 | table, the facility still operates, and performs whatever part of
131 | its purpose remains meaningful.
132 |
133 | (For example, a function in a library to compute square roots has
134 | a purpose that is entirely well-defined independent of the
135 | application. Therefore, Subsection 2d requires that any
136 | application-supplied function or table used by this function must
137 | be optional: if the application does not supply it, the square
138 | root function must still compute square roots.)
139 |
140 | These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the
141 | Library, and can be reasonably considered independent and separate works in themselves, then this License, and its
142 | terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same
143 | sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of
144 | this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part
145 | regardless of who wrote it.
146 |
147 | Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you;
148 | rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the
149 | Library.
150 |
151 | In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the
152 | Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
153 |
154 | 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of
155 | the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the
156 | ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the
157 | ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make
158 | any other change in these notices.
159 |
160 | Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License
161 | applies to all subsequent copies and derivative works made from that copy.
162 |
163 | This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
164 |
165 | 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or
166 | executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete
167 | corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a
168 | medium customarily used for software interchange.
169 |
170 | If distribution of object code is made by offering access to copy from a designated place, then offering equivalent
171 | access to copy the source code from the same place satisfies the requirement to distribute the source code, even though
172 | third parties are not compelled to copy the source along with the object code.
173 |
174 | 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by
175 | being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a
176 | derivative work of the Library, and therefore falls outside the scope of this License.
177 |
178 | However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the
179 | Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is
180 | therefore covered by this License. Section 6 states terms for distribution of such executables.
181 |
182 | When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for
183 | the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially
184 | significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to
185 | be true is not precisely defined by law.
186 |
187 | If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small
188 | inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether
189 | it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall
190 | under Section 6.)
191 |
192 | Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms
193 | of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly
194 | with the Library itself.
195 |
196 | 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library
197 | to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided
198 | that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such
199 | modifications.
200 |
201 | You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its
202 | use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright
203 | notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to
204 | the copy of this License. Also, you must do one of these things:
205 |
206 | a) Accompany the work with the complete corresponding
207 | machine-readable source code for the Library including whatever
208 | changes were used in the work (which must be distributed under
209 | Sections 1 and 2 above); and, if the work is an executable linked
210 | with the Library, with the complete machine-readable "work that
211 | uses the Library", as object code and/or source code, so that the
212 | user can modify the Library and then relink to produce a modified
213 | executable containing the modified Library. (It is understood
214 | that the user who changes the contents of definitions files in the
215 | Library will not necessarily be able to recompile the application
216 | to use the modified definitions.)
217 |
218 | b) Use a suitable shared library mechanism for linking with the
219 | Library. A suitable mechanism is one that (1) uses at run time a
220 | copy of the library already present on the user's computer system,
221 | rather than copying library functions into the executable, and (2)
222 | will operate properly with a modified version of the library, if
223 | the user installs one, as long as the modified version is
224 | interface-compatible with the version that the work was made with.
225 |
226 | c) Accompany the work with a written offer, valid for at
227 | least three years, to give the same user the materials
228 | specified in Subsection 6a, above, for a charge no more
229 | than the cost of performing this distribution.
230 |
231 | d) If distribution of the work is made by offering access to copy
232 | from a designated place, offer equivalent access to copy the above
233 | specified materials from the same place.
234 |
235 | e) Verify that the user has already received a copy of these
236 | materials or that you have already sent this user a copy.
237 |
238 | For an executable, the required form of the "work that uses the Library" must include any data and utility programs
239 | needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not
240 | include anything that is normally distributed (in either source or binary form) with the major components (compiler,
241 | kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the
242 | executable.
243 |
244 | It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not
245 | normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in
246 | an executable that you distribute.
247 |
248 | 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with
249 | other library facilities not covered by this License, and distribute such a combined library, provided that the
250 | separate distribution of the work based on the Library and of the other library facilities is otherwise permitted,
251 | and provided that you do these two things:
252 |
253 | a) Accompany the combined library with a copy of the same work
254 | based on the Library, uncombined with any other library
255 | facilities. This must be distributed under the terms of the
256 | Sections above.
257 |
258 | b) Give prominent notice with the combined library of the fact
259 | that part of it is a work based on the Library, and explaining
260 | where to find the accompanying uncombined form of the same work.
261 |
262 | 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this
263 | License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will
264 | automatically terminate your rights under this License. However, parties who have received copies, or rights, from
265 | you under this License will not have their licenses terminated so long as such parties remain in full compliance.
266 |
267 | 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you
268 | permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do
269 | not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you
270 | indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or
271 | modifying the Library or works based on it.
272 |
273 | 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a
274 | license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and
275 | conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein.
276 | You are not responsible for enforcing compliance by third parties with this License.
277 |
278 | 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited
279 | to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict
280 | the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute
281 | so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a
282 | consequence you may not distribute the Library at all. For example, if a patent license would not permit
283 | royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then
284 | the only way you could satisfy both it and this License would be to refrain entirely from distribution of the
285 | Library.
286 |
287 | If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the
288 | section is intended to apply, and the section as a whole is intended to apply in other circumstances.
289 |
290 | It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest
291 | validity of any such claims; this section has the sole purpose of protecting the integrity of the free software
292 | distribution system which is implemented by public license practices. Many people have made generous contributions to
293 | the wide range of software distributed through that system in reliance on consistent application of that system; it is
294 | up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee
295 | cannot impose that choice.
296 |
297 | This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
298 |
299 | 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted
300 | interfaces, the original copyright holder who places the Library under this License may add an explicit geographical
301 | distribution limitation excluding those countries, so that distribution is permitted only in or among countries not
302 | thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
303 |
304 | 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time
305 | to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new
306 | problems or concerns.
307 |
308 | Each version is given a distinguishing version number. If the Library specifies a version number of this License which
309 | applies to it and "any later version", you have the option of following the terms and conditions either of that version
310 | or of any later version published by the Free Software Foundation. If the Library does not specify a license version
311 | number, you may choose any version ever published by the Free Software Foundation.
312 |
313 | 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are
314 | incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free
315 | Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will
316 | be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting
317 | the sharing and reuse of software generally.
318 |
319 | NO WARRANTY
320 |
321 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
322 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
323 | LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
324 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
325 | PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
326 | SERVICING, REPAIR OR CORRECTION.
327 |
328 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY
329 | WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
330 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
331 | (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
332 | PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
333 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
334 |
335 | END OF TERMS AND CONDITIONS
336 |
337 | How to Apply These Terms to Your New Libraries
338 |
339 | If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it
340 | free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms
341 | (or, alternatively, under the terms of the ordinary General Public License).
342 |
343 | To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each
344 | source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright"
345 | line and a pointer to where the full notice is found.
346 |
347 |
348 | Copyright (C)
349 |
350 | This library is free software; you can redistribute it and/or
351 | modify it under the terms of the GNU Lesser General Public
352 | License as published by the Free Software Foundation; either
353 | version 2.1 of the License, or (at your option) any later version.
354 |
355 | This library is distributed in the hope that it will be useful,
356 | but WITHOUT ANY WARRANTY; without even the implied warranty of
357 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
358 | Lesser General Public License for more details.
359 |
360 | You should have received a copy of the GNU Lesser General Public
361 | License along with this library; if not, write to the Free Software
362 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
363 | USA
364 |
365 | Also add information on how to contact you by electronic and paper mail.
366 |
367 | You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer"
368 | for the library, if necessary. Here is a sample; alter the names:
369 |
370 | Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by
371 | James Random Hacker.
372 |
373 | , 1 April 1990 Ty Coon, President of Vice
374 |
375 | That's all there is to it!
376 |
--------------------------------------------------------------------------------
/examples/preact/deno.lock:
--------------------------------------------------------------------------------
1 | {
2 | "version": "4",
3 | "specifiers": {
4 | "jsr:@logtape/logtape@~0.8.2": "0.8.2",
5 | "jsr:@std/assert@0.223": "0.223.0",
6 | "jsr:@std/assert@0.226": "0.226.0",
7 | "jsr:@std/assert@~0.225.2": "0.225.3",
8 | "jsr:@std/encoding@0.223": "0.223.0",
9 | "jsr:@std/fmt@0.223": "0.223.0",
10 | "jsr:@std/fs@0.223": "0.223.0",
11 | "jsr:@std/path@0.223": "0.223.0",
12 | "jsr:@std/path@~0.225.1": "0.225.2",
13 | "jsr:@std/semver@^1.0.2": "1.0.3",
14 | "npm:@coderspirit/nominal@^4.1.1": "4.1.1",
15 | "npm:@preact/compat@*": "18.3.1_preact@10.24.3",
16 | "npm:@preact/compat@^18.3.1": "18.3.1_preact@10.24.3",
17 | "npm:@prefresh/core@*": "1.5.3_preact@10.24.3",
18 | "npm:@prefresh/core@^1.5.2": "1.5.3_preact@10.24.3",
19 | "npm:@prefresh/utils@*": "1.2.0",
20 | "npm:@prefresh/utils@^1.2.0": "1.2.0",
21 | "npm:@prefresh/vite@^2.4.6": "2.4.7_preact@10.24.3_vite@5.4.14__@types+node@22.5.4_@types+node@22.5.4",
22 | "npm:@types/node@*": "22.5.4",
23 | "npm:acorn-walk@^8.3.3": "8.3.4",
24 | "npm:acorn@^8.12.1": "8.13.0",
25 | "npm:lebab@^3.2.4": "3.2.4",
26 | "npm:preact@*": "10.24.3",
27 | "npm:preact@^10.24.3": "10.24.3",
28 | "npm:resolve.exports@^2.0.2": "2.0.2",
29 | "npm:validate-npm-package-name@^5.0.1": "5.0.1",
30 | "npm:vite@^5.2.12": "5.4.14_@types+node@22.5.4",
31 | "npm:vite@^6.1.1": "6.1.1_@types+node@22.5.4",
32 | "npm:zod@^3.22.5": "3.23.8"
33 | },
34 | "jsr": {
35 | "@logtape/logtape@0.8.2": {
36 | "integrity": "e2ae1fc2561e8d010359b9894efb39bdb559dae44f5824540cbb26a78eee36bc"
37 | },
38 | "@std/assert@0.223.0": {
39 | "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24",
40 | "dependencies": [
41 | "jsr:@std/fmt"
42 | ]
43 | },
44 | "@std/assert@0.225.3": {
45 | "integrity": "b3c2847aecf6955b50644cdb9cf072004ea3d1998dd7579fc0acb99dbb23bd4f"
46 | },
47 | "@std/assert@0.226.0": {
48 | "integrity": "0dfb5f7c7723c18cec118e080fec76ce15b4c31154b15ad2bd74822603ef75b3"
49 | },
50 | "@std/encoding@0.223.0": {
51 | "integrity": "2b5615a75e00337ce113f34cf2f9b8c18182c751a8dcc8b1a2c2fc0e117bef00"
52 | },
53 | "@std/fmt@0.223.0": {
54 | "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208"
55 | },
56 | "@std/fs@0.223.0": {
57 | "integrity": "3b4b0550b2c524cbaaa5a9170c90e96cbb7354e837ad1bdaf15fc9df1ae9c31c",
58 | "dependencies": [
59 | "jsr:@std/assert@0.223",
60 | "jsr:@std/path@0.223"
61 | ]
62 | },
63 | "@std/path@0.223.0": {
64 | "integrity": "593963402d7e6597f5a6e620931661053572c982fc014000459edc1f93cc3989",
65 | "dependencies": [
66 | "jsr:@std/assert@0.223"
67 | ]
68 | },
69 | "@std/path@0.225.2": {
70 | "integrity": "0f2db41d36b50ef048dcb0399aac720a5348638dd3cb5bf80685bf2a745aa506",
71 | "dependencies": [
72 | "jsr:@std/assert@0.226"
73 | ]
74 | },
75 | "@std/semver@1.0.3": {
76 | "integrity": "7c139c6076a080eeaa4252c78b95ca5302818d7eafab0470d34cafd9930c13c8"
77 | }
78 | },
79 | "npm": {
80 | "@ampproject/remapping@2.3.0": {
81 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
82 | "dependencies": [
83 | "@jridgewell/gen-mapping",
84 | "@jridgewell/trace-mapping"
85 | ]
86 | },
87 | "@babel/code-frame@7.26.2": {
88 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
89 | "dependencies": [
90 | "@babel/helper-validator-identifier",
91 | "js-tokens",
92 | "picocolors"
93 | ]
94 | },
95 | "@babel/compat-data@7.26.8": {
96 | "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ=="
97 | },
98 | "@babel/core@7.26.9": {
99 | "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==",
100 | "dependencies": [
101 | "@ampproject/remapping",
102 | "@babel/code-frame",
103 | "@babel/generator",
104 | "@babel/helper-compilation-targets",
105 | "@babel/helper-module-transforms",
106 | "@babel/helpers",
107 | "@babel/parser",
108 | "@babel/template",
109 | "@babel/traverse",
110 | "@babel/types",
111 | "convert-source-map",
112 | "debug",
113 | "gensync",
114 | "json5",
115 | "semver"
116 | ]
117 | },
118 | "@babel/generator@7.26.9": {
119 | "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
120 | "dependencies": [
121 | "@babel/parser",
122 | "@babel/types",
123 | "@jridgewell/gen-mapping",
124 | "@jridgewell/trace-mapping",
125 | "jsesc"
126 | ]
127 | },
128 | "@babel/helper-compilation-targets@7.26.5": {
129 | "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
130 | "dependencies": [
131 | "@babel/compat-data",
132 | "@babel/helper-validator-option",
133 | "browserslist",
134 | "lru-cache@5.1.1",
135 | "semver"
136 | ]
137 | },
138 | "@babel/helper-module-imports@7.25.9": {
139 | "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
140 | "dependencies": [
141 | "@babel/traverse",
142 | "@babel/types"
143 | ]
144 | },
145 | "@babel/helper-module-transforms@7.26.0_@babel+core@7.26.9": {
146 | "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
147 | "dependencies": [
148 | "@babel/core",
149 | "@babel/helper-module-imports",
150 | "@babel/helper-validator-identifier",
151 | "@babel/traverse"
152 | ]
153 | },
154 | "@babel/helper-string-parser@7.25.9": {
155 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="
156 | },
157 | "@babel/helper-validator-identifier@7.25.9": {
158 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="
159 | },
160 | "@babel/helper-validator-option@7.25.9": {
161 | "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw=="
162 | },
163 | "@babel/helpers@7.26.9": {
164 | "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
165 | "dependencies": [
166 | "@babel/template",
167 | "@babel/types"
168 | ]
169 | },
170 | "@babel/parser@7.26.9": {
171 | "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
172 | "dependencies": [
173 | "@babel/types"
174 | ]
175 | },
176 | "@babel/template@7.26.9": {
177 | "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
178 | "dependencies": [
179 | "@babel/code-frame",
180 | "@babel/parser",
181 | "@babel/types"
182 | ]
183 | },
184 | "@babel/traverse@7.26.9": {
185 | "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
186 | "dependencies": [
187 | "@babel/code-frame",
188 | "@babel/generator",
189 | "@babel/parser",
190 | "@babel/template",
191 | "@babel/types",
192 | "debug",
193 | "globals"
194 | ]
195 | },
196 | "@babel/types@7.26.9": {
197 | "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
198 | "dependencies": [
199 | "@babel/helper-string-parser",
200 | "@babel/helper-validator-identifier"
201 | ]
202 | },
203 | "@coderspirit/nominal-symbols@2.0.1_typescript@5.6.3": {
204 | "integrity": "sha512-OV2eZ9wJkukMCW5KXCGrhPcp8pSeB517/0BaRL3r979U18Q7oYmNxnGogyIWQOUUglMrhB/jnUpP77QbZuZsNA==",
205 | "dependencies": [
206 | "typescript"
207 | ]
208 | },
209 | "@coderspirit/nominal@4.1.1": {
210 | "integrity": "sha512-m37GfF/N1QzJBE1HHGpSJhAyDtkExzwx3AnGk0n2SRyFSVxtwpTRWLl6lkubUfXiZeOTFqXjVjOxseMh3YffLg==",
211 | "dependencies": [
212 | "@coderspirit/nominal-symbols"
213 | ]
214 | },
215 | "@esbuild/aix-ppc64@0.21.5": {
216 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="
217 | },
218 | "@esbuild/aix-ppc64@0.24.2": {
219 | "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="
220 | },
221 | "@esbuild/android-arm64@0.21.5": {
222 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="
223 | },
224 | "@esbuild/android-arm64@0.24.2": {
225 | "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="
226 | },
227 | "@esbuild/android-arm@0.21.5": {
228 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="
229 | },
230 | "@esbuild/android-arm@0.24.2": {
231 | "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="
232 | },
233 | "@esbuild/android-x64@0.21.5": {
234 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="
235 | },
236 | "@esbuild/android-x64@0.24.2": {
237 | "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="
238 | },
239 | "@esbuild/darwin-arm64@0.21.5": {
240 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="
241 | },
242 | "@esbuild/darwin-arm64@0.24.2": {
243 | "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="
244 | },
245 | "@esbuild/darwin-x64@0.21.5": {
246 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="
247 | },
248 | "@esbuild/darwin-x64@0.24.2": {
249 | "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="
250 | },
251 | "@esbuild/freebsd-arm64@0.21.5": {
252 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="
253 | },
254 | "@esbuild/freebsd-arm64@0.24.2": {
255 | "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="
256 | },
257 | "@esbuild/freebsd-x64@0.21.5": {
258 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="
259 | },
260 | "@esbuild/freebsd-x64@0.24.2": {
261 | "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="
262 | },
263 | "@esbuild/linux-arm64@0.21.5": {
264 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="
265 | },
266 | "@esbuild/linux-arm64@0.24.2": {
267 | "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="
268 | },
269 | "@esbuild/linux-arm@0.21.5": {
270 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="
271 | },
272 | "@esbuild/linux-arm@0.24.2": {
273 | "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="
274 | },
275 | "@esbuild/linux-ia32@0.21.5": {
276 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="
277 | },
278 | "@esbuild/linux-ia32@0.24.2": {
279 | "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="
280 | },
281 | "@esbuild/linux-loong64@0.21.5": {
282 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="
283 | },
284 | "@esbuild/linux-loong64@0.24.2": {
285 | "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="
286 | },
287 | "@esbuild/linux-mips64el@0.21.5": {
288 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="
289 | },
290 | "@esbuild/linux-mips64el@0.24.2": {
291 | "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="
292 | },
293 | "@esbuild/linux-ppc64@0.21.5": {
294 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="
295 | },
296 | "@esbuild/linux-ppc64@0.24.2": {
297 | "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="
298 | },
299 | "@esbuild/linux-riscv64@0.21.5": {
300 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="
301 | },
302 | "@esbuild/linux-riscv64@0.24.2": {
303 | "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="
304 | },
305 | "@esbuild/linux-s390x@0.21.5": {
306 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="
307 | },
308 | "@esbuild/linux-s390x@0.24.2": {
309 | "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="
310 | },
311 | "@esbuild/linux-x64@0.21.5": {
312 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="
313 | },
314 | "@esbuild/linux-x64@0.24.2": {
315 | "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="
316 | },
317 | "@esbuild/netbsd-arm64@0.24.2": {
318 | "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="
319 | },
320 | "@esbuild/netbsd-x64@0.21.5": {
321 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="
322 | },
323 | "@esbuild/netbsd-x64@0.24.2": {
324 | "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="
325 | },
326 | "@esbuild/openbsd-arm64@0.24.2": {
327 | "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="
328 | },
329 | "@esbuild/openbsd-x64@0.21.5": {
330 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="
331 | },
332 | "@esbuild/openbsd-x64@0.24.2": {
333 | "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="
334 | },
335 | "@esbuild/sunos-x64@0.21.5": {
336 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="
337 | },
338 | "@esbuild/sunos-x64@0.24.2": {
339 | "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="
340 | },
341 | "@esbuild/win32-arm64@0.21.5": {
342 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="
343 | },
344 | "@esbuild/win32-arm64@0.24.2": {
345 | "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="
346 | },
347 | "@esbuild/win32-ia32@0.21.5": {
348 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="
349 | },
350 | "@esbuild/win32-ia32@0.24.2": {
351 | "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="
352 | },
353 | "@esbuild/win32-x64@0.21.5": {
354 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="
355 | },
356 | "@esbuild/win32-x64@0.24.2": {
357 | "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="
358 | },
359 | "@isaacs/cliui@8.0.2": {
360 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
361 | "dependencies": [
362 | "string-width@5.1.2",
363 | "string-width-cjs@npm:string-width@4.2.3",
364 | "strip-ansi@7.1.0",
365 | "strip-ansi-cjs@npm:strip-ansi@6.0.1",
366 | "wrap-ansi@8.1.0",
367 | "wrap-ansi-cjs@npm:wrap-ansi@7.0.0"
368 | ]
369 | },
370 | "@jridgewell/gen-mapping@0.3.8": {
371 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
372 | "dependencies": [
373 | "@jridgewell/set-array",
374 | "@jridgewell/sourcemap-codec",
375 | "@jridgewell/trace-mapping"
376 | ]
377 | },
378 | "@jridgewell/resolve-uri@3.1.2": {
379 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="
380 | },
381 | "@jridgewell/set-array@1.2.1": {
382 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="
383 | },
384 | "@jridgewell/sourcemap-codec@1.5.0": {
385 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
386 | },
387 | "@jridgewell/trace-mapping@0.3.25": {
388 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
389 | "dependencies": [
390 | "@jridgewell/resolve-uri",
391 | "@jridgewell/sourcemap-codec"
392 | ]
393 | },
394 | "@pkgjs/parseargs@0.11.0": {
395 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="
396 | },
397 | "@preact/compat@18.3.1_preact@10.24.3": {
398 | "integrity": "sha512-Kog4PSRxtT4COtOXjsuQPV1vMXpUzREQfv+6Dmcy9/rMk0HOPK0HTE9fspFjAmY8R80T/T8gtgmZ68u5bOSngw==",
399 | "dependencies": [
400 | "preact"
401 | ]
402 | },
403 | "@prefresh/babel-plugin@0.5.1": {
404 | "integrity": "sha512-uG3jGEAysxWoyG3XkYfjYHgaySFrSsaEb4GagLzYaxlydbuREtaX+FTxuIidp241RaLl85XoHg9Ej6E4+V1pcg=="
405 | },
406 | "@prefresh/core@1.5.3_preact@10.24.3": {
407 | "integrity": "sha512-nDzxj0tA1/M6APNAWqaxkZ+3sTdPHESa+gol4+Bw7rMc2btWdkLoNH7j9rGhUb8SThC0Vz0VoXtq+U+9azGLHg==",
408 | "dependencies": [
409 | "preact"
410 | ]
411 | },
412 | "@prefresh/utils@1.2.0": {
413 | "integrity": "sha512-KtC/fZw+oqtwOLUFM9UtiitB0JsVX0zLKNyRTA332sqREqSALIIQQxdUCS1P3xR/jT1e2e8/5rwH6gdcMLEmsQ=="
414 | },
415 | "@prefresh/vite@2.4.7_preact@10.24.3_vite@5.4.14__@types+node@22.5.4_@types+node@22.5.4": {
416 | "integrity": "sha512-zmCEDWSFHl5A7PciXa/fe+OUjoGi4iiCQclpWfpIg7LjxwWrtlUT4DfxDBcQwHfTyipS/XDm8x7WYrkiTW0q+w==",
417 | "dependencies": [
418 | "@babel/core",
419 | "@prefresh/babel-plugin",
420 | "@prefresh/core",
421 | "@prefresh/utils",
422 | "@rollup/pluginutils",
423 | "preact",
424 | "vite@5.4.14_@types+node@22.5.4"
425 | ]
426 | },
427 | "@rollup/pluginutils@4.2.1": {
428 | "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
429 | "dependencies": [
430 | "estree-walker",
431 | "picomatch"
432 | ]
433 | },
434 | "@rollup/rollup-android-arm-eabi@4.34.8": {
435 | "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw=="
436 | },
437 | "@rollup/rollup-android-arm64@4.34.8": {
438 | "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q=="
439 | },
440 | "@rollup/rollup-darwin-arm64@4.34.8": {
441 | "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q=="
442 | },
443 | "@rollup/rollup-darwin-x64@4.34.8": {
444 | "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw=="
445 | },
446 | "@rollup/rollup-freebsd-arm64@4.34.8": {
447 | "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA=="
448 | },
449 | "@rollup/rollup-freebsd-x64@4.34.8": {
450 | "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q=="
451 | },
452 | "@rollup/rollup-linux-arm-gnueabihf@4.34.8": {
453 | "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g=="
454 | },
455 | "@rollup/rollup-linux-arm-musleabihf@4.34.8": {
456 | "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA=="
457 | },
458 | "@rollup/rollup-linux-arm64-gnu@4.34.8": {
459 | "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A=="
460 | },
461 | "@rollup/rollup-linux-arm64-musl@4.34.8": {
462 | "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q=="
463 | },
464 | "@rollup/rollup-linux-loongarch64-gnu@4.34.8": {
465 | "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ=="
466 | },
467 | "@rollup/rollup-linux-powerpc64le-gnu@4.34.8": {
468 | "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw=="
469 | },
470 | "@rollup/rollup-linux-riscv64-gnu@4.34.8": {
471 | "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw=="
472 | },
473 | "@rollup/rollup-linux-s390x-gnu@4.34.8": {
474 | "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA=="
475 | },
476 | "@rollup/rollup-linux-x64-gnu@4.34.8": {
477 | "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA=="
478 | },
479 | "@rollup/rollup-linux-x64-musl@4.34.8": {
480 | "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ=="
481 | },
482 | "@rollup/rollup-win32-arm64-msvc@4.34.8": {
483 | "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ=="
484 | },
485 | "@rollup/rollup-win32-ia32-msvc@4.34.8": {
486 | "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w=="
487 | },
488 | "@rollup/rollup-win32-x64-msvc@4.34.8": {
489 | "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g=="
490 | },
491 | "@types/estree@1.0.6": {
492 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
493 | },
494 | "@types/node@22.5.4": {
495 | "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
496 | "dependencies": [
497 | "undici-types"
498 | ]
499 | },
500 | "acorn-jsx@5.3.2_acorn@8.13.0": {
501 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
502 | "dependencies": [
503 | "acorn"
504 | ]
505 | },
506 | "acorn-walk@8.3.4": {
507 | "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
508 | "dependencies": [
509 | "acorn"
510 | ]
511 | },
512 | "acorn@8.13.0": {
513 | "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w=="
514 | },
515 | "ansi-regex@5.0.1": {
516 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
517 | },
518 | "ansi-regex@6.1.0": {
519 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="
520 | },
521 | "ansi-styles@4.3.0": {
522 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
523 | "dependencies": [
524 | "color-convert"
525 | ]
526 | },
527 | "ansi-styles@6.2.1": {
528 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
529 | },
530 | "ast-types@0.16.1": {
531 | "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
532 | "dependencies": [
533 | "tslib"
534 | ]
535 | },
536 | "balanced-match@1.0.2": {
537 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
538 | },
539 | "brace-expansion@2.0.1": {
540 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
541 | "dependencies": [
542 | "balanced-match"
543 | ]
544 | },
545 | "browserslist@4.24.4": {
546 | "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
547 | "dependencies": [
548 | "caniuse-lite",
549 | "electron-to-chromium",
550 | "node-releases",
551 | "update-browserslist-db"
552 | ]
553 | },
554 | "caniuse-lite@1.0.30001700": {
555 | "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ=="
556 | },
557 | "color-convert@2.0.1": {
558 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
559 | "dependencies": [
560 | "color-name"
561 | ]
562 | },
563 | "color-name@1.1.4": {
564 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
565 | },
566 | "commander@11.1.0": {
567 | "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="
568 | },
569 | "convert-source-map@2.0.0": {
570 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
571 | },
572 | "cross-spawn@7.0.3": {
573 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
574 | "dependencies": [
575 | "path-key",
576 | "shebang-command",
577 | "which"
578 | ]
579 | },
580 | "debug@4.4.0": {
581 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
582 | "dependencies": [
583 | "ms"
584 | ]
585 | },
586 | "eastasianwidth@0.2.0": {
587 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
588 | },
589 | "electron-to-chromium@1.5.102": {
590 | "integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q=="
591 | },
592 | "emoji-regex@8.0.0": {
593 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
594 | },
595 | "emoji-regex@9.2.2": {
596 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
597 | },
598 | "esbuild@0.21.5": {
599 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
600 | "dependencies": [
601 | "@esbuild/aix-ppc64@0.21.5",
602 | "@esbuild/android-arm@0.21.5",
603 | "@esbuild/android-arm64@0.21.5",
604 | "@esbuild/android-x64@0.21.5",
605 | "@esbuild/darwin-arm64@0.21.5",
606 | "@esbuild/darwin-x64@0.21.5",
607 | "@esbuild/freebsd-arm64@0.21.5",
608 | "@esbuild/freebsd-x64@0.21.5",
609 | "@esbuild/linux-arm@0.21.5",
610 | "@esbuild/linux-arm64@0.21.5",
611 | "@esbuild/linux-ia32@0.21.5",
612 | "@esbuild/linux-loong64@0.21.5",
613 | "@esbuild/linux-mips64el@0.21.5",
614 | "@esbuild/linux-ppc64@0.21.5",
615 | "@esbuild/linux-riscv64@0.21.5",
616 | "@esbuild/linux-s390x@0.21.5",
617 | "@esbuild/linux-x64@0.21.5",
618 | "@esbuild/netbsd-x64@0.21.5",
619 | "@esbuild/openbsd-x64@0.21.5",
620 | "@esbuild/sunos-x64@0.21.5",
621 | "@esbuild/win32-arm64@0.21.5",
622 | "@esbuild/win32-ia32@0.21.5",
623 | "@esbuild/win32-x64@0.21.5"
624 | ]
625 | },
626 | "esbuild@0.24.2": {
627 | "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
628 | "dependencies": [
629 | "@esbuild/aix-ppc64@0.24.2",
630 | "@esbuild/android-arm@0.24.2",
631 | "@esbuild/android-arm64@0.24.2",
632 | "@esbuild/android-x64@0.24.2",
633 | "@esbuild/darwin-arm64@0.24.2",
634 | "@esbuild/darwin-x64@0.24.2",
635 | "@esbuild/freebsd-arm64@0.24.2",
636 | "@esbuild/freebsd-x64@0.24.2",
637 | "@esbuild/linux-arm@0.24.2",
638 | "@esbuild/linux-arm64@0.24.2",
639 | "@esbuild/linux-ia32@0.24.2",
640 | "@esbuild/linux-loong64@0.24.2",
641 | "@esbuild/linux-mips64el@0.24.2",
642 | "@esbuild/linux-ppc64@0.24.2",
643 | "@esbuild/linux-riscv64@0.24.2",
644 | "@esbuild/linux-s390x@0.24.2",
645 | "@esbuild/linux-x64@0.24.2",
646 | "@esbuild/netbsd-arm64",
647 | "@esbuild/netbsd-x64@0.24.2",
648 | "@esbuild/openbsd-arm64",
649 | "@esbuild/openbsd-x64@0.24.2",
650 | "@esbuild/sunos-x64@0.24.2",
651 | "@esbuild/win32-arm64@0.24.2",
652 | "@esbuild/win32-ia32@0.24.2",
653 | "@esbuild/win32-x64@0.24.2"
654 | ]
655 | },
656 | "escalade@3.2.0": {
657 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="
658 | },
659 | "escope@4.0.0": {
660 | "integrity": "sha512-E36qlD/r6RJHVpPKArgMoMlNJzoRJFH8z/cAZlI9lbc45zB3+S7i9k6e/MNb+7bZQzNEa6r8WKN3BovpeIBwgA==",
661 | "dependencies": [
662 | "esrecurse",
663 | "estraverse@4.3.0"
664 | ]
665 | },
666 | "eslint-visitor-keys@3.4.3": {
667 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="
668 | },
669 | "espree@9.6.1_acorn@8.13.0": {
670 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
671 | "dependencies": [
672 | "acorn",
673 | "acorn-jsx",
674 | "eslint-visitor-keys"
675 | ]
676 | },
677 | "esprima@4.0.1": {
678 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
679 | },
680 | "esrecurse@4.3.0": {
681 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
682 | "dependencies": [
683 | "estraverse@5.3.0"
684 | ]
685 | },
686 | "estraverse@4.3.0": {
687 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
688 | },
689 | "estraverse@5.3.0": {
690 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
691 | },
692 | "estree-walker@2.0.2": {
693 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
694 | },
695 | "f-matches@1.1.0": {
696 | "integrity": "sha512-8NALQS5oB1+9hkEwiRjsRroTAQ7zKmXjxe0ZcMHDRrFIR54PhSJp7Rm+Q5+tgJ7eO5ejCgbUPNXeiflX18Rt0Q==",
697 | "dependencies": [
698 | "lodash"
699 | ]
700 | },
701 | "foreground-child@3.3.0": {
702 | "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
703 | "dependencies": [
704 | "cross-spawn",
705 | "signal-exit"
706 | ]
707 | },
708 | "fsevents@2.3.3": {
709 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="
710 | },
711 | "gensync@1.0.0-beta.2": {
712 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
713 | },
714 | "glob@10.4.5": {
715 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
716 | "dependencies": [
717 | "foreground-child",
718 | "jackspeak",
719 | "minimatch",
720 | "minipass",
721 | "package-json-from-dist",
722 | "path-scurry"
723 | ]
724 | },
725 | "globals@11.12.0": {
726 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
727 | },
728 | "is-fullwidth-code-point@3.0.0": {
729 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
730 | },
731 | "isexe@2.0.0": {
732 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
733 | },
734 | "jackspeak@3.4.3": {
735 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
736 | "dependencies": [
737 | "@isaacs/cliui",
738 | "@pkgjs/parseargs"
739 | ]
740 | },
741 | "js-tokens@4.0.0": {
742 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
743 | },
744 | "jsesc@3.1.0": {
745 | "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="
746 | },
747 | "json5@2.2.3": {
748 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
749 | },
750 | "lebab@3.2.4": {
751 | "integrity": "sha512-rtffzCSZ3LFG92Mqd05i2HcaMq73HfXtZWvP3AkvS3DdvfLAEr2pAcgpeQ7r/6DVoNBiFmMyK5Ho4t6AIkQU1w==",
752 | "dependencies": [
753 | "commander",
754 | "escope",
755 | "espree",
756 | "estraverse@5.3.0",
757 | "f-matches",
758 | "glob",
759 | "lodash",
760 | "recast"
761 | ]
762 | },
763 | "lodash@4.17.21": {
764 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
765 | },
766 | "lru-cache@10.4.3": {
767 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
768 | },
769 | "lru-cache@5.1.1": {
770 | "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
771 | "dependencies": [
772 | "yallist"
773 | ]
774 | },
775 | "minimatch@9.0.5": {
776 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
777 | "dependencies": [
778 | "brace-expansion"
779 | ]
780 | },
781 | "minipass@7.1.2": {
782 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
783 | },
784 | "ms@2.1.3": {
785 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
786 | },
787 | "nanoid@3.3.8": {
788 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="
789 | },
790 | "node-releases@2.0.19": {
791 | "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="
792 | },
793 | "package-json-from-dist@1.0.1": {
794 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
795 | },
796 | "path-key@3.1.1": {
797 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
798 | },
799 | "path-scurry@1.11.1": {
800 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
801 | "dependencies": [
802 | "lru-cache@10.4.3",
803 | "minipass"
804 | ]
805 | },
806 | "picocolors@1.1.1": {
807 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
808 | },
809 | "picomatch@2.3.1": {
810 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
811 | },
812 | "postcss@8.5.3": {
813 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
814 | "dependencies": [
815 | "nanoid",
816 | "picocolors",
817 | "source-map-js"
818 | ]
819 | },
820 | "preact@10.24.3": {
821 | "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA=="
822 | },
823 | "recast@0.23.9": {
824 | "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==",
825 | "dependencies": [
826 | "ast-types",
827 | "esprima",
828 | "source-map",
829 | "tiny-invariant",
830 | "tslib"
831 | ]
832 | },
833 | "resolve.exports@2.0.2": {
834 | "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg=="
835 | },
836 | "rollup@4.34.8": {
837 | "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
838 | "dependencies": [
839 | "@rollup/rollup-android-arm-eabi",
840 | "@rollup/rollup-android-arm64",
841 | "@rollup/rollup-darwin-arm64",
842 | "@rollup/rollup-darwin-x64",
843 | "@rollup/rollup-freebsd-arm64",
844 | "@rollup/rollup-freebsd-x64",
845 | "@rollup/rollup-linux-arm-gnueabihf",
846 | "@rollup/rollup-linux-arm-musleabihf",
847 | "@rollup/rollup-linux-arm64-gnu",
848 | "@rollup/rollup-linux-arm64-musl",
849 | "@rollup/rollup-linux-loongarch64-gnu",
850 | "@rollup/rollup-linux-powerpc64le-gnu",
851 | "@rollup/rollup-linux-riscv64-gnu",
852 | "@rollup/rollup-linux-s390x-gnu",
853 | "@rollup/rollup-linux-x64-gnu",
854 | "@rollup/rollup-linux-x64-musl",
855 | "@rollup/rollup-win32-arm64-msvc",
856 | "@rollup/rollup-win32-ia32-msvc",
857 | "@rollup/rollup-win32-x64-msvc",
858 | "@types/estree",
859 | "fsevents"
860 | ]
861 | },
862 | "semver@6.3.1": {
863 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
864 | },
865 | "shebang-command@2.0.0": {
866 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
867 | "dependencies": [
868 | "shebang-regex"
869 | ]
870 | },
871 | "shebang-regex@3.0.0": {
872 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
873 | },
874 | "signal-exit@4.1.0": {
875 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
876 | },
877 | "source-map-js@1.2.1": {
878 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
879 | },
880 | "source-map@0.6.1": {
881 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
882 | },
883 | "string-width@4.2.3": {
884 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
885 | "dependencies": [
886 | "emoji-regex@8.0.0",
887 | "is-fullwidth-code-point",
888 | "strip-ansi@6.0.1"
889 | ]
890 | },
891 | "string-width@5.1.2": {
892 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
893 | "dependencies": [
894 | "eastasianwidth",
895 | "emoji-regex@9.2.2",
896 | "strip-ansi@7.1.0"
897 | ]
898 | },
899 | "strip-ansi@6.0.1": {
900 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
901 | "dependencies": [
902 | "ansi-regex@5.0.1"
903 | ]
904 | },
905 | "strip-ansi@7.1.0": {
906 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
907 | "dependencies": [
908 | "ansi-regex@6.1.0"
909 | ]
910 | },
911 | "tiny-invariant@1.3.3": {
912 | "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
913 | },
914 | "tslib@2.8.0": {
915 | "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA=="
916 | },
917 | "typescript@5.6.3": {
918 | "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="
919 | },
920 | "undici-types@6.19.8": {
921 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
922 | },
923 | "update-browserslist-db@1.1.2_browserslist@4.24.4": {
924 | "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
925 | "dependencies": [
926 | "browserslist",
927 | "escalade",
928 | "picocolors"
929 | ]
930 | },
931 | "validate-npm-package-name@5.0.1": {
932 | "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="
933 | },
934 | "vite@5.4.14_@types+node@22.5.4": {
935 | "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==",
936 | "dependencies": [
937 | "@types/node",
938 | "esbuild@0.21.5",
939 | "fsevents",
940 | "postcss",
941 | "rollup"
942 | ]
943 | },
944 | "vite@6.1.1_@types+node@22.5.4": {
945 | "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==",
946 | "dependencies": [
947 | "@types/node",
948 | "esbuild@0.24.2",
949 | "fsevents",
950 | "postcss",
951 | "rollup"
952 | ]
953 | },
954 | "which@2.0.2": {
955 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
956 | "dependencies": [
957 | "isexe"
958 | ]
959 | },
960 | "wrap-ansi@7.0.0": {
961 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
962 | "dependencies": [
963 | "ansi-styles@4.3.0",
964 | "string-width@4.2.3",
965 | "strip-ansi@6.0.1"
966 | ]
967 | },
968 | "wrap-ansi@8.1.0": {
969 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
970 | "dependencies": [
971 | "ansi-styles@6.2.1",
972 | "string-width@5.1.2",
973 | "strip-ansi@7.1.0"
974 | ]
975 | },
976 | "yallist@3.1.1": {
977 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
978 | },
979 | "zod@3.23.8": {
980 | "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
981 | }
982 | },
983 | "workspace": {
984 | "dependencies": [
985 | "jsr:@logtape/logtape@~0.8.2",
986 | "jsr:@std/assert@0.223",
987 | "jsr:@std/encoding@0.223",
988 | "jsr:@std/fs@0.223",
989 | "jsr:@std/path@~0.225.1",
990 | "jsr:@std/semver@^1.0.2",
991 | "npm:@coderspirit/nominal@^4.1.1",
992 | "npm:@preact/compat@^18.3.1",
993 | "npm:@prefresh/core@^1.5.2",
994 | "npm:@prefresh/utils@^1.2.0",
995 | "npm:@prefresh/vite@^2.4.6",
996 | "npm:acorn-walk@^8.3.3",
997 | "npm:acorn@^8.12.1",
998 | "npm:lebab@^3.2.4",
999 | "npm:preact@^10.24.3",
1000 | "npm:resolve.exports@^2.0.2",
1001 | "npm:validate-npm-package-name@^5.0.1",
1002 | "npm:vite@^6.1.1",
1003 | "npm:zod@^3.22.5"
1004 | ]
1005 | }
1006 | }
1007 |
--------------------------------------------------------------------------------