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

tbonelee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new d75de68ed8 [ZEPPELIN-6648] Add unit test conventions and coverage 
reporting for the new UI
d75de68ed8 is described below

commit d75de68ed8ac9783a2138ad561b3ab4d78422ed7
Author: YONGJAE LEE (이용재) <[email protected]>
AuthorDate: Wed Aug 26 00:38:15 2026 +0900

    [ZEPPELIN-6648] Add unit test conventions and coverage reporting for the 
new UI
    
    ### What is this PR for?
    ZEPPELIN-6567 gave `zeppelin-web-angular` a self-contained Vitest/jsdom 
setup, and `test:shell` runs in the Maven `test` phase. Almost nothing runs on 
it: `src/` holds 222 source files and two specs, and the five specs under 
`projects/zeppelin-react` cover theme helpers and two components.
    
    The root `AGENTS.md` asks every change to include unit tests without saying 
how to write one, there is no coverage reporting on the unit side, and nothing 
stops a spec that cannot fail from being merged — the e2e suite gets that 
protection from `eslint-plugin-playwright`, the unit side had no equivalent.
    
    This adds the conventions, the measurement, the enforcement, and three 
example specs so the conventions have something to point at.
    
    * `AGENTS.md` for the package, following the shape of `e2e/AGENTS.md`. It 
is the baseline for `src/` and for the two libraries under `projects/` that 
have no file of their own. A second file under `projects/zeppelin-react` 
records only what differs there, so a rule has one home rather than two copies 
that drift.
    * Coverage via `<at>vitest/coverage-v8` on both sides. Reported, not gated: 
with a handful of specs in the tree any threshold set today is either 
meaningless or permanently red. Coverage sets no `include` — naming a directory 
makes the provider parse every source under it, and decorator syntax fails 
there while ZEPPELIN-6637 is open. Coverage parses through a separate path from 
the test transform, so widening it after 6637 needs re-checking rather than 
assuming it follows.
    * Vitest lint rules on every unit spec in the package. These catch specs 
that cannot fail: no assertion, an assertion inside a conditional, a duplicate 
title, a stray `it.only`. The React remote gets them too; its lint runs on 
every pull request through `lint:react` — inside the `run-playwright-e2e-tests` 
job, since `frontend.yml` builds this module with `-DskipTests` — so they take 
effect there immediately even though its test suite does not run in CI yet.
    * `test:shell` now also covers `projects/zeppelin-sdk` and 
`projects/zeppelin-visualization`. Neither needs a runner of its own, but until 
now a spec added there would have sat unrun, and the lint rules would not have 
reached it either.
    * `e2e/AGENTS.md` gains one corrected line: it is no longer a companion to 
the repository root, but to this package file.
    * `vite` is now pinned in both `package.json` files. Neither declared it, 
