feat: update imitate data pipeline, models, and tests

This commit is contained in:
pyr0ball 2026-07-11 22:38:59 -07:00
parent c123492a1c
commit 73db8f1402
5 changed files with 379 additions and 287 deletions

View file

@ -14,6 +14,7 @@ from __future__ import annotations
import base64 import base64
import json import json
import logging import logging
import threading
import time import time
import uuid import uuid
from datetime import datetime, timezone from datetime import datetime, timezone
@ -22,6 +23,13 @@ from typing import Any
from urllib.error import URLError from urllib.error import URLError
from urllib.request import Request, urlopen from urllib.request import Request, urlopen
try:
from starlette.requests import Request as StarletteRequest
from starlette.responses import Response as StarletteResponse
except ImportError:
StarletteRequest = Any # type: ignore[assignment,misc]
StarletteResponse = Any # type: ignore[assignment,misc]
import httpx import httpx
import yaml import yaml
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
@ -303,7 +311,11 @@ def _run_cftext(
polling the service health endpoint this fails fast on model load errors instead polling the service health endpoint this fails fast on model load errors instead
of waiting out the full timeout. of waiting out the full timeout.
""" """
# Allocate # Allocate — retry on 503 (previous allocation may still be releasing)
_alloc_delays = [3.0, 6.0, 12.0]
for _attempt, _delay in enumerate([0.0] + _alloc_delays):
if _delay:
time.sleep(_delay)
alloc_resp = httpx.post( alloc_resp = httpx.post(
f"{cforch_base}/api/services/cf-text/allocate", f"{cforch_base}/api/services/cf-text/allocate",
json={ json={
@ -314,6 +326,8 @@ def _run_cftext(
}, },
timeout=30.0, timeout=30.0,
) )
if alloc_resp.status_code != 503 or _attempt == len(_alloc_delays):
break
alloc_resp.raise_for_status() alloc_resp.raise_for_status()
data = alloc_resp.json() data = alloc_resp.json()
service_url: str = data["url"] service_url: str = data["url"]
@ -498,7 +512,10 @@ def get_catalog() -> dict:
# ── GET /run (SSE) ───────────────────────────────────────────────────────────── # ── GET /run (SSE) ─────────────────────────────────────────────────────────────
def _get_imitate_session(request: Any, response: Any) -> "CloudUser | None": def _get_imitate_session(
request: StarletteRequest,
response: StarletteResponse,
) -> "CloudUser | None":
"""Optional session dependency — returns None when cloud_session is unavailable.""" """Optional session dependency — returns None when cloud_session is unavailable."""
try: try:
from app.cloud_session import get_session from app.cloud_session import get_session
@ -625,43 +642,50 @@ def run_imitate(
yield _sse({"type": "model_done", **result}) yield _sse({"type": "model_done", **result})
if cftext_real: if cftext_real:
from concurrent.futures import ThreadPoolExecutor, as_completed
# Announce all models upfront so the UI can show loading states immediately
for model_id in cftext_real:
yield _sse({"type": "model_start", "model": model_id, "service": "cf-text"})
_user_id: str | None = getattr(session, "user_id", None) _user_id: str | None = getattr(session, "user_id", None)
# Only forward real cloud user IDs — skip local/anon sessions # Only forward real cloud user IDs — skip local/anon sessions
if _user_id in (None, "local", "local-dev") or (_user_id or "").startswith("anon-"): if _user_id in (None, "local", "local-dev") or (_user_id or "").startswith("anon-"):
_user_id = None _user_id = None
with ThreadPoolExecutor(max_workers=len(cftext_real)) as pool: for model_id in cftext_real:
future_to_model = { yield _sse({"type": "model_start", "model": model_id, "service": "cf-text"})
pool.submit(
_run_cftext, cforch_base, mid, prompt, system_ctx, temperature, # Run blocking cf-text call in a thread; yield heartbeats every 15 s
180.0, _user_id, # so proxies/browsers don't kill the idle SSE connection during cold starts.
): mid _slot: dict = {}
for mid in cftext_real _done = threading.Event()
}
for future in as_completed(future_to_model): def _worker(mid: str = model_id) -> None:
model_id = future_to_model[future]
try: try:
response, elapsed_ms, cold_started = future.result() r, e, c = _run_cftext(
if cold_started: cforch_base, mid, prompt, system_ctx, temperature,
yield _sse({"type": "model_coldstart", "model": model_id}) 180.0, _user_id,
result = { )
"model": model_id, _slot.update({"response": r, "elapsed_ms": e, "cold_started": c})
"response": response,
"elapsed_ms": elapsed_ms,
"error": None,
}
except Exception as exc: except Exception as exc:
_slot["error"] = str(exc)
finally:
_done.set()
threading.Thread(target=_worker, daemon=True).start()
while not _done.wait(timeout=15.0):
yield _sse({"type": "heartbeat"})
if "error" in _slot:
result = { result = {
"model": model_id, "model": model_id,
"response": "", "response": "",
"elapsed_ms": 0, "elapsed_ms": 0,
"error": str(exc), "error": _slot["error"],
}
else:
if _slot.get("cold_started"):
yield _sse({"type": "model_coldstart", "model": model_id})
result = {
"model": model_id,
"response": _slot["response"],
"elapsed_ms": _slot["elapsed_ms"],
"error": None,
} }
results.append(result) results.append(result)
yield _sse({"type": "model_done", **result}) yield _sse({"type": "model_done", **result})

View file

@ -318,9 +318,28 @@ def _register_in_node_catalogs(
) )
return [] return []
# Resolve the primary GGUF file — skip mmproj (vision projection matrices).
# If no .gguf file exists the model is safetensors-only: llama.cpp cannot
# load it, so catalog registration would produce a broken entry.
gguf_files = sorted(
(f for f in local_path.glob("*.gguf") if "mmproj" not in f.name.lower()),
key=lambda f: f.stat().st_size,
reverse=True,
)
if not gguf_files:
logger.warning(
"%s: no .gguf files found in %s — safetensors-only model, "
"skipping catalog registration",
repo_id, local_path,
)
return []
# Pick the largest GGUF (highest quality when multiple quant levels downloaded)
gguf_file = gguf_files[0]
gguf_filename = gguf_file.name
model_key = _catalog_key(repo_id) model_key = _catalog_key(repo_id)
local_path_str = str(local_path) local_path_str = str(local_path)
vram_4bit = round(vram_mb_fp16 / 4 * 1.1)
updated: list[str] = [] updated: list[str] = []
for yaml_file in sorted(profiles_dir.glob("*.yaml")): for yaml_file in sorted(profiles_dir.glob("*.yaml")):
@ -335,67 +354,52 @@ def _register_in_node_catalogs(
max_mb: int = cf_text.get("max_mb", 0) max_mb: int = cf_text.get("max_mb", 0)
catalog: dict = cf_text.get("catalog") or {} catalog: dict = cf_text.get("catalog") or {}
# If the node has a different local model dir, remap the NFS path. # If the node stores models at a different root (model_base_path),
# remap to that root while keeping the dir name and GGUF filename.
model_base = cf_text.get("model_base_path", "").rstrip("/") model_base = cf_text.get("model_base_path", "").rstrip("/")
if model_base: if model_base:
nfs_base = str(_CF_TEXT_MODELS_DIR).rstrip("/") effective_path_str = f"{model_base}/{local_path.name}/{gguf_filename}"
model_name = local_path.name
effective_path_str = f"{model_base}/{model_name}"
else: else:
effective_path_str = local_path_str effective_path_str = str(gguf_file)
# Skip if key already exists # Skip if key already exists
if model_key in catalog: if model_key in catalog:
logger.debug("Key %r already in %s — skipping", model_key, yaml_file.name) logger.debug("Key %r already in %s — skipping", model_key, yaml_file.name)
continue continue
# Skip if any existing entry already points at this path (or a file within it) # Skip if this GGUF file or its parent directory is already registered
registered_paths = { registered_paths = {
str(entry.get("path", "")) str(entry.get("path", ""))
for entry in catalog.values() for entry in catalog.values()
if isinstance(entry, dict) if isinstance(entry, dict)
} }
if effective_path_str in registered_paths or any( if (
p.startswith(effective_path_str + "/") for p in registered_paths effective_path_str in registered_paths
or local_path_str in registered_paths
or any(p.startswith(local_path_str + "/") for p in registered_paths)
): ):
logger.debug("Path %s already registered in %s — skipping", effective_path_str, yaml_file.name) logger.debug(
"Path %s already registered in %s — skipping",
effective_path_str, yaml_file.name,
)
continue continue
# Determine whether model fits at FP16 or needs 4-bit # GGUF models are already quantized; vram_mb_fp16 is the file size.
if vram_mb_fp16 <= max_mb: # No 4-bit fallback needed — the file is what it is.
vram_for_node = vram_mb_fp16 if vram_mb_fp16 > max_mb:
needs_4bit = False
elif vram_4bit <= max_mb:
vram_for_node = vram_4bit
needs_4bit = True
else:
logger.debug( logger.debug(
"%s too large for %s (fp16=%d MB, 4bit=%d MB, max=%d MB)", "%s too large for %s (vram=%d MB, max=%d MB)",
repo_id, yaml_file.name, vram_mb_fp16, vram_4bit, max_mb, repo_id, yaml_file.name, vram_mb_fp16, max_mb,
) )
continue continue
desc = f"{repo_id} ({role}, downloaded via avocet)" desc = f"{repo_id} ({role}, downloaded via avocet)"
if needs_4bit:
desc += " — CF_TEXT_4BIT=1 required"
vram_comment = (
f" # 4-bit estimate; FP16 footprint is {vram_mb_fp16} MB"
if needs_4bit
else f" # FP16 file-size estimate"
)
env_block = (
f" env:\n"
f" CF_TEXT_4BIT: \"1\"\n"
if needs_4bit else ""
)
entry_block = ( entry_block = (
f" # auto-registered by avocet on download\n" f" # auto-registered by avocet on download\n"
f" {model_key}:\n" f" {model_key}:\n"
f" path: {effective_path_str}\n" f" path: {effective_path_str}\n"
f" vram_mb: {vram_for_node}{vram_comment}\n" f" vram_mb: {vram_mb_fp16} # {gguf_filename}\n"
f" description: \"{desc}\"\n" f" description: \"{desc}\"\n"
f"{env_block}"
) )
new_content = _insert_catalog_entry(content, entry_block) new_content = _insert_catalog_entry(content, entry_block)
@ -406,8 +410,8 @@ def _register_in_node_catalogs(
yaml_file.write_text(new_content, encoding="utf-8") yaml_file.write_text(new_content, encoding="utf-8")
updated.append(yaml_file.stem) updated.append(yaml_file.stem)
logger.info( logger.info(
"Registered %s in %s (vram_mb=%d, 4bit=%s)", "Registered %s in %s (path=%s, vram_mb=%d)",
model_key, yaml_file.name, vram_for_node, needs_4bit, model_key, yaml_file.name, effective_path_str, vram_mb_fp16,
) )
except Exception as exc: except Exception as exc:

View file

@ -566,15 +566,20 @@ def _make_node_yaml(tmp_path: Path, max_mb: int = 8192) -> Path:
return p return p
def test_catalog_registration_fp16_no_env_block(tmp_path): def test_catalog_registration_writes_gguf_path(tmp_path):
"""When model fits at FP16, no env block should be written.""" """Registration writes the full GGUF file path, not the directory."""
from app import models as models_module from app import models as models_module
model_dir = tmp_path / "org--SmallModel"
model_dir.mkdir()
gguf = model_dir / "smallmodel-Q4_K_M.gguf"
gguf.write_bytes(b"fake")
node_yaml = _make_node_yaml(tmp_path, max_mb=8192) node_yaml = _make_node_yaml(tmp_path, max_mb=8192)
with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path): with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path):
updated = models_module._register_in_node_catalogs( updated = models_module._register_in_node_catalogs(
repo_id="org/SmallModel", repo_id="org/SmallModel",
local_path=tmp_path / "org--SmallModel", local_path=model_dir,
vram_mb_fp16=4000, vram_mb_fp16=4000,
role="generator", role="generator",
) )
@ -583,45 +588,86 @@ def test_catalog_registration_fp16_no_env_block(tmp_path):
content = node_yaml.read_text() content = node_yaml.read_text()
# _catalog_key strips org prefix and lowercases: "org/SmallModel" → "smallmodel" # _catalog_key strips org prefix and lowercases: "org/SmallModel" → "smallmodel"
assert "smallmodel:" in content assert "smallmodel:" in content
assert str(gguf) in content
assert "CF_TEXT_4BIT" not in content assert "CF_TEXT_4BIT" not in content
assert "env:" not in content assert "env:" not in content
def test_catalog_registration_needs_4bit_writes_env_block(tmp_path): def test_catalog_registration_safetensors_skipped(tmp_path):
"""When model only fits at 4-bit, env: CF_TEXT_4BIT: '1' must be written.""" """Safetensors-only models (no .gguf) are skipped — llama.cpp cannot load them."""
from app import models as models_module from app import models as models_module
model_dir = tmp_path / "org--SftModel"
model_dir.mkdir()
(model_dir / "model.safetensors").write_bytes(b"fake")
node_yaml = _make_node_yaml(tmp_path, max_mb=8192) node_yaml = _make_node_yaml(tmp_path, max_mb=8192)
original_content = node_yaml.read_text()
with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path): with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path):
updated = models_module._register_in_node_catalogs( updated = models_module._register_in_node_catalogs(
repo_id="org/BigModel", repo_id="org/SftModel",
local_path=tmp_path / "org--BigModel", local_path=model_dir,
vram_mb_fp16=20000, # won't fit at FP16 on 8 GB vram_mb_fp16=5000,
role="generator", role="generator",
) )
assert "testnode" in updated assert updated == []
content = node_yaml.read_text() assert node_yaml.read_text() == original_content
# _catalog_key: "org/BigModel" → "bigmodel"
assert "bigmodel:" in content
assert "env:" in content
assert 'CF_TEXT_4BIT: "1"' in content
assert "CF_TEXT_4BIT=1 required" in content # description note
def test_catalog_registration_too_large_skipped(tmp_path): def test_catalog_registration_too_large_skipped(tmp_path):
"""Model too large even at 4-bit should not be registered.""" """GGUF whose VRAM exceeds node max_mb is not registered."""
from app import models as models_module from app import models as models_module
model_dir = tmp_path / "org--HugeModel"
model_dir.mkdir()
(model_dir / "huge-Q8_0.gguf").write_bytes(b"fake")
node_yaml = _make_node_yaml(tmp_path, max_mb=8192) node_yaml = _make_node_yaml(tmp_path, max_mb=8192)
with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path): with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path):
updated = models_module._register_in_node_catalogs( updated = models_module._register_in_node_catalogs(
repo_id="org/HugeModel", repo_id="org/HugeModel",
local_path=tmp_path / "org--HugeModel", local_path=model_dir,
vram_mb_fp16=80000, # 4-bit ~22 GB, still won't fit on 8 GB vram_mb_fp16=80000,
role="generator", role="generator",
) )
assert updated == [] assert updated == []
content = node_yaml.read_text() content = node_yaml.read_text()
assert "hugemodel" not in content assert "hugemodel" not in content
def test_catalog_registration_model_base_path_remapped(tmp_path):
"""When node has model_base_path, the entry uses the remapped path with GGUF filename."""
from app import models as models_module
model_dir = tmp_path / "org--ReMapped"
model_dir.mkdir()
(model_dir / "remapped-Q6_K.gguf").write_bytes(b"fake")
node_yaml = tmp_path / "remapnode.yaml"
node_yaml.write_text(
"services:\n"
" cf-text:\n"
" max_mb: 8192\n"
" model_base_path: /custom/models\n"
" catalog:\n"
" placeholder:\n"
" path: /custom/models/placeholder/model.gguf\n"
" vram_mb: 100\n"
" description: placeholder\n",
encoding="utf-8",
)
with patch.object(models_module, "_CF_ORCH_PROFILES_DIR", tmp_path):
updated = models_module._register_in_node_catalogs(
repo_id="org/ReMapped",
local_path=model_dir,
vram_mb_fp16=4000,
role="generator",
)
assert "remapnode" in updated
content = node_yaml.read_text()
assert "/custom/models/org--ReMapped/remapped-Q6_K.gguf" in content

