From 5d8797027494efa11f76522917e28cc8170727ea Mon Sep 17 00:00:00 2001 From: Eric Rodrigues Pires Date: Fri, 24 Oct 2025 08:00:34 -0300 Subject: [PATCH] First version of working WASM interface --- Cargo.lock | 10 + Cargo.toml | 1 + axum_duper/README.md | 6 + duper-js-wasm/.gitignore | 2 + duper-js-wasm/Cargo.toml | 26 + duper-js-wasm/LICENSE | 1 + duper-js-wasm/README.md | 54 + duper-js-wasm/index.html | 19 + duper-js-wasm/package-lock.json | 1665 +++++++++++++++++++++++ duper-js-wasm/package.json | 32 + duper-js-wasm/src/de.rs | 191 +++ duper-js-wasm/src/lib.rs | 77 ++ duper-js-wasm/src/ser.rs | 248 ++++ duper-js-wasm/vite.config.js | 12 + duper-python/Cargo.toml | 3 + duper-python/README.md | 8 + duper-python/src/ser/well_known_type.rs | 6 +- duper.code-workspace | 4 + duper/README.md | 6 - duper/src/ast.rs | 18 + serde_duper/README.md | 8 + 21 files changed, 2388 insertions(+), 9 deletions(-) create mode 100644 duper-js-wasm/.gitignore create mode 100644 duper-js-wasm/Cargo.toml create mode 120000 duper-js-wasm/LICENSE create mode 100644 duper-js-wasm/README.md create mode 100644 duper-js-wasm/index.html create mode 100644 duper-js-wasm/package-lock.json create mode 100644 duper-js-wasm/package.json create mode 100644 duper-js-wasm/src/de.rs create mode 100644 duper-js-wasm/src/lib.rs create mode 100644 duper-js-wasm/src/ser.rs create mode 100644 duper-js-wasm/vite.config.js diff --git a/Cargo.lock b/Cargo.lock index 0804a84..e2395e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -319,6 +319,16 @@ dependencies = [ "unicode-general-category", ] +[[package]] +name = "duper-js-wasm" +version = "0.0.0" +dependencies = [ + "duper", + "js-sys", + "miette", + "wasm-bindgen", +] + [[package]] name = "duper-python" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index df516f2..e208438 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "3" members = [ "axum_duper", "duper", + "duper-js-wasm", "duper-python", "serde_duper", "serde_duper_macros", diff --git a/axum_duper/README.md b/axum_duper/README.md index 88af6da..a2199cb 100644 --- a/axum_duper/README.md +++ b/axum_duper/README.md @@ -12,6 +12,12 @@ Duper extractor / response for `axum`. [Check out the official website for Duper.](https://duper.dev.br) +## Installation + +```bash +cargo add axum_duper +``` + ## Example ```rust diff --git a/duper-js-wasm/.gitignore b/duper-js-wasm/.gitignore new file mode 100644 index 0000000..9853693 --- /dev/null +++ b/duper-js-wasm/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +pkg/ diff --git a/duper-js-wasm/Cargo.toml b/duper-js-wasm/Cargo.toml new file mode 100644 index 0000000..f86c88b --- /dev/null +++ b/duper-js-wasm/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "duper-js-wasm" +description = "The format that's super!" +version = "0.0.0" +edition = "2024" +rust-version = "1.88" +license = "MIT" +authors = ["Eric Rodrigues Pires "] +repository = "https://github.com/EpicEric/duper" +homepage = "https://github.com/EpicEric/duper" +readme = "README.md" +categories = ["encoding", "parser-implementations"] +keywords = ["duper", "serialization", "wasm"] +publish = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +duper = { path = "../duper", version = "0.2.0" } +js-sys = "0.3.81" +miette = "7.6.0" +wasm-bindgen = "0.2.104" + +[profile.release] +lto = true diff --git a/duper-js-wasm/LICENSE b/duper-js-wasm/LICENSE new file mode 120000 index 0000000..ea5b606 --- /dev/null +++ b/duper-js-wasm/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/duper-js-wasm/README.md b/duper-js-wasm/README.md new file mode 100644 index 0000000..dee1b00 --- /dev/null +++ b/duper-js-wasm/README.md @@ -0,0 +1,54 @@ +

+ The Duper logo, with a confident spectacled mole wearing a flailing blue cape.
+

+

@duper-js/wasm

+ +

+ PyPI version + GitHub license +

+ +Duper support for JavaScript/TypeScript via WASM. + +[Check out the official website for Duper.](https://duper.dev.br) + +## Installation + +```bash +npm install --save @duper-js/wasm +``` + +## Examples + +```typescript +import { parse, stringify } from "@duper-js/wasm"; + +const duper_data = ` +APIResponse({ + status: 200, + headers: { + content_type: "application/duper", + cache_control: "max-age=3600", + }, + body: { + users: [ + User({ + id: Uuid("7039311b-02d2-4849-a6de-900d4dbe9acb"), + name: "Alice", + email: Email("alice@example.com"), + roles: ["admin", "user"], + metadata: { + last_login: DateTime("2024-01-15T10:30:00Z"), + ip: IPV4("173.255.230.79"), + }, + }), + ], + }, +}) +`; + +const obj = parse(duper_data); + +console.log(stringify, { stripIdentifiers: false }); +console.log(JSON.stringify(obj)); +``` diff --git a/duper-js-wasm/index.html b/duper-js-wasm/index.html new file mode 100644 index 0000000..30a4aaa --- /dev/null +++ b/duper-js-wasm/index.html @@ -0,0 +1,19 @@ + + + + + @duper-js/wasm + + + + + diff --git a/duper-js-wasm/package-lock.json b/duper-js-wasm/package-lock.json new file mode 100644 index 0000000..40698e5 --- /dev/null +++ b/duper-js-wasm/package-lock.json @@ -0,0 +1,1665 @@ +{ + "name": "@duper-js/wasm", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@duper-js/wasm", + "version": "0.1.0", + "license": "MIT", + "devDependencies": { + "@wasm-tool/wasm-pack-plugin": "^1.7.0", + "vite": "^7.1.12", + "vite-plugin-top-level-await": "^1.6.0", + "vite-plugin-wasm": "^3.5.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/plugin-virtual": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", + "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/core": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz", + "integrity": "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.24" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.13.5", + "@swc/core-darwin-x64": "1.13.5", + "@swc/core-linux-arm-gnueabihf": "1.13.5", + "@swc/core-linux-arm64-gnu": "1.13.5", + "@swc/core-linux-arm64-musl": "1.13.5", + "@swc/core-linux-x64-gnu": "1.13.5", + "@swc/core-linux-x64-musl": "1.13.5", + "@swc/core-win32-arm64-msvc": "1.13.5", + "@swc/core-win32-ia32-msvc": "1.13.5", + "@swc/core-win32-x64-msvc": "1.13.5" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.5.tgz", + "integrity": "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.5.tgz", + "integrity": "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.5.tgz", + "integrity": "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.5.tgz", + "integrity": "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.5.tgz", + "integrity": "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.5.tgz", + "integrity": "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.5.tgz", + "integrity": "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.5.tgz", + "integrity": "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.5.tgz", + "integrity": "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.5.tgz", + "integrity": "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", + "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@swc/wasm": { + "version": "1.13.21", + "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.13.21.tgz", + "integrity": "sha512-fnirreOh8nsRgZoHvBRW9bJL9y2cbiEM6qzSxVEU07PWTD+xFxLdBs0829tf3XSqRDPuivAPc2bDvw1K5itnXA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wasm-tool/wasm-pack-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@wasm-tool/wasm-pack-plugin/-/wasm-pack-plugin-1.7.0.tgz", + "integrity": "sha512-WikzYsw7nTd5CZxH75h7NxM/FLJAgqfWt+/gk3EL3wYKxiIlpMIYPja+sHQl3ARiicIYy4BDfxkbAVjRYlouTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.1", + "command-exists": "^1.2.7", + "watchpack": "^2.1.1", + "which": "^2.0.2" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vite": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", + "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-top-level-await": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.6.0.tgz", + "integrity": "sha512-bNhUreLamTIkoulCR9aDXbTbhLk6n1YE8NJUTTxl5RYskNRtzOR0ASzSjBVRtNdjIfngDXo11qOsybGLNsrdww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/plugin-virtual": "^3.0.2", + "@swc/core": "^1.12.14", + "@swc/wasm": "^1.12.14", + "uuid": "10.0.0" + }, + "peerDependencies": { + "vite": ">=2.8" + } + }, + "node_modules/vite-plugin-wasm": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.5.0.tgz", + "integrity": "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/duper-js-wasm/package.json b/duper-js-wasm/package.json new file mode 100644 index 0000000..aeffe5b --- /dev/null +++ b/duper-js-wasm/package.json @@ -0,0 +1,32 @@ +{ + "name": "@duper-js/wasm", + "version": "0.1.0", + "description": "The format that's super!", + "keywords": [ + "duper", + "serialization", + "wasm" + ], + "homepage": "https://github.com/EpicEric/duper#readme", + "bugs": { + "url": "https://github.com/EpicEric/duper/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/EpicEric/duper.git" + }, + "license": "MIT", + "author": "Eric Rodrigues Pires ", + "type": "module", + "main": "index.js", + "scripts": { + "build": "cargo build --target wasm32-unknown-unknown --release && wasm-bindgen ../target/wasm32-unknown-unknown/release/duper_js_wasm.wasm --out-dir ./pkg --target bundler", + "dev": "vite" + }, + "devDependencies": { + "@wasm-tool/wasm-pack-plugin": "^1.7.0", + "vite": "^7.1.12", + "vite-plugin-top-level-await": "^1.6.0", + "vite-plugin-wasm": "^3.5.0" + } +} diff --git a/duper-js-wasm/src/de.rs b/duper-js-wasm/src/de.rs new file mode 100644 index 0000000..ada1662 --- /dev/null +++ b/duper-js-wasm/src/de.rs @@ -0,0 +1,191 @@ +use duper::visitor::DuperVisitor; +use js_sys::{Array, Object, Reflect, Symbol}; +use wasm_bindgen::prelude::*; + +use crate::{SYMBOL_DUPER_IDENTIFIER, SYMBOL_DUPER_TYPE, SYMBOL_DUPER_VALUE}; + +#[derive(Clone)] +pub(crate) struct Visitor; + +impl DuperVisitor for Visitor { + type Value = Result; + + fn visit_object<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + object: &duper::DuperObject<'a>, + ) -> Self::Value { + let js_object = Object::new(); + + for (key, value) in object.iter() { + let value_result = value.accept(self)?; + Reflect::set(&js_object, &JsValue::from(key.as_ref()), &value_result).map_err(|e| { + JsError::new(&format!("Failed to set property {}: {:?}", key.as_ref(), e)) + })?; + } + + // Mark as object + let type_symbol = Symbol::for_(SYMBOL_DUPER_TYPE); + Reflect::set(&js_object, &type_symbol, &JsValue::from_str("object")) + .map_err(|e| JsError::new(&format!("Failed to set object symbol: {:?}", e)))?; + + if let Some(identifier) = identifier { + let duper_symbol = Symbol::for_(SYMBOL_DUPER_IDENTIFIER); + Reflect::set( + &js_object, + &duper_symbol, + &JsValue::from_str(identifier.as_ref()), + ) + .map_err(|e| JsError::new(&format!("Failed to set Duper identifier: {:?}", e)))?; + } + + Ok(js_object.into()) + } + + fn visit_array<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + array: &duper::DuperArray<'a>, + ) -> Self::Value { + let js_array = Array::new_with_length(array.len() as u32); + + for (index, value) in array.iter().enumerate() { + let value_result = value.accept(self)?; + js_array.set(index as u32, value_result); + } + + // Mark as array + let type_symbol = Symbol::for_(SYMBOL_DUPER_TYPE); + Reflect::set(&js_array, &type_symbol, &JsValue::from_str("array")) + .map_err(|e| JsError::new(&format!("Failed to set array symbol: {:?}", e)))?; + + if let Some(identifier) = identifier { + let duper_symbol = Symbol::for_(SYMBOL_DUPER_IDENTIFIER); + Reflect::set( + &js_array, + &duper_symbol, + &JsValue::from_str(identifier.as_ref()), + ) + .map_err(|e| JsError::new(&format!("Failed to set Duper identifier: {:?}", e)))?; + } + + Ok(js_array.into()) + } + + fn visit_tuple<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + tuple: &duper::DuperTuple<'a>, + ) -> Self::Value { + let js_array = Array::new_with_length(tuple.len() as u32); + + for (index, value) in tuple.iter().enumerate() { + let value_result = value.accept(self)?; + js_array.set(index as u32, value_result); + } + + // Mark as tuple + let type_symbol = Symbol::for_(SYMBOL_DUPER_TYPE); + Reflect::set(&js_array, &type_symbol, &JsValue::from_str("tuple")) + .map_err(|e| JsError::new(&format!("Failed to set tuple symbol: {:?}", e)))?; + + if let Some(identifier) = identifier { + let duper_symbol = Symbol::for_(SYMBOL_DUPER_IDENTIFIER); + Reflect::set( + &js_array, + &duper_symbol, + &JsValue::from_str(identifier.as_ref()), + ) + .map_err(|e| JsError::new(&format!("Failed to set Duper identifier: {:?}", e)))?; + } + + Ok(js_array.into()) + } + + fn visit_string<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + string: &duper::DuperString<'a>, + ) -> Self::Value { + let value = JsValue::from_str(string.as_ref()); + attach_identifier(value, identifier, "string") + } + + fn visit_bytes<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + bytes: &duper::DuperBytes<'a>, + ) -> Self::Value { + let uint8_array = js_sys::Uint8Array::from(bytes.as_ref()); + let value: JsValue = uint8_array.into(); + attach_identifier(value, identifier, "bytes") + } + + fn visit_integer<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + integer: i64, + ) -> Self::Value { + // TO-DO: Handle big integers + let value = JsValue::from_f64(integer as f64); + attach_identifier(value, identifier, "integer") + } + + fn visit_float<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + float: f64, + ) -> Self::Value { + let value = JsValue::from_f64(float); + attach_identifier(value, identifier, "float") + } + + fn visit_boolean<'a>( + &mut self, + identifier: Option<&duper::DuperIdentifier<'a>>, + boolean: bool, + ) -> Self::Value { + let value = JsValue::from_bool(boolean); + attach_identifier(value, identifier, "boolean") + } + + fn visit_null<'a>(&mut self, identifier: Option<&duper::DuperIdentifier<'a>>) -> Self::Value { + let value = JsValue::NULL; + attach_identifier(value, identifier, "null") + } +} + +fn attach_identifier( + value: JsValue, + identifier: Option<&duper::DuperIdentifier>, + typ: &'static str, +) -> Result { + if let Some(identifier) = identifier { + let boxed = Object::new(); + let value_key = Symbol::for_(SYMBOL_DUPER_VALUE); + let identifier_symbol = Symbol::for_(SYMBOL_DUPER_IDENTIFIER); + let type_symbol = Symbol::for_(SYMBOL_DUPER_TYPE); + + Reflect::set(&boxed, &value_key, &value) + .map_err(|e| JsError::new(&format!("Failed to set Duper value: {:?}", e)))?; + Reflect::set( + &boxed, + &identifier_symbol, + &JsValue::from_str(identifier.as_ref()), + ) + .map_err(|e| JsError::new(&format!("Failed to set Duper identifier symbol: {:?}", e)))?; + Reflect::set(&boxed, &type_symbol, &JsValue::from_str(typ)) + .map_err(|e| JsError::new(&format!("Failed to set Duper type: {:?}", e)))?; + + let to_json = js_sys::Function::new_with_args( + "", + &format!(r#"return this[Symbol.for("{SYMBOL_DUPER_VALUE}")];"#), + ); + Reflect::set(&boxed, &JsValue::from("toJSON"), &to_json) + .map_err(|e| JsError::new(&format!("Failed to set toJSON function: {:?}", e)))?; + + Ok(boxed.into()) + } else { + Ok(value) + } +} diff --git a/duper-js-wasm/src/lib.rs b/duper-js-wasm/src/lib.rs new file mode 100644 index 0000000..f0bce31 --- /dev/null +++ b/duper-js-wasm/src/lib.rs @@ -0,0 +1,77 @@ +use duper::{DuperParser, DuperValue, PrettyPrinter, Serializer}; +use js_sys::Reflect; +use wasm_bindgen::prelude::*; + +use crate::{de::Visitor, ser::serialize_jsvalue}; + +mod de; +mod ser; + +pub(crate) static SYMBOL_DUPER_VALUE: &str = "$duper.value"; +pub(crate) static SYMBOL_DUPER_IDENTIFIER: &str = "$duper.identifier"; +pub(crate) static SYMBOL_DUPER_TYPE: &str = "$duper.type"; + +struct StringifyOptions { + indent: Option, + strip_identifiers: bool, +} + +#[wasm_bindgen(typescript_custom_section)] +const I_STRINGIFY_OPTIONS: &'static str = r#" +interface IStringifyOptions { + indent?: string | number; + stripIdentifiers?: boolean; +}"#; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(typescript_type = "IStringifyOptions")] + pub type IStringifyOptions; +} + +#[wasm_bindgen] +pub fn stringify(value: &JsValue, options: Option) -> Result { + let value: DuperValue = serialize_jsvalue(value) + .map_err(|e| JsError::new(&format!("Failed to serialize into Duper value: {:?}", e)))?; + let options: JsValue = options.into(); + let StringifyOptions { + indent, + strip_identifiers, + } = if options.is_truthy() { + let indent = Reflect::get(&options, &JsValue::from_str("indent")) + .map_err(|e| JsError::new(&format!("Failed to get property indent: {:?}", e)))?; + let strip_identifiers = Reflect::get(&options, &JsValue::from_str("stripIdentifiers")) + .map_err(|e| { + JsError::new(&format!("Failed to get property stripIdentifiers: {:?}", e)) + })?; + StringifyOptions { + indent: if let Some(indent) = indent.as_f64() { + Some((0..indent as u32).map(|_| ' ').collect()) + } else if let Some(indent) = indent.as_string() { + Some(indent) + } else { + None + }, + strip_identifiers: strip_identifiers.is_truthy(), + } + } else { + StringifyOptions { + indent: None, + strip_identifiers: false, + } + }; + if let Some(indent) = indent { + Ok(PrettyPrinter::new(strip_identifiers, &indent) + .map_err(|e| JsError::new(&format!("Failed to pretty print Duper: {:?}", e)))? + .pretty_print(value)) + } else { + Ok(Serializer::new(strip_identifiers).serialize(value)) + } +} + +#[wasm_bindgen] +pub fn parse(value: &str) -> Result { + let value = DuperParser::parse_duper_value(value) + .map_err(|err| JsError::new(&format!("{:?}", miette::Error::new(err.into_miette()))))?; + value.accept(&mut Visitor) +} diff --git a/duper-js-wasm/src/ser.rs b/duper-js-wasm/src/ser.rs new file mode 100644 index 0000000..35547cf --- /dev/null +++ b/duper-js-wasm/src/ser.rs @@ -0,0 +1,248 @@ +use std::borrow::Cow; + +use duper::{ + DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, + DuperTuple, DuperValue, +}; +use js_sys::{Array, BigInt, Boolean, Object, Reflect, Symbol, Uint8Array, try_iter}; +use wasm_bindgen::prelude::*; + +use crate::{SYMBOL_DUPER_IDENTIFIER, SYMBOL_DUPER_TYPE, SYMBOL_DUPER_VALUE}; + +pub(crate) fn serialize_jsvalue(value: &JsValue) -> Result, JsValue> { + let identifier = if value.is_instance_of::() { + let identifier = Reflect::get(value, &Symbol::for_(SYMBOL_DUPER_IDENTIFIER))?; + let identifier = if identifier.is_truthy() { + if identifier.is_string() { + identifier + .as_string() + .map(|identifier| DuperIdentifier::try_from(identifier)) + .transpose() + .map_err(|e| JsValue::from_str(&e.to_string()))? + } else { + return Err(JsValue::from_str(&format!( + "invalid Duper identifier {identifier:?}" + ))); + } + } else { + None + }; + let typ = Reflect::get(value, &Symbol::for_(SYMBOL_DUPER_TYPE))?; + if typ.is_truthy() { + if typ.is_string() { + match typ.as_string().expect("checked Duper type").as_str() { + "object" => return serialize_object(value, identifier), + "array" => return serialize_array(value, identifier), + "tuple" => return serialize_tuple(value, identifier), + "string" => { + return serialize_string( + &Reflect::get(value, &Symbol::for_(SYMBOL_DUPER_VALUE))?, + identifier, + ); + } + "bytes" => (), + "integer" => { + return serialize_integer( + &Reflect::get(value, &Symbol::for_(SYMBOL_DUPER_VALUE))?, + identifier, + ); + } + "float" => { + return serialize_float( + &Reflect::get(value, &Symbol::for_(SYMBOL_DUPER_VALUE))?, + identifier, + ); + } + "boolean" => { + return serialize_boolean( + &Reflect::get(value, &Symbol::for_(SYMBOL_DUPER_VALUE))?, + identifier, + ); + } + "null" => return serialize_null(identifier), + _ => return Err(JsValue::from_str(&format!("invalid Duper type {typ:?}"))), + } + } else { + return Err(JsValue::from_str(&format!( + " + invalid Duper type {typ:?}" + ))); + } + } + identifier + } else { + None + }; + + // Not a Duper deserialized value; detect which type it actually is + if value.is_null() || value.is_undefined() { + serialize_null(identifier) + } else if Boolean::is_type_of(value) { + serialize_boolean(value, identifier) + } else if value.is_bigint() { + serialize_integer(value, identifier) + } else if value.as_f64().is_some() { + serialize_float(value, identifier) + } else if Uint8Array::is_type_of(value) { + serialize_bytes(value, identifier) + } else if value.as_string().is_some() { + serialize_string(value, identifier) + } else if Array::is_array(value) { + serialize_array(value, identifier) + } else if !value.is_function() && !value.is_symbol() { + serialize_object(value, identifier) + } else { + Err(JsValue::from_str(&format!("unknown value {value:?}"))) + } +} + +fn serialize_object( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + let entries = Object::entries( + value + .dyn_ref() + .ok_or_else(|| format!("expected object, found {value:?}"))?, + ); + let values: Result, JsValue> = entries + .into_iter() + .map(|tup| { + let tup: Array = tup.dyn_into().expect("expected key-value tuple"); + let key = tup + .get(0) + .as_string() + .ok_or_else(|| format!("expected key string, found {tup:?}"))?; + let value = serialize_jsvalue(&tup.get(1))?; + Ok((DuperKey::from(key), value)) + }) + .collect(); + Ok(DuperValue { + identifier, + inner: DuperInner::Object(DuperObject::try_from(values?).map_err(|err| err.to_string())?), + }) +} + +fn serialize_array( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + let iterator = try_iter(value)?.ok_or_else(|| "cannot iterate over array")?; + let elements: Result, JsValue> = + iterator.map(|value| serialize_jsvalue(&value?)).collect(); + Ok(DuperValue { + identifier, + inner: DuperInner::Array(DuperArray::from(elements?)), + }) +} + +fn serialize_tuple( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + let iterator = try_iter(value)?.ok_or_else(|| "cannot iterate over tuple")?; + let elements: Result, JsValue> = + iterator.map(|value| serialize_jsvalue(&value?)).collect(); + Ok(DuperValue { + identifier, + inner: DuperInner::Tuple(DuperTuple::from(elements?)), + }) +} + +fn serialize_string( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + let string = value + .as_string() + .ok_or_else(|| format!("expected string, found {value:?}"))?; + Ok(DuperValue { + identifier, + inner: DuperInner::String(DuperString::from(Cow::Owned(string))), + }) +} + +fn serialize_bytes( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + let bytes: &Uint8Array = + JsCast::dyn_ref(value).ok_or_else(|| format!("expected bytes, found {value:?}"))?; + Ok(DuperValue { + identifier, + inner: DuperInner::Bytes(DuperBytes::from(Cow::Owned(bytes.to_vec()))), + }) +} + +fn serialize_integer( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + if let Some(bigint) = JsCast::dyn_ref::(value) { + match i64::try_from(bigint.clone()) { + Ok(integer) => Ok(DuperValue { + identifier, + inner: DuperInner::Integer(integer), + }), + Err(_) => Ok(DuperValue { + identifier: Some(identifier.unwrap_or_else(|| { + DuperIdentifier::try_from(Cow::Borrowed("Integer")).expect("valid identifier") + })), + inner: DuperInner::String(DuperString::from(Cow::Owned( + value + .as_string() + .ok_or_else(|| format!("expected integer, found {value:?}"))?, + ))), + }), + } + } else if let Some(float) = value.as_f64() { + if float.fract() == 0.0 { + Ok(DuperValue { + identifier, + inner: DuperInner::Integer(float as i64), + }) + } else { + Ok(DuperValue { + identifier, + inner: DuperInner::Float(float), + }) + } + } else { + Err(JsValue::from_str(&format!( + "expected integer, found {value:?}" + ))) + } +} + +fn serialize_float( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + Ok(DuperValue { + identifier, + inner: DuperInner::Float( + value + .as_f64() + .ok_or_else(|| format!("expected float, found {value:?}"))?, + ), + }) +} + +fn serialize_boolean( + value: &JsValue, + identifier: Option>, +) -> Result, JsValue> { + Ok(DuperValue { + identifier, + inner: DuperInner::Boolean(value.is_truthy()), + }) +} + +fn serialize_null( + identifier: Option>, +) -> Result, JsValue> { + Ok(DuperValue { + identifier, + inner: DuperInner::Null, + }) +} diff --git a/duper-js-wasm/vite.config.js b/duper-js-wasm/vite.config.js new file mode 100644 index 0000000..ebe1e6b --- /dev/null +++ b/duper-js-wasm/vite.config.js @@ -0,0 +1,12 @@ +import { + defineConfig +} from 'vite' +import wasm from "vite-plugin-wasm"; +import topLevelAwait from "vite-plugin-top-level-await"; + +export default defineConfig({ + plugins: [ + wasm(), + topLevelAwait() + ], +}); \ No newline at end of file diff --git a/duper-python/Cargo.toml b/duper-python/Cargo.toml index eb4b22a..55ea2ef 100644 --- a/duper-python/Cargo.toml +++ b/duper-python/Cargo.toml @@ -24,3 +24,6 @@ pyo3 = { version = "0.27.1", features = [ "extension-module", "generate-import-lib", ] } + +[profile.release] +lto = true diff --git a/duper-python/README.md b/duper-python/README.md index 00a858a..67a1d38 100644 --- a/duper-python/README.md +++ b/duper-python/README.md @@ -12,6 +12,14 @@ Duper support for Python. [Check out the official website for Duper.](https://duper.dev.br) +## Installation + +```bash +uv add duper-python +# -- or -- +pip install duper-python +``` + ## Examples The basic `json`/`pickle`-like interface: diff --git a/duper-python/src/ser/well_known_type.rs b/duper-python/src/ser/well_known_type.rs index 98087f3..bf7f604 100644 --- a/duper-python/src/ser/well_known_type.rs +++ b/duper-python/src/ser/well_known_type.rs @@ -786,7 +786,7 @@ fn serialize_pydantic_model<'py>(obj: Bound<'py, PyAny>) -> PyResult() - .expect("Duper instance") + .expect("checked Duper instance") .get() .identifier .clone() @@ -803,12 +803,12 @@ fn serialize_pydantic_model<'py>(obj: Bound<'py, PyAny>) -> PyResult(format!( - "Unsupported type: {}", + "unsupported type: {}", obj.get_type() ))) } diff --git a/duper.code-workspace b/duper.code-workspace index 9ed56ea..a577367 100644 --- a/duper.code-workspace +++ b/duper.code-workspace @@ -12,6 +12,10 @@ "name": "duper", "path": "duper" }, + { + "name": "duper-js-wasm", + "path": "duper-js-wasm" + }, { "name": "duper-python", "path": "duper-python" diff --git a/duper/README.md b/duper/README.md index f55f053..a01483f 100644 --- a/duper/README.md +++ b/duper/README.md @@ -46,12 +46,6 @@ Product({ - It includes support for extra types: integers, tuples, bytes, raw strings, and raw bytes. - Finally, Duper has the notion of _identifiers_: optional type-like annotations (`MyIdentifier(...)`) to help with readability, or to suggest that the parser handles/validates the data in a specific manner. -## Quick start - -```bash -cargo add duper -``` - ## See also: - [`serde_duper`](https://docs.rs/serde_duper): `serde` serialization / deserialization support for Duper. diff --git a/duper/src/ast.rs b/duper/src/ast.rs index 05ebd28..691c92b 100644 --- a/duper/src/ast.rs +++ b/duper/src/ast.rs @@ -230,6 +230,12 @@ impl<'a> From> for DuperKey<'a> { } } +impl From for DuperKey<'static> { + fn from(value: String) -> Self { + Self(Cow::Owned(value)) + } +} + impl<'a> DuperValue<'a> { /// Accepts a [`DuperVisitor`] and visits it with the current value. pub fn accept(&self, visitor: &mut V) -> V::Value { @@ -416,6 +422,12 @@ impl<'a> From> for DuperString<'a> { } } +impl From for DuperString<'static> { + fn from(value: String) -> Self { + Self(Cow::Owned(value)) + } +} + impl<'a> AsRef for DuperString<'a> { fn as_ref(&self) -> &str { &self.0 @@ -435,6 +447,12 @@ impl<'a> From> for DuperBytes<'a> { } } +impl From> for DuperBytes<'static> { + fn from(value: Vec) -> Self { + Self(Cow::Owned(value)) + } +} + impl<'a> AsRef<[u8]> for DuperBytes<'a> { fn as_ref(&self) -> &[u8] { &self.0 diff --git a/serde_duper/README.md b/serde_duper/README.md index 555b44c..d3e03a3 100644 --- a/serde_duper/README.md +++ b/serde_duper/README.md @@ -12,6 +12,14 @@ Adds `serde` support for Duper. [See the main project on GitHub.](https://github.com/EpicEric/duper) +## Installation + +```bash +cargo add serde_duper +# -- or -- +cargo add serde_duper --features macros,uuid,chrono +``` + ## Example ```rust -- 2.51.2