This is an automated email from the ASF dual-hosted git repository.

uranusjr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new f57229b4607 Add TypeScript task SDK public interface (#67908)
f57229b4607 is described below

commit f57229b4607c1e1182aae7343f85421e52f52643
Author: Shivam Rastogi <[email protected]>
AuthorDate: Sat Jun 27 17:28:10 2026 -0700

    Add TypeScript task SDK public interface (#67908)
---
 .pre-commit-config.yaml               |   15 +
 ts-sdk/.prettierignore                |   20 +
 ts-sdk/.prettierrc.json               |    5 +
 ts-sdk/LICENSE                        |  201 ++++
 ts-sdk/NOTICE                         |    5 +
 ts-sdk/README.md                      |  145 +++
 ts-sdk/eslint.config.js               |   39 +
 ts-sdk/package.json                   |   64 ++
 ts-sdk/pnpm-lock.yaml                 | 1989 +++++++++++++++++++++++++++++++++
 ts-sdk/scripts/ci/prek/ts_sdk_lint.py |   39 +
 ts-sdk/src/index.ts                   |   25 +
 ts-sdk/src/sdk/client-types.ts        |   68 ++
 ts-sdk/src/sdk/client.ts              |   88 ++
 ts-sdk/src/sdk/registry.ts            |   90 ++
 ts-sdk/src/sdk/task.ts                |   61 +
 ts-sdk/tests/public-api.test.ts       |  133 +++
 ts-sdk/tests/sdk/registry.test.ts     |  104 ++
 ts-sdk/tsconfig.build.json            |   10 +
 ts-sdk/tsconfig.json                  |   27 +
 ts-sdk/vitest.config.ts               |   26 +
 20 files changed, 3154 insertions(+)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 14b57af8f8a..07b5967c91a 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -249,6 +249,21 @@ repos:
           ^pyproject\.toml$
         pass_filenames: false
         require_serial: true
+      - id: ts-sdk-lint
+        name: Lint TypeScript SDK
+        entry: ./ts-sdk/scripts/ci/prek/ts_sdk_lint.py
+        language: node
+        files: |
+          (?x)
+          ^ts-sdk/.*\.(js|ts|json)$
+        exclude: |
+          (?x)
+          ^ts-sdk/node_modules/.*|
+          ^ts-sdk/.pnpm-store/.*|
+          ^ts-sdk/dist/.*
+        additional_dependencies: ['[email protected]']
+        pass_filenames: false
+        require_serial: true
       - id: check-ci-workflows-in-sync
         name: Check ci-arm.yml and ci-amd.yml stay in sync
         entry: ./scripts/ci/prek/check_ci_workflows_in_sync.py
diff --git a/ts-sdk/.prettierignore b/ts-sdk/.prettierignore
new file mode 100644
index 00000000000..4d0d3a67c0e
--- /dev/null
+++ b/ts-sdk/.prettierignore
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+dist/
+coverage/
+node_modules/
diff --git a/ts-sdk/.prettierrc.json b/ts-sdk/.prettierrc.json
new file mode 100644
index 00000000000..72bb8a7acff
--- /dev/null
+++ b/ts-sdk/.prettierrc.json
@@ -0,0 +1,5 @@
+{
+  "tabWidth": 2,
+  "printWidth": 100,
+  "trailingComma": "all"
+}
diff --git a/ts-sdk/LICENSE b/ts-sdk/LICENSE
new file mode 100644
index 00000000000..11069edd790
--- /dev/null
+++ b/ts-sdk/LICENSE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/ts-sdk/NOTICE b/ts-sdk/NOTICE
new file mode 100644
index 00000000000..a51bd9390d0
--- /dev/null
+++ b/ts-sdk/NOTICE
@@ -0,0 +1,5 @@
+Apache Airflow
+Copyright 2016-2026 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/ts-sdk/README.md b/ts-sdk/README.md
new file mode 100644
index 00000000000..f69f9fe7588
--- /dev/null
+++ b/ts-sdk/README.md
@@ -0,0 +1,145 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+# Airflow TypeScript SDK
+
+Public TypeScript interfaces for writing Apache Airflow task handlers.
+
+**Status:** alpha · API will change · Node 22+ · ESM-only
+
+This package defines the user-facing task handler contract: task registration,
+runtime context types, and the `TaskClient` interface used for Airflow
+Variables, Connections, and XCom. Runtime transports implement this interface
+separately.
+
+## Install
+
+```bash
+pnpm add @apache-airflow/ts-sdk
+```
+
+## Task Handlers
+
+```ts
+import { registerTask, type TaskHandlerArgs } from "@apache-airflow/ts-sdk";
+
+export async function sayHello({ ctx, client }: TaskHandlerArgs) {
+  const greeting = await client.getVariable("greeting");
+  return { message: `Hello from ${ctx.taskId}: ${greeting}` };
+}
+
+registerTask({ dagId: "example_dag", taskId: "say_hello" }, sayHello);
+```
+
+Non-`undefined` return values are pushed to XCom under the `"return_value"`
+key by the active runtime, matching Python `@task` behavior.
+
+## Intended Coordinator Usage
+
+This PR only adds the TypeScript-side public interface. The coordinator runtime
+will be added separately. Declaring Airflow Dags in TypeScript is not supported
+yet; the Dag is still declared in Python. The intended authoring shape matches
+the other non-Python SDKs: a Python Dag declares the scheduling shape with stub
+tasks, and the TypeScript module registers handlers with matching task IDs.
+
+Python Dag:
+
+```python
+from airflow.sdk import dag, task
+
+
+@dag
+def sales_pipeline():
+    @task.stub(queue="typescript")
+    def extract(): ...
+
+    @task.stub(queue="typescript")
+    def transform(extracted): ...
+
+    transform(extract())
+
+
+sales_pipeline()
+```
+
+TypeScript handlers:
+
+```ts
+import { registerTask, type TaskHandlerArgs } from "@apache-airflow/ts-sdk";
+
+export async function extract({ client }: TaskHandlerArgs) {
+  const connection = await client.getConnection("sales_db");
+  const rowCount = Number((await client.getVariable("daily_row_count")) ?? 
"0");
+
+  return {
+    connectionId: connection?.id ?? null,
+    rowCount,
+  };
+}
+
+export async function transform({ client }: TaskHandlerArgs) {
+  const extracted = await client.getXCom<{ rowCount: number }>({
+    key: "return_value",
+    taskId: "extract",
+  });
+
+  return {
+    transformedRows: extracted?.rowCount ?? 0,
+  };
+}
+
+registerTask({ dagId: "sales_pipeline", taskId: "extract" }, extract);
+registerTask({ dagId: "sales_pipeline", taskId: "transform" }, transform);
+```
+
+The Python stub defines the Dag dependency graph. The TypeScript handler does
+the work and uses `TaskClient` for task-time Airflow data access. Register each
+handler with the Python Dag's `dag_id` and the stub task's `task_id`. The
+handler function is the reusable task implementation; `registerTask` binds that
+handler to a Python stub Dag/task identity for coordinator mode. A future
+TypeScript Dag authoring API can attach the same handlers without changing the
+handler code.
+
+## TaskClient
+
+Every task handler receives a `TaskClient` for task-time Airflow data access:
+
+| Method                                    | Description         |
+| ----------------------------------------- | ------------------- |
+| `getVariable(key)` / `getVariableOrThrow` | Airflow Variables   |
+| `getXCom(opts)` / `setXCom(opts)`         | XCom read/write     |
+| `getConnection(connId)`                   | Airflow Connections |
+
+Locator fields such as `dagId`, `runId`, and `taskId` default to the
+current task context when omitted.
+
+## Cancellation
+
+`ctx.signal` is an `AbortSignal` controlled by the active runtime. Pass it to
+`fetch()`, timers, database clients, child processes, or other abortable APIs
+so tasks can clean up cooperatively when Airflow terminates the task attempt.
+
+## Development
+
+```bash
+pnpm install
+pnpm test
+pnpm run typecheck
+pnpm run build
+```
diff --git a/ts-sdk/eslint.config.js b/ts-sdk/eslint.config.js
new file mode 100644
index 00000000000..9fed412ab7e
--- /dev/null
+++ b/ts-sdk/eslint.config.js
@@ -0,0 +1,39 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import js from "@eslint/js";
+import tseslint from "typescript-eslint";
+
+export default tseslint.config(
+  {
+    ignores: ["dist/**", "node_modules/**", "coverage/**"],
+  },
+  js.configs.recommended,
+  ...tseslint.configs.recommended,
+  {
+    files: ["src/**/*.ts", "tests/**/*.ts"],
+    rules: {
+      "@typescript-eslint/no-explicit-any": "error",
+      "@typescript-eslint/no-unused-vars": [
+        "error",
+        { argsIgnorePattern: "^_" },
+      ],
+    },
+  },
+);
diff --git a/ts-sdk/package.json b/ts-sdk/package.json
new file mode 100644
index 00000000000..2a36a73058d
--- /dev/null
+++ b/ts-sdk/package.json
@@ -0,0 +1,64 @@
+{
+  "name": "@apache-airflow/ts-sdk",
+  "version": "0.1.0-alpha.0",
+  "packageManager": "[email protected]",
+  "description": "Public TypeScript Task SDK interfaces for Apache Airflow 
task handlers",
+  "license": "Apache-2.0",
+  "type": "module",
+  "main": "./dist/index.js",
+  "types": "./dist/index.d.ts",
+  "homepage": "https://airflow.apache.org";,
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/apache/airflow.git";,
+    "directory": "ts-sdk"
+  },
+  "bugs": {
+    "url": "https://github.com/apache/airflow/issues";
+  },
+  "exports": {
+    ".": {
+      "types": "./dist/index.d.ts",
+      "import": "./dist/index.js"
+    }
+  },
+  "files": [
+    "dist",
+    "README.md",
+    "LICENSE",
+    "NOTICE"
+  ],
+  "scripts": {
+    "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, 
force: true })\"",
+    "lint": "eslint src tests",
+    "lint:fix": "eslint src tests --fix",
+    "format:check": "prettier --check src tests",
+    "format": "prettier --write src tests",
+    "typecheck": "tsc --noEmit",
+    "test": "vitest run",
+    "test:watch": "vitest",
+    "build": "pnpm run clean && tsc -p tsconfig.build.json",
+    "prepack": "pnpm run build"
+  },
+  "keywords": [
+    "airflow",
+    "apache-airflow",
+    "task-sdk",
+    "typescript",
+    "aip-72",
+    "aip-108"
+  ],
+  "engines": {
+    "node": ">=22"
+  },
+  "devDependencies": {
+    "@eslint/js": "^10.0.1",
+    "@types/node": "^22.19.17",
+    "eslint": "^10.4.0",
+    "prettier": "^3.8.3",
+    "tsx": "^4.21.0",
+    "typescript": "^6.0.2",
+    "typescript-eslint": "^8.60.0",
+    "vitest": "^4.1.7"
+  }
+}
diff --git a/ts-sdk/pnpm-lock.yaml b/ts-sdk/pnpm-lock.yaml
new file mode 100644
index 00000000000..808dc51c451
--- /dev/null
+++ b/ts-sdk/pnpm-lock.yaml
@@ -0,0 +1,1989 @@
+lockfileVersion: '9.0'
+
+settings:
+  autoInstallPeers: true
+  excludeLinksFromLockfile: false
+
+importers:
+
+  .:
+    devDependencies:
+      '@eslint/js':
+        specifier: ^10.0.1
+        version: 10.0.1([email protected])
+      '@types/node':
+        specifier: ^22.19.17
+        version: 22.19.17
+      eslint:
+        specifier: ^10.4.0
+        version: 10.4.0
+      prettier:
+        specifier: ^3.8.3
+        version: 3.8.3
+      tsx:
+        specifier: ^4.21.0
+        version: 4.21.0
+      typescript:
+        specifier: ^6.0.2
+        version: 6.0.3
+      typescript-eslint:
+        specifier: ^8.60.0
+        version: 8.60.0([email protected])([email protected])
+      vitest:
+        specifier: ^4.1.7
+        version: 
4.1.7(@types/[email protected])(@vitest/[email protected])([email protected](@types/[email protected])([email protected])([email protected]))
+
+packages:
+
+  '@babel/[email protected]':
+    resolution: {integrity: 
sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+    engines: {node: '>=6.9.0'}
+
+  '@babel/[email protected]':
+    resolution: {integrity: 
sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+    engines: {node: '>=6.9.0'}
+
+  '@babel/[email protected]':
+    resolution: {integrity: 
sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+
+  '@babel/[email protected]':
+    resolution: {integrity: 
sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
+    engines: {node: '>=6.9.0'}
+
+  '@bcoe/[email protected]':
+    resolution: {integrity: 
sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
+    engines: {node: '>=18'}
+
+  '@emnapi/[email protected]':
+    resolution: {integrity: 
sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
+
+  '@emnapi/[email protected]':
+    resolution: {integrity: 
sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
+
+  '@emnapi/[email protected]':
+    resolution: {integrity: 
sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+    engines: {node: '>=18'}
+    cpu: [ppc64]
+    os: [aix]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [android]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+    engines: {node: '>=18'}
+    cpu: [arm]
+    os: [android]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [android]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [darwin]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [darwin]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [freebsd]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [freebsd]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+    engines: {node: '>=18'}
+    cpu: [arm]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+    engines: {node: '>=18'}
+    cpu: [ia32]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+    engines: {node: '>=18'}
+    cpu: [loong64]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+    engines: {node: '>=18'}
+    cpu: [mips64el]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+    engines: {node: '>=18'}
+    cpu: [ppc64]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+    engines: {node: '>=18'}
+    cpu: [riscv64]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+    engines: {node: '>=18'}
+    cpu: [s390x]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [linux]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [netbsd]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [netbsd]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [openbsd]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [openbsd]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [openharmony]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [sunos]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [win32]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+    engines: {node: '>=18'}
+    cpu: [ia32]
+    os: [win32]
+
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [win32]
+
+  '@eslint-community/[email protected]':
+    resolution: {integrity: 
sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+  '@eslint-community/[email protected]':
+    resolution: {integrity: 
sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
+    engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+  '@eslint/[email protected]':
+    resolution: {integrity: 
sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  '@eslint/[email protected]':
+    resolution: {integrity: 
sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  '@eslint/[email protected]':
+    resolution: {integrity: 
sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  '@eslint/[email protected]':
+    resolution: {integrity: 
sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+    peerDependencies:
+      eslint: ^10.0.0
+    peerDependenciesMeta:
+      eslint:
+        optional: true
+
+  '@eslint/[email protected]':
+    resolution: {integrity: 
sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  '@eslint/[email protected]':
+    resolution: {integrity: 
sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  '@humanfs/[email protected]':
+    resolution: {integrity: 
sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
+    engines: {node: '>=18.18.0'}
+
+  '@humanfs/[email protected]':
+    resolution: {integrity: 
sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
+    engines: {node: '>=18.18.0'}
+
+  '@humanfs/[email protected]':
+    resolution: {integrity: 
sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
+    engines: {node: '>=18.18.0'}
+
+  '@humanwhocodes/[email protected]':
+    resolution: {integrity: 
sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+    engines: {node: '>=12.22'}
+
+  '@humanwhocodes/[email protected]':
+    resolution: {integrity: 
sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
+    engines: {node: '>=18.18'}
+
+  '@jridgewell/[email protected]':
+    resolution: {integrity: 
sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+    engines: {node: '>=6.0.0'}
+
+  '@jridgewell/[email protected]':
+    resolution: {integrity: 
sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+  '@jridgewell/[email protected]':
+    resolution: {integrity: 
sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+  '@napi-rs/[email protected]':
+    resolution: {integrity: 
sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
+    peerDependencies:
+      '@emnapi/core': ^1.7.1
+      '@emnapi/runtime': ^1.7.1
+
+  '@oxc-project/[email protected]':
+    resolution: {integrity: 
sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==}
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm64]
+    os: [android]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm64]
+    os: [darwin]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [x64]
+    os: [darwin]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [x64]
+    os: [freebsd]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm64]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm64]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [ppc64]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [s390x]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [x64]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [x64]
+    os: [linux]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm64]
+    os: [openharmony]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [wasm32]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [arm64]
+    os: [win32]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    cpu: [x64]
+    os: [win32]
+
+  '@rolldown/[email protected]':
+    resolution: {integrity: 
sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==}
+
+  '@standard-schema/[email protected]':
+    resolution: {integrity: 
sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+  '@tybys/[email protected]':
+    resolution: {integrity: 
sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
+
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
+
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==}
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      '@typescript-eslint/parser': ^8.60.0
+      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+      typescript: '>=4.8.4 <6.1.0'
+
+  '@typescript-eslint/[email protected]':
+    resolution: {integrity: 
sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==}
+    peerDependencies:
+      '@vitest/browser': 4.1.7
+      vitest: 4.1.7
+    peerDependenciesMeta:
+      '@vitest/browser':
+        optional: true
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==}
+    peerDependencies:
+      msw: ^2.4.9
+      vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+    peerDependenciesMeta:
+      msw:
+        optional: true
+      vite:
+        optional: true
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+    peerDependencies:
+      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+  [email protected]:
+    resolution: {integrity: 
sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+    engines: {node: '>=12'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+    engines: {node: 18 || 20 || >=22}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
+    engines: {node: 18 || 20 || >=22}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+    engines: {node: '>=18'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+    engines: {node: '>= 8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+    engines: {node: '>=18'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+    hasBin: true
+    peerDependencies:
+      jiti: '*'
+    peerDependenciesMeta:
+      jiti:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==}
+    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
+    engines: {node: '>=0.10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+    engines: {node: '>=4.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+    engines: {node: '>=4.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+    engines: {node: '>=0.10.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
+    engines: {node: '>=12.0.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+    engines: {node: '>=12.0.0'}
+    peerDependencies:
+      picomatch: ^3 || ^4
+    peerDependenciesMeta:
+      picomatch:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+    engines: {node: '>=16.0.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+    engines: {node: '>=16'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+    engines: {node: '>=10.13.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+    engines: {node: '>= 4'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
+    engines: {node: '>= 4'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+    engines: {node: '>=0.8.19'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+    engines: {node: '>=0.10.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+    engines: {node: '>=0.10.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+    engines: {node: '>= 0.8.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [arm64]
+    os: [android]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [arm64]
+    os: [darwin]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [x64]
+    os: [darwin]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [x64]
+    os: [freebsd]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [arm]
+    os: [linux]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [arm64]
+    os: [linux]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [arm64]
+    os: [linux]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [x64]
+    os: [linux]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [x64]
+    os: [linux]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [arm64]
+    os: [win32]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
+    engines: {node: '>= 12.0.0'}
+    cpu: [x64]
+    os: [win32]
+
+  [email protected]:
+    resolution: {integrity: 
sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
+    engines: {node: '>= 12.0.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+    engines: {node: 18 || 20 || >=22}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+    engines: {node: '>= 0.8.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
+    engines: {node: '>=12'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==}
+    engines: {node: ^10 || ^12 || >=14}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+    engines: {node: '>= 0.8.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
+    engines: {node: '>=14'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+    engines: {node: '>=6'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==}
+    engines: {node: '>=10'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+    engines: {node: '>=0.10.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==}
+    engines: {node: '>=18'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
+    engines: {node: '>=12.0.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
+    engines: {node: '>=14.0.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
+    engines: {node: '>=18.12'}
+    peerDependencies:
+      typescript: '>=4.8.4'
+
+  [email protected]:
+    resolution: {integrity: 
sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
+    engines: {node: '>=18.0.0'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+    engines: {node: '>= 0.8.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-9f65qWLZdAW9m1JaxBDUHcqRUfL8bkxxXL7XxEfI+F09q56PkBvIfCjLF3yInsDM/BBmwkqmCQdCZe/RYlIWEw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+      typescript: '>=4.8.4 <6.1.0'
+
+  [email protected]:
+    resolution: {integrity: 
sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
+    engines: {node: '>=14.17'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': ^20.19.0 || >=22.12.0
+      '@vitejs/devtools': ^0.1.0
+      esbuild: ^0.27.0 || ^0.28.0
+      jiti: '>=1.21.0'
+      less: ^4.0.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
+      '@vitejs/devtools':
+        optional: true
+      esbuild:
+        optional: true
+      jiti:
+        optional: true
+      less:
+        optional: true
+      sass:
+        optional: true
+      sass-embedded:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+      tsx:
+        optional: true
+      yaml:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==}
+    engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+    hasBin: true
+    peerDependencies:
+      '@edge-runtime/vm': '*'
+      '@opentelemetry/api': ^1.9.0
+      '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+      '@vitest/browser-playwright': 4.1.7
+      '@vitest/browser-preview': 4.1.7
+      '@vitest/browser-webdriverio': 4.1.7
+      '@vitest/coverage-istanbul': 4.1.7
+      '@vitest/coverage-v8': 4.1.7
+      '@vitest/ui': 4.1.7
+      happy-dom: '*'
+      jsdom: '*'
+      vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+    peerDependenciesMeta:
+      '@edge-runtime/vm':
+        optional: true
+      '@opentelemetry/api':
+        optional: true
+      '@types/node':
+        optional: true
+      '@vitest/browser-playwright':
+        optional: true
+      '@vitest/browser-preview':
+        optional: true
+      '@vitest/browser-webdriverio':
+        optional: true
+      '@vitest/coverage-istanbul':
+        optional: true
+      '@vitest/coverage-v8':
+        optional: true
+      '@vitest/ui':
+        optional: true
+      happy-dom:
+        optional: true
+      jsdom:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+    engines: {node: '>= 8'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+    engines: {node: '>=8'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+    engines: {node: '>=0.10.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+    engines: {node: '>=10'}
+
+snapshots:
+
+  '@babel/[email protected]':
+    optional: true
+
+  '@babel/[email protected]':
+    optional: true
+
+  '@babel/[email protected]':
+    dependencies:
+      '@babel/types': 7.29.7
+    optional: true
+
+  '@babel/[email protected]':
+    dependencies:
+      '@babel/helper-string-parser': 7.29.7
+      '@babel/helper-validator-identifier': 7.29.7
+    optional: true
+
+  '@bcoe/[email protected]':
+    optional: true
+
+  '@emnapi/[email protected]':
+    dependencies:
+      '@emnapi/wasi-threads': 1.2.1
+      tslib: 2.8.1
+    optional: true
+
+  '@emnapi/[email protected]':
+    dependencies:
+      tslib: 2.8.1
+    optional: true
+
+  '@emnapi/[email protected]':
+    dependencies:
+      tslib: 2.8.1
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@eslint-community/[email protected]([email protected])':
+    dependencies:
+      eslint: 10.4.0
+      eslint-visitor-keys: 3.4.3
+
+  '@eslint-community/[email protected]': {}
+
+  '@eslint/[email protected]':
+    dependencies:
+      '@eslint/object-schema': 3.0.5
+      debug: 4.4.3
+      minimatch: 10.2.5
+    transitivePeerDependencies:
+      - supports-color
+
+  '@eslint/[email protected]':
+    dependencies:
+      '@eslint/core': 1.2.1
+
+  '@eslint/[email protected]':
+    dependencies:
+      '@types/json-schema': 7.0.15
+
+  '@eslint/[email protected]([email protected])':
+    optionalDependencies:
+      eslint: 10.4.0
+
+  '@eslint/[email protected]': {}
+
+  '@eslint/[email protected]':
+    dependencies:
+      '@eslint/core': 1.2.1
+      levn: 0.4.1
+
+  '@humanfs/[email protected]':
+    dependencies:
+      '@humanfs/types': 0.15.0
+
+  '@humanfs/[email protected]':
+    dependencies:
+      '@humanfs/core': 0.19.2
+      '@humanfs/types': 0.15.0
+      '@humanwhocodes/retry': 0.4.3
+
+  '@humanfs/[email protected]': {}
+
+  '@humanwhocodes/[email protected]': {}
+
+  '@humanwhocodes/[email protected]': {}
+
+  '@jridgewell/[email protected]':
+    optional: true
+
+  '@jridgewell/[email protected]': {}
+
+  '@jridgewell/[email protected]':
+    dependencies:
+      '@jridgewell/resolve-uri': 3.1.2
+      '@jridgewell/sourcemap-codec': 1.5.5
+    optional: true
+
+  '@napi-rs/[email protected](@emnapi/[email protected])(@emnapi/[email protected])':
+    dependencies:
+      '@emnapi/core': 1.10.0
+      '@emnapi/runtime': 1.10.0
+      '@tybys/wasm-util': 0.10.1
+    optional: true
+
+  '@oxc-project/[email protected]': {}
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    dependencies:
+      '@emnapi/core': 1.10.0
+      '@emnapi/runtime': 1.10.0
+      '@napi-rs/wasm-runtime': 
1.1.4(@emnapi/[email protected])(@emnapi/[email protected])
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]':
+    optional: true
+
+  '@rolldown/[email protected]': {}
+
+  '@standard-schema/[email protected]': {}
+
+  '@tybys/[email protected]':
+    dependencies:
+      tslib: 2.8.1
+    optional: true
+
+  '@types/[email protected]':
+    dependencies:
+      '@types/deep-eql': 4.0.2
+      assertion-error: 2.0.1
+
+  '@types/[email protected]': {}
+
+  '@types/[email protected]': {}
+
+  '@types/[email protected]': {}
+
+  '@types/[email protected]': {}
+
+  '@types/[email protected]':
+    dependencies:
+      undici-types: 6.21.0
+
+  
'@typescript-eslint/[email protected](@typescript-eslint/[email protected]([email protected])([email protected]))([email protected])([email protected])':
+    dependencies:
+      '@eslint-community/regexpp': 4.12.2
+      '@typescript-eslint/parser': 8.60.0([email protected])([email protected])
+      '@typescript-eslint/scope-manager': 8.60.0
+      '@typescript-eslint/type-utils': 8.60.0([email protected])([email protected])
+      '@typescript-eslint/utils': 8.60.0([email protected])([email protected])
+      '@typescript-eslint/visitor-keys': 8.60.0
+      eslint: 10.4.0
+      ignore: 7.0.5
+      natural-compare: 1.4.0
+      ts-api-utils: 2.5.0([email protected])
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/[email protected]([email protected])([email protected])':
+    dependencies:
+      '@typescript-eslint/scope-manager': 8.60.0
+      '@typescript-eslint/types': 8.60.0
+      '@typescript-eslint/typescript-estree': 8.60.0([email protected])
+      '@typescript-eslint/visitor-keys': 8.60.0
+      debug: 4.4.3
+      eslint: 10.4.0
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/[email protected]([email protected])':
+    dependencies:
+      '@typescript-eslint/tsconfig-utils': 8.60.0([email protected])
+      '@typescript-eslint/types': 8.60.0
+      debug: 4.4.3
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/[email protected]':
+    dependencies:
+      '@typescript-eslint/types': 8.60.0
+      '@typescript-eslint/visitor-keys': 8.60.0
+
+  '@typescript-eslint/[email protected]([email protected])':
+    dependencies:
+      typescript: 6.0.3
+
+  '@typescript-eslint/[email protected]([email protected])([email protected])':
+    dependencies:
+      '@typescript-eslint/types': 8.60.0
+      '@typescript-eslint/typescript-estree': 8.60.0([email protected])
+      '@typescript-eslint/utils': 8.60.0([email protected])([email protected])
+      debug: 4.4.3
+      eslint: 10.4.0
+      ts-api-utils: 2.5.0([email protected])
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/[email protected]': {}
+
+  '@typescript-eslint/[email protected]([email protected])':
+    dependencies:
+      '@typescript-eslint/project-service': 8.60.0([email protected])
+      '@typescript-eslint/tsconfig-utils': 8.60.0([email protected])
+      '@typescript-eslint/types': 8.60.0
+      '@typescript-eslint/visitor-keys': 8.60.0
+      debug: 4.4.3
+      minimatch: 10.2.5
+      semver: 7.8.1
+      tinyglobby: 0.2.16
+      ts-api-utils: 2.5.0([email protected])
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/[email protected]([email protected])([email protected])':
+    dependencies:
+      '@eslint-community/eslint-utils': 4.9.1([email protected])
+      '@typescript-eslint/scope-manager': 8.60.0
+      '@typescript-eslint/types': 8.60.0
+      '@typescript-eslint/typescript-estree': 8.60.0([email protected])
+      eslint: 10.4.0
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/[email protected]':
+    dependencies:
+      '@typescript-eslint/types': 8.60.0
+      eslint-visitor-keys: 5.0.1
+
+  '@vitest/[email protected]([email protected])':
+    dependencies:
+      '@bcoe/v8-coverage': 1.0.2
+      '@vitest/utils': 4.1.7
+      ast-v8-to-istanbul: 1.0.2
+      istanbul-lib-coverage: 3.2.2
+      istanbul-lib-report: 3.0.1
+      istanbul-reports: 3.2.0
+      magicast: 0.5.3
+      obug: 2.1.1
+      std-env: 4.1.0
+      tinyrainbow: 3.1.0
+      vitest: 
4.1.7(@types/[email protected])(@vitest/[email protected])([email protected](@types/[email protected])([email protected])([email protected]))
+    optional: true
+
+  '@vitest/[email protected]':
+    dependencies:
+      '@standard-schema/spec': 1.1.0
+      '@types/chai': 5.2.3
+      '@vitest/spy': 4.1.7
+      '@vitest/utils': 4.1.7
+      chai: 6.2.2
+      tinyrainbow: 3.1.0
+
+  
'@vitest/[email protected]([email protected](@types/[email protected])([email protected])([email protected]))':
+    dependencies:
+      '@vitest/spy': 4.1.7
+      estree-walker: 3.0.3
+      magic-string: 0.30.21
+    optionalDependencies:
+      vite: 8.0.10(@types/[email protected])([email protected])([email protected])
+
+  '@vitest/[email protected]':
+    dependencies:
+      tinyrainbow: 3.1.0
+
+  '@vitest/[email protected]':
+    dependencies:
+      '@vitest/utils': 4.1.7
+      pathe: 2.0.3
+
+  '@vitest/[email protected]':
+    dependencies:
+      '@vitest/pretty-format': 4.1.7
+      '@vitest/utils': 4.1.7
+      magic-string: 0.30.21
+      pathe: 2.0.3
+
+  '@vitest/[email protected]': {}
+
+  '@vitest/[email protected]':
+    dependencies:
+      '@vitest/pretty-format': 4.1.7
+      convert-source-map: 2.0.0
+      tinyrainbow: 3.1.0
+
+  [email protected]([email protected]):
+    dependencies:
+      acorn: 8.16.0
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      fast-deep-equal: 3.1.3
+      fast-json-stable-stringify: 2.1.0
+      json-schema-traverse: 0.4.1
+      uri-js: 4.4.1
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      '@jridgewell/trace-mapping': 0.3.31
+      estree-walker: 3.0.3
+      js-tokens: 10.0.0
+    optional: true
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      balanced-match: 4.0.4
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      path-key: 3.1.1
+      shebang-command: 2.0.0
+      which: 2.0.2
+
+  [email protected]:
+    dependencies:
+      ms: 2.1.3
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    optionalDependencies:
+      '@esbuild/aix-ppc64': 0.27.7
+      '@esbuild/android-arm': 0.27.7
+      '@esbuild/android-arm64': 0.27.7
+      '@esbuild/android-x64': 0.27.7
+      '@esbuild/darwin-arm64': 0.27.7
+      '@esbuild/darwin-x64': 0.27.7
+      '@esbuild/freebsd-arm64': 0.27.7
+      '@esbuild/freebsd-x64': 0.27.7
+      '@esbuild/linux-arm': 0.27.7
+      '@esbuild/linux-arm64': 0.27.7
+      '@esbuild/linux-ia32': 0.27.7
+      '@esbuild/linux-loong64': 0.27.7
+      '@esbuild/linux-mips64el': 0.27.7
+      '@esbuild/linux-ppc64': 0.27.7
+      '@esbuild/linux-riscv64': 0.27.7
+      '@esbuild/linux-s390x': 0.27.7
+      '@esbuild/linux-x64': 0.27.7
+      '@esbuild/netbsd-arm64': 0.27.7
+      '@esbuild/netbsd-x64': 0.27.7
+      '@esbuild/openbsd-arm64': 0.27.7
+      '@esbuild/openbsd-x64': 0.27.7
+      '@esbuild/openharmony-arm64': 0.27.7
+      '@esbuild/sunos-x64': 0.27.7
+      '@esbuild/win32-arm64': 0.27.7
+      '@esbuild/win32-ia32': 0.27.7
+      '@esbuild/win32-x64': 0.27.7
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      '@types/esrecurse': 4.3.1
+      '@types/estree': 1.0.8
+      esrecurse: 4.3.0
+      estraverse: 5.3.0
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      '@eslint-community/eslint-utils': 4.9.1([email protected])
+      '@eslint-community/regexpp': 4.12.2
+      '@eslint/config-array': 0.23.5
+      '@eslint/config-helpers': 0.6.0
+      '@eslint/core': 1.2.1
+      '@eslint/plugin-kit': 0.7.1
+      '@humanfs/node': 0.16.8
+      '@humanwhocodes/module-importer': 1.0.1
+      '@humanwhocodes/retry': 0.4.3
+      '@types/estree': 1.0.8
+      ajv: 6.15.0
+      cross-spawn: 7.0.6
+      debug: 4.4.3
+      escape-string-regexp: 4.0.0
+      eslint-scope: 9.1.2
+      eslint-visitor-keys: 5.0.1
+      espree: 11.2.0
+      esquery: 1.7.0
+      esutils: 2.0.3
+      fast-deep-equal: 3.1.3
+      file-entry-cache: 8.0.0
+      find-up: 5.0.0
+      glob-parent: 6.0.2
+      ignore: 5.3.2
+      imurmurhash: 0.1.4
+      is-glob: 4.0.3
+      json-stable-stringify-without-jsonify: 1.0.1
+      minimatch: 10.2.5
+      natural-compare: 1.4.0
+      optionator: 0.9.4
+    transitivePeerDependencies:
+      - supports-color
+
+  [email protected]:
+    dependencies:
+      acorn: 8.16.0
+      acorn-jsx: 5.3.2([email protected])
+      eslint-visitor-keys: 5.0.1
+
+  [email protected]:
+    dependencies:
+      estraverse: 5.3.0
+
+  [email protected]:
+    dependencies:
+      estraverse: 5.3.0
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      '@types/estree': 1.0.8
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]([email protected]):
+    optionalDependencies:
+      picomatch: 4.0.4
+
+  [email protected]:
+    dependencies:
+      flat-cache: 4.0.1
+
+  [email protected]:
+    dependencies:
+      locate-path: 6.0.0
+      path-exists: 4.0.0
+
+  [email protected]:
+    dependencies:
+      flatted: 3.4.2
+      keyv: 4.5.4
+
+  [email protected]: {}
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    dependencies:
+      resolve-pkg-maps: 1.0.0
+
+  [email protected]:
+    dependencies:
+      is-glob: 4.0.3
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      is-extglob: 2.1.1
+
+  [email protected]: {}
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    dependencies:
+      istanbul-lib-coverage: 3.2.2
+      make-dir: 4.0.0
+      supports-color: 7.2.0
+    optional: true
+
+  [email protected]:
+    dependencies:
+      html-escaper: 2.0.2
+      istanbul-lib-report: 3.0.1
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      json-buffer: 3.0.1
+
+  [email protected]:
+    dependencies:
+      prelude-ls: 1.2.1
+      type-check: 0.4.0
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    dependencies:
+      detect-libc: 2.1.2
+    optionalDependencies:
+      lightningcss-android-arm64: 1.32.0
+      lightningcss-darwin-arm64: 1.32.0
+      lightningcss-darwin-x64: 1.32.0
+      lightningcss-freebsd-x64: 1.32.0
+      lightningcss-linux-arm-gnueabihf: 1.32.0
+      lightningcss-linux-arm64-gnu: 1.32.0
+      lightningcss-linux-arm64-musl: 1.32.0
+      lightningcss-linux-x64-gnu: 1.32.0
+      lightningcss-linux-x64-musl: 1.32.0
+      lightningcss-win32-arm64-msvc: 1.32.0
+      lightningcss-win32-x64-msvc: 1.32.0
+
+  [email protected]:
+    dependencies:
+      p-locate: 5.0.0
+
+  [email protected]:
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.5.5
+
+  [email protected]:
+    dependencies:
+      '@babel/parser': 7.29.7
+      '@babel/types': 7.29.7
+      source-map-js: 1.2.1
+    optional: true
+
+  [email protected]:
+    dependencies:
+      semver: 7.8.1
+    optional: true
+
+  [email protected]:
+    dependencies:
+      brace-expansion: 5.0.6
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      deep-is: 0.1.4
+      fast-levenshtein: 2.0.6
+      levn: 0.4.1
+      prelude-ls: 1.2.1
+      type-check: 0.4.0
+      word-wrap: 1.2.5
+
+  [email protected]:
+    dependencies:
+      yocto-queue: 0.1.0
+
+  [email protected]:
+    dependencies:
+      p-limit: 3.1.0
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      nanoid: 3.3.11
+      picocolors: 1.1.1
+      source-map-js: 1.2.1
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      '@oxc-project/types': 0.127.0
+      '@rolldown/pluginutils': 1.0.0-rc.17
+    optionalDependencies:
+      '@rolldown/binding-android-arm64': 1.0.0-rc.17
+      '@rolldown/binding-darwin-arm64': 1.0.0-rc.17
+      '@rolldown/binding-darwin-x64': 1.0.0-rc.17
+      '@rolldown/binding-freebsd-x64': 1.0.0-rc.17
+      '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17
+      '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17
+      '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17
+      '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17
+      '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17
+      '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17
+      '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17
+      '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17
+      '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17
+      '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17
+      '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      shebang-regex: 3.0.0
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      has-flag: 4.0.0
+    optional: true
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      fdir: 6.5.0([email protected])
+      picomatch: 4.0.4
+
+  [email protected]: {}
+
+  [email protected]([email protected]):
+    dependencies:
+      typescript: 6.0.3
+
+  [email protected]:
+    optional: true
+
+  [email protected]:
+    dependencies:
+      esbuild: 0.27.7
+      get-tsconfig: 4.14.0
+    optionalDependencies:
+      fsevents: 2.3.3
+
+  [email protected]:
+    dependencies:
+      prelude-ls: 1.2.1
+
+  [email protected]([email protected])([email protected]):
+    dependencies:
+      '@typescript-eslint/eslint-plugin': 
8.60.0(@typescript-eslint/[email protected]([email protected])([email protected]))([email protected])([email protected])
+      '@typescript-eslint/parser': 8.60.0([email protected])([email protected])
+      '@typescript-eslint/typescript-estree': 8.60.0([email protected])
+      '@typescript-eslint/utils': 8.60.0([email protected])([email protected])
+      eslint: 10.4.0
+      typescript: 6.0.3
+    transitivePeerDependencies:
+      - supports-color
+
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      punycode: 2.3.1
+
+  [email protected](@types/[email protected])([email protected])([email protected]):
+    dependencies:
+      lightningcss: 1.32.0
+      picomatch: 4.0.4
+      postcss: 8.5.12
+      rolldown: 1.0.0-rc.17
+      tinyglobby: 0.2.16
+    optionalDependencies:
+      '@types/node': 22.19.17
+      esbuild: 0.27.7
+      fsevents: 2.3.3
+      tsx: 4.21.0
+
+  
[email protected](@types/[email protected])(@vitest/[email protected])([email protected](@types/[email protected])([email protected])([email protected])):
+    dependencies:
+      '@vitest/expect': 4.1.7
+      '@vitest/mocker': 
4.1.7([email protected](@types/[email protected])([email protected])([email protected]))
+      '@vitest/pretty-format': 4.1.7
+      '@vitest/runner': 4.1.7
+      '@vitest/snapshot': 4.1.7
+      '@vitest/spy': 4.1.7
+      '@vitest/utils': 4.1.7
+      es-module-lexer: 2.1.0
+      expect-type: 1.3.0
+      magic-string: 0.30.21
+      obug: 2.1.1
+      pathe: 2.0.3
+      picomatch: 4.0.4
+      std-env: 4.1.0
+      tinybench: 2.9.0
+      tinyexec: 1.1.1
+      tinyglobby: 0.2.16
+      tinyrainbow: 3.1.0
+      vite: 8.0.10(@types/[email protected])([email protected])([email protected])
+      why-is-node-running: 2.3.0
+    optionalDependencies:
+      '@types/node': 22.19.17
+      '@vitest/coverage-v8': 4.1.7([email protected])
+    transitivePeerDependencies:
+      - msw
+
+  [email protected]:
+    dependencies:
+      isexe: 2.0.0
+
+  [email protected]:
+    dependencies:
+      siginfo: 2.0.0
+      stackback: 0.0.2
+
+  [email protected]: {}
+
+  [email protected]: {}
diff --git a/ts-sdk/scripts/ci/prek/ts_sdk_lint.py 
b/ts-sdk/scripts/ci/prek/ts_sdk_lint.py
new file mode 100644
index 00000000000..c46ccc81d85
--- /dev/null
+++ b/ts-sdk/scripts/ci/prek/ts_sdk_lint.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import sys
+from pathlib import Path
+
+sys.path.insert(0, str(Path(__file__).resolve().parents[4] / "scripts" / "ci" 
/ "prek"))
+
+from common_prek_utils import AIRFLOW_ROOT_PATH, run_command
+
+if __name__ not in ("__main__", "__mp_main__"):
+    raise SystemExit(
+        "This file is intended to be executed as an executable program. You 
cannot use it as a module."
+        f"To run this script, run the ./{__file__} command"
+    )
+
+if __name__ == "__main__":
+    directory = AIRFLOW_ROOT_PATH / "ts-sdk"
+    run_command(["pnpm", "config", "set", "store-dir", ".pnpm-store"], 
cwd=directory)
+    run_command(["pnpm", "install", "--frozen-lockfile", 
"--config.confirmModulesPurge=false"], cwd=directory)
+    run_command(["pnpm", "run", "lint:fix"], cwd=directory)
+    run_command(["pnpm", "run", "format"], cwd=directory)
+    run_command(["pnpm", "run", "typecheck"], cwd=directory)
diff --git a/ts-sdk/src/index.ts b/ts-sdk/src/index.ts
new file mode 100644
index 00000000000..30d79bfef85
--- /dev/null
+++ b/ts-sdk/src/index.ts
@@ -0,0 +1,25 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export { registerTask, listRegisteredTasks } from "./sdk/registry.js";
+export { VariableNotFoundError } from "./sdk/client.js";
+export type { TaskClient } from "./sdk/client.js";
+export type { ConnectionResult, GetXComOpts, JsonValue, SetXComOpts } from 
"./sdk/client-types.js";
+export type { TaskRegistration } from "./sdk/registry.js";
+export type { TaskContext, TaskHandler, TaskHandlerArgs } from "./sdk/task.js";
diff --git a/ts-sdk/src/sdk/client-types.ts b/ts-sdk/src/sdk/client-types.ts
new file mode 100644
index 00000000000..23b8e7060ea
--- /dev/null
+++ b/ts-sdk/src/sdk/client-types.ts
@@ -0,0 +1,68 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/** JSON-compatible value accepted by Airflow for XCom payloads. */
+export type JsonValue =
+  | string
+  | number
+  | boolean
+  | null
+  | JsonValue[]
+  | { [key: string]: JsonValue };
+
+/**
+ * Options for pulling an XCom value.
+ *
+ * `dagId`, `taskId`, and `runId` default to the running task's context.
+ * Pass them only when pulling an XCom value from another task or run.
+ */
+export interface GetXComOpts {
+  key: string;
+  dagId?: string;
+  runId?: string;
+  taskId?: string;
+  mapIndex?: number | null;
+  includePriorDates?: boolean;
+}
+
+/**
+ * Options for pushing an XCom value.
+ *
+ * `dagId`, `taskId`, and `runId` default to the running task's context.
+ */
+export interface SetXComOpts {
+  key: string;
+  value: JsonValue;
+  dagId?: string;
+  runId?: string;
+  taskId?: string;
+  mapIndex?: number | null;
+}
+
+/** Airflow Connection details returned by a task client. */
+export interface ConnectionResult {
+  id: string;
+  type: string;
+  host?: string | null;
+  schema?: string | null;
+  login?: string | null;
+  password?: string | null;
+  port?: number | null;
+  extra?: string | null;
+}
diff --git a/ts-sdk/src/sdk/client.ts b/ts-sdk/src/sdk/client.ts
new file mode 100644
index 00000000000..461dc01f637
--- /dev/null
+++ b/ts-sdk/src/sdk/client.ts
@@ -0,0 +1,88 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import type { ConnectionResult, GetXComOpts, SetXComOpts } from 
"./client-types.js";
+
+/**
+ * Client for reading and writing Airflow task-time data from a task handler.
+ *
+ * The active runtime selects the concrete transport and implements this
+ * interface for the current task attempt.
+ */
+export interface TaskClient {
+  /**
+   * Look up an Airflow Variable.
+   *
+   * Returns `null` when the key is missing or stored with a null value.
+   * Throws on any other error.
+   *
+   * This is intentionally JS-friendly behavior. Use
+   * {@link getVariableOrThrow} when missing variables should raise.
+   */
+  getVariable(key: string): Promise<string | null>;
+
+  /**
+   * Look up an Airflow Variable and raise when it is missing.
+   *
+   * This matches Python `Variable.get` behavior when no default value is
+   * supplied.
+   *
+   * @throws {@link VariableNotFoundError} when the key is missing.
+   */
+  getVariableOrThrow(key: string): Promise<string>;
+
+  /**
+   * Pull an XCom value.
+   *
+   * Returns `null` when the row is missing. Locator fields default to the
+   * current task's context.
+   *
+   * The generic `T` lets callers narrow the return type when the shape is
+   * known:
+   *
+   * ```ts
+   * const data = await client.getXCom<{ count: number }>({ key: "result" });
+   * // data is { count: number } | null
+   * ```
+   */
+  getXCom<T = unknown>(opts: GetXComOpts): Promise<T | null>;
+
+  /**
+   * Push an XCom value.
+   *
+   * Target fields default to the current task's context.
+   */
+  setXCom(opts: SetXComOpts): Promise<void>;
+
+  /**
+   * Look up an Airflow Connection by ID.
+   *
+   * Returns `null` when the connection does not exist. Throws on any other
+   * error.
+   */
+  getConnection(connId: string): Promise<ConnectionResult | null>;
+}
+
+/** Error thrown by {@link TaskClient.getVariableOrThrow}. */
+export class VariableNotFoundError extends Error {
+  constructor(public readonly key: string) {
+    super(`Variable not found: ${key}`);
+    this.name = "VariableNotFoundError";
+  }
+}
diff --git a/ts-sdk/src/sdk/registry.ts b/ts-sdk/src/sdk/registry.ts
new file mode 100644
index 00000000000..4d701721dae
--- /dev/null
+++ b/ts-sdk/src/sdk/registry.ts
@@ -0,0 +1,90 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import type { TaskHandler } from "./task.js";
+
+/** Identifies the Airflow task handled by a TypeScript function. */
+export interface TaskRegistration {
+  /** Identifier of the Dag containing this task. */
+  readonly dagId: string;
+  /** Airflow task ID, including any TaskGroup prefix. */
+  readonly taskId: string;
+}
+
+/** Registry of TypeScript task handlers keyed by Dag ID and task ID. */
+export class TaskRegistry {
+  readonly #tasks = new Map<string, Map<string, TaskHandler>>();
+
+  /**
+   * Register a TypeScript handler for an Airflow task.
+   *
+   * `dagId` must match the Python Dag's `dag_id`. `taskId` must match the
+   * Dag-side operator's `task_id` exactly, including any TaskGroup prefix.
+   */
+  register<TReturn = unknown>(registration: TaskRegistration, handler: 
TaskHandler<TReturn>): void {
+    const { dagId, taskId } = registration;
+    if (!dagId || typeof dagId !== "string") {
+      throw new Error("dagId must be a non-empty string");
+    }
+    if (!taskId || typeof taskId !== "string") {
+      throw new Error("taskId must be a non-empty string");
+    }
+    if (typeof handler !== "function") {
+      throw new Error(`handler for Dag "${dagId}" task "${taskId}" must be a 
function`);
+    }
+    const dagTasks = this.#tasks.get(dagId) ?? new Map<string, TaskHandler>();
+    if (dagTasks.has(taskId)) {
+      throw new Error(`Task "${taskId}" is already registered for Dag 
"${dagId}"`);
+    }
+    dagTasks.set(taskId, handler as TaskHandler);
+    this.#tasks.set(dagId, dagTasks);
+  }
+
+  /** Look up a registered handler. Returns `undefined` when no handler 
exists. */
+  get(dagId: string, taskId: string): TaskHandler | undefined {
+    return this.#tasks.get(dagId)?.get(taskId);
+  }
+
+  /** List all registered tasks. */
+  list(): TaskRegistration[] {
+    return [...this.#tasks.entries()].flatMap(([dagId, tasks]) =>
+      [...tasks.keys()].map((taskId) => ({ dagId, taskId })),
+    );
+  }
+}
+
+const defaultRegistry = new TaskRegistry();
+
+/** Register a TypeScript handler in the default task registry. */
+export function registerTask<TReturn = unknown>(
+  registration: TaskRegistration,
+  handler: TaskHandler<TReturn>,
+): void {
+  defaultRegistry.register(registration, handler);
+}
+
+/** Look up a registered handler. Returns `undefined` when no handler exists. 
*/
+export function getRegisteredTask(dagId: string, taskId: string): TaskHandler 
| undefined {
+  return defaultRegistry.get(dagId, taskId);
+}
+
+/** List all registered tasks. */
+export function listRegisteredTasks(): TaskRegistration[] {
+  return defaultRegistry.list();
+}
diff --git a/ts-sdk/src/sdk/task.ts b/ts-sdk/src/sdk/task.ts
new file mode 100644
index 00000000000..a61638745d4
--- /dev/null
+++ b/ts-sdk/src/sdk/task.ts
@@ -0,0 +1,61 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// The task-handler call surface — types every user task handler sees.
+
+import type { TaskClient } from "./client.js";
+
+/** Runtime metadata for the current task invocation. */
+export interface TaskContext {
+  /** Identifier of the Dag containing this task. */
+  readonly dagId: string;
+  /** Task ID for this handler invocation, including any TaskGroup prefix. */
+  readonly taskId: string;
+  /** Dag run identifier for the current task attempt. */
+  readonly runId: string;
+  /** Airflow try number for the current task attempt. */
+  readonly tryNumber: number;
+  /** -1 for non-mapped tasks, 0..N-1 for mapped instances. */
+  readonly mapIndex: number;
+  /**
+   * AbortSignal that fires when Airflow terminates the task subprocess
+   * with SIGTERM or SIGINT.
+   *
+   * Pass this signal to `fetch()`, timers, or other abortable APIs for
+   * cooperative cancellation and cleanup.
+   */
+  readonly signal: AbortSignal;
+}
+
+/** Arguments passed to every task handler. */
+export interface TaskHandlerArgs {
+  /** Runtime metadata for the current task invocation. */
+  readonly ctx: TaskContext;
+  /** Client for reading and writing Airflow task-time data. */
+  readonly client: TaskClient;
+}
+
+/**
+ * Function signature for a TypeScript task handler.
+ *
+ * Non-`undefined` return values are automatically pushed to XCom under
+ * the `"return_value"` key, matching Python `@task` behavior. Return
+ * `undefined` or omit a return value to skip the automatic XCom push.
+ */
+export type TaskHandler<TReturn = unknown> = (args: TaskHandlerArgs) => 
TReturn | Promise<TReturn>;
diff --git a/ts-sdk/tests/public-api.test.ts b/ts-sdk/tests/public-api.test.ts
new file mode 100644
index 00000000000..1243092a9b4
--- /dev/null
+++ b/ts-sdk/tests/public-api.test.ts
@@ -0,0 +1,133 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { describe, expect, expectTypeOf, it } from "vitest";
+import type {
+  ConnectionResult,
+  GetXComOpts,
+  SetXComOpts,
+  TaskClient,
+  TaskContext,
+  TaskRegistration,
+} from "../src/index.js";
+import { listRegisteredTasks, registerTask, VariableNotFoundError } from 
"../src/index.js";
+
+describe("public API", () => {
+  it("exports task registration helpers", () => {
+    const registration = { dagId: "public_api_dag", taskId: "public_api_task" 
};
+    registerTask(registration, async () => undefined);
+    expect(listRegisteredTasks()).toContainEqual(registration);
+  });
+
+  it("exports public error classes", () => {
+    const err = new VariableNotFoundError("missing");
+    expect(err).toBeInstanceOf(Error);
+    expect(err.name).toBe("VariableNotFoundError");
+    expect(err.key).toBe("missing");
+  });
+
+  it("uses idiomatic TypeScript names for public client types", () => {
+    expectTypeOf<TaskRegistration>().toEqualTypeOf<{
+      readonly dagId: string;
+      readonly taskId: string;
+    }>();
+    expectTypeOf<TaskContext>().toEqualTypeOf<{
+      readonly dagId: string;
+      readonly taskId: string;
+      readonly runId: string;
+      readonly tryNumber: number;
+      readonly mapIndex: number;
+      readonly signal: AbortSignal;
+    }>();
+    expectTypeOf<GetXComOpts>().toEqualTypeOf<{
+      key: string;
+      dagId?: string;
+      runId?: string;
+      taskId?: string;
+      mapIndex?: number | null;
+      includePriorDates?: boolean;
+    }>();
+    expectTypeOf<SetXComOpts>().toEqualTypeOf<{
+      key: string;
+      value: SetXComOpts["value"];
+      dagId?: string;
+      runId?: string;
+      taskId?: string;
+      mapIndex?: number | null;
+    }>();
+    expectTypeOf<ConnectionResult>().toEqualTypeOf<{
+      id: string;
+      type: string;
+      host?: string | null;
+      schema?: string | null;
+      login?: string | null;
+      password?: string | null;
+      port?: number | null;
+      extra?: string | null;
+    }>();
+    expectTypeOf<TaskClient["getConnection"]>().toEqualTypeOf<
+      (connId: string) => Promise<ConnectionResult | null>
+    >();
+    expectTypeOf<TaskClient["getXCom"]>().toEqualTypeOf<
+      <T = unknown>(opts: GetXComOpts) => Promise<T | null>
+    >();
+  });
+
+  it("rejects wire-format names and non-JSON XCom values", () => {
+    function acceptsGetXComOpts(_opts: GetXComOpts): void {}
+    function acceptsSetXComOpts(_opts: SetXComOpts): void {}
+    function acceptsTaskRegistration(_registration: TaskRegistration): void {}
+
+    // TODO: Add coordinator-runtime tests that validate these camelCase
+    // public options map to the supervisor schema's snake_case fields.
+    acceptsGetXComOpts({
+      key: "result",
+      dagId: "example",
+      runId: "manual__2026-01-01T00:00:00+00:00",
+      taskId: "extract",
+      mapIndex: 0,
+      includePriorDates: true,
+    });
+    acceptsSetXComOpts({
+      key: "result",
+      value: { count: 1 },
+      dagId: "example",
+      runId: "manual__2026-01-01T00:00:00+00:00",
+      taskId: "extract",
+      mapIndex: null,
+    });
+
+    // @ts-expect-error public options use dagId, not dag_id.
+    acceptsGetXComOpts({ key: "result", dag_id: "example" });
+    // @ts-expect-error public options use includePriorDates, not 
include_prior_dates.
+    acceptsGetXComOpts({ key: "result", include_prior_dates: true });
+    // @ts-expect-error public ConnectionResult uses id/type, not wire-format 
names.
+    expectTypeOf<ConnectionResult>().toEqualTypeOf<{ conn_id: string; 
conn_type: string }>();
+    // @ts-expect-error public ConnectionResult uses id/type, not 
connId/connType.
+    expectTypeOf<ConnectionResult>().toEqualTypeOf<{ connId: string; connType: 
string }>();
+    // @ts-expect-error public TaskContext does not expose the raw 
task-instance id.
+    expectTypeOf<TaskContext>().toHaveProperty("taskInstanceId");
+    // @ts-expect-error task registration requires explicit dagId/taskId 
fields.
+    acceptsTaskRegistration("public_api_task");
+    // @ts-expect-error task registration uses dagId, not dag_id.
+    acceptsTaskRegistration({ dag_id: "example", taskId: "extract" });
+    // @ts-expect-error XCom values must be JSON-compatible.
+    acceptsSetXComOpts({ key: "result", value: new Date() });
+  });
+});
diff --git a/ts-sdk/tests/sdk/registry.test.ts 
b/ts-sdk/tests/sdk/registry.test.ts
new file mode 100644
index 00000000000..8cadc09c4f9
--- /dev/null
+++ b/ts-sdk/tests/sdk/registry.test.ts
@@ -0,0 +1,104 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { describe, it, expect } from "vitest";
+import { TaskRegistry } from "../../src/sdk/registry.js";
+
+describe("registry", () => {
+  it("registers and retrieves a handler", async () => {
+    const registry = new TaskRegistry();
+    const handler = async () => "hello";
+    registry.register({ dagId: "example_dag", taskId: "my_task" }, handler);
+    const got = registry.get("example_dag", "my_task");
+    expect(got).toBe(handler);
+  });
+
+  it("returns undefined for unknown taskIds", () => {
+    const registry = new TaskRegistry();
+    expect(registry.get("example_dag", "nope")).toBeUndefined();
+    expect(registry.get("unknown_dag", "my_task")).toBeUndefined();
+  });
+
+  it("returns an empty list when no tasks are registered", () => {
+    const registry = new TaskRegistry();
+    expect(registry.list()).toEqual([]);
+  });
+
+  it("lists registered tasks", () => {
+    const registry = new TaskRegistry();
+    registry.register({ dagId: "dag_a", taskId: "a" }, async () => undefined);
+    registry.register({ dagId: "dag_b", taskId: "b" }, async () => undefined);
+    const registered = registry.list();
+    expect(registered).toHaveLength(2);
+    expect(registered).toContainEqual({ dagId: "dag_a", taskId: "a" });
+    expect(registered).toContainEqual({ dagId: "dag_b", taskId: "b" });
+  });
+
+  it("rejects duplicate registration within a Dag", () => {
+    const registry = new TaskRegistry();
+    registry.register({ dagId: "example_dag", taskId: "dup" }, async () => 
undefined);
+    expect(() =>
+      registry.register({ dagId: "example_dag", taskId: "dup" }, async () => 
undefined),
+    ).toThrowError(/already registered/);
+  });
+
+  it("allows the same taskId in different Dags", () => {
+    const registry = new TaskRegistry();
+    const first = async () => "first";
+    const second = async () => "second";
+    registry.register({ dagId: "first_dag", taskId: "extract" }, first);
+    registry.register({ dagId: "second_dag", taskId: "extract" }, second);
+
+    expect(registry.get("first_dag", "extract")).toBe(first);
+    expect(registry.get("second_dag", "extract")).toBe(second);
+  });
+
+  it("rejects an empty dagId", () => {
+    const registry = new TaskRegistry();
+    expect(() =>
+      registry.register({ dagId: "", taskId: "my_task" }, async () => 
undefined),
+    ).toThrowError(/dagId must be a non-empty string/);
+  });
+
+  it("rejects an empty taskId", () => {
+    const registry = new TaskRegistry();
+    expect(() =>
+      registry.register({ dagId: "example_dag", taskId: "" }, async () => 
undefined),
+    ).toThrowError(/taskId must be a non-empty string/);
+  });
+
+  it("rejects non-function handlers", () => {
+    const registry = new TaskRegistry();
+    expect(() =>
+      registry.register(
+        { dagId: "example_dag", taskId: "x" },
+        "not a function" as unknown as () => Promise<unknown>,
+      ),
+    ).toThrowError(/must be a function/);
+  });
+
+  it("treats a dotted TaskGroup taskId as a single taskId (group.task)", () => 
{
+    const registry = new TaskRegistry();
+    registry.register({ dagId: "example_dag", taskId: "transforms.normalize" 
}, async () => "ok");
+    expect(registry.get("example_dag", "transforms.normalize")).toBeDefined();
+    // Should NOT accidentally match the prefix alone
+    expect(registry.get("example_dag", "transforms")).toBeUndefined();
+    expect(registry.get("example_dag", "normalize")).toBeUndefined();
+  });
+});
diff --git a/ts-sdk/tsconfig.build.json b/ts-sdk/tsconfig.build.json
new file mode 100644
index 00000000000..7685d3fb626
--- /dev/null
+++ b/ts-sdk/tsconfig.build.json
@@ -0,0 +1,10 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "noEmit": false,
+    "outDir": "./dist",
+    "rootDir": "./src"
+  },
+  "include": ["src/**/*.ts"],
+  "exclude": ["src/**/*.test.ts", "tests/**/*"]
+}
diff --git a/ts-sdk/tsconfig.json b/ts-sdk/tsconfig.json
new file mode 100644
index 00000000000..d1c294a5f23
--- /dev/null
+++ b/ts-sdk/tsconfig.json
@@ -0,0 +1,27 @@
+{
+  "compilerOptions": {
+    "target": "es2023",
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",
+    "moduleDetection": "force",
+    "lib": ["es2023"],
+    "types": ["node"],
+
+    "strict": true,
+    "noUncheckedIndexedAccess": true,
+    "verbatimModuleSyntax": true,
+    "noFallthroughCasesInSwitch": true,
+    "forceConsistentCasingInFileNames": true,
+
+    "esModuleInterop": true,
+    "isolatedModules": true,
+    "resolveJsonModule": true,
+    "skipLibCheck": true,
+
+    "noEmit": true,
+    "declaration": true,
+    "declarationMap": true,
+    "sourceMap": true
+  },
+  "include": ["src/**/*.ts", "tests/**/*.ts"]
+}
diff --git a/ts-sdk/vitest.config.ts b/ts-sdk/vitest.config.ts
new file mode 100644
index 00000000000..d8c2aeb8d2b
--- /dev/null
+++ b/ts-sdk/vitest.config.ts
@@ -0,0 +1,26 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { defineConfig } from "vitest/config";
+
+export default defineConfig({
+  test: {
+    include: ["tests/**/*.test.ts"],
+  },
+});

Reply via email to