388
web/package-lock.json generated
View file

@ -28,8 +28,8 @@
"jsdom": "^28.1.0", "jsdom": "^28.1.0",
"typescript": "~5.9.3", "typescript": "~5.9.3",
"unocss": "^66.6.4", "unocss": "^66.6.4",
"vite": "^7.3.1", "vite": "^7.3.5",
"vitest": "^4.0.18", "vitest": "^4.1.0",
"vue-tsc": "^3.1.5" "vue-tsc": "^3.1.5"
} }
}, },
@ -334,9 +334,9 @@
} }
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
"integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -351,9 +351,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
"integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -368,9 +368,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
"integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -385,9 +385,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
"integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -402,9 +402,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
"integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -419,9 +419,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
"integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -436,9 +436,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
"integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -453,9 +453,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
"integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -470,9 +470,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
"integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -487,9 +487,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
"integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -504,9 +504,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
"integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -521,9 +521,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
"integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -538,9 +538,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
"integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@ -555,9 +555,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
"integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -572,9 +572,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
"integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -589,9 +589,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
"integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -606,9 +606,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
"integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -623,9 +623,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-arm64": { "node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
"integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -640,9 +640,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
"integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -657,9 +657,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-arm64": { "node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
"integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -674,9 +674,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
"integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -691,9 +691,9 @@
} }
}, },
"node_modules/@esbuild/openharmony-arm64": { "node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
"integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -708,9 +708,9 @@
} }
}, },
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
"integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -725,9 +725,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
"integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -742,9 +742,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
"integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -759,9 +759,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
"integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -2073,31 +2073,31 @@
} }
}, },
"node_modules/@vitest/expect": { "node_modules/@vitest/expect": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz",
"integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==", "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@standard-schema/spec": "^1.0.0", "@standard-schema/spec": "^1.1.0",
"@types/chai": "^5.2.2", "@types/chai": "^5.2.2",
"@vitest/spy": "4.0.18", "@vitest/spy": "4.1.10",
"@vitest/utils": "4.0.18", "@vitest/utils": "4.1.10",
"chai": "^6.2.1", "chai": "^6.2.2",
"tinyrainbow": "^3.0.3" "tinyrainbow": "^3.1.0"
}, },
"funding": { "funding": {
"url": "https://opencollective.com/vitest" "url": "https://opencollective.com/vitest"
} }
}, },
"node_modules/@vitest/mocker": { "node_modules/@vitest/mocker": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz",
"integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "4.0.18", "@vitest/spy": "4.1.10",
"estree-walker": "^3.0.3", "estree-walker": "^3.0.3",
"magic-string": "^0.30.21" "magic-string": "^0.30.21"
}, },
@ -2106,7 +2106,7 @@
}, },
"peerDependencies": { "peerDependencies": {
"msw": "^2.4.9", "msw": "^2.4.9",
"vite": "^6.0.0 || ^7.0.0-0" "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"msw": { "msw": {
@ -2128,26 +2128,26 @@
} }
}, },
"node_modules/@vitest/pretty-format": { "node_modules/@vitest/pretty-format": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz",
"integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"tinyrainbow": "^3.0.3" "tinyrainbow": "^3.1.0"
}, },
"funding": { "funding": {
"url": "https://opencollective.com/vitest" "url": "https://opencollective.com/vitest"
} }
}, },
"node_modules/@vitest/runner": { "node_modules/@vitest/runner": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz",
"integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==", "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/utils": "4.0.18", "@vitest/utils": "4.1.10",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
"funding": { "funding": {
@ -2155,13 +2155,14 @@
} }
}, },
"node_modules/@vitest/snapshot": { "node_modules/@vitest/snapshot": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz",
"integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "4.0.18", "@vitest/pretty-format": "4.1.10",
"@vitest/utils": "4.1.10",
"magic-string": "^0.30.21", "magic-string": "^0.30.21",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
@ -2170,9 +2171,9 @@
} }
}, },
"node_modules/@vitest/spy": { "node_modules/@vitest/spy": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz",
"integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"funding": { "funding": {
@ -2180,14 +2181,15 @@
} }
}, },
"node_modules/@vitest/utils": { "node_modules/@vitest/utils": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz",
"integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "4.0.18", "@vitest/pretty-format": "4.1.10",
"tinyrainbow": "^3.0.3" "convert-source-map": "^2.0.0",
"tinyrainbow": "^3.1.0"
}, },
"funding": { "funding": {
"url": "https://opencollective.com/vitest" "url": "https://opencollective.com/vitest"
@ -2784,6 +2786,13 @@
"node": "^14.18.0 || >=16.10.0" "node": "^14.18.0 || >=16.10.0"
} }
}, },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true,
"license": "MIT"
},
"node_modules/copy-anything": { "node_modules/copy-anything": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz",
@ -2956,16 +2965,16 @@
} }
}, },
"node_modules/es-module-lexer": { "node_modules/es-module-lexer": {
"version": "1.7.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.0.tgz",
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "integrity": "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.27.3", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
"integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
@ -2976,32 +2985,32 @@
"node": ">=18" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.3", "@esbuild/aix-ppc64": "0.28.1",
"@esbuild/android-arm": "0.27.3", "@esbuild/android-arm": "0.28.1",
"@esbuild/android-arm64": "0.27.3", "@esbuild/android-arm64": "0.28.1",
"@esbuild/android-x64": "0.27.3", "@esbuild/android-x64": "0.28.1",
"@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-arm64": "0.28.1",
"@esbuild/darwin-x64": "0.27.3", "@esbuild/darwin-x64": "0.28.1",
"@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-arm64": "0.28.1",
"@esbuild/freebsd-x64": "0.27.3", "@esbuild/freebsd-x64": "0.28.1",
"@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm": "0.28.1",
"@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-arm64": "0.28.1",
"@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-ia32": "0.28.1",
"@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-loong64": "0.28.1",
"@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-mips64el": "0.28.1",
"@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-ppc64": "0.28.1",
"@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-riscv64": "0.28.1",
"@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-s390x": "0.28.1",
"@esbuild/linux-x64": "0.27.3", "@esbuild/linux-x64": "0.28.1",
"@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-arm64": "0.28.1",
"@esbuild/netbsd-x64": "0.27.3", "@esbuild/netbsd-x64": "0.28.1",
"@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-arm64": "0.28.1",
"@esbuild/openbsd-x64": "0.27.3", "@esbuild/openbsd-x64": "0.28.1",
"@esbuild/openharmony-arm64": "0.27.3", "@esbuild/openharmony-arm64": "0.28.1",
"@esbuild/sunos-x64": "0.27.3", "@esbuild/sunos-x64": "0.28.1",
"@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-arm64": "0.28.1",
"@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-ia32": "0.28.1",
"@esbuild/win32-x64": "0.27.3" "@esbuild/win32-x64": "0.28.1"
} }
}, },
"node_modules/estree-walker": { "node_modules/estree-walker": {
@ -3252,14 +3261,11 @@
} }
}, },
"node_modules/js-cookie": { "node_modules/js-cookie": {
"version": "3.0.5", "version": "3.0.8",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz",
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT"
"engines": {
"node": ">=14"
}
}, },
"node_modules/jsdom": { "node_modules/jsdom": {
"version": "28.1.0", "version": "28.1.0",
@ -4030,9 +4036,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/std-env": { "node_modules/std-env": {
"version": "3.10.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
"integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -4193,9 +4199,9 @@
} }
}, },
"node_modules/tinyrainbow": { "node_modules/tinyrainbow": {
"version": "3.0.3", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
"integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -4325,9 +4331,9 @@
} }
}, },
"node_modules/undici": { "node_modules/undici": {
"version": "7.25.0", "version": "7.28.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz",
"integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -4422,13 +4428,13 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "7.3.2", "version": "7.3.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
"integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "^0.27.0", "esbuild": "^0.27.0 || ^0.28.0",
"fdir": "^6.5.0", "fdir": "^6.5.0",
"picomatch": "^4.0.3", "picomatch": "^4.0.3",
"postcss": "^8.5.6", "postcss": "^8.5.6",
@ -4497,31 +4503,31 @@
} }
}, },
"node_modules/vitest": { "node_modules/vitest": {
"version": "4.0.18", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz",
"integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/expect": "4.0.18", "@vitest/expect": "4.1.10",
"@vitest/mocker": "4.0.18", "@vitest/mocker": "4.1.10",
"@vitest/pretty-format": "4.0.18", "@vitest/pretty-format": "4.1.10",
"@vitest/runner": "4.0.18", "@vitest/runner": "4.1.10",
"@vitest/snapshot": "4.0.18", "@vitest/snapshot": "4.1.10",
"@vitest/spy": "4.0.18", "@vitest/spy": "4.1.10",
"@vitest/utils": "4.0.18", "@vitest/utils": "4.1.10",
"es-module-lexer": "^1.7.0", "es-module-lexer": "^2.0.0",
"expect-type": "^1.2.2", "expect-type": "^1.3.0",
"magic-string": "^0.30.21", "magic-string": "^0.30.21",
"obug": "^2.1.1", "obug": "^2.1.1",
"pathe": "^2.0.3", "pathe": "^2.0.3",
"picomatch": "^4.0.3", "picomatch": "^4.0.3",
"std-env": "^3.10.0", "std-env": "^4.0.0-rc.1",
"tinybench": "^2.9.0", "tinybench": "^2.9.0",
"tinyexec": "^1.0.2", "tinyexec": "^1.0.2",
"tinyglobby": "^0.2.15", "tinyglobby": "^0.2.15",
"tinyrainbow": "^3.0.3", "tinyrainbow": "^3.1.0",
"vite": "^6.0.0 || ^7.0.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
"why-is-node-running": "^2.3.0" "why-is-node-running": "^2.3.0"
}, },
"bin": { "bin": {
@ -4537,12 +4543,15 @@
"@edge-runtime/vm": "*", "@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0", "@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
"@vitest/browser-playwright": "4.0.18", "@vitest/browser-playwright": "4.1.10",
"@vitest/browser-preview": "4.0.18", "@vitest/browser-preview": "4.1.10",
"@vitest/browser-webdriverio": "4.0.18", "@vitest/browser-webdriverio": "4.1.10",
"@vitest/ui": "4.0.18", "@vitest/coverage-istanbul": "4.1.10",
"@vitest/coverage-v8": "4.1.10",
"@vitest/ui": "4.1.10",
"happy-dom": "*", "happy-dom": "*",
"jsdom": "*" "jsdom": "*",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@edge-runtime/vm": { "@edge-runtime/vm": {
@ -4563,6 +4572,12 @@
"@vitest/browser-webdriverio": { "@vitest/browser-webdriverio": {
"optional": true "optional": true
}, },
"@vitest/coverage-istanbul": {
"optional": true
},
"@vitest/coverage-v8": {
"optional": true
},
"@vitest/ui": { "@vitest/ui": {
"optional": true "optional": true
}, },
@ -4571,6 +4586,9 @@
}, },
"jsdom": { "jsdom": {
"optional": true "optional": true
},
"vite": {
"optional": false
} }
} }
}, },

View file

@ -31,8 +31,8 @@
"jsdom": "^28.1.0", "jsdom": "^28.1.0",
"typescript": "~5.9.3", "typescript": "~5.9.3",
"unocss": "^66.6.4", "unocss": "^66.6.4",
"vite": "^7.3.1", "vite": "^7.3.5",
"vitest": "^4.0.18", "vitest": "^4.1.0",
"vue-tsc": "^3.1.5" "vue-tsc": "^3.1.5"
} }
} }