so vitest's transitive resolution had drifted — 8.2.1 in the shell, 8.0.16 in 
the remote — and a config warning fired in one but not the other. Aligning the 
remote surfaces that warning, so `vitest.config.ts` becomes `.mts`, matching 
the shell config. 36 tests pass on either version and coverage is unchanged; 
this is version hygiene, not a fix. It rides along because this change already 
touches both `package.jso [...]
    
    One thing the exercise turned up: `get-keyword-positions` and the 
`line-map` module it builds on have no callers. The spec is kept as a worked 
example and says so at the top; whether to keep or remove the code is left to a 
follow-up.
    
    Scope is deliberately limited to code that can be tested today. 
TestBed-based component specs need ZEPPELIN-6637, and wiring the React suite 
into regular pull-request CI is ZEPPELIN-6566.
    
    ### What type of PR is it?
    Improvement
    
    ### Todos
    * [x] `AGENTS.md` for the package and for the React remote
    * [x] Coverage reporting on both sides, no thresholds
    * [x] Vitest lint rules on both sides
    * [x] Example specs for `get-keyword-positions`, `HumanizeBytesPipe` and 
`textUtils`
    * [x] Reach `projects/zeppelin-sdk` and `projects/zeppelin-visualization` 
from the runner, the spec tsconfig and lint
    * [x] Pin `vite` in both packages and rename the remote's vitest config to 
`.mts`
    
    ### What is the Jira issue?
    ZEPPELIN-6648
    
    ### How should this be tested?
    ```
    cd zeppelin-web-angular
    npm run test:shell                 # 19 tests
    npm run test:shell -- --coverage   # report under coverage/, no gate
    npm run lint                       # includes lint:react
    
    cd projects/zeppelin-react
    npm test                           # 36 tests
    ```
    To confirm the lint rules bite, add a spec with no assertion to either 
package and run the matching lint command; it is reported as an error.
    
    ### Screenshots (if appropriate)
    N/A
    
    ### Questions:
    * Does the license files need to update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No, the added `AGENTS.md` files are the 
documentation
    
    
    
    
    Closes #5433 from voidmatcha/unit-test-conventions.
    
    Signed-off-by: ChanHo Lee <[email protected]>
---
 zeppelin-web-angular/.prettierignore               |    1 +
 zeppelin-web-angular/AGENTS.md                     |  138 ++
 zeppelin-web-angular/e2e/AGENTS.md                 |    2 +-
 zeppelin-web-angular/eslint.config.js              |   23 +-
 zeppelin-web-angular/package-lock.json             | 1491 ++++----------------
 zeppelin-web-angular/package.json                  |    3 +
 .../projects/zeppelin-react/.gitignore             |    1 +
 .../projects/zeppelin-react/AGENTS.md              |   54 +
 .../projects/zeppelin-react/eslint.config.js       |   16 +
 .../projects/zeppelin-react/package-lock.json      |  560 +++++---
 .../projects/zeppelin-react/package.json           |    3 +
 .../zeppelin-react/src/utils/textUtils.spec.ts     |   45 +
 .../{vitest.config.ts => vitest.config.mts}        |   17 +-
 .../app/share/pipes/humanize-bytes.pipe.spec.ts    |   53 +
 .../src/app/utility/get-keyword-positions.spec.ts  |   59 +
 zeppelin-web-angular/src/tsconfig.spec.json        |    8 +-
 zeppelin-web-angular/vitest.shell.config.mts       |   14 +-
 17 files changed, 1030 insertions(+), 1458 deletions(-)

diff --git a/zeppelin-web-angular/.prettierignore 
b/zeppelin-web-angular/.prettierignore
index cf9d45a672..a16d95f394 100644
--- a/zeppelin-web-angular/.prettierignore
+++ b/zeppelin-web-angular/.prettierignore
@@ -11,6 +11,7 @@ target/*
 tslint-rules/**/*.js
 
 coverage/*
+projects/*/coverage/*
 playwright-report/*
 playwright-coverage/*
 test-results/*
diff --git a/zeppelin-web-angular/AGENTS.md b/zeppelin-web-angular/AGENTS.md
new file mode 100644
index 0000000000..c6fbaf21ba
--- /dev/null
+++ b/zeppelin-web-angular/AGENTS.md
@@ -0,0 +1,138 @@
+<!--
+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.
+-->
+
+# AGENTS.md
+
+Unit test conventions for this package. They apply to the Angular shell in 
`src/` and to the libraries under `projects/` that have no file of their own: 
`zeppelin-sdk`, which is framework-neutral, and `zeppelin-visualization`, which 
is mostly so apart from one `@Component` base class.
+
+Two subtrees override this file: [`e2e/AGENTS.md`](e2e/AGENTS.md) for the 
Playwright suite, and 
[`projects/zeppelin-react/AGENTS.md`](projects/zeppelin-react/AGENTS.md) for 
the React remote, which has a different CI status and one exception of its own.
+
+The repository root `AGENTS.md` asks every change to include unit tests. This 
file is how.
+
+## Layout
+
+- A spec lives next to its source: `foo.ts` / `foo.spec.ts`.
+- The runner is Vitest on jsdom. There is no Karma and no `TestBed` bootstrap 
in the setup file; `test/test-setup.ts` loads `zone.js` and nothing else.
+- `npm run test:shell` covers `src/`, `projects/zeppelin-sdk` and 
`projects/zeppelin-visualization`. The two libraries have no runner of their 
own; they ride on the shell config because their code needs nothing extra. 
`projects/zeppelin-react` is separate. It has its own Vitest config and its own 
file here.
+
+## Running
+
+| Command | Purpose |
+| --- | --- |
+| `npm run test:shell` | Run the unit tests for `src/` and the two libraries |
+| `npm run test:shell -- --coverage` | Same, with a coverage report |
+| `npm run test:shell -- foo.spec.ts` | Run one file |
+
+`test:shell` is bound to the Maven `test` phase (`pom.xml`), so a spec added 
here starts running in CI the day it merges. It does not run where you would 
expect. `frontend.yml` builds this module with `-DskipTests`, which 
frontend-maven-plugin honours by skipping `test`-phase executions, so the run 
that counts is `mvnw verify -Pweb-e2e` inside the `run-playwright-e2e-tests` 
job. A failing spec surfaces there, under an e2e job name. Giving the unit 
tests a step of their own is [ZEPPELIN-6 [...]
+
+## Where a test belongs
+
+The frontend has two test layers, not three. There is no integration tier.
+
+| Layer | Runner | Answers |
+| --- | --- | --- |
+| Unit | Vitest + jsdom | Is the judgement we wrote correct? |
+| E2E | Playwright | Does the page actually work in a browser? |
+
+Prefer a unit test when the question can be answered without a browser. Reach 
for e2e when the answer depends on wiring: routing, mounting a federated 
remote, authentication, or anything a user would have to click.
+
+The two layers do not substitute for each other, and neither replaces the 
cross-framework parity checks the React migration needs.
+
+A third kind is planned but does not exist yet: contract specs that replay 
captured WebSocket traffic against the notebook runtime, arriving with 
[ZEPPELIN-6627](https://issues.apache.org/jira/browse/ZEPPELIN-6627). Those 
will run on Vitest as well and live under `test/contract/`, with the captured 
traffic beside them. Conventions for them are added once they exist.
+
+## What to test
+
+The judgement we wrote: branches, boundaries, error paths.
+
+If a function has an `if`, it is worth a spec. If it only forwards to a 
framework API, it usually is not.
+
+Boundaries are where the bugs are. `HumanizeBytesPipe` switches units at 1000 
but divides by 1024, so `transform(1000)` renders `0.98 KB`. A spec pins that 
down, a reviewer's intuition does not.
+
+## What not to test
+
+- **Framework internals.** Change detection, lifecycle ordering, dependency 
injection itself. Test the code we wrote, not Angular.
+- **Template render snapshots.** Markup changes when a surface is restyled or 
migrated; a snapshot only records that it changed.
+- **Flows already covered by e2e.** Wiring between components, navigation, and 
anything that needs a real browser belongs in `e2e/`.
+- **Functions with no logic to check.** `element.ts` feature-detects a DOM API 
and forwards to it. A spec would assert that a mock was called.
+
+## Specs that cannot fail
+
+A spec with no assertion, or one whose assertion sits inside an `if`, passes 
by skipping the check it exists to make. These are caught by lint, not review:
+
+| Rule | Catches |
+| --- | --- |
+| `vitest/expect-expect` | a test with no assertion |
+| `vitest/no-conditional-expect` | an assertion only some runs reach |
+| `vitest/no-identical-title` | a duplicate name silently shadowing another |
+| `vitest/valid-expect` | `expect(x)` with no matcher |
+| `vitest/no-focused-tests` | `it.only` left behind, hiding the rest |
+| `vitest/no-disabled-tests` | `it.skip` left behind (warning) |
+
+The e2e suite gets the same protection from `eslint-plugin-playwright`.
+
+## Determinism
+
+No clock, no randomness, no network. A spec that reads `Date.now()` or fetches 
will eventually fail for reasons unrelated to the code under test.
+
+## Naming
+
+The failure message must say what broke. `should work` does not.
+
+```ts
+it('renders a dash for null and undefined', ...)     // good
+it('handles input', ...)                             // not a test name
+```
+
+## Angular classes without TestBed
+
+Directives, pipes and services are plain classes. Construct them directly and 
pass mocks to the constructor. `TestBed` is not needed and is slower.
+
+```ts
+const loader = { loadModule } as Pick<ReactRemoteLoaderService, 'loadModule'>;
+const directive = new ReactMountDirective(host, ngZone, loader as 
ReactRemoteLoaderService);
+```
+
+See `src/app/share/react-mount/react-mount.directive.spec.ts` for a worked 
example, and `src/app/share/pipes/humanize-bytes.pipe.spec.ts` for a pipe.
+
+**A spec cannot declare a decorator of its own.** Importing a decorated class 
from source works (the pipe and directive specs here do exactly that), but 
writing `@Injectable()` inside a spec file fails with `SyntaxError: Invalid or 
unexpected token`. Spec files are excluded from the nearest `tsconfig.json` 
(`src/tsconfig.json` for the shell, each library's own under `projects/`), so 
the transform never picks up the decorator settings; that is 
[ZEPPELIN-6637](https://issues.apache.org/jir [...]
+
+## Migration (Angular to React)
+
+**Write the spec while Angular is still the source of truth.**
+
+A spec written after a surface moves to React pins the new implementation's 
behaviour, not the behaviour we were trying to preserve. That turns a 
regression into the expected result. The migration 
([ZEPPELIN-6627](https://issues.apache.org/jira/browse/ZEPPELIN-6627)) gates on 
"does this still behave the same?", which cannot be judged when the previous 
behaviour was never written down.
+
+`src/app/pages/workspace/notebook/paragraph/paragraph-patch.spec.ts` is the 
pattern: a regression was fixed and the behaviour was pinned in the same change.
+
+## Coverage
+
+`--coverage` produces a v8 report under `coverage/`. It is measured, not 
gated. There are no thresholds.
+
+**Read the percentage carefully: it is not whole-tree coverage.** The 
denominator is only the files the specs actually load, because `include` is 
left unset while ZEPPELIN-6637 is open (see `vitest.shell.config.mts`). Most of 
the tree is absent from the report rather than counted as zero, so the figure 
reads far better than the real state, and it can *fall* as specs are added, 
since each new spec pulls more files into the denominator. Expect a large drop 
when `include` is eventually turned on.
+
+That is deliberate. `src/` currently holds a few specs against 222 source 
files, so any threshold set today is either meaningless or permanently red. The 
intended progression is: measure only, then ratchet so the number cannot fall, 
then require coverage on changed files. A whole-tree percentage is the wrong 
target during a migration, because much of the tree is going to be rewritten 
anyway.
+
+This is a different measurement from `e2e/reporter.coverage.ts`, which counts 
annotated component pages rather than lines. The two numbers are not comparable 
and are not merged.
+
+## Adding a Test (Agents Start Here)
+
+1. Pick a target with logic to check: a branch, a boundary, an error path.
+2. Create `foo.spec.ts` next to `foo.ts`.
+3. Import from `vitest` (`describe`, `expect`, `it`), not from Jasmine or Jest.
+   Check the target has callers before you invest in it. 
`get-keyword-positions.spec.ts` is a worked example of a function that turned 
out to have none.
+4. Construct the class directly; do not reach for `TestBed`.
+5. Run `npm run test:shell` and confirm it passes before opening a PR.
diff --git a/zeppelin-web-angular/e2e/AGENTS.md 
b/zeppelin-web-angular/e2e/AGENTS.md
index af81bb2303..43e18edf9c 100644
--- a/zeppelin-web-angular/e2e/AGENTS.md
+++ b/zeppelin-web-angular/e2e/AGENTS.md
@@ -17,7 +17,7 @@ limitations under the License.
 
 # AGENTS.md
 
-> E2E (Playwright) conventions for `zeppelin-web-angular/e2e/`. A scoped 
companion to the repository-root AGENTS.md, loaded only when working under 
`e2e/`. See [AGENTS.md specification](https://github.com/agentsmd/agents.md).
+> E2E (Playwright) conventions for `zeppelin-web-angular/e2e/`. Loaded only 
when working under `e2e/`; the package baseline is 
`zeppelin-web-angular/AGENTS.md`, which covers unit tests. See [AGENTS.md 
specification](https://github.com/agentsmd/agents.md).
 
 Config: `zeppelin-web-angular/playwright.config.js` (Angular UI) and 
`playwright.classic.config.js` (legacy classic UI), sharing 
`playwright.shared.js`. This document is the source of truth for E2E 
conventions, for contributors and for coding agents alike.
 
diff --git a/zeppelin-web-angular/eslint.config.js 
b/zeppelin-web-angular/eslint.config.js
index aa5cbc21ae..23b87ff73a 100644
--- a/zeppelin-web-angular/eslint.config.js
+++ b/zeppelin-web-angular/eslint.config.js
@@ -24,6 +24,7 @@ const prettier = require('eslint-config-prettier');
 const localRules = require('./eslint-rules');
 const perfectionist = require('eslint-plugin-perfectionist');
 const playwright = require('eslint-plugin-playwright');
+const vitest = require('@vitest/eslint-plugin');
 
 module.exports = tseslint.config(
   {
@@ -160,7 +161,12 @@ module.exports = tseslint.config(
   {
     // Shell unit specs live outside the Angular build tsconfig, which excludes
     // *.spec.ts. Point type-aware linting at the spec program explicitly.
-    files: ['src/**/*.spec.ts', 'test/test-setup.ts', 
'vitest.shell.config.mts'],
+    files: [
+      'src/**/*.spec.ts',
+      'projects/zeppelin-{sdk,visualization}/**/*.spec.ts',
+      'test/test-setup.ts',
+      'vitest.shell.config.mts'
+    ],
     languageOptions: {
       parserOptions: {
         project: ['./src/tsconfig.spec.json'],
@@ -168,6 +174,21 @@ module.exports = tseslint.config(
       }
     }
   },
+  {
+    // Catch specs that cannot fail, as eslint-plugin-playwright does for e2e.
+    files: ['src/**/*.spec.ts', 
'projects/zeppelin-{sdk,visualization}/**/*.spec.ts'],
+    plugins: { vitest },
+    rules: {
+      'vitest/expect-expect': 'error',
+      'vitest/no-conditional-expect': 'error',
+      'vitest/no-identical-title': 'error',
+      'vitest/no-standalone-expect': 'error',
+      'vitest/valid-expect': 'error',
+      'vitest/valid-describe-callback': 'error',
+      'vitest/no-disabled-tests': 'warn',
+      'vitest/no-focused-tests': 'error'
+    }
+  },
   {
     // The shell test setup intentionally loads Zone.js for its side effects.
     files: ['test/test-setup.ts'],
diff --git a/zeppelin-web-angular/package-lock.json 
b/zeppelin-web-angular/package-lock.json
index b5ded7cabe..4725357f04 100644
--- a/zeppelin-web-angular/package-lock.json
+++ b/zeppelin-web-angular/package-lock.json
@@ -60,6 +60,8 @@
         "@types/node": "22.12.0",
         "@types/parse5": "^5.0.2",
         "@types/webpack-env": "^1.18.8",
+        "@vitest/coverage-v8": "4.1.8",
+        "@vitest/eslint-plugin": "^1.6.27",
         "angular-eslint": "21.4.0",
         "concurrently": "9.2.1",
         "cross-env": "^10.1.0",
@@ -83,6 +85,7 @@
         "ts-node": "~7.0.0",
         "typescript": "~5.9.3",
         "typescript-eslint": "^8.33.1",
+        "vite": "8.2.1",
         "vitest": "4.1.8"
       },
       "engines": {
@@ -3780,6 +3783,16 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@bcoe/v8-coverage": {
+      "version": "1.0.2",
+      "resolved": 
"https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz";,
+      "integrity": 
"sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/@bramus/specificity": {
       "version": "2.4.2",
       "dev": true,
@@ -5577,9 +5590,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5597,9 +5607,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5617,9 +5624,6 @@
         "ppc64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5637,9 +5641,6 @@
         "riscv64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5657,9 +5658,6 @@
         "s390x"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5677,9 +5675,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5697,9 +5692,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -5777,28 +5769,6 @@
         "node": ">= 10"
       }
     },
-    "node_modules/@napi-rs/wasm-runtime": {
-      "version": "1.2.3",
-      "resolved": 
"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz";,
-      "integrity": 
"sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@tybys/wasm-util": "^0.10.3"
-      },
-      "engines": {
-        "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/Brooooooklyn";
-      },
-      "peerDependencies": {
-        "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
-        "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4"
-      }
-    },
     "node_modules/@ngtools/webpack": {
       "version": "21.2.13",
       "dev": true,
@@ -6156,9 +6126,6 @@
         "arm"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6180,9 +6147,6 @@
         "arm"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6204,9 +6168,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6228,9 +6189,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6252,9 +6210,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6276,9 +6231,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6622,9 +6574,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6642,9 +6591,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6662,9 +6608,6 @@
         "ppc64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6682,9 +6625,6 @@
         "s390x"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6702,9 +6642,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6722,9 +6659,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6768,6 +6702,25 @@
         "node": ">=14.0.0"
       }
     },
+    
"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime":
 {
+      "version": "1.1.4",
+      "resolved": 
"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz";,
+      "integrity": 
"sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@tybys/wasm-util": "^0.10.1"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/Brooooooklyn";
+      },
+      "peerDependencies": {
+        "@emnapi/core": "^1.7.1",
+        "@emnapi/runtime": "^1.7.1"
+      }
+    },
     "node_modules/@rolldown/binding-win32-arm64-msvc": {
       "version": "1.0.0-rc.4",
       "resolved": 
"https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.4.tgz";,
@@ -6937,9 +6890,6 @@
         "arm"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6954,9 +6904,6 @@
         "arm"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6971,9 +6918,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -6988,9 +6932,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7005,9 +6946,6 @@
         "loong64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7022,9 +6960,6 @@
         "loong64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7039,9 +6974,6 @@
         "ppc64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7056,9 +6988,6 @@
         "ppc64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7073,9 +7002,6 @@
         "riscv64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7090,9 +7016,6 @@
         "riscv64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7107,9 +7030,6 @@
         "s390x"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7124,9 +7044,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7141,9 +7058,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -7864,6 +7778,68 @@
         "url": "https://opencollective.com/eslint";
       }
     },
+    "node_modules/@vitest/coverage-v8": {
+      "version": "4.1.8",
+      "resolved": 
"https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.8.tgz";,
+      "integrity": 
"sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@bcoe/v8-coverage": "^1.0.2",
+        "@vitest/utils": "4.1.8",
+        "ast-v8-to-istanbul": "^1.0.0",
+        "istanbul-lib-coverage": "^3.2.2",
+        "istanbul-lib-report": "^3.0.1",
+        "istanbul-reports": "^3.2.0",
+        "magicast": "^0.5.2",
+        "obug": "^2.1.1",
+        "std-env": "^4.0.0-rc.1",
+        "tinyrainbow": "^3.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/vitest";
+      },
+      "peerDependencies": {
+        "@vitest/browser": "4.1.8",
+        "vitest": "4.1.8"
+      },
+      "peerDependenciesMeta": {
+        "@vitest/browser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vitest/eslint-plugin": {
+      "version": "1.6.27",
+      "resolved": 
"https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.27.tgz";,
+      "integrity": 
"sha512-X1RCAfwbatG4GFbJ/1PIHP9MSZMt0JJThqbYID+vS4L783k6QGlLPe421wQE8dHXuGCcenVLsydiM4qzsYWxhg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "^8.58.0",
+        "@typescript-eslint/utils": "^8.58.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/eslint-plugin": "*",
+        "eslint": ">=8.57.0",
+        "typescript": ">=5.0.0",
+        "vitest": "*"
+      },
+      "peerDependenciesMeta": {
+        "@typescript-eslint/eslint-plugin": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        },
+        "vitest": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@vitest/expect": {
       "version": "4.1.8",
       "dev": true,
@@ -8614,6 +8590,35 @@
         "node": ">=12"
       }
     },
+    "node_modules/ast-v8-to-istanbul": {
+      "version": "1.0.5",
+      "resolved": 
"https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.5.tgz";,
+      "integrity": 
"sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.31",
+        "estree-walker": "^3.0.3",
+        "js-tokens": "^10.0.0"
+      }
+    },
+    "node_modules/ast-v8-to-istanbul/node_modules/estree-walker": {
+      "version": "3.0.3",
+      "resolved": 
"https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz";,
+      "integrity": 
"sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "^1.0.0"
+      }
+    },
+    "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": {
+      "version": "10.0.0",
+      "resolved": 
"https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz";,
+      "integrity": 
"sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/async-function": {
       "version": "1.0.0",
       "license": "MIT",
@@ -12187,6 +12192,28 @@
         }
       }
     },
+    "node_modules/html-encoding-sniffer/node_modules/@noble/hashes": {
+      "version": "2.3.0",
+      "resolved": 
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz";,
+      "integrity": 
"sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 20.19.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/";
+      }
+    },
+    "node_modules/html-escaper": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz";,
+      "integrity": 
"sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/htmlparser2": {
       "version": "10.1.0",
       "dev": true,
@@ -13053,6 +13080,64 @@
         "node": ">=10"
       }
     },
+    "node_modules/istanbul-lib-report": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz";,
+      "integrity": 
"sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^4.0.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-lib-report/node_modules/make-dir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz";,
+      "integrity": 
"sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus";
+      }
+    },
+    "node_modules/istanbul-lib-report/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": 
"https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz";,
+      "integrity": 
"sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-reports": {
+      "version": "3.2.0",
+      "resolved": 
"https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz";,
+      "integrity": 
"sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/jest-worker": {
       "version": "27.5.1",
       "dev": true,
@@ -13164,6 +13249,21 @@
         }
       }
     },
+    "node_modules/jsdom/node_modules/@noble/hashes": {
+      "version": "2.3.0",
+      "resolved": 
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz";,
+      "integrity": 
"sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 20.19.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/";
+      }
+    },
     "node_modules/jsdom/node_modules/entities": {
       "version": "8.0.0",
       "dev": true,
@@ -13552,9 +13652,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MPL-2.0",
       "optional": true,
       "os": [
@@ -13576,9 +13673,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MPL-2.0",
       "optional": true,
       "os": [
@@ -13600,9 +13694,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MPL-2.0",
       "optional": true,
       "os": [
@@ -13624,9 +13715,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MPL-2.0",
       "optional": true,
       "os": [
@@ -14021,6 +14109,18 @@
         "@jridgewell/sourcemap-codec": "^1.5.5"
       }
     },
+    "node_modules/magicast": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz";,
+      "integrity": 
"sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.7",
+        "@babel/types": "^7.29.7",
+        "source-map-js": "^1.2.1"
+      }
+    },
     "node_modules/make-dir": {
       "version": "2.1.0",
       "dev": true,
@@ -18194,14 +18294,16 @@
       }
     },
     "node_modules/vite": {
-      "version": "8.2.2",
+      "version": "8.2.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz";,
+      "integrity": 
"sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "lightningcss": "^1.33.0",
         "picomatch": "^4.0.5",
-        "postcss": "^8.5.26",
-        "rolldown": "~1.2.4",
+        "postcss": "^8.5.25",
+        "rolldown": "~1.2.1",
         "tinyglobby": "^0.2.17"
       },
       "bin": {
@@ -18218,7 +18320,7 @@
       },
       "peerDependencies": {
         "@types/node": "^20.19.0 || >=22.12.0",
-        "@vitejs/devtools": "^0.4.0 || ^0.5.0",
+        "@vitejs/devtools": "^0.4.0",
         "esbuild": "^0.27.0 || ^0.28.0",
         "jiti": ">=1.21.0",
         "less": "^4.0.0",
@@ -18368,9 +18470,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -18388,9 +18487,6 @@
         "arm64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -18408,9 +18504,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "glibc"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -18428,9 +18521,6 @@
         "x64"
       ],
       "dev": true,
-      "libc": [
-        "musl"
-      ],
       "license": "MIT",
       "optional": true,
       "os": [
@@ -19364,6 +19454,21 @@
         }
       }
     },
+    "node_modules/whatwg-url/node_modules/@noble/hashes": {
+      "version": "2.3.0",
+      "resolved": 
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz";,
+      "integrity": 
"sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 20.19.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/";
+      }
+    },
     "node_modules/which": {
       "version": "2.0.2",
       "dev": true,
@@ -19759,1100 +19864,6 @@
     "node_modules/zone.js": {
       "version": "0.15.1",
       "license": "MIT"
-    },
-    "node_modules/html-encoding-sniffer/node_modules/@noble/hashes": {
-      "version": "2.3.0",
-      "resolved": 
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz";,
-      "integrity": 
"sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">= 20.19.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/";
-      }
-    },
-    "node_modules/jsdom/node_modules/@noble/hashes": {
-      "version": "2.3.0",
-      "resolved": 
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz";,
-      "integrity": 
"sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">= 20.19.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/";
-      }
-    },
-    "node_modules/whatwg-url/node_modules/@noble/hashes": {
-      "version": "2.3.0",
-      "resolved": 
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.3.0.tgz";,
-      "integrity": 
"sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">= 20.19.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/";
-      }
-    },
-    "node_modules/@angular-architects/module-federation": {
-      "version": "21.2.2",
-      "resolved": 
"https://registry.npmjs.org/@angular-architects/module-federation/-/module-federation-21.2.2.tgz";,
-      "integrity": 
"sha512-aM6Oys+RGlUZ+GuVz1gx9LlJNMnb+niEtEsCQ3NmgoIMOZDBlfYnm+jbDO0F1TJWrTOBbAvfbKvJbLHfG25r8Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@angular-architects/module-federation-runtime": "~21.2.2",
-        "callsite": "^1.0.0",
-        "node-fetch": "^3.3.2",
-        "semver": "~7.7.1",
-        "word-wrap": "^1.2.5"
-      }
-    },
-    "node_modules/@angular-architects/module-federation-runtime": {
-      "version": "21.2.2",
-      "resolved": 
"https://registry.npmjs.org/@angular-architects/module-federation-runtime/-/module-federation-runtime-21.2.2.tgz";,
-      "integrity": 
"sha512-Akl6fLcD2dYXqxW4pLVgytq7NKQ998g4OUjEgcLQnhqyvlu+qdPRUfSDPlTGUiIY01/J2M9ZXcIWmUJJ5tOT5Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.3.0"
-      },
-      "peerDependencies": {
-        "@angular/common": "^21.2.0",
-        "@angular/core": "^21.2.0",
-        "@module-federation/enhanced": "^2.2.2",
-        "@module-federation/runtime-core": "^2.2.2"
-      }
-    },
-    "node_modules/@angular-builders/custom-webpack/node_modules/@types/node": {
-      "version": "26.1.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz";,
-      "integrity": 
"sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "undici-types": "~8.3.0"
-      }
-    },
-    "node_modules/@angular-devkit/build-angular/node_modules/@types/node": {
-      "version": "26.1.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz";,
-      "integrity": 
"sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "undici-types": "~8.3.0"
-      }
-    },
-    "node_modules/@angular/cli/node_modules/@types/node": {
-      "version": "26.1.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz";,
-      "integrity": 
"sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "undici-types": "~8.3.0"
-      }
-    },
-    "node_modules/@module-federation/bridge-react-webpack-plugin": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-2.5.0.tgz";,
-      "integrity": 
"sha512-Ux9XVW//K6K+KHKPdc0Jnc7RtTpZaEXgbVhp5yovtFkCJVt8hEClcTeuI18MvvLiV/q2hUpCU5Wsf9zNaIYStQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/sdk": "2.5.0",
-        "@types/semver": "7.5.8",
-        "semver": "7.6.3"
-      }
-    },
-    
"node_modules/@module-federation/bridge-react-webpack-plugin/node_modules/semver":
 {
-      "version": "7.6.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz";,
-      "integrity": 
"sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
-      "dev": true,
-      "license": "ISC",
-      "peer": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@module-federation/cli": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/cli/-/cli-2.5.0.tgz";,
-      "integrity": 
"sha512-+czXA6yoiiF9W6+YEOCpQE6zpGZpA89X0oCEz3EaWPTkL4chEbxurjpME8CMnJk9iuFxl167+cBQiQlVBiHGGg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/dts-plugin": "2.5.0",
-        "@module-federation/sdk": "2.5.0",
-        "commander": "11.1.0",
-        "jiti": "2.4.2"
-      },
-      "bin": {
-        "mf": "bin/mf.js"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@module-federation/dts-plugin": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-2.5.0.tgz";,
-      "integrity": 
"sha512-q7KDhJ5tn2HrUV7uMuh/L3TaaztUosE+4LAb90sxx0pPPqWRwlpBpxu1REubv5BWXmU1K/Ozn14u6jRbjLVaGA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/error-codes": "2.5.0",
-        "@module-federation/managers": "2.5.0",
-        "@module-federation/sdk": "2.5.0",
-        "@module-federation/third-party-dts-extractor": "2.5.0",
-        "adm-zip": "0.5.10",
-        "ansi-colors": "4.1.3",
-        "isomorphic-ws": "5.0.0",
-        "node-schedule": "2.1.1",
-        "undici": "7.24.7",
-        "ws": "8.18.0"
-      },
-      "peerDependencies": {
-        "typescript": "^4.9.0 || ^5.0.0",
-        "vue-tsc": ">=1.0.24"
-      },
-      "peerDependenciesMeta": {
-        "vue-tsc": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@module-federation/enhanced": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-2.5.0.tgz";,
-      "integrity": 
"sha512-P91tzwyKSCQ6AwirqvAvTqWqmTY79ndpH0uenejFw+bbLpWrjuY0q+iZUXCV/7CSNmqwH2bkA/ssuyZljmcMVQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/bridge-react-webpack-plugin": "2.5.0",
-        "@module-federation/cli": "2.5.0",
-        "@module-federation/dts-plugin": "2.5.0",
-        "@module-federation/error-codes": "2.5.0",
-        "@module-federation/inject-external-runtime-core-plugin": "2.5.0",
-        "@module-federation/managers": "2.5.0",
-        "@module-federation/manifest": "2.5.0",
-        "@module-federation/rspack": "2.5.0",
-        "@module-federation/runtime-tools": "2.5.0",
-        "@module-federation/sdk": "2.5.0",
-        "@module-federation/webpack-bundler-runtime": "2.5.0",
-        "schema-utils": "4.3.0",
-        "tapable": "2.3.0",
-        "upath": "2.0.1"
-      },
-      "bin": {
-        "mf": "bin/mf.js"
-      },
-      "peerDependencies": {
-        "typescript": "^4.9.0 || ^5.0.0",
-        "vue-tsc": ">=1.0.24",
-        "webpack": "^5.0.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        },
-        "vue-tsc": {
-          "optional": true
-        },
-        "webpack": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@module-federation/error-codes": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-2.5.0.tgz";,
-      "integrity": 
"sha512-sq05/8Gp3csy1nr2/f76K3vLy0/xRqVtP71ibGy8BiLg7h1UxWN7G4EwAKSrPZ4FnsERGeFlIszg5Z+MqlwhFg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/@module-federation/inject-external-runtime-core-plugin": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-2.5.0.tgz";,
-      "integrity": 
"sha512-e2KyTHpesBrPXGHMh4d4+s2xBiNoxbiFJkPRYHMCl81a/Gu+byrMkriZcV4VM/TFvBIlrgOJisVc1nnBI5UDRQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "peerDependencies": {
-        "@module-federation/runtime-tools": "2.5.0"
-      }
-    },
-    "node_modules/@module-federation/managers": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/managers/-/managers-2.5.0.tgz";,
-      "integrity": 
"sha512-9b5mU/7OYbKrYUJmhZ1kkfeJCZqR7qX6/FWp+oOfZMzUynN7Rb41dwoUs3TdnOKzbZ3CCwtZ2WsR4pF9ZNvuJA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/sdk": "2.5.0",
-        "find-pkg": "2.0.0"
-      }
-    },
-    "node_modules/@module-federation/manifest": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/manifest/-/manifest-2.5.0.tgz";,
-      "integrity": 
"sha512-pmwQCGWjM2oKY7CkR7nEDOfMK0bNFJUifuDxuOB5iOWhU+Rp92UyyBI9IbJAtiISTSFGtuKRy40peJGvQq2VcQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/dts-plugin": "2.5.0",
-        "@module-federation/managers": "2.5.0",
-        "@module-federation/sdk": "2.5.0",
-        "find-pkg": "2.0.0"
-      }
-    },
-    "node_modules/@module-federation/rspack": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/rspack/-/rspack-2.5.0.tgz";,
-      "integrity": 
"sha512-OAFMpMXuLEQFmWBuC1I7LNDQ8N3CDANXe0YGPWkIPNxKq5Tj/KNfDidmutoYgvXlZKOM4yKBKBsL6Xt/UvtOIw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/bridge-react-webpack-plugin": "2.5.0",
-        "@module-federation/dts-plugin": "2.5.0",
-        "@module-federation/inject-external-runtime-core-plugin": "2.5.0",
-        "@module-federation/managers": "2.5.0",
-        "@module-federation/manifest": "2.5.0",
-        "@module-federation/runtime-tools": "2.5.0",
-        "@module-federation/sdk": "2.5.0"
-      },
-      "peerDependencies": {
-        "@rspack/core": "^0.7.0 || ^1.0.0 || ^2.0.0-0",
-        "typescript": "^4.9.0 || ^5.0.0",
-        "vue-tsc": ">=1.0.24"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        },
-        "vue-tsc": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@module-federation/runtime": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/runtime/-/runtime-2.5.0.tgz";,
-      "integrity": 
"sha512-dOc7pFEf8aruHBk5hoJLnvwkCa5ELT78q3o9dqcdaa/TT74X5z0FT0BsaGaRBPcse/iP6czK3fWd7RLv5ZKP5g==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/error-codes": "2.5.0",
-        "@module-federation/runtime-core": "2.5.0",
-        "@module-federation/sdk": "2.5.0"
-      }
-    },
-    "node_modules/@module-federation/runtime-core": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-2.5.0.tgz";,
-      "integrity": 
"sha512-STmhQ3c6/hunba2FMP6GrHazXU/8GuN7Gk4dOkWNRpnqYIoD8Wx4MNl76j3HdCzBESC7uSMXTniksVaM1+xxyA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/error-codes": "2.5.0",
-        "@module-federation/sdk": "2.5.0"
-      }
-    },
-    "node_modules/@module-federation/runtime-tools": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-2.5.0.tgz";,
-      "integrity": 
"sha512-fR3Na6V78ov3/O17Mev+1vydfmqlYWP4ZNxD/bBkmqKhCO7jMdthNTT02yDljlCyhYl6+X90UJlFhwFle6rIsw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/runtime": "2.5.0",
-        "@module-federation/webpack-bundler-runtime": "2.5.0"
-      }
-    },
-    "node_modules/@module-federation/sdk": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/sdk/-/sdk-2.5.0.tgz";,
-      "integrity": 
"sha512-ScU22XDyV77l50njjzewMpMlNN1CYo0tHS1D6iy+vNKWrHGq8DWVB0vwG8dmvx/WZ4uq+sXgUsQet17MoKsfZw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "peerDependencies": {
-        "node-fetch": "^2.7.0 || ^3.3.2"
-      },
-      "peerDependenciesMeta": {
-        "node-fetch": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@module-federation/third-party-dts-extractor": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-2.5.0.tgz";,
-      "integrity": 
"sha512-5di43LGk2ies86Cj8QyzYr540Ijc+nyPqYziyFotL6Pparnu+uf3b3ERfEyQfBmEcyGk1MpitQIO2J3bd9BcNw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "find-pkg": "2.0.0",
-        "resolve": "1.22.8"
-      }
-    },
-    "node_modules/@module-federation/webpack-bundler-runtime": {
-      "version": "2.5.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-2.5.0.tgz";,
-      "integrity": 
"sha512-UxVad+tNZYkBnZzqJQsZa0pB5gO5cJoCjMumOo3bhzXBJVqHsFupfeHa8Nk7WrRVbJE6zRT9ZHK0s0NDWBMyJw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/error-codes": "2.5.0",
-        "@module-federation/runtime": "2.5.0",
-        "@module-federation/sdk": "2.5.0"
-      }
-    },
-    
"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime":
 {
-      "version": "1.1.4",
-      "resolved": 
"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz";,
-      "integrity": 
"sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@tybys/wasm-util": "^0.10.1"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/Brooooooklyn";
-      },
-      "peerDependencies": {
-        "@emnapi/core": "^1.7.1",
-        "@emnapi/runtime": "^1.7.1"
-      }
-    },
-    "node_modules/@rspack/binding": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding/-/binding-1.7.11.tgz";,
-      "integrity": 
"sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "optionalDependencies": {
-        "@rspack/binding-darwin-arm64": "1.7.11",
-        "@rspack/binding-darwin-x64": "1.7.11",
-        "@rspack/binding-linux-arm64-gnu": "1.7.11",
-        "@rspack/binding-linux-arm64-musl": "1.7.11",
-        "@rspack/binding-linux-x64-gnu": "1.7.11",
-        "@rspack/binding-linux-x64-musl": "1.7.11",
-        "@rspack/binding-wasm32-wasi": "1.7.11",
-        "@rspack/binding-win32-arm64-msvc": "1.7.11",
-        "@rspack/binding-win32-ia32-msvc": "1.7.11",
-        "@rspack/binding-win32-x64-msvc": "1.7.11"
-      }
-    },
-    "node_modules/@rspack/binding-darwin-arm64": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.11.tgz";,
-      "integrity": 
"sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-darwin-x64": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.11.tgz";,
-      "integrity": 
"sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-linux-arm64-gnu": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.11.tgz";,
-      "integrity": 
"sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-linux-arm64-musl": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.11.tgz";,
-      "integrity": 
"sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-linux-x64-gnu": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.11.tgz";,
-      "integrity": 
"sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-linux-x64-musl": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.11.tgz";,
-      "integrity": 
"sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-wasm32-wasi": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.11.tgz";,
-      "integrity": 
"sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ==",
-      "cpu": [
-        "wasm32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "@napi-rs/wasm-runtime": "1.0.7"
-      }
-    },
-    "node_modules/@rspack/binding-win32-arm64-msvc": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.11.tgz";,
-      "integrity": 
"sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-win32-ia32-msvc": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.11.tgz";,
-      "integrity": 
"sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/binding-win32-x64-msvc": {
-      "version": "1.7.11",
-      "resolved": 
"https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.11.tgz";,
-      "integrity": 
"sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "peer": true
-    },
-    "node_modules/@rspack/core": {
-      "version": "1.7.11",
-      "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.7.11.tgz";,
-      "integrity": 
"sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/runtime-tools": "0.22.0",
-        "@rspack/binding": "1.7.11",
-        "@rspack/lite-tapable": "1.1.0"
-      },
-      "engines": {
-        "node": ">=18.12.0"
-      },
-      "peerDependencies": {
-        "@swc/helpers": ">=0.5.1"
-      },
-      "peerDependenciesMeta": {
-        "@swc/helpers": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@rspack/core/node_modules/@module-federation/error-codes": {
-      "version": "0.22.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz";,
-      "integrity": 
"sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/@rspack/core/node_modules/@module-federation/runtime": {
-      "version": "0.22.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz";,
-      "integrity": 
"sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/error-codes": "0.22.0",
-        "@module-federation/runtime-core": "0.22.0",
-        "@module-federation/sdk": "0.22.0"
-      }
-    },
-    "node_modules/@rspack/core/node_modules/@module-federation/runtime-core": {
-      "version": "0.22.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz";,
-      "integrity": 
"sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/error-codes": "0.22.0",
-        "@module-federation/sdk": "0.22.0"
-      }
-    },
-    "node_modules/@rspack/core/node_modules/@module-federation/runtime-tools": 
{
-      "version": "0.22.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz";,
-      "integrity": 
"sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/runtime": "0.22.0",
-        "@module-federation/webpack-bundler-runtime": "0.22.0"
-      }
-    },
-    "node_modules/@rspack/core/node_modules/@module-federation/sdk": {
-      "version": "0.22.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz";,
-      "integrity": 
"sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    
"node_modules/@rspack/core/node_modules/@module-federation/webpack-bundler-runtime":
 {
-      "version": "0.22.0",
-      "resolved": 
"https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz";,
-      "integrity": 
"sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@module-federation/runtime": "0.22.0",
-        "@module-federation/sdk": "0.22.0"
-      }
-    },
-    "node_modules/@rspack/lite-tapable": {
-      "version": "1.1.0",
-      "resolved": 
"https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz";,
-      "integrity": 
"sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/@types/semver": {
-      "version": "7.5.8",
-      "resolved": 
"https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz";,
-      "integrity": 
"sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/adm-zip": {
-      "version": "0.5.10",
-      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz";,
-      "integrity": 
"sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=6.0"
-      }
-    },
-    "node_modules/callsite": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz";,
-      "integrity": 
"sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/commander": {
-      "version": "11.1.0",
-      "resolved": 
"https://registry.npmjs.org/commander/-/commander-11.1.0.tgz";,
-      "integrity": 
"sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/cron-parser": {
-      "version": "4.9.0",
-      "resolved": 
"https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz";,
-      "integrity": 
"sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "luxon": "^3.2.1"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/data-uri-to-buffer": {
-      "version": "4.0.1",
-      "resolved": 
"https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz";,
-      "integrity": 
"sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 12"
-      }
-    },
-    "node_modules/expand-tilde": {
-      "version": "2.0.2",
-      "resolved": 
"https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz";,
-      "integrity": 
"sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "homedir-polyfill": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/fetch-blob": {
-      "version": "3.2.0",
-      "resolved": 
"https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz";,
-      "integrity": 
"sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/jimmywarting";
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/jimmywarting";
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "node-domexception": "^1.0.0",
-        "web-streams-polyfill": "^3.0.3"
-      },
-      "engines": {
-        "node": "^12.20 || >= 14.13"
-      }
-    },
-    "node_modules/find-file-up": {
-      "version": "2.0.1",
-      "resolved": 
"https://registry.npmjs.org/find-file-up/-/find-file-up-2.0.1.tgz";,
-      "integrity": 
"sha512-qVdaUhYO39zmh28/JLQM5CoYN9byEOKEH4qfa8K1eNV17W0UUMJ9WgbR/hHFH+t5rcl+6RTb5UC7ck/I+uRkpQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "resolve-dir": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/find-pkg": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-2.0.0.tgz";,
-      "integrity": 
"sha512-WgZ+nKbELDa6N3i/9nrHeNznm+lY3z4YfhDDWgW+5P0pdmMj26bxaxU11ookgY3NyP9GC7HvZ9etp0jRFqGEeQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "find-file-up": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/formdata-polyfill": {
-      "version": "4.0.10",
-      "resolved": 
"https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz";,
-      "integrity": 
"sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fetch-blob": "^3.1.2"
-      },
-      "engines": {
-        "node": ">=12.20.0"
-      }
-    },
-    "node_modules/global-modules": {
-      "version": "1.0.0",
-      "resolved": 
"https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz";,
-      "integrity": 
"sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "global-prefix": "^1.0.1",
-        "is-windows": "^1.0.1",
-        "resolve-dir": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/global-prefix": {
-      "version": "1.0.2",
-      "resolved": 
"https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz";,
-      "integrity": 
"sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "expand-tilde": "^2.0.2",
-        "homedir-polyfill": "^1.0.1",
-        "ini": "^1.3.4",
-        "is-windows": "^1.0.1",
-        "which": "^1.2.14"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/global-prefix/node_modules/ini": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz";,
-      "integrity": 
"sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "dev": true,
-      "license": "ISC",
-      "peer": true
-    },
-    "node_modules/global-prefix/node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz";,
-      "integrity": 
"sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dev": true,
-      "license": "ISC",
-      "peer": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/homedir-polyfill": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz";,
-      "integrity": 
"sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "parse-passwd": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-windows": {
-      "version": "1.0.2",
-      "resolved": 
"https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz";,
-      "integrity": 
"sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/isomorphic-ws": {
-      "version": "5.0.0",
-      "resolved": 
"https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz";,
-      "integrity": 
"sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "peerDependencies": {
-        "ws": "*"
-      }
-    },
-    "node_modules/jiti": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz";,
-      "integrity": 
"sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "bin": {
-        "jiti": "lib/jiti-cli.mjs"
-      }
-    },
-    "node_modules/long-timeout": {
-      "version": "0.1.1",
-      "resolved": 
"https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz";,
-      "integrity": 
"sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/luxon": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz";,
-      "integrity": 
"sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/ngx-build-plus": {
-      "version": "20.0.0",
-      "resolved": 
"https://registry.npmjs.org/ngx-build-plus/-/ngx-build-plus-20.0.0.tgz";,
-      "integrity": 
"sha512-cm1ZMTACAN3DEqBt/alS84zwVGgL5HAl5Dk/wh7CPyGUBQnLaxiAhjFZ6iykxgSO3e9ebIZmDBvTC480piC1eA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "webpack-merge": "^6.0.0"
-      },
-      "peerDependencies": {
-        "@angular-devkit/build-angular": ">=20.0.0",
-        "@schematics/angular": ">=20.0.0",
-        "rxjs": ">= 6.0.0"
-      }
-    },
-    "node_modules/node-domexception": {
-      "version": "1.0.0",
-      "resolved": 
"https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz";,
-      "integrity": 
"sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
-      "deprecated": "Use your platform's native DOMException instead",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/jimmywarting";
-        },
-        {
-          "type": "github",
-          "url": "https://paypal.me/jimmywarting";
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.5.0"
-      }
-    },
-    "node_modules/node-fetch": {
-      "version": "3.3.2",
-      "resolved": 
"https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz";,
-      "integrity": 
"sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "data-uri-to-buffer": "^4.0.0",
-        "fetch-blob": "^3.1.4",
-        "formdata-polyfill": "^4.0.10"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/node-fetch";
-      }
-    },
-    "node_modules/node-schedule": {
-      "version": "2.1.1",
-      "resolved": 
"https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz";,
-      "integrity": 
"sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "cron-parser": "^4.2.0",
-        "long-timeout": "0.1.1",
-        "sorted-array-functions": "^1.3.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/parse-passwd": {
-      "version": "1.0.0",
-      "resolved": 
"https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz";,
-      "integrity": 
"sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/resolve-dir": {
-      "version": "1.0.1",
-      "resolved": 
"https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz";,
-      "integrity": 
"sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "expand-tilde": "^2.0.0",
-        "global-modules": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sorted-array-functions": {
-      "version": "1.3.0",
-      "resolved": 
"https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz";,
-      "integrity": 
"sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/undici": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.7.tgz";,
-      "integrity": 
"sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=20.18.1"
-      }
-    },
-    "node_modules/undici-types": {
-      "version": "8.3.0",
-      "resolved": 
"https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz";,
-      "integrity": 
"sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true
-    },
-    "node_modules/upath": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz";,
-      "integrity": 
"sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=4",
-        "yarn": "*"
-      }
-    },
-    "node_modules/web-streams-polyfill": {
-      "version": "3.3.3",
-      "resolved": 
"https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz";,
-      "integrity": 
"sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    
"node_modules/@rspack/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
-      "version": "1.0.7",
-      "resolved": 
"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz";,
-      "integrity": 
"sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "@emnapi/core": "^1.5.0",
-        "@emnapi/runtime": "^1.5.0",
-        "@tybys/wasm-util": "^0.10.1"
-      }
     }
   }
 }
diff --git a/zeppelin-web-angular/package.json 
b/zeppelin-web-angular/package.json
index 5428c64463..8acdda44a6 100644
--- a/zeppelin-web-angular/package.json
+++ b/zeppelin-web-angular/package.json
@@ -89,6 +89,8 @@
     "@types/node": "22.12.0",
     "@types/parse5": "^5.0.2",
     "@types/webpack-env": "^1.18.8",
+    "@vitest/coverage-v8": "4.1.8",
+    "@vitest/eslint-plugin": "^1.6.27",
     "angular-eslint": "21.4.0",
     "concurrently": "9.2.1",
     "cross-env": "^10.1.0",
@@ -112,6 +114,7 @@
     "ts-node": "~7.0.0",
     "typescript": "~5.9.3",
     "typescript-eslint": "^8.33.1",
+    "vite": "8.2.1",
     "vitest": "4.1.8"
   },
   "overrides": {
diff --git a/zeppelin-web-angular/projects/zeppelin-react/.gitignore 
b/zeppelin-web-angular/projects/zeppelin-react/.gitignore
index de4d1f007d..007ea8a7ce 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/.gitignore
+++ b/zeppelin-web-angular/projects/zeppelin-react/.gitignore
@@ -1,2 +1,3 @@
 dist
 node_modules
+coverage
diff --git a/zeppelin-web-angular/projects/zeppelin-react/AGENTS.md 
b/zeppelin-web-angular/projects/zeppelin-react/AGENTS.md
new file mode 100644
index 0000000000..8f01d9dabc
--- /dev/null
+++ b/zeppelin-web-angular/projects/zeppelin-react/AGENTS.md
@@ -0,0 +1,54 @@
+<!--
+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.
+-->
+
+# AGENTS.md
+
+Unit test conventions for the React remote, covering only what differs from 
the package.
+
+[`zeppelin-web-angular/AGENTS.md`](../../AGENTS.md) is the baseline and 
applies here unchanged: spec beside source, what to test and what not to, 
determinism, naming, coverage measured but not gated, and the lint rules that 
catch specs which cannot fail. Read it first. This file records the three 
places where this package is not the same.
+
+## Running
+
+| Command | Purpose |
+| --- | --- |
+| `npm test` | Run once |
+| `npm run test:watch` | Re-run on change |
+| `npm test -- --coverage` | With a coverage report |
+
+**`npm test` never runs in pull-request CI.** The build does, through 
`build:react` at the Maven `generate-resources` phase. The lint does too, 
through `lint:react`, but only inside the `run-playwright-e2e-tests` job, 
because `npm lint` is bound to the `test` phase and `frontend.yml` builds this 
module with `-DskipTests`. `npm audit` has its own job. The test suite is 
invoked from the npm-audit remediation workflow, not from the normal PR path, 
and connecting it is [ZEPPELIN-6566](https: [...]
+
+Specs are `Foo.spec.tsx` beside `Foo.tsx`, picked up by this package's own 
`vitest.config.mts`. `@testing-library/react` is available.
+
+Coverage works the same way as the baseline describes, including the caveat: 
the denominator is only the files the specs load, so the percentage is not 
whole-tree coverage.
+
+## What is worth testing here
+
+The code that decides what to render. `SingleResultRenderer` picks a renderer 
from `DatasetType`; picking wrong leaves the user with a blank result. 
`HTMLRenderer` assigns `innerHTML` on a ref and then replaces `<script>` nodes 
by hand so that they execute, which React's own `dangerouslySetInnerHTML` would 
not do. That is worth pinning for both behaviour and safety.
+
+Assert on what a user can see (a role, a label, a value) rather than on the 
DOM tree. Snapshot dumps of rendered markup record that markup changed, which 
it will, since these surfaces are being migrated.
+
+## Do not pin behaviour that is already wrong
+
+The baseline says to write the spec while Angular is still the source of 
truth. On this side there is an exception worth naming.
+
+`TableVisualization` keeps its display mode in `useState` and has no save 
callback, so a setting the user changes is never persisted. Angular stores the 
same choice in `GraphConfig`. Writing a spec that asserts the current behaviour 
would turn that defect into the expected result.
+
+**That surface is something to fix, not something to pin.** Test it once the 
state is lifted to the host. When in doubt: a spec records what the code 
*should* do. If the current behaviour is known to be wrong, fix it first or 
leave it alone.
+
+## Adding a Test
+
+`src/utils/` is the easiest start; `textUtils.spec.ts` is a worked example. 
Everything else follows the baseline.
diff --git a/zeppelin-web-angular/projects/zeppelin-react/eslint.config.js 
b/zeppelin-web-angular/projects/zeppelin-react/eslint.config.js
index 4cc363261d..c7f5de412d 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/eslint.config.js
+++ b/zeppelin-web-angular/projects/zeppelin-react/eslint.config.js
@@ -25,6 +25,7 @@ const globals = require('globals');
 const tseslint = require('typescript-eslint');
 const react = require('eslint-plugin-react');
 const reactHooks = require('eslint-plugin-react-hooks');
+const vitest = require('@vitest/eslint-plugin');
 
 module.exports = tseslint.config(
   {
@@ -89,5 +90,20 @@ module.exports = tseslint.config(
       yoda: 'error',
       'react-hooks/exhaustive-deps': 'error'
     }
+  },
+  {
+    // Catch specs that cannot fail, as eslint-plugin-playwright does for e2e.
+    files: ['src/**/*.spec.{ts,tsx}'],
+    plugins: { vitest },
+    rules: {
+      'vitest/expect-expect': 'error',
+      'vitest/no-conditional-expect': 'error',
+      'vitest/no-identical-title': 'error',
+      'vitest/no-standalone-expect': 'error',
+      'vitest/valid-expect': 'error',
+      'vitest/valid-describe-callback': 'error',
+      'vitest/no-disabled-tests': 'warn',
+      'vitest/no-focused-tests': 'error'
+    }
   }
 );
diff --git a/zeppelin-web-angular/projects/zeppelin-react/package-lock.json 
b/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
index 757bd13946..d68ffc83ba 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
+++ b/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
@@ -30,6 +30,8 @@
         "@types/react-dom": "18.3.7",
         "@typescript-eslint/eslint-plugin": "^8.56.1",
         "@typescript-eslint/parser": "^8.56.1",
+        "@vitest/coverage-v8": "4.1.8",
+        "@vitest/eslint-plugin": "^1.6.27",
         "css-loader": "6.8.0",
         "eslint": "^9.28.0",
         "eslint-plugin-react": "^7.37.5",
@@ -41,6 +43,7 @@
         "ts-loader": "9.5.7",
         "typescript": "5.9.3",
         "typescript-eslint": "^8.33.1",
+        "vite": "8.2.1",
         "vitest": "4.1.8",
         "webpack": "5.105.4",
         "webpack-cli": "5.1.4",
@@ -220,6 +223,16 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.29.7",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz";,
+      "integrity": 
"sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-validator-identifier": {
       "version": "7.29.7",
       "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz";,
@@ -230,6 +243,22 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/parser": {
+      "version": "7.29.8",
+      "resolved": 
"https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz";,
+      "integrity": 
"sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.8"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
     "node_modules/@babel/runtime": {
       "version": "7.29.7",
       "resolved": 
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz";,
@@ -239,6 +268,30 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz";,
+      "integrity": 
"sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@bcoe/v8-coverage": {
+      "version": "1.0.2",
+      "resolved": 
"https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz";,
+      "integrity": 
"sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/@bramus/specificity": {
       "version": "2.4.2",
       "resolved": 
"https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz";,
@@ -411,40 +464,6 @@
         "node": ">=10.0.0"
       }
     },
-    "node_modules/@emnapi/core": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz";,
-      "integrity": 
"sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@emnapi/wasi-threads": "1.2.1",
-        "tslib": "^2.4.0"
-      }
-    },
-    "node_modules/@emnapi/runtime": {
-      "version": "1.10.0",
-      "resolved": 
"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz";,
-      "integrity": 
"sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "tslib": "^2.4.0"
-      }
-    },
-    "node_modules/@emnapi/wasi-threads": {
-      "version": "1.2.1",
-      "resolved": 
"https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz";,
-      "integrity": 
"sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "tslib": "^2.4.0"
-      }
-    },
     "node_modules/@emotion/hash": {
       "version": "0.8.0",
       "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz";,
@@ -1189,29 +1208,10 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/@napi-rs/wasm-runtime": {
-      "version": "1.1.4",
-      "resolved": 
"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz";,
-      "integrity": 
"sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@tybys/wasm-util": "^0.10.1"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/Brooooooklyn";
-      },
-      "peerDependencies": {
-        "@emnapi/core": "^1.7.1",
-        "@emnapi/runtime": "^1.7.1"
-      }
-    },
     "node_modules/@oxc-project/types": {
-      "version": "0.133.0",
-      "resolved": 
"https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz";,
-      "integrity": 
"sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
+      "version": "0.146.0",
+      "resolved": 
"https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz";,
+      "integrity": 
"sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==",
       "dev": true,
       "license": "MIT",
       "funding": {
@@ -1535,10 +1535,27 @@
         "react-dom": ">=16.9.0"
       }
     },
+    "node_modules/@rolldown/binding-android-arm-eabi": {
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz";,
+      "integrity": 
"sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": "^20.19.0 || >=22.12.0"
+      }
+    },
     "node_modules/@rolldown/binding-android-arm64": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz";,
-      "integrity": 
"sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz";,
+      "integrity": 
"sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==",
       "cpu": [
         "arm64"
       ],
@@ -1553,9 +1570,9 @@
       }
     },
     "node_modules/@rolldown/binding-darwin-arm64": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz";,
-      "integrity": 
"sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz";,
+      "integrity": 
"sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==",
       "cpu": [
         "arm64"
       ],
@@ -1570,9 +1587,9 @@
       }
     },
     "node_modules/@rolldown/binding-darwin-x64": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz";,
-      "integrity": 
"sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz";,
+      "integrity": 
"sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==",
       "cpu": [
         "x64"
       ],
@@ -1587,9 +1604,9 @@
       }
     },
     "node_modules/@rolldown/binding-freebsd-x64": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz";,
-      "integrity": 
"sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz";,
+      "integrity": 
"sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==",
       "cpu": [
         "x64"
       ],
@@ -1604,9 +1621,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz";,
-      "integrity": 
"sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz";,
+      "integrity": 
"sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==",
       "cpu": [
         "arm"
       ],
@@ -1621,9 +1638,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-arm64-gnu": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz";,
-      "integrity": 
"sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz";,
+      "integrity": 
"sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==",
       "cpu": [
         "arm64"
       ],
@@ -1638,9 +1655,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-arm64-musl": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz";,
-      "integrity": 
"sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz";,
+      "integrity": 
"sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==",
       "cpu": [
         "arm64"
       ],
@@ -1655,9 +1672,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-ppc64-gnu": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz";,
-      "integrity": 
"sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz";,
+      "integrity": 
"sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==",
       "cpu": [
         "ppc64"
       ],
@@ -1672,9 +1689,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-s390x-gnu": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz";,
-      "integrity": 
"sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz";,
+      "integrity": 
"sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==",
       "cpu": [
         "s390x"
       ],
@@ -1689,9 +1706,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-x64-gnu": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz";,
-      "integrity": 
"sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz";,
+      "integrity": 
"sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==",
       "cpu": [
         "x64"
       ],
@@ -1706,9 +1723,9 @@
       }
     },
     "node_modules/@rolldown/binding-linux-x64-musl": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz";,
-      "integrity": 
"sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz";,
+      "integrity": 
"sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==",
       "cpu": [
         "x64"
       ],
@@ -1723,9 +1740,9 @@
       }
     },
     "node_modules/@rolldown/binding-openharmony-arm64": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz";,
-      "integrity": 
"sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz";,
+      "integrity": 
"sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==",
       "cpu": [
         "arm64"
       ],
@@ -1739,29 +1756,10 @@
         "node": "^20.19.0 || >=22.12.0"
       }
     },
-    "node_modules/@rolldown/binding-wasm32-wasi": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz";,
-      "integrity": 
"sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
-      "cpu": [
-        "wasm32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@emnapi/core": "1.10.0",
-        "@emnapi/runtime": "1.10.0",
-        "@napi-rs/wasm-runtime": "^1.1.4"
-      },
-      "engines": {
-        "node": "^20.19.0 || >=22.12.0"
-      }
-    },
     "node_modules/@rolldown/binding-win32-arm64-msvc": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz";,
-      "integrity": 
"sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz";,
+      "integrity": 
"sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==",
       "cpu": [
         "arm64"
       ],
@@ -1776,9 +1774,9 @@
       }
     },
     "node_modules/@rolldown/binding-win32-x64-msvc": {
-      "version": "1.0.3",
-      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz";,
-      "integrity": 
"sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
+      "version": "1.2.5",
+      "resolved": 
"https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz";,
+      "integrity": 
"sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==",
       "cpu": [
         "x64"
       ],
@@ -1854,17 +1852,6 @@
         }
       }
     },
-    "node_modules/@tybys/wasm-util": {
-      "version": "0.10.2",
-      "resolved": 
"https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz";,
-      "integrity": 
"sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "tslib": "^2.4.0"
-      }
-    },
     "node_modules/@types/aria-query": {
       "version": "5.0.4",
       "resolved": 
"https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz";,
@@ -2340,6 +2327,68 @@
         "url": "https://opencollective.com/eslint";
       }
     },
+    "node_modules/@vitest/coverage-v8": {
+      "version": "4.1.8",
+      "resolved": 
"https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.8.tgz";,
+      "integrity": 
"sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@bcoe/v8-coverage": "^1.0.2",
+        "@vitest/utils": "4.1.8",
+        "ast-v8-to-istanbul": "^1.0.0",
+        "istanbul-lib-coverage": "^3.2.2",
+        "istanbul-lib-report": "^3.0.1",
+        "istanbul-reports": "^3.2.0",
+        "magicast": "^0.5.2",
+        "obug": "^2.1.1",
+        "std-env": "^4.0.0-rc.1",
+        "tinyrainbow": "^3.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/vitest";
+      },
+      "peerDependencies": {
+        "@vitest/browser": "4.1.8",
+        "vitest": "4.1.8"
+      },
+      "peerDependenciesMeta": {
+        "@vitest/browser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vitest/eslint-plugin": {
+      "version": "1.6.27",
+      "resolved": 
"https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.27.tgz";,
+      "integrity": 
"sha512-X1RCAfwbatG4GFbJ/1PIHP9MSZMt0JJThqbYID+vS4L783k6QGlLPe421wQE8dHXuGCcenVLsydiM4qzsYWxhg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "^8.58.0",
+        "@typescript-eslint/utils": "^8.58.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/eslint-plugin": "*",
+        "eslint": ">=8.57.0",
+        "typescript": ">=5.0.0",
+        "vitest": "*"
+      },
+      "peerDependenciesMeta": {
+        "@typescript-eslint/eslint-plugin": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        },
+        "vitest": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@vitest/expect": {
       "version": "4.1.8",
       "resolved": 
"https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz";,
@@ -3141,6 +3190,25 @@
         "node": ">=12"
       }
     },
+    "node_modules/ast-v8-to-istanbul": {
+      "version": "1.0.5",
+      "resolved": 
"https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.5.tgz";,
+      "integrity": 
"sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.31",
+        "estree-walker": "^3.0.3",
+        "js-tokens": "^10.0.0"
+      }
+    },
+    "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": {
+      "version": "10.0.0",
+      "resolved": 
"https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz";,
+      "integrity": 
"sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/async-function": {
       "version": "1.0.0",
       "resolved": 
"https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz";,
@@ -5464,6 +5532,13 @@
         "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
       }
     },
+    "node_modules/html-escaper": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz";,
+      "integrity": 
"sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/html-minifier-terser": {
       "version": "6.1.0",
       "resolved": 
"https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz";,
@@ -6257,6 +6332,45 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/istanbul-lib-coverage": {
+      "version": "3.2.2",
+      "resolved": 
"https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz";,
+      "integrity": 
"sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-report": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz";,
+      "integrity": 
"sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^4.0.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-reports": {
+      "version": "3.2.0",
+      "resolved": 
"https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz";,
+      "integrity": 
"sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/iterator.prototype": {
       "version": "1.1.5",
       "resolved": 
"https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz";,
@@ -6475,9 +6589,9 @@
       }
     },
     "node_modules/lightningcss": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz";,
-      "integrity": 
"sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz";,
+      "integrity": 
"sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
       "dev": true,
       "license": "MPL-2.0",
       "dependencies": {
@@ -6491,23 +6605,23 @@
         "url": "https://opencollective.com/parcel";
       },
       "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"
+        "lightningcss-android-arm64": "1.33.0",
+        "lightningcss-darwin-arm64": "1.33.0",
+        "lightningcss-darwin-x64": "1.33.0",
+        "lightningcss-freebsd-x64": "1.33.0",
+        "lightningcss-linux-arm-gnueabihf": "1.33.0",
+        "lightningcss-linux-arm64-gnu": "1.33.0",
+        "lightningcss-linux-arm64-musl": "1.33.0",
+        "lightningcss-linux-x64-gnu": "1.33.0",
+        "lightningcss-linux-x64-musl": "1.33.0",
+        "lightningcss-win32-arm64-msvc": "1.33.0",
+        "lightningcss-win32-x64-msvc": "1.33.0"
       }
     },
     "node_modules/lightningcss-android-arm64": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz";,
-      "integrity": 
"sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz";,
+      "integrity": 
"sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
       "cpu": [
         "arm64"
       ],
@@ -6526,9 +6640,9 @@
       }
     },
     "node_modules/lightningcss-darwin-arm64": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz";,
-      "integrity": 
"sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz";,
+      "integrity": 
"sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
       "cpu": [
         "arm64"
       ],
@@ -6547,9 +6661,9 @@
       }
     },
     "node_modules/lightningcss-darwin-x64": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz";,
-      "integrity": 
"sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz";,
+      "integrity": 
"sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
       "cpu": [
         "x64"
       ],
@@ -6568,9 +6682,9 @@
       }
     },
     "node_modules/lightningcss-freebsd-x64": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz";,
-      "integrity": 
"sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz";,
+      "integrity": 
"sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
       "cpu": [
         "x64"
       ],
@@ -6589,9 +6703,9 @@
       }
     },
     "node_modules/lightningcss-linux-arm-gnueabihf": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz";,
-      "integrity": 
"sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz";,
+      "integrity": 
"sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
       "cpu": [
         "arm"
       ],
@@ -6610,9 +6724,9 @@
       }
     },
     "node_modules/lightningcss-linux-arm64-gnu": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz";,
-      "integrity": 
"sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz";,
+      "integrity": 
"sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
       "cpu": [
         "arm64"
       ],
@@ -6631,9 +6745,9 @@
       }
     },
     "node_modules/lightningcss-linux-arm64-musl": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz";,
-      "integrity": 
"sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz";,
+      "integrity": 
"sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
       "cpu": [
         "arm64"
       ],
@@ -6652,9 +6766,9 @@
       }
     },
     "node_modules/lightningcss-linux-x64-gnu": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz";,
-      "integrity": 
"sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz";,
+      "integrity": 
"sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
       "cpu": [
         "x64"
       ],
@@ -6673,9 +6787,9 @@
       }
     },
     "node_modules/lightningcss-linux-x64-musl": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz";,
-      "integrity": 
"sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz";,
+      "integrity": 
"sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
       "cpu": [
         "x64"
       ],
@@ -6694,9 +6808,9 @@
       }
     },
     "node_modules/lightningcss-win32-arm64-msvc": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz";,
-      "integrity": 
"sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz";,
+      "integrity": 
"sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
       "cpu": [
         "arm64"
       ],
@@ -6715,9 +6829,9 @@
       }
     },
     "node_modules/lightningcss-win32-x64-msvc": {
-      "version": "1.32.0",
-      "resolved": 
"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz";,
-      "integrity": 
"sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+      "version": "1.33.0",
+      "resolved": 
"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz";,
+      "integrity": 
"sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
       "cpu": [
         "x64"
       ],
@@ -6850,6 +6964,34 @@
         "@jridgewell/sourcemap-codec": "^1.5.5"
       }
     },
+    "node_modules/magicast": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz";,
+      "integrity": 
"sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.7",
+        "@babel/types": "^7.29.7",
+        "source-map-js": "^1.2.1"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz";,
+      "integrity": 
"sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus";
+      }
+    },
     "node_modules/math-intrinsics": {
       "version": "1.1.0",
       "resolved": 
"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz";,
@@ -7498,9 +7640,9 @@
       "license": "ISC"
     },
     "node_modules/picomatch": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz";,
-      "integrity": 
"sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz";,
+      "integrity": 
"sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -7621,9 +7763,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.5.23",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz";,
-      "integrity": 
"sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
+      "version": "8.5.26",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz";,
+      "integrity": 
"sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==",
       "dev": true,
       "funding": [
         {
@@ -7641,7 +7783,7 @@
       ],
       "license": "MIT",
       "dependencies": {
-        "nanoid": "^3.3.16",
+        "nanoid": "^3.3.17",
         "picocolors": "^1.1.1",
         "source-map-js": "^1.2.1"
       },
@@ -8769,13 +8911,13 @@
       }
     },
     "node_modules/rolldown": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz";,
-      "integrity": 
"sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.5.tgz";,
+      "integrity": 
"sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@oxc-project/types": "=0.133.0",
+        "@oxc-project/types": "=0.146.0",
         "@rolldown/pluginutils": "^1.0.0"
       },
       "bin": {
@@ -8785,21 +8927,21 @@
         "node": "^20.19.0 || >=22.12.0"
       },
       "optionalDependencies": {
-        "@rolldown/binding-android-arm64": "1.0.3",
-        "@rolldown/binding-darwin-arm64": "1.0.3",
-        "@rolldown/binding-darwin-x64": "1.0.3",
-        "@rolldown/binding-freebsd-x64": "1.0.3",
-        "@rolldown/binding-linux-arm-gnueabihf": "1.0.3",
-        "@rolldown/binding-linux-arm64-gnu": "1.0.3",
-        "@rolldown/binding-linux-arm64-musl": "1.0.3",
-        "@rolldown/binding-linux-ppc64-gnu": "1.0.3",
-        "@rolldown/binding-linux-s390x-gnu": "1.0.3",
-        "@rolldown/binding-linux-x64-gnu": "1.0.3",
-        "@rolldown/binding-linux-x64-musl": "1.0.3",
-        "@rolldown/binding-openharmony-arm64": "1.0.3",
-        "@rolldown/binding-wasm32-wasi": "1.0.3",
-        "@rolldown/binding-win32-arm64-msvc": "1.0.3",
-        "@rolldown/binding-win32-x64-msvc": "1.0.3"
+        "@rolldown/binding-android-arm-eabi": "1.2.5",
+        "@rolldown/binding-android-arm64": "1.2.5",
+        "@rolldown/binding-darwin-arm64": "1.2.5",
+        "@rolldown/binding-darwin-x64": "1.2.5",
+        "@rolldown/binding-freebsd-x64": "1.2.5",
+        "@rolldown/binding-linux-arm-gnueabihf": "1.2.5",
+        "@rolldown/binding-linux-arm64-gnu": "1.2.5",
+        "@rolldown/binding-linux-arm64-musl": "1.2.5",
+        "@rolldown/binding-linux-ppc64-gnu": "1.2.5",
+        "@rolldown/binding-linux-s390x-gnu": "1.2.5",
+        "@rolldown/binding-linux-x64-gnu": "1.2.5",
+        "@rolldown/binding-linux-x64-musl": "1.2.5",
+        "@rolldown/binding-openharmony-arm64": "1.2.5",
+        "@rolldown/binding-win32-arm64-msvc": "1.2.5",
+        "@rolldown/binding-win32-x64-msvc": "1.2.5"
       }
     },
     "node_modules/router": {
@@ -10292,16 +10434,16 @@
       }
     },
     "node_modules/vite": {
-      "version": "8.0.16",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz";,
-      "integrity": 
"sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
+      "version": "8.2.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz";,
+      "integrity": 
"sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "lightningcss": "^1.32.0",
-        "picomatch": "^4.0.4",
-        "postcss": "^8.5.15",
-        "rolldown": "1.0.3",
+        "lightningcss": "^1.33.0",
+        "picomatch": "^4.0.5",
+        "postcss": "^8.5.25",
+        "rolldown": "~1.2.1",
         "tinyglobby": "^0.2.17"
       },
       "bin": {
@@ -10318,7 +10460,7 @@
       },
       "peerDependencies": {
         "@types/node": "^20.19.0 || >=22.12.0",
-        "@vitejs/devtools": "^0.1.18",
+        "@vitejs/devtools": "^0.4.0",
         "esbuild": "^0.27.0 || ^0.28.0",
         "jiti": ">=1.21.0",
         "less": "^4.0.0",
diff --git a/zeppelin-web-angular/projects/zeppelin-react/package.json 
b/zeppelin-web-angular/projects/zeppelin-react/package.json
index 3dd2c0e0ce..1d99fda253 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/package.json
+++ b/zeppelin-web-angular/projects/zeppelin-react/package.json
@@ -36,6 +36,8 @@
     "@types/react-dom": "18.3.7",
     "@typescript-eslint/eslint-plugin": "^8.56.1",
     "@typescript-eslint/parser": "^8.56.1",
+    "@vitest/coverage-v8": "4.1.8",
+    "@vitest/eslint-plugin": "^1.6.27",
     "css-loader": "6.8.0",
     "eslint": "^9.28.0",
     "eslint-plugin-react": "^7.37.5",
@@ -47,6 +49,7 @@
     "ts-loader": "9.5.7",
     "typescript": "5.9.3",
     "typescript-eslint": "^8.33.1",
+    "vite": "8.2.1",
     "vitest": "4.1.8",
     "webpack": "5.105.4",
     "webpack-cli": "5.1.4",
diff --git 
a/zeppelin-web-angular/projects/zeppelin-react/src/utils/textUtils.spec.ts 
b/zeppelin-web-angular/projects/zeppelin-react/src/utils/textUtils.spec.ts
new file mode 100644
index 0000000000..b7df1158f0
--- /dev/null
+++ b/zeppelin-web-angular/projects/zeppelin-react/src/utils/textUtils.spec.ts
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+import { describe, expect, it } from 'vitest';
+
+import { checkAndReplaceCarriageReturn } from './textUtils';
+
+describe('checkAndReplaceCarriageReturn', () => {
+  it('leaves text without carriage returns untouched', () => {
+    expect(checkAndReplaceCarriageReturn('plain\ntext')).toBe('plain\ntext');
+  });
+
+  it('normalises CRLF to LF', () => {
+    expect(checkAndReplaceCarriageReturn('a\r\nb')).toBe('a\nb');
+  });
+
+  it('overwrites the start of the line, the way a terminal progress bar does', 
() => {
+    expect(checkAndReplaceCarriageReturn('12345\rab')).toBe('ab345');
+  });
+
+  it('keeps the longer previous content visible behind a shorter overwrite', 
() => {
+    expect(checkAndReplaceCarriageReturn('loading...\rok')).toBe('okading...');
+  });
+
+  it('drops the previous content when the overwrite is at least as long', () 
=> {
+    expect(checkAndReplaceCarriageReturn('ab\r1234')).toBe('1234');
+  });
+
+  it('rewrites only the lines that contain a carriage return', () => {
+    expect(checkAndReplaceCarriageReturn('keep\n12345\rab\nkeep 
too')).toBe('keep\nab345\nkeep too');
+  });
+
+  it('returns an empty string unchanged', () => {
+    expect(checkAndReplaceCarriageReturn('')).toBe('');
+  });
+});
diff --git a/zeppelin-web-angular/projects/zeppelin-react/vitest.config.ts 
b/zeppelin-web-angular/projects/zeppelin-react/vitest.config.mts
similarity index 54%
rename from zeppelin-web-angular/projects/zeppelin-react/vitest.config.ts
rename to zeppelin-web-angular/projects/zeppelin-react/vitest.config.mts
index ffddd37ae3..e2ebae3144 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/vitest.config.ts
+++ b/zeppelin-web-angular/projects/zeppelin-react/vitest.config.mts
@@ -10,20 +10,29 @@
  * limitations under the License.
  */
 
-import path from 'path';
+// vite is pinned in package.json: the React remote keeps its own lockfile and 
drifted to a different minor.
+import { fileURLToPath } from 'node:url';
 import { defineConfig } from 'vitest/config';
 
 export default defineConfig({
   // Kept in sync with the `resolve.alias` block in webpack.config.js.
   resolve: {
     alias: {
-      '@': path.resolve(__dirname, 'src'),
-      '@zeppelin/sdk': path.resolve(__dirname, '../zeppelin-sdk/src')
+      '@': fileURLToPath(new URL('./src', import.meta.url)),
+      '@zeppelin/sdk': fileURLToPath(new URL('../zeppelin-sdk/src', 
import.meta.url))
     }
   },
   test: {
     environment: 'jsdom',
     include: ['src/**/*.spec.{ts,tsx}'],
-    setupFiles: ['./src/test-setup.ts']
+    setupFiles: ['./src/test-setup.ts'],
+    coverage: {
+      provider: 'v8',
+      reporter: ['text', 'lcov'],
+      reportsDirectory: './coverage',
+      // No `include`: v4 reports only the files the specs load.
+      exclude: ['**/*.spec.{ts,tsx}', '**/index.ts', 'src/test-setup.ts', 
'src/main.ts']
+      // No thresholds on purpose: see zeppelin-web-angular/AGENTS.md.
+    }
   }
 });
diff --git 
a/zeppelin-web-angular/src/app/share/pipes/humanize-bytes.pipe.spec.ts 
b/zeppelin-web-angular/src/app/share/pipes/humanize-bytes.pipe.spec.ts
new file mode 100644
index 0000000000..c3c650cb64
--- /dev/null
+++ b/zeppelin-web-angular/src/app/share/pipes/humanize-bytes.pipe.spec.ts
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+import { describe, expect, it } from 'vitest';
+
+import { HumanizeBytesPipe } from './humanize-bytes.pipe';
+
+describe('HumanizeBytesPipe', () => {
+  const pipe = new HumanizeBytesPipe();
+
+  it('renders a dash for null and undefined', () => {
+    expect(pipe.transform(null)).toBe('-');
+    expect(pipe.transform(undefined)).toBe('-');
+  });
+
+  it('renders a dash for a string that is not a number', () => {
+    expect(pipe.transform('not a number')).toBe('-');
+  });
+
+  it('accepts a numeric string', () => {
+    expect(pipe.transform('2048')).toBe('2.00 KB');
+  });
+
+  it('reports values below 1000 as raw bytes', () => {
+    expect(pipe.transform(0)).toBe('0 B');
+    expect(pipe.transform(999)).toBe('999 B');
+  });
+
+  it('switches from bytes to KB at 1000 but divides by 1024', () => {
+    // 1000 is already reported in KB even though it is below 1024, so the 
first kilobyte value rendered is less than 1.
+    expect(pipe.transform(1000)).toBe('0.98 KB');
+    expect(pipe.transform(1024)).toBe('1.00 KB');
+  });
+
+  it('climbs to the next unit once the value reaches 1000 times the base', () 
=> {
+    expect(pipe.transform(1024 * 1024)).toBe('1.00 MB');
+    expect(pipe.transform(1024 * 1024 * 1024)).toBe('1.00 GB');
+  });
+
+  it('uses two decimals below the base and three significant digits above it', 
() => {
+    expect(pipe.transform(1000)).toBe('0.98 KB'); // below the base: toFixed(2)
+    expect(pipe.transform(10752)).toBe('10.5 KB'); // above it: toPrecision(3)
+  });
+});
diff --git a/zeppelin-web-angular/src/app/utility/get-keyword-positions.spec.ts 
b/zeppelin-web-angular/src/app/utility/get-keyword-positions.spec.ts
new file mode 100644
index 0000000000..7f04d2b24d
--- /dev/null
+++ b/zeppelin-web-angular/src/app/utility/get-keyword-positions.spec.ts
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+import { describe, expect, it } from 'vitest';
+
+import { getKeywordPositions } from './get-keyword-positions';
+
+// This function has no callers today, and neither does the line-map module it 
builds on.
+// It is kept as a worked example because it has the shape the conventions 
describe (branches, boundaries, a regular expression), and writing the spec is 
what surfaced that it is unused.
+describe('getKeywordPositions', () => {
+  it('returns no positions when the keyword is absent', () => {
+    expect(getKeywordPositions(['missing'], 'nothing to find 
here')).toEqual([]);
+  });
+
+  it('reports line and character for a match on the first line', () => {
+    expect(getKeywordPositions(['world'], 'hello world')).toEqual([{ line: 0, 
character: 6, length: 5 }]);
+  });
+
+  it('counts lines from zero and restarts the character offset on each line', 
() => {
+    expect(getKeywordPositions(['target'], 'first\nsecond target')).toEqual([{ 
line: 1, character: 7, length: 6 }]);
+  });
+
+  it('reports every occurrence of the same keyword', () => {
+    expect(getKeywordPositions(['ab'], 'ab\nab')).toEqual([
+      { line: 0, character: 0, length: 2 },
+      { line: 1, character: 0, length: 2 }
+    ]);
+  });
+
+  it('matches case-insensitively', () => {
+    expect(getKeywordPositions(['SELECT'], 'select 1')).toEqual([{ line: 0, 
character: 0, length: 6 }]);
+  });
+
+  it('groups results by keyword rather than by position in the text', () => {
+    expect(getKeywordPositions(['a', 'b'], 'b a')).toEqual([
+      { line: 0, character: 2, length: 1 },
+      { line: 0, character: 0, length: 1 }
+    ]);
+  });
+
+  it('treats the keyword as a regular expression, not a literal', () => {
+    // `new RegExp(keyword, 'ig')`: `.` matches any character, and the 
reported length is the keyword's, not the match's.
+    expect(getKeywordPositions(['a.'], 'ab')).toEqual([{ line: 0, character: 
0, length: 2 }]);
+    expect(getKeywordPositions(['a+'], 'aaa')).toEqual([{ line: 0, character: 
0, length: 2 }]);
+  });
+
+  it('returns an empty result for an empty keyword list', () => {
+    expect(getKeywordPositions([], 'hello')).toEqual([]);
+  });
+});
diff --git a/zeppelin-web-angular/src/tsconfig.spec.json 
b/zeppelin-web-angular/src/tsconfig.spec.json
index ba47facd5a..e4233dd1d4 100644
--- a/zeppelin-web-angular/src/tsconfig.spec.json
+++ b/zeppelin-web-angular/src/tsconfig.spec.json
@@ -4,6 +4,12 @@
     "outDir": "../out-tsc/spec",
     "types": ["mathjax", "node"]
   },
-  "include": ["**/*.spec.ts", "../test/test-setup.ts", 
"../vitest.shell.config.mts"],
+  "include": [
+    "**/*.spec.ts",
+    "../projects/zeppelin-sdk/**/*.spec.ts",
+    "../projects/zeppelin-visualization/**/*.spec.ts",
+    "../test/test-setup.ts",
+    "../vitest.shell.config.mts"
+  ],
   "exclude": []
 }
diff --git a/zeppelin-web-angular/vitest.shell.config.mts 
b/zeppelin-web-angular/vitest.shell.config.mts
index 4799e537f6..190081607b 100644
--- a/zeppelin-web-angular/vitest.shell.config.mts
+++ b/zeppelin-web-angular/vitest.shell.config.mts
@@ -10,12 +10,22 @@
  * limitations under the License.
  */
 
+// vite is pinned in package.json: the React remote keeps its own lockfile and 
drifted to a different minor.
 import { defineConfig } from 'vitest/config';
 
 export default defineConfig({
   test: {
     environment: 'jsdom',
-    include: ['src/**/*.spec.ts'],
-    setupFiles: ['./test/test-setup.ts']
+    include: ['src/**/*.spec.ts', 'projects/zeppelin-sdk/**/*.spec.ts', 
'projects/zeppelin-visualization/**/*.spec.ts'],
+    setupFiles: ['./test/test-setup.ts'],
+    coverage: {
+      provider: 'v8',
+      reporter: ['text', 'lcov'],
+      reportsDirectory: './coverage',
+      // No `include`: v4 then reports only the files the specs load. Naming a 
directory makes the provider parse every source under it, which fails on 
decorator syntax while ZEPPELIN-6637 is open. Re-measure before widening, since 
coverage parses separately from the test transform. Note the reported 
percentage is therefore not whole-tree coverage; see AGENTS.md.
+      // TS exclusions are aligned with the e2e coverage reporter's where they 
overlap. The two measurements stay separate and are not comparable.
+      exclude: ['**/*.spec.ts', '**/*.module.ts', '**/*.guard.ts', 
'**/*.routing.ts', '**/public-api.ts', '**/index.ts']
+      // No thresholds on purpose: see zeppelin-web-angular/AGENTS.md.
+    }
   }
 });

Reply via email to