From 0806de8135c9a9898dda3a45eedaf03280208ff9 Mon Sep 17 00:00:00 2001 From: TheMeinerLP Date: Sun, 9 Aug 2026 11:16:52 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=205b=20=E2=80=94=20dashboard=20fo?= =?UTF-8?q?r=20tenants=20and=20platform=20operators?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dashboard on top of Phase 5a. Nuxt 4 in SPA mode, Vue 3, Tailwind 4, Nuxt UI — matching the launchpad house standard. Two levels, separated by the role in the token: tenants manage their own sources, maps, renders and hosting; platform operators manage tenants, quotas and allowed domains. - Frontend role checks are convenience only; enforcement stays in the API, and nothing here is built to look like the frontend enforces rights. - Progress is displayed honestly: when telemetry degrades without the render being at risk, the API reports -1 and degraded: true, and the UI says so instead of drawing a bar at zero or inventing a value. - Tokens live in memory only, never in localStorage/sessionStorage, so a bearer JWT can't be scraped from Web Storage by XSS; a hard reload drops it, covered by silent renewal against the broker's own session. - Fixes a runtime error in the shared layout: Nuxt's directory-prefixed component names meant `` failed to resolve at runtime despite passing vue-tsc and nuxt build cleanly. Now guarded by a test that mounts the layout and fails if a component doesn't resolve — a guard validated by reverting the fix and watching the test fail exactly as the original bug manifested. - Fixes two API gaps that made the platform level unusable, per spec §10.3: no way to change an existing tenant's quota, and no cluster-wide view of running renders (GET /api/renders always resolved the caller's own tenant namespace). The new cluster-wide endpoint is hard-restricted to platform-admin with a test proving every other role is refused. - 107 frontend tests plus lint, typecheck and a production build with a runtime smoke test; API tests green including the new endpoints. This branch replaces feat/phase-5b-ui (PR #7). The stepwise history is not preserved here: the phase branches were rebuilt from scratch as single squash commits stacked on the new clean/* branches, because a secret scanner flagged disposable test credentials in old test data commits and history cannot be rewritten in this environment. --- .gitignore | 12 + .../rest/render/BlueMapRenderController.java | 50 +- .../rest/render/ClusterRenderResponse.java | 39 + .../rest/tenant/FabricTenantRepository.java | 5 + .../api/rest/tenant/TenantController.java | 38 +- .../api/rest/tenant/TenantRepository.java | 8 + .../api/rest/tenant/UpdateTenantRequest.java | 36 + .../render/BlueMapRenderControllerTest.java | 67 +- .../rest/tenant/InMemoryTenantRepository.java | 16 +- .../api/rest/tenant/TenantControllerTest.java | 51 + ui/.env.example | 12 + ui/.nvmrc | 1 + ui/README.md | 266 + ui/app/app.vue | 13 + ui/app/assets/css/main.css | 2 + ui/app/components/layout/AppHeader.vue | 24 + ui/app/components/layout/AppNav.vue | 29 + .../platform/ClusterRenderTable.vue | 100 + .../components/platform/CreateTenantForm.vue | 138 + ui/app/components/platform/EditTenantForm.vue | 115 + ui/app/components/platform/TenantList.vue | 142 + .../components/tenant/ConditionsBadgeList.vue | 29 + ui/app/components/tenant/HostingTable.vue | 62 + ui/app/components/tenant/MapTable.vue | 98 + ui/app/components/tenant/RenderLogViewer.vue | 78 + .../components/tenant/RenderProgressBar.vue | 82 + ui/app/components/tenant/RenderTable.vue | 66 + ui/app/components/tenant/SourceTable.vue | 60 + ui/app/components/tenant/TenantAccessGate.vue | 20 + ui/app/components/tenant/TenantNav.vue | 33 + ui/app/composables/useApiClient.ts | 19 + ui/app/composables/useAuth.ts | 119 + ui/app/layouts/default.vue | 8 + ui/app/middleware/auth.global.ts | 31 + ui/app/pages/auth/callback.vue | 29 + ui/app/pages/auth/silent-renew.vue | 15 + ui/app/pages/index.vue | 60 + ui/app/pages/platform/index.vue | 66 + ui/app/pages/tenant/hosting.vue | 48 + ui/app/pages/tenant/index.vue | 81 + ui/app/pages/tenant/maps.vue | 48 + ui/app/pages/tenant/renders/[id].vue | 108 + ui/app/pages/tenant/renders/index.vue | 48 + ui/app/pages/tenant/sources.vue | 48 + ui/app/plugins/oidc.client.ts | 10 + ui/app/utils/apiClient.ts | 204 + ui/app/utils/apiErrors.ts | 48 + ui/app/utils/apiTypes.ts | 237 + ui/app/utils/domainValidation.ts | 99 + ui/app/utils/formatTimestamp.ts | 12 + ui/app/utils/jwt.ts | 42 + ui/app/utils/renderProgress.ts | 85 + ui/app/utils/role.ts | 101 + ui/app/utils/sse.ts | 59 + ui/app/utils/sseController.ts | 59 + ui/app/utils/storageUsage.ts | 170 + ui/eslint.config.mjs | 31 + ui/nuxt.config.ts | 39 + ui/package.json | 43 + ui/pnpm-lock.yaml | 11123 ++++++++++++++++ ui/pnpm-workspace.yaml | 4 + ui/tests/nuxt/defaultLayout.nuxt.spec.ts | 50 + ui/tests/unit/apiClient.spec.ts | 291 + ui/tests/unit/jwt.spec.ts | 51 + .../unit/platform/domainValidation.spec.ts | 95 + ui/tests/unit/platform/storageUsage.spec.ts | 126 + ui/tests/unit/role.spec.ts | 134 + ui/tests/unit/sse.spec.ts | 72 + ui/tests/unit/tenant/renderProgress.spec.ts | 91 + ui/tests/unit/tenant/sseController.spec.ts | 87 + ui/tsconfig.json | 4 + ui/vitest.config.ts | 18 + ui/vitest.nuxt.config.ts | 14 + 73 files changed, 15811 insertions(+), 8 deletions(-) create mode 100644 api/src/main/java/net/onelitefeather/apus/api/rest/render/ClusterRenderResponse.java create mode 100644 api/src/main/java/net/onelitefeather/apus/api/rest/tenant/UpdateTenantRequest.java create mode 100644 ui/.env.example create mode 100644 ui/.nvmrc create mode 100644 ui/README.md create mode 100644 ui/app/app.vue create mode 100644 ui/app/assets/css/main.css create mode 100644 ui/app/components/layout/AppHeader.vue create mode 100644 ui/app/components/layout/AppNav.vue create mode 100644 ui/app/components/platform/ClusterRenderTable.vue create mode 100644 ui/app/components/platform/CreateTenantForm.vue create mode 100644 ui/app/components/platform/EditTenantForm.vue create mode 100644 ui/app/components/platform/TenantList.vue create mode 100644 ui/app/components/tenant/ConditionsBadgeList.vue create mode 100644 ui/app/components/tenant/HostingTable.vue create mode 100644 ui/app/components/tenant/MapTable.vue create mode 100644 ui/app/components/tenant/RenderLogViewer.vue create mode 100644 ui/app/components/tenant/RenderProgressBar.vue create mode 100644 ui/app/components/tenant/RenderTable.vue create mode 100644 ui/app/components/tenant/SourceTable.vue create mode 100644 ui/app/components/tenant/TenantAccessGate.vue create mode 100644 ui/app/components/tenant/TenantNav.vue create mode 100644 ui/app/composables/useApiClient.ts create mode 100644 ui/app/composables/useAuth.ts create mode 100644 ui/app/layouts/default.vue create mode 100644 ui/app/middleware/auth.global.ts create mode 100644 ui/app/pages/auth/callback.vue create mode 100644 ui/app/pages/auth/silent-renew.vue create mode 100644 ui/app/pages/index.vue create mode 100644 ui/app/pages/platform/index.vue create mode 100644 ui/app/pages/tenant/hosting.vue create mode 100644 ui/app/pages/tenant/index.vue create mode 100644 ui/app/pages/tenant/maps.vue create mode 100644 ui/app/pages/tenant/renders/[id].vue create mode 100644 ui/app/pages/tenant/renders/index.vue create mode 100644 ui/app/pages/tenant/sources.vue create mode 100644 ui/app/plugins/oidc.client.ts create mode 100644 ui/app/utils/apiClient.ts create mode 100644 ui/app/utils/apiErrors.ts create mode 100644 ui/app/utils/apiTypes.ts create mode 100644 ui/app/utils/domainValidation.ts create mode 100644 ui/app/utils/formatTimestamp.ts create mode 100644 ui/app/utils/jwt.ts create mode 100644 ui/app/utils/renderProgress.ts create mode 100644 ui/app/utils/role.ts create mode 100644 ui/app/utils/sse.ts create mode 100644 ui/app/utils/sseController.ts create mode 100644 ui/app/utils/storageUsage.ts create mode 100644 ui/eslint.config.mjs create mode 100644 ui/nuxt.config.ts create mode 100644 ui/package.json create mode 100644 ui/pnpm-lock.yaml create mode 100644 ui/pnpm-workspace.yaml create mode 100644 ui/tests/nuxt/defaultLayout.nuxt.spec.ts create mode 100644 ui/tests/unit/apiClient.spec.ts create mode 100644 ui/tests/unit/jwt.spec.ts create mode 100644 ui/tests/unit/platform/domainValidation.spec.ts create mode 100644 ui/tests/unit/platform/storageUsage.spec.ts create mode 100644 ui/tests/unit/role.spec.ts create mode 100644 ui/tests/unit/sse.spec.ts create mode 100644 ui/tests/unit/tenant/renderProgress.spec.ts create mode 100644 ui/tests/unit/tenant/sseController.spec.ts create mode 100644 ui/tsconfig.json create mode 100644 ui/vitest.config.ts create mode 100644 ui/vitest.nuxt.config.ts diff --git a/.gitignore b/.gitignore index 9325bb6..809e511 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,15 @@ build/ .idea/ *.iml runner/vendor/ + +# ui/ (Nuxt) -- not a Gradle module, see ui/README.md. Node dependencies and build/test +# output never belong in the repository. +ui/node_modules/ +ui/.nuxt/ +ui/.output/ +ui/dist/ +ui/coverage/ +ui/.env +# Local marker @nuxt/test-utils writes recording which version last ran -- see +# vitest.nuxt.config.ts/tests/nuxt/ (added for the layout render regression test). +ui/.nuxtrc diff --git a/api/src/main/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderController.java b/api/src/main/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderController.java index e9b7021..36e8440 100644 --- a/api/src/main/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderController.java +++ b/api/src/main/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderController.java @@ -25,8 +25,10 @@ import io.micronaut.security.authentication.Authentication; import io.micronaut.security.rules.SecurityRule; import java.util.List; +import java.util.stream.Stream; import net.onelitefeather.apus.api.rest.support.NotFoundException; import net.onelitefeather.apus.api.rest.support.TenantAccess; +import net.onelitefeather.apus.api.rest.tenant.TenantRepository; import net.onelitefeather.apus.api.security.ApusPrincipal; import net.onelitefeather.apus.api.security.ForbiddenException; import net.onelitefeather.apus.api.security.TenantResolver; @@ -37,6 +39,16 @@ * tenant only. A render belonging to a different tenant looks up empty in this tenant's * namespace and, per task-2-brief.md's central rule, produces the exact same 404 as a render * that does not exist anywhere -- see {@link NotFoundException}'s Javadoc. + * + *

{@code GET /api/renders/cluster} is the one deliberate exception to "the caller's own + * tenant only": {@code platform-admin}'s cluster-wide view (design spec §10.3). It is a + * literal route, checked before the {@code /{id}} route can match it, and its own method + * ({@link #listCluster}) does not go through {@link TenantResolver} at all -- same reasoning as + * {@code TenantController} not going through it (see that class's Javadoc): a platform-admin is + * not necessarily a member of any tenant, so resolving *a* namespace for it would be wrong even + * if one happened to exist. This is the only method on this controller allowed to see more than + * one tenant's resources; everything else keeps the invariant that the tenant comes from the + * token and the token alone. */ @Controller("/api/renders") @Secured(SecurityRule.IS_AUTHENTICATED) @@ -45,12 +57,17 @@ public class BlueMapRenderController { private final BlueMapRenderRepository repository; private final PrincipalResolver principalResolver; private final TenantResolver tenantResolver; + private final TenantRepository tenantRepository; public BlueMapRenderController( - BlueMapRenderRepository repository, PrincipalResolver principalResolver, TenantResolver tenantResolver) { + BlueMapRenderRepository repository, + PrincipalResolver principalResolver, + TenantResolver tenantResolver, + TenantRepository tenantRepository) { this.repository = repository; this.principalResolver = principalResolver; this.tenantResolver = tenantResolver; + this.tenantRepository = tenantRepository; } @Get @@ -65,6 +82,37 @@ public HttpResponse> list(Authentication authenticat return HttpResponse.ok(renders); } + /** + * The cluster-wide view (design spec §10.3, §11.2: "laufende Jobs clusterweit"), + * {@code platform-admin} only. Walks every {@code Tenant} the platform-admin has cluster-wide + * reach to (via {@link TenantRepository}, exactly like {@code TenantController} does), and + * for each one lists renders in that tenant's own namespace -- the same {@link + * BlueMapRenderRepository#list(String)} every tenant-scoped call already uses, just invoked + * once per tenant instead of once for the caller's own. A tenant with no namespace recorded + * yet in its status (freshly created, not yet reconciled) is skipped rather than failing the + * whole call. + */ + @Get("/cluster") + public HttpResponse> listCluster(Authentication authentication) { + ApusPrincipal principal = principalResolver.resolve(authentication); + if (!principal.isPlatformAdmin()) { + throw new ForbiddenException("principal '" + principal.subject() + "' is not a platform-admin"); + } + + List renders = tenantRepository.list().stream() + .flatMap(tenant -> { + String namespace = tenant.getStatus().getNamespace(); + if (namespace == null || namespace.isBlank()) { + return Stream.empty(); + } + String tenantName = tenant.getMetadata().getName(); + return repository.list(namespace).stream() + .map(render -> ClusterRenderResponse.from(tenantName, render)); + }) + .toList(); + return HttpResponse.ok(renders); + } + @Get("/{id}") public HttpResponse getById(Authentication authentication, @PathVariable String id) { ApusPrincipal principal = principalResolver.resolve(authentication); diff --git a/api/src/main/java/net/onelitefeather/apus/api/rest/render/ClusterRenderResponse.java b/api/src/main/java/net/onelitefeather/apus/api/rest/render/ClusterRenderResponse.java new file mode 100644 index 0000000..d1a666f --- /dev/null +++ b/api/src/main/java/net/onelitefeather/apus/api/rest/render/ClusterRenderResponse.java @@ -0,0 +1,39 @@ +/** + * Apus - render and host BlueMap maps on Kubernetes. + * Copyright (C) 2026 OneLiteFeather and contributors + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + *

+ * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package net.onelitefeather.apus.api.rest.render; + +import io.micronaut.serde.annotation.Serdeable; +import net.onelitefeather.apus.operator.api.BlueMapRender; + +/** + * One render, as {@code GET /api/renders/cluster} exposes it -- the {@code platform-admin}-only + * cluster-wide view (design spec §10.3: "clusterweite Sicht"). Wraps the ordinary {@link + * BlueMapRenderResponse} rather than duplicating its fields, and adds exactly the one thing a + * single tenant's own {@code GET /api/renders} does not need to say about itself: which tenant + * this render belongs to. {@code tenant} is the {@code Tenant} custom resource's own {@code + * metadata.name} -- resolved by {@link BlueMapRenderController#listCluster} from {@code + * TenantRepository}, never guessed back out of a namespace string (that reverse mapping belongs + * to no one; see {@code TenantResolver}'s Javadoc on why it has exactly one public method). + */ +@Serdeable +public record ClusterRenderResponse(String tenant, BlueMapRenderResponse render) { + + public static ClusterRenderResponse from(String tenant, BlueMapRender render) { + return new ClusterRenderResponse(tenant, BlueMapRenderResponse.from(render)); + } +} diff --git a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/FabricTenantRepository.java b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/FabricTenantRepository.java index a4fd2da..9082ea3 100644 --- a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/FabricTenantRepository.java +++ b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/FabricTenantRepository.java @@ -47,4 +47,9 @@ public Optional findByName(String name) { public Tenant create(Tenant tenant) { return client.resource(tenant).create(); } + + @Override + public Tenant update(Tenant tenant) { + return client.resource(tenant).update(); + } } diff --git a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantController.java b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantController.java index 9f0aefb..a8c0e45 100644 --- a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantController.java +++ b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantController.java @@ -21,12 +21,15 @@ import io.micronaut.http.annotation.Body; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Patch; +import io.micronaut.http.annotation.PathVariable; import io.micronaut.http.annotation.Post; import io.micronaut.security.annotation.Secured; import io.micronaut.security.authentication.Authentication; import io.micronaut.security.rules.SecurityRule; import java.util.List; import net.onelitefeather.apus.api.rest.support.BadRequestException; +import net.onelitefeather.apus.api.rest.support.NotFoundException; import net.onelitefeather.apus.api.security.ApusPrincipal; import net.onelitefeather.apus.api.security.ForbiddenException; import net.onelitefeather.apus.api.support.PrincipalResolver; @@ -34,9 +37,10 @@ import net.onelitefeather.apus.operator.api.TenantSpec; /** - * {@code GET /api/tenants} and {@code POST /api/tenants} -- platform-level, {@code - * platform-admin} only (design spec §10.3, §11.1). Unlike every other controller in {@code - * rest/}, this one never calls {@code TenantResolver}: {@code Tenant} is cluster-scoped, and a + * {@code GET /api/tenants}, {@code POST /api/tenants}, and {@code PATCH /api/tenants/{name}} -- + * platform-level, {@code platform-admin} only (design spec §10.3, §11.1). Unlike every other + * controller in {@code rest/}, this one never calls {@code TenantResolver}: {@code Tenant} is + * cluster-scoped, and a * platform-admin's reach here is deliberately cluster-wide, not confined to a single namespace * -- see {@code TenantResolverTest#namespaceForRejectsAPlatformAdminWithoutATenantToo}'s Javadoc * from task 1, which is exactly the boundary this controller sits on the other side of. @@ -96,6 +100,34 @@ public HttpResponse create(Authentication authentication, @Body return HttpResponse.created(TenantResponse.from(created)); } + /** + * Changes an existing tenant's storage quota and/or allowed hosting domains (design spec + * §10.3: {@code platform-admin} may "Tenants anlegen/ändern/löschen, Quotas"). {@code name} + * comes from the path, exactly like every other tenant-identifying value in this module -- + * never re-derived from the body. Closes the gap the platform dashboard flagged: before this, + * a quota was only settable at {@link #create}-time. + */ + @Patch("/{name}") + public HttpResponse update( + Authentication authentication, @PathVariable String name, @Body UpdateTenantRequest request) { + requirePlatformAdmin(authentication); + Tenant tenant = repository.findByName(name).orElseThrow(() -> new NotFoundException("no tenant '" + name + "'")); + + TenantSpec spec = tenant.getSpec(); + if (request.storageQuota() != null) { + spec.getStorage().setQuota(request.storageQuota()); + } + if (request.maxObjects() != null) { + spec.getStorage().setMaxObjects(request.maxObjects()); + } + if (request.allowedHostingDomains() != null) { + spec.getHosting().setAllowedDomains(request.allowedHostingDomains()); + } + + Tenant updated = repository.update(tenant); + return HttpResponse.ok(TenantResponse.from(updated)); + } + private ApusPrincipal requirePlatformAdmin(Authentication authentication) { ApusPrincipal principal = principalResolver.resolve(authentication); if (!principal.isPlatformAdmin()) { diff --git a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantRepository.java b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantRepository.java index ceb55d4..d384f97 100644 --- a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantRepository.java +++ b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantRepository.java @@ -42,4 +42,12 @@ public interface TenantRepository { Optional findByName(String name); Tenant create(Tenant tenant); + + /** + * Persists changes to an already-existing {@link Tenant} (design spec §10.3: {@code + * platform-admin} may "Tenants anlegen/ändern/löschen, Quotas"). {@code tenant} must be one + * previously returned by {@link #findByName(String)} (or {@link #list()}) with its fields + * mutated -- this method does not create a new resource if the name does not already exist. + */ + Tenant update(Tenant tenant); } diff --git a/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/UpdateTenantRequest.java b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/UpdateTenantRequest.java new file mode 100644 index 0000000..b3a2253 --- /dev/null +++ b/api/src/main/java/net/onelitefeather/apus/api/rest/tenant/UpdateTenantRequest.java @@ -0,0 +1,36 @@ +/** + * Apus - render and host BlueMap maps on Kubernetes. + * Copyright (C) 2026 OneLiteFeather and contributors + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + *

+ * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package net.onelitefeather.apus.api.rest.tenant; + +import io.micronaut.serde.annotation.Serdeable; +import java.util.List; + +/** + * Request body for {@code PATCH /api/tenants/{name}} -- the only way to change quota or allowed + * hosting domains on a tenant after creation (design spec §10.3: {@code platform-admin} may + * "Tenants anlegen/ändern/löschen, Quotas"). {@code name} is deliberately not repeated here, nor + * is it ever taken from anywhere but the path -- see {@code TenantController#update}. + * + *

Partial-update semantics, same as {@link CreateTenantRequest}: a {@code null} field leaves + * the current value untouched rather than clearing it, so a caller changing only the storage + * quota does not have to first re-read and resend the current allowed domains. There is + * deliberately no way to change {@code displayName} here -- out of this endpoint's stated scope + * (design spec §10.3: quota and domains only). + */ +@Serdeable +public record UpdateTenantRequest(String storageQuota, Long maxObjects, List allowedHostingDomains) {} diff --git a/api/src/test/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderControllerTest.java b/api/src/test/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderControllerTest.java index 19dd75d..d9c338c 100644 --- a/api/src/test/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderControllerTest.java +++ b/api/src/test/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderControllerTest.java @@ -19,23 +19,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import io.micronaut.security.authentication.Authentication; import java.util.List; import java.util.Map; import net.onelitefeather.apus.api.rest.support.NotFoundException; +import net.onelitefeather.apus.api.rest.tenant.InMemoryTenantRepository; import net.onelitefeather.apus.api.security.ForbiddenException; import net.onelitefeather.apus.api.security.TenantResolver; import net.onelitefeather.apus.api.support.PrincipalResolver; import net.onelitefeather.apus.operator.api.BlueMapRender; import net.onelitefeather.apus.operator.api.Ref; +import net.onelitefeather.apus.operator.api.Tenant; import org.junit.jupiter.api.Test; class BlueMapRenderControllerTest { private final InMemoryBlueMapRenderRepository repository = new InMemoryBlueMapRenderRepository(); - private final BlueMapRenderController controller = - new BlueMapRenderController(repository, new PrincipalResolver(), new TenantResolver()); + private final InMemoryTenantRepository tenantRepository = new InMemoryTenantRepository(); + private final BlueMapRenderController controller = new BlueMapRenderController( + repository, new PrincipalResolver(), new TenantResolver(), tenantRepository); private static Authentication viewer(String tenant) { return Authentication.build("carol", List.of("tenant-viewer"), Map.of(PrincipalResolver.TENANT_CLAIM, tenant)); @@ -45,6 +49,25 @@ private static Authentication noRoles(String tenant) { return Authentication.build("service-token", List.of(), Map.of(PrincipalResolver.TENANT_CLAIM, tenant)); } + private static Authentication platformAdmin() { + return Authentication.build("root", List.of("platform-admin"), Map.of()); + } + + private static Authentication owner(String tenant) { + return Authentication.build("alice", List.of("tenant-owner"), Map.of(PrincipalResolver.TENANT_CLAIM, tenant)); + } + + private static Authentication operator(String tenant) { + return Authentication.build("bob", List.of("tenant-operator"), Map.of(PrincipalResolver.TENANT_CLAIM, tenant)); + } + + private static Tenant tenant(String name, String namespace) { + Tenant tenant = new Tenant(); + tenant.getMetadata().setName(name); + tenant.getStatus().setNamespace(namespace); + return tenant; + } + private static BlueMapRender render(String name, String mapName) { BlueMapRender render = new BlueMapRender(); render.getMetadata().setName(name); @@ -93,4 +116,44 @@ void getByIdRejectsACallerWithNoTenantRole() { repository.put("bluemap-acme", render("render-1", "survival-overworld")); assertThrows(ForbiddenException.class, () -> controller.getById(noRoles("acme"), "render-1")); } + + @Test + void listClusterReturnsRendersAcrossEveryTenantForAPlatformAdmin() { + tenantRepository.put(tenant("acme", "bluemap-acme")); + tenantRepository.put(tenant("globex", "bluemap-globex")); + repository.put("bluemap-acme", render("render-1", "survival-overworld")); + repository.put("bluemap-globex", render("render-2", "creative-overworld")); + + var response = controller.listCluster(platformAdmin()); + + assertEquals(200, response.getStatus().getCode()); + assertEquals(2, response.body().size()); + assertTrue(response.body().stream() + .anyMatch(entry -> entry.tenant().equals("acme") && entry.render().name().equals("render-1"))); + assertTrue(response.body().stream() + .anyMatch(entry -> entry.tenant().equals("globex") && entry.render().name().equals("render-2"))); + } + + @Test + void listClusterSkipsATenantWithNoNamespaceInStatusYet() { + tenantRepository.put(tenant("brandNew", null)); + + var response = controller.listCluster(platformAdmin()); + + assertEquals(0, response.body().size()); + } + + /** + * The security-critical case (task brief C2): every role other than {@code platform-admin} + * must be rejected, not just "a caller with no roles" -- including the tenant-level roles + * that *do* pass {@code /api/renders}' own gate, since this is the one endpoint on this + * controller that would otherwise leak every tenant's renders to any authenticated caller. + */ + @Test + void listClusterRejectsEveryNonPlatformAdminRole() { + assertThrows(ForbiddenException.class, () -> controller.listCluster(owner("acme"))); + assertThrows(ForbiddenException.class, () -> controller.listCluster(operator("acme"))); + assertThrows(ForbiddenException.class, () -> controller.listCluster(viewer("acme"))); + assertThrows(ForbiddenException.class, () -> controller.listCluster(noRoles("acme"))); + } } diff --git a/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/InMemoryTenantRepository.java b/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/InMemoryTenantRepository.java index 2e27644..6bce2e7 100644 --- a/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/InMemoryTenantRepository.java +++ b/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/InMemoryTenantRepository.java @@ -28,12 +28,18 @@ * kubernetes-server-mock}/{@code micronaut-test-junit5}, neither of which is on this module's * test classpath (task-1-report.md's "Concerns" section) -- see {@code TenantRepository}'s * Javadoc for why the repository is an interface in the first place. + * + *

Public (not package-private): {@code BlueMapRenderControllerTest} (in the sibling {@code + * rest.render} test package) also needs a {@code TenantRepository} fake for {@code + * GET /api/renders/cluster}'s tests, and this is the one already exercised by {@code + * TenantControllerTest} -- reusing it keeps there from being two divergent in-memory fakes for + * the same interface. */ -final class InMemoryTenantRepository implements TenantRepository { +public final class InMemoryTenantRepository implements TenantRepository { private final Map byName = new LinkedHashMap<>(); - void put(Tenant tenant) { + public void put(Tenant tenant) { byName.put(tenant.getMetadata().getName(), tenant); } @@ -52,4 +58,10 @@ public Tenant create(Tenant tenant) { put(tenant); return tenant; } + + @Override + public Tenant update(Tenant tenant) { + put(tenant); + return tenant; + } } diff --git a/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/TenantControllerTest.java b/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/TenantControllerTest.java index b8a0fec..6756df4 100644 --- a/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/TenantControllerTest.java +++ b/api/src/test/java/net/onelitefeather/apus/api/rest/tenant/TenantControllerTest.java @@ -24,6 +24,7 @@ import io.micronaut.security.authentication.Authentication; import java.util.List; import net.onelitefeather.apus.api.rest.support.BadRequestException; +import net.onelitefeather.apus.api.rest.support.NotFoundException; import net.onelitefeather.apus.api.security.ForbiddenException; import net.onelitefeather.apus.api.support.PrincipalResolver; import net.onelitefeather.apus.operator.api.Tenant; @@ -92,4 +93,54 @@ void createRejectsABlankName() { var request = new CreateTenantRequest(" ", "Globex", null, null, List.of()); assertThrows(BadRequestException.class, () -> controller.create(platformAdmin(), request)); } + + @Test + void updateChangesQuotaAndAllowedDomainsForAPlatformAdmin() { + Tenant tenant = new Tenant(); + tenant.getMetadata().setName("acme"); + tenant.getSpec().setDisplayName("Acme Corp"); + tenant.getSpec().getStorage().setQuota("100Gi"); + repository.put(tenant); + + var request = new UpdateTenantRequest("500Gi", 42_000L, List.of("*.acme.example.net")); + var response = controller.update(platformAdmin(), "acme", request); + + assertEquals(200, response.getStatus().getCode()); + assertEquals("500Gi", response.body().storage().quota()); + assertEquals(42_000L, response.body().storage().maxObjects()); + assertEquals(List.of("*.acme.example.net"), response.body().allowedHostingDomains()); + // displayName is untouched -- this endpoint only ever changes quota/domains. + assertEquals("Acme Corp", response.body().displayName()); + } + + @Test + void updateLeavesAFieldUntouchedWhenItsRequestValueIsNull() { + Tenant tenant = new Tenant(); + tenant.getMetadata().setName("acme"); + tenant.getSpec().getStorage().setQuota("100Gi"); + tenant.getSpec().getHosting().setAllowedDomains(List.of("maps.acme.example.net")); + repository.put(tenant); + + var request = new UpdateTenantRequest(null, null, null); + var response = controller.update(platformAdmin(), "acme", request); + + assertEquals("100Gi", response.body().storage().quota()); + assertEquals(List.of("maps.acme.example.net"), response.body().allowedHostingDomains()); + } + + @Test + void updateRejectsANonPlatformAdmin() { + Tenant tenant = new Tenant(); + tenant.getMetadata().setName("acme"); + repository.put(tenant); + + var request = new UpdateTenantRequest("500Gi", null, null); + assertThrows(ForbiddenException.class, () -> controller.update(tenantOwner(), "acme", request)); + } + + @Test + void updateRejectsAnUnknownTenant() { + var request = new UpdateTenantRequest("500Gi", null, null); + assertThrows(NotFoundException.class, () -> controller.update(platformAdmin(), "does-not-exist", request)); + } } diff --git a/ui/.env.example b/ui/.env.example new file mode 100644 index 0000000..a0b72cc --- /dev/null +++ b/ui/.env.example @@ -0,0 +1,12 @@ +# Copy to .env for local development. All values are public (client-side, SPA build) -- +# never put a client secret here, this is a public OIDC client (Authorization Code + PKCE). + +# The api module's base URL (see api/src/main/resources/application.yml). +NUXT_PUBLIC_API_BASE_URL=http://localhost:8080 + +# Must match APUS_JWT_ISSUER on the api module -- same identity broker, same issuer. +# Which broker (Keycloak, Zitadel, ...) is still open, see design spec §15. +NUXT_PUBLIC_OIDC_ISSUER=https://id.example.net/realms/apus + +# The public (no-secret) OIDC client registered for this SPA at the broker. +NUXT_PUBLIC_OIDC_CLIENT_ID=apus-ui diff --git a/ui/.nvmrc b/ui/.nvmrc new file mode 100644 index 0000000..a45fd52 --- /dev/null +++ b/ui/.nvmrc @@ -0,0 +1 @@ +24 diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..98ea61f --- /dev/null +++ b/ui/README.md @@ -0,0 +1,266 @@ +# Apus UI + +Web frontend for Apus (design spec `docs/superpowers/specs/2026-08-08-apus-design.md`, §11.2): +Nuxt 4 in SPA mode (`ssr: false`), Vue 3, Tailwind 4, Nuxt UI, VueUse. + +## Not part of the Gradle build, on purpose + +This module lives beside the Java modules but is **not** included in `settings.gradle.kts` and +has no `build.gradle.kts`. It is a self-contained Node/pnpm project with its own toolchain +(Vite, Vitest, ESLint), none of which Gradle can drive without an extra plugin +(`gradle-node-plugin` or similar) whose only job would be shelling out to `pnpm` anyway. +Wiring that up would add a second build system's worth of dependency-locking and caching +concerns to Gradle's dependency graph for no benefit: nothing here produces a JAR another module +consumes, and nothing in the Java modules is a build input to this one. Build and test it +directly, as below. + +## Building and testing + +```bash +corepack enable # or: npm install -g pnpm +pnpm install +pnpm dev # local dev server +pnpm build # production build (static SPA output, see nuxt.config.ts) +pnpm test # vitest, unit tests +pnpm lint # eslint, includes eslint-plugin-vuejs-accessibility +pnpm typecheck # vue-tsc +``` + +Copy `.env.example` to `.env` for local development and fill in the three variables (API base +URL, OIDC issuer, OIDC client ID) — see "Configuration" below. + +## Versions (pinned, verified against npm on 2026-08-09) + +| Package | Version | Why this one | +|---|---|---| +| `nuxt` | 4.5.2 | current stable Nuxt 4 | +| `vue` | 3.5.41 | pulled in by Nuxt 4 | +| `@nuxt/ui` | 4.10.0 | current stable; bundles its own Tailwind 4 wiring | +| `tailwindcss` | 4.3.3 | `@nuxt/ui`'s declared peer (`^4.0.0`) | +| `@vueuse/nuxt` / `@vueuse/core` | 14.4.0 | matches what `@nuxt/ui` itself depends on | +| `@nuxt/eslint` | 1.17.0 | flat-config ESLint integration, house standard (`launchpad`) | +| `eslint` | 10.8.1 | current stable major | +| `eslint-plugin-vuejs-accessibility` | 2.5.0 | binding requirement, design spec §11.2 | +| `typescript` | 6.0.3 | current stable **6.x**, not the newer `7.0.2` — `@nuxt/ui`'s declared peer range is `^5.6.3 \|\| ^6.0.0` and does not (yet) include 7 | +| `vue-tsc` | 3.3.9 | matches `typescript` 6.x (peer: `>=5.0.0`) | +| `vitest` | 4.1.10 | current stable | +| `@vue/test-utils` | 2.4.11 | current stable | +| `happy-dom` | 20.11.2 | vitest environment | +| `oidc-client-ts` | 3.5.0 | see "Authentication" below | + +All pinned exactly (no `^`/`~`), matching this repository's own convention in +`settings.gradle.kts` of exact-pinning dependency versions with a comment on why. There is no +Renovate config for this repo yet (out of scope for this task); until there is, bumps are +manual — check each package's current npm version before raising the pin, the same way this +table was built. + +## Project layout + +Nuxt 4's actual current default: an `app/` directory holds everything client-side +(`app/pages`, `app/components`, `app/composables`, `app/layouts`, `app/middleware`, +`app/plugins`, `app/utils`, `app.vue`). There is no `server/` directory — this is a pure SPA +with no Nitro API routes of its own; the only thing Nitro does here is serve the built static +assets (see "Why no server-side session" below). + +``` +app/ + app.vue -- + layouts/default.vue -- header + nav, wraps every page + components/layout/ + AppHeader.vue -- branding, signed-in user, sign-out + AppNav.vue -- nav links; shows "Platform" only for platform-admin + pages/ + index.vue -- REQUIRED page: signed-in user + their tenant (§11.2 task scope) + auth/callback.vue -- OIDC Authorization Code redirect target + auth/silent-renew.vue -- OIDC silent-renew iframe target + middleware/auth.global.ts -- requires a session on every route but /auth/* + plugins/oidc.client.ts -- restores the in-memory session before first render + composables/ + useAuth.ts -- oidc-client-ts wrapper: user, principal, login/logout + useApiClient.ts -- wires useAuth()'s token into createApusApiClient() + utils/ -- plain TypeScript, NO Nuxt auto-imports/composables used + apiClient.ts -- createApusApiClient(): the typed client, see below + apiTypes.ts -- one interface per Java response/request record + apiErrors.ts -- ApusApiError + sse.ts -- parseSseStream(): SSE framing over a fetch body reader + role.ts -- UI-side role helpers (convenience only, see below) + jwt.ts -- decodeJwtPayload(): unverified, display-only decode +tests/unit/ -- vitest; mirrors app/utils/, one spec file per module +``` + +`app/utils/*` is deliberately framework-agnostic (no `useRuntimeConfig`, no `$fetch`, no +`ref`/`computed` from Vue) so it can be unit-tested with plain Vitest and no Nuxt test harness +— see "Why plain Vitest" below. The two Nuxt-aware composables in `app/composables/` are thin +wrappers around it. + +### Why plain Vitest, not `@nuxt/test-utils` + +Everything with real logic (`apiClient.ts`, `role.ts`, `jwt.ts`, `sse.ts`) is plain TypeScript +with no Nuxt runtime dependency, so a full Nuxt test environment (module resolution, virtual +`#imports`, a mounted app) would only add startup cost and indirection for no benefit. `useAuth` +and `useApiClient` themselves are thin enough (a few lines of wiring) that they are exercised +indirectly through the pure functions they call, per the task brief's "reine Darstellung braucht +keine Tests" — the composables' own logic content is effectively zero. + +### Why no server-side session + +`ssr: false` plus a static/`node-server`-served SPA output means there is no reliable backend +component to hold a confidential OIDC client or a session cookie behind — the deploy target for +this module (per the design spec, presumably a plain Deployment serving static files, mirroring +how `BlueMapHosting` serves rendered maps) may not run any per-request server code at all. That +ruled out `nuxt-oidc-auth` (built around a server-side session) and shaped the client-only, +public-client design in `useAuth.ts` below. + +## Authentication (task 2 requirement) + +**Library: `oidc-client-ts`.** The maintained, TypeScript-native successor to `oidc-client`, +widely used, and — critically for the storage decision below — it exposes a pluggable +`userStore` instead of hardcoding `localStorage`. No Nuxt-specific OIDC module was used; see +"Why no server-side session" above for why the usual Nuxt choice (`nuxt-oidc-auth`) does not fit +this deployment shape. + +Flow: Authorization Code + PKCE, public client (no client secret — there is nowhere safe to +keep one in a pure SPA). Configuration is three environment variables +(`NUXT_PUBLIC_API_BASE_URL`, `NUXT_PUBLIC_OIDC_ISSUER`, `NUXT_PUBLIC_OIDC_CLIENT_ID`), matching +the design spec's instruction to keep the broker choice (§15: Keycloak vs. Zitadel, undecided) +out of code entirely. + +### Token storage — binding requirement, and the reasoning + +**Tokens are held in memory only** (`oidc-client-ts`'s `InMemoryWebStorage`, wired in +`app/composables/useAuth.ts`), never in `localStorage` and — one step further than the library's +own default — never in `sessionStorage` either. + +Why: an XSS bug anywhere on this page can read anything in `localStorage`/`sessionStorage` at +any time for as long as that data sits there, which for a bearer JWT means full API access to +everything the signed-in user's tenant can see, for as long as the token is valid (typically +minutes to hours) — and `localStorage` specifically survives tab close and even browser +restart, so a *stored* XSS elsewhere on the same origin could scrape it well after the +originating page load. A plain in-memory object is not reachable by that class of bug at all +unless the malicious script is executing at the exact moment the token is in use — the smallest +exposure window achievable without a confidential backend to hold a session behind (which, per +"Why no server-side session" above, does not exist here). + +The cost: a hard page reload loses the in-memory token, since nothing persists it. This is +absorbed by `automaticSilentRenew: true` plus an explicit `signinSilent()` call on every route +load with no session (`app/middleware/auth.global.ts`) — a hidden iframe re-authenticates +against the broker's own session, which lives in an httpOnly cookie the broker controls and this +page's JavaScript cannot read regardless. If that broker session has also expired, the user sees +an interactive login redirect — the same as a first visit, not a broken app. + +**Known caveat, to verify once the broker is chosen (design spec §15):** which claims carry +roles and the tenant/organization depends on the broker's own claim-mapping configuration (a +Keycloak client scope mapper vs. a Zitadel action, for instance). `app/utils/role.ts` hardcodes +the claim names `roles` and `organization` to match what the `api` module already expects +(`PrincipalResolver.ROLES_CLAIM`/`TENANT_CLAIM`) — the broker must be configured to put them +there, in the *access* token specifically (the token this UI sends as the bearer credential and +the one the API actually validates), not only the ID token. Silent renew via a hidden iframe +also assumes the broker allows being framed for that purpose (no `X-Frame-Options: DENY` on its +authorize endpoint) — most modern brokers support this for a registered redirect URI, but it is +worth a five-minute check against whichever broker Phase 5 lands on, before relying on it. + +## Typed API client (task 3 requirement) — structure for the two follow-up agents + +`app/utils/apiClient.ts` exports `createApusApiClient(options)`, a factory (not a class you +`new`) returning an object with one method per endpoint. `app/composables/useApiClient.ts` is +the Nuxt-facing entry point — call `useApiClient()` from a page/component and it is already +wired to the current access token and configured API base URL. + +Every request/response type in `app/utils/apiTypes.ts` is a direct mirror of the Java record it +is named after, with the exact source file cited in a comment on each type — read those Java +files (`api/src/main/java/net/onelitefeather/apus/api/rest/**`, +`api/src/main/java/net/onelitefeather/apus/api/events/RenderProgress.java`) before extending +this client, rather than guessing at a field. + +```ts +const api = useApiClient() + +// Platform level (platform-admin only, enforced server-side — see "Role logic" below) +await api.listTenants() // TenantResponse[] +await api.createTenant(body) // TenantResponse + +// Tenant level (caller's own tenant only, resolved server-side from the token) +await api.listSources() // WorldSourceResponse[] +await api.createSource(body) // WorldSourceResponse +await api.listMaps() // BlueMapMapResponse[] +await api.getMap(id) // BlueMapMapResponse +await api.triggerRender(id, { force: false }) // BlueMapRenderResponse +await api.listRenders() // BlueMapRenderResponse[] +await api.getRender(id) // BlueMapRenderResponse +await api.listHostings() // BlueMapHostingResponse[] + +// Live streams (SSE) -- see app/utils/sse.ts for why these use `fetch`, not `EventSource` +await api.streamRenderEvents(id, { onMessage, onClose, onError }, abortSignal) // RenderProgressEvent +await api.streamRenderLogs(id, { onMessage, onClose, onError }, abortSignal) // raw log line (string) +``` + +**Error handling:** every failure — a non-2xx response *and* a network/`fetch` failure alike — +comes out as one type, `ApusApiError` (`app/utils/apiErrors.ts`), with `status` (0 for a network +failure that never got an HTTP response), `message` (parsed from the response body's `message` +field when present — matches `BadRequestExceptionHandler`'s `{"message": "..."}` — otherwise a +sane per-status default), and `body` (the raw parsed error body, if any). `403`/`404` from the +api module carry no body at all by design (see `ForbiddenExceptionHandler`/ +`NotFoundExceptionHandler`'s Javadoc — a 404 is also what a resource in a *different* tenant's +namespace returns, deliberately indistinguishable from "does not exist"), so do not assume every +`ApusApiError` has a parseable `body`. + +`api/src/main/java/net/onelitefeather/apus/api/rest/support/*ExceptionHandler.java` is the +source of truth for this mapping; re-check it if the api module adds a new error shape. + +**Not yet in the api module, therefore not in this client:** `POST /api/uploads` and +`POST /api/push/{token}` from the design spec's §11.1 endpoint table are Phase 6 work (push +sources, §14) and have no controller yet — nothing to point a client method at. + +## Role logic (task 4 requirement) — convenience only, read before extending + +`app/utils/role.ts` mirrors the four roles from design spec §10.3 +(`platform-admin`/`tenant-owner`/`tenant-operator`/`tenant-viewer`) and the exact same gating +logic the api module applies in +`api/src/main/java/net/onelitefeather/apus/api/security/ApusPrincipal.java` and +`api/src/main/java/net/onelitefeather/apus/api/rest/support/TenantAccess.java` +(`isPlatformAdmin`, `canWriteTenant`, `canReadTenant`). + +**This exists purely to decide what the UI shows.** It enforces nothing, and it must never be +extended as though it did. The api module is the sole enforcement point (design spec §10.3: +"Das Backend ist der Durchsetzungspunkt") and re-checks every one of these on every request, +regardless of what a compromised or simply out-of-date client renders. Concretely: hiding the +"Platform" nav link from a non-`platform-admin` user is a convenience so they are not staring at +a dashboard that will 403 on every call — it is not, and must not become, the reason `GET +/api/tenants` is safe to expose. If a future change here ever reads like "and therefore the +request is safe to send", that is the signal something has gone wrong; stop and re-read this +section. + +## Base layout and pages (task 5 requirement) + +`app/layouts/default.vue` + `app/components/layout/{AppHeader,AppNav}.vue`: header with branding +and sign-out, nav that conditionally shows a "Platform" link via `isPlatformAdmin()` (see above). +The link target (`/platform`) does not have a page behind it yet — that dashboard is the next +task's scope, not this one's. + +`app/pages/index.vue` is the one page this task ships: the signed-in user's subject, email, +tenant, and roles. Nothing else — both dashboard levels (design spec §11.2: platform and tenant) +are explicitly out of scope here. + +## Tests (task 6 requirement) + +`pnpm test` runs Vitest against `tests/unit/**/*.spec.ts` (47 tests as of this task). Covered, +per the task brief's "what carries logic" standard: + +- `apiClient.spec.ts` — request/response wiring (auth header, JSON body, URL-encoding, 204 + handling), every documented error shape (400 with a body, 403/404 without one, a raw network + failure, a non-JSON error body), and both SSE streaming methods (JSON-parsed events vs. + raw-string log lines, plus a failed-to-open stream). +- `role.spec.ts` — claim parsing (recognised vs. unknown roles, case/whitespace normalisation, + blank/missing tenant → `null`) and all three derived predicates, including the two + API-mirrored edge cases (`platform-admin` excluded from `canWriteTenant`, + `platform-admin` alone failing `canReadTenant`). +- `sse.spec.ts` — the SSE framer directly: single/multiple events, an event split across chunk + boundaries, multi-`data:`-line joining, a trailing event with no final blank line, comment + lines ignored, an empty stream. +- `jwt.spec.ts` — the unverified JWT payload decoder: normal decode, non-ASCII claim values, + an unpadded base64url payload, and the two rejection paths. + +Not tested, per the same standard ("für reine Darstellung braucht es keine Tests"): the `.vue` +files themselves (layout, nav, the account page) and the two thin composables +(`useAuth`/`useApiClient`), whose own logic content is close to zero — see "Why plain Vitest" +above. diff --git a/ui/app/app.vue b/ui/app/app.vue new file mode 100644 index 0000000..768a936 --- /dev/null +++ b/ui/app/app.vue @@ -0,0 +1,13 @@ + + + diff --git a/ui/app/assets/css/main.css b/ui/app/assets/css/main.css new file mode 100644 index 0000000..7c95c6f --- /dev/null +++ b/ui/app/assets/css/main.css @@ -0,0 +1,2 @@ +@import "tailwindcss"; +@import "@nuxt/ui"; diff --git a/ui/app/components/layout/AppHeader.vue b/ui/app/components/layout/AppHeader.vue new file mode 100644 index 0000000..59b71cc --- /dev/null +++ b/ui/app/components/layout/AppHeader.vue @@ -0,0 +1,24 @@ + + + diff --git a/ui/app/components/layout/AppNav.vue b/ui/app/components/layout/AppNav.vue new file mode 100644 index 0000000..ed76b1e --- /dev/null +++ b/ui/app/components/layout/AppNav.vue @@ -0,0 +1,29 @@ + + + diff --git a/ui/app/components/platform/ClusterRenderTable.vue b/ui/app/components/platform/ClusterRenderTable.vue new file mode 100644 index 0000000..509cf97 --- /dev/null +++ b/ui/app/components/platform/ClusterRenderTable.vue @@ -0,0 +1,100 @@ + + + diff --git a/ui/app/components/platform/CreateTenantForm.vue b/ui/app/components/platform/CreateTenantForm.vue new file mode 100644 index 0000000..adddde0 --- /dev/null +++ b/ui/app/components/platform/CreateTenantForm.vue @@ -0,0 +1,138 @@ + + + diff --git a/ui/app/components/platform/EditTenantForm.vue b/ui/app/components/platform/EditTenantForm.vue new file mode 100644 index 0000000..b44e1b0 --- /dev/null +++ b/ui/app/components/platform/EditTenantForm.vue @@ -0,0 +1,115 @@ + + + diff --git a/ui/app/components/platform/TenantList.vue b/ui/app/components/platform/TenantList.vue new file mode 100644 index 0000000..e8807fa --- /dev/null +++ b/ui/app/components/platform/TenantList.vue @@ -0,0 +1,142 @@ + + + diff --git a/ui/app/components/tenant/ConditionsBadgeList.vue b/ui/app/components/tenant/ConditionsBadgeList.vue new file mode 100644 index 0000000..f2503b5 --- /dev/null +++ b/ui/app/components/tenant/ConditionsBadgeList.vue @@ -0,0 +1,29 @@ + + + diff --git a/ui/app/components/tenant/HostingTable.vue b/ui/app/components/tenant/HostingTable.vue new file mode 100644 index 0000000..3814706 --- /dev/null +++ b/ui/app/components/tenant/HostingTable.vue @@ -0,0 +1,62 @@ + + + diff --git a/ui/app/components/tenant/MapTable.vue b/ui/app/components/tenant/MapTable.vue new file mode 100644 index 0000000..25dd27a --- /dev/null +++ b/ui/app/components/tenant/MapTable.vue @@ -0,0 +1,98 @@ + + + diff --git a/ui/app/components/tenant/RenderLogViewer.vue b/ui/app/components/tenant/RenderLogViewer.vue new file mode 100644 index 0000000..a62a791 --- /dev/null +++ b/ui/app/components/tenant/RenderLogViewer.vue @@ -0,0 +1,78 @@ + + + diff --git a/ui/app/components/tenant/RenderProgressBar.vue b/ui/app/components/tenant/RenderProgressBar.vue new file mode 100644 index 0000000..9d15327 --- /dev/null +++ b/ui/app/components/tenant/RenderProgressBar.vue @@ -0,0 +1,82 @@ + + + diff --git a/ui/app/components/tenant/RenderTable.vue b/ui/app/components/tenant/RenderTable.vue new file mode 100644 index 0000000..871ad2d --- /dev/null +++ b/ui/app/components/tenant/RenderTable.vue @@ -0,0 +1,66 @@ + + + diff --git a/ui/app/components/tenant/SourceTable.vue b/ui/app/components/tenant/SourceTable.vue new file mode 100644 index 0000000..016776b --- /dev/null +++ b/ui/app/components/tenant/SourceTable.vue @@ -0,0 +1,60 @@ + + + diff --git a/ui/app/components/tenant/TenantAccessGate.vue b/ui/app/components/tenant/TenantAccessGate.vue new file mode 100644 index 0000000..94b0863 --- /dev/null +++ b/ui/app/components/tenant/TenantAccessGate.vue @@ -0,0 +1,20 @@ + + + diff --git a/ui/app/components/tenant/TenantNav.vue b/ui/app/components/tenant/TenantNav.vue new file mode 100644 index 0000000..ebcf244 --- /dev/null +++ b/ui/app/components/tenant/TenantNav.vue @@ -0,0 +1,33 @@ + + + diff --git a/ui/app/composables/useApiClient.ts b/ui/app/composables/useApiClient.ts new file mode 100644 index 0000000..198a091 --- /dev/null +++ b/ui/app/composables/useApiClient.ts @@ -0,0 +1,19 @@ +import { createApusApiClient, type ApusApiClient } from '~/utils/apiClient' + +/** + * Nuxt-facing entry point to the api module client. Thin on purpose -- all the actual logic + * (request handling, error mapping, SSE framing) lives in app/utils/apiClient.ts, which stays + * plain TypeScript so it is unit-testable without a Nuxt runtime (tests/unit/apiClient.spec.ts). + * + * Both dashboard levels (platform, tenant -- see design spec §11.2) should go through this + * rather than constructing their own client. + */ +export function useApiClient(): ApusApiClient { + const config = useRuntimeConfig() + const { getAccessToken } = useAuth() + + return createApusApiClient({ + baseUrl: config.public.apiBaseUrl, + getAccessToken + }) +} diff --git a/ui/app/composables/useAuth.ts b/ui/app/composables/useAuth.ts new file mode 100644 index 0000000..d675c5e --- /dev/null +++ b/ui/app/composables/useAuth.ts @@ -0,0 +1,119 @@ +import { InMemoryWebStorage, UserManager, WebStorageStateStore, type User } from 'oidc-client-ts' +import { decodeJwtPayload } from '~/utils/jwt' +import { parsePrincipal, type ApusUiPrincipal } from '~/utils/role' + +/** + * Client-only OIDC session (Authorization Code + PKCE, public client -- design spec §10.3, + * §11.2). One `UserManager` per page load, shared by every `useAuth()` caller; the reactive + * state around it lives at module scope for the same reason (a composable that re-created its + * state per call would let two components disagree about who is logged in). + * + * ## Token storage (binding requirement, see the design spec and ui/README.md) + * + * `userStore` below is `InMemoryWebStorage`, not the library's own default + * (`window.sessionStorage`) and not `localStorage`. A plain JS object is not reachable by + * `localStorage.getItem(...)`-style scraping and does not survive a reload -- so an XSS bug + * elsewhere on the page can only exfiltrate a token while it is actively being used, not read + * it out of storage at leisure or find it still sitting there after the tab was closed and + * reopened. The cost: a hard reload loses the in-memory token. `automaticSilentRenew` plus the + * `signinSilent()` call in `init()` below paper over that by re-authenticating against the + * broker's own (httpOnly, broker-controlled, not readable by this page's JS) session cookie via + * a hidden iframe -- standard OIDC "silent renew". If the broker session has also expired, that + * falls through to an interactive `login()` redirect, same as a first visit. + */ +let manager: UserManager | undefined + +function getUserManager(): UserManager { + if (manager) return manager + + const config = useRuntimeConfig() + const origin = window.location.origin + manager = new UserManager({ + authority: config.public.oidcIssuer, + client_id: config.public.oidcClientId, + redirect_uri: `${origin}/auth/callback`, + silent_redirect_uri: `${origin}/auth/silent-renew`, + post_logout_redirect_uri: origin, + response_type: 'code', + scope: 'openid profile email', + automaticSilentRenew: true, + userStore: new WebStorageStateStore({ store: new InMemoryWebStorage() }) + }) + return manager +} + +const currentUser = ref(null) +const initialized = ref(false) + +const principal = computed(() => { + const token = currentUser.value?.access_token + if (!token) return null + try { + return parsePrincipal(decodeJwtPayload(token)) + } catch { + // A token the broker issued that this helper cannot parse is a display problem, not a + // reason to crash the app -- the api module validates the real token independently. + return null + } +}) + +export function useAuth() { + const oidc = getUserManager() + + /** Restores a session already known to `oidc-client-ts` (in-memory only, see above) and + * wires up event listeners. Call once, e.g. from app/plugins/oidc.client.ts. */ + async function init(): Promise { + if (initialized.value) return + initialized.value = true + + oidc.events.addUserLoaded((user) => { + currentUser.value = user + }) + oidc.events.addUserUnloaded(() => { + currentUser.value = null + }) + oidc.events.addSilentRenewError(() => { + currentUser.value = null + }) + + currentUser.value = await oidc.getUser() + } + + /** Redirects to the broker to sign in. `returnTo` is restored from `state` after the callback. */ + async function login(returnTo: string = '/'): Promise { + await oidc.signinRedirect({ state: { returnTo } }) + } + + async function logout(): Promise { + await oidc.removeUser() + currentUser.value = null + } + + /** Attempts to restore the session silently (hidden iframe against the broker's own session). + * Returns `false` rather than throwing when the broker has no active session either. */ + async function trySilentSignin(): Promise { + try { + const user = await oidc.signinSilent() + currentUser.value = user + return user !== null + } catch { + return false + } + } + + async function getAccessToken(): Promise { + return currentUser.value?.access_token ?? null + } + + return { + oidc, + user: currentUser, + principal, + isAuthenticated: computed(() => currentUser.value !== null), + init, + login, + logout, + trySilentSignin, + getAccessToken + } +} diff --git a/ui/app/layouts/default.vue b/ui/app/layouts/default.vue new file mode 100644 index 0000000..85906e7 --- /dev/null +++ b/ui/app/layouts/default.vue @@ -0,0 +1,8 @@ + diff --git a/ui/app/middleware/auth.global.ts b/ui/app/middleware/auth.global.ts new file mode 100644 index 0000000..f5fa3b5 --- /dev/null +++ b/ui/app/middleware/auth.global.ts @@ -0,0 +1,31 @@ +/** + * Requires a signed-in user for every route except the two OIDC redirect targets. This is a UX + * guard, not an access-control boundary -- it decides whether to *show* a login redirect, never + * whether a request is allowed; the api module enforces that independently on every call (see + * app/utils/role.ts's module Javadoc for the same point applied to roles). + * + * On an already-restored session (see useAuth().init(), called from the oidc plugin before any + * route renders) this is a no-op. On a fresh load with no in-memory session -- e.g. after a hard + * reload, since tokens are deliberately not persisted to Web Storage, see useAuth.ts -- it first + * tries a silent renew against the broker's own session before falling back to an interactive + * redirect, so a reload does not force a full login round-trip whenever the broker session is + * still valid. + */ +export default defineNuxtRouteMiddleware(async (to) => { + if (to.path.startsWith('/auth/')) { + return + } + + const { isAuthenticated, trySilentSignin, login } = useAuth() + if (isAuthenticated.value) { + return + } + + const restored = await trySilentSignin() + if (restored) { + return + } + + await login(to.fullPath) + return abortNavigation() +}) diff --git a/ui/app/pages/auth/callback.vue b/ui/app/pages/auth/callback.vue new file mode 100644 index 0000000..28b6533 --- /dev/null +++ b/ui/app/pages/auth/callback.vue @@ -0,0 +1,29 @@ + + + diff --git a/ui/app/pages/auth/silent-renew.vue b/ui/app/pages/auth/silent-renew.vue new file mode 100644 index 0000000..deedff7 --- /dev/null +++ b/ui/app/pages/auth/silent-renew.vue @@ -0,0 +1,15 @@ + + + diff --git a/ui/app/pages/index.vue b/ui/app/pages/index.vue new file mode 100644 index 0000000..420c4d3 --- /dev/null +++ b/ui/app/pages/index.vue @@ -0,0 +1,60 @@ + + + diff --git a/ui/app/pages/platform/index.vue b/ui/app/pages/platform/index.vue new file mode 100644 index 0000000..1ef951e --- /dev/null +++ b/ui/app/pages/platform/index.vue @@ -0,0 +1,66 @@ + + + diff --git a/ui/app/pages/tenant/hosting.vue b/ui/app/pages/tenant/hosting.vue new file mode 100644 index 0000000..e7ab3f4 --- /dev/null +++ b/ui/app/pages/tenant/hosting.vue @@ -0,0 +1,48 @@ + + + diff --git a/ui/app/pages/tenant/index.vue b/ui/app/pages/tenant/index.vue new file mode 100644 index 0000000..d2996b9 --- /dev/null +++ b/ui/app/pages/tenant/index.vue @@ -0,0 +1,81 @@ + + + diff --git a/ui/app/pages/tenant/maps.vue b/ui/app/pages/tenant/maps.vue new file mode 100644 index 0000000..5e365bd --- /dev/null +++ b/ui/app/pages/tenant/maps.vue @@ -0,0 +1,48 @@ + + + diff --git a/ui/app/pages/tenant/renders/[id].vue b/ui/app/pages/tenant/renders/[id].vue new file mode 100644 index 0000000..fdf5e36 --- /dev/null +++ b/ui/app/pages/tenant/renders/[id].vue @@ -0,0 +1,108 @@ + + + diff --git a/ui/app/pages/tenant/renders/index.vue b/ui/app/pages/tenant/renders/index.vue new file mode 100644 index 0000000..2fb4049 --- /dev/null +++ b/ui/app/pages/tenant/renders/index.vue @@ -0,0 +1,48 @@ + + + diff --git a/ui/app/pages/tenant/sources.vue b/ui/app/pages/tenant/sources.vue new file mode 100644 index 0000000..0a3aa53 --- /dev/null +++ b/ui/app/pages/tenant/sources.vue @@ -0,0 +1,48 @@ + + + diff --git a/ui/app/plugins/oidc.client.ts b/ui/app/plugins/oidc.client.ts new file mode 100644 index 0000000..9356788 --- /dev/null +++ b/ui/app/plugins/oidc.client.ts @@ -0,0 +1,10 @@ +/** + * Restores whatever OIDC session `oidc-client-ts` already knows about (in-memory only, see + * app/composables/useAuth.ts) before the app renders its first route. `.client.ts` suffix: this + * touches `window`, so it must never run during SSR -- moot in this app (`ssr: false`), but the + * suffix documents the constraint even if that ever changes. + */ +export default defineNuxtPlugin(async () => { + const { init } = useAuth() + await init() +}) diff --git a/ui/app/utils/apiClient.ts b/ui/app/utils/apiClient.ts new file mode 100644 index 0000000..af4e551 --- /dev/null +++ b/ui/app/utils/apiClient.ts @@ -0,0 +1,204 @@ +import { ApusApiError, defaultMessageForStatus } from './apiErrors' +import { parseSseStream } from './sse' +import type { + BlueMapHostingResponse, + BlueMapMapResponse, + BlueMapRenderResponse, + ClusterRenderResponse, + CreateTenantRequest, + CreateWorldSourceRequest, + RenderProgressEvent, + TenantResponse, + TriggerRenderRequest, + UpdateTenantRequest, + WorldSourceResponse +} from './apiTypes' + +/** A `fetch`-compatible function -- swapped out in tests, otherwise the global `fetch`. */ +export type FetchLike = typeof fetch + +export interface ApusApiClientOptions { + /** The api module's base URL, e.g. `https://api.apus.example.net` -- no trailing slash needed. */ + baseUrl: string + /** + * Resolves the current access token, or `null` if there is none (an unauthenticated request + * is still sent -- the api module answers with 401, see apiErrors.ts -- rather than the + * client guessing whether a token is required for a given endpoint). + */ + getAccessToken: () => Promise | string | null + /** Defaults to the global `fetch`; override in tests. */ + fetchImpl?: FetchLike +} + +export interface SseHandlers { + onMessage: (event: T) => void + onError?: (error: unknown) => void + /** Called when the stream ends normally (the api module closes it once the render is terminal). */ + onClose?: () => void +} + +/** + * Typed client for the `api` module's REST/SSE surface (design spec §11.1). Every method name + * and shape below is read from the actual controllers under + * api/src/main/java/net/onelitefeather/apus/api/{rest,events}/ -- see apiTypes.ts's own + * per-type comments for the exact source file. + * + * Deliberately framework-agnostic: no Nuxt composables, no `$fetch`, no global state. Use + * `useApiClient()` (app/composables/useApiClient.ts) from within Nuxt code; construct this + * directly (with a mocked `fetchImpl`) in tests -- see tests/unit/apiClient.spec.ts. + */ +export function createApusApiClient(options: ApusApiClientOptions) { + const baseUrl = options.baseUrl.replace(/\/+$/, '') + const fetchImpl = options.fetchImpl ?? fetch + + async function resolveToken(): Promise { + return await options.getAccessToken() + } + + async function request(path: string, init: RequestInit = {}): Promise { + const token = await resolveToken() + const headers = new Headers(init.headers) + headers.set('Accept', 'application/json') + if (init.body !== undefined && !headers.has('Content-Type')) { + headers.set('Content-Type', 'application/json') + } + if (token) { + headers.set('Authorization', `Bearer ${token}`) + } + + let response: Response + try { + response = await fetchImpl(`${baseUrl}${path}`, { ...init, headers }) + } catch (cause) { + throw new ApusApiError({ status: 0, message: 'Could not reach the Apus API.', cause }) + } + + if (!response.ok) { + throw await toApiError(response) + } + if (response.status === 204) { + return undefined as T + } + + const text = await response.text() + if (text.length === 0) { + return undefined as T + } + return JSON.parse(text) as T + } + + async function toApiError(response: Response): Promise { + let body: unknown + let message: string | undefined + try { + const text = await response.text() + if (text.length > 0) { + body = JSON.parse(text) + if (typeof body === 'object' && body !== null && 'message' in body) { + const candidate = (body as { message?: unknown }).message + if (typeof candidate === 'string') { + message = candidate + } + } + } + } catch { + // Non-JSON or empty error body (403/404 send none at all, see apiErrors.ts) -- fall + // through to the default message below. + } + return new ApusApiError({ + status: response.status, + message: message ?? defaultMessageForStatus(response.status), + body + }) + } + + async function streamSse(path: string, parse: (raw: string) => T, handlers: SseHandlers, signal?: AbortSignal) { + const token = await resolveToken() + const headers = new Headers({ Accept: 'text/event-stream' }) + if (token) { + headers.set('Authorization', `Bearer ${token}`) + } + + let response: Response + try { + response = await fetchImpl(`${baseUrl}${path}`, { headers, signal }) + } catch (cause) { + throw new ApusApiError({ status: 0, message: 'Could not open the event stream.', cause }) + } + if (!response.ok || !response.body) { + throw await toApiError(response) + } + + const reader = response.body.getReader() + try { + for await (const raw of parseSseStream(reader)) { + handlers.onMessage(parse(raw)) + } + handlers.onClose?.() + } catch (error) { + handlers.onError?.(error) + throw error + } + } + + return { + // -- Tenants: platform-admin only (design spec §10.3, §11.1) ------------------------------- + listTenants: () => request('/api/tenants'), + createTenant: (body: CreateTenantRequest) => + request('/api/tenants', { method: 'POST', body: JSON.stringify(body) }), + /** Changes an existing tenant's quota and/or allowed hosting domains -- `displayName` is + * not settable here, see `UpdateTenantRequest`'s own comment. */ + updateTenant: (name: string, body: UpdateTenantRequest) => + request(`/api/tenants/${encodeURIComponent(name)}`, { + method: 'PATCH', + body: JSON.stringify(body) + }), + + // -- World sources: caller's own tenant ----------------------------------------------------- + listSources: () => request('/api/sources'), + createSource: (body: CreateWorldSourceRequest) => + request('/api/sources', { method: 'POST', body: JSON.stringify(body) }), + + // -- Maps: caller's own tenant --------------------------------------------------------------- + listMaps: () => request('/api/maps'), + getMap: (id: string) => request(`/api/maps/${encodeURIComponent(id)}`), + triggerRender: (id: string, body?: TriggerRenderRequest) => + request(`/api/maps/${encodeURIComponent(id)}/render`, { + method: 'POST', + body: body === undefined ? undefined : JSON.stringify(body) + }), + + // -- Renders: caller's own tenant, read-only -------------------------------------------------- + listRenders: () => request('/api/renders'), + getRender: (id: string) => request(`/api/renders/${encodeURIComponent(id)}`), + + /** Cluster-wide render view -- `GET /api/renders/cluster`, `platform-admin` only (design + * spec §10.3, §11.2: "laufende Jobs clusterweit"). */ + listClusterRenders: () => request('/api/renders/cluster'), + + /** + * Live progress for one render -- `GET /api/renders/{id}/events`. Ends when the render + * reaches a terminal phase (`onClose`) or the caller aborts via `signal`. + */ + streamRenderEvents: (id: string, handlers: SseHandlers, signal?: AbortSignal) => + streamSse( + `/api/renders/${encodeURIComponent(id)}/events`, + (raw) => JSON.parse(raw) as RenderProgressEvent, + handlers, + signal + ), + + /** + * Live log lines for one render's job -- `GET /api/renders/{id}/logs`. Each event is one + * raw log line (not JSON) -- unlike `streamRenderEvents`, the api module's `Event` + * payload here is the line's text itself. + */ + streamRenderLogs: (id: string, handlers: SseHandlers, signal?: AbortSignal) => + streamSse(`/api/renders/${encodeURIComponent(id)}/logs`, (raw) => raw, handlers, signal), + + // -- Hostings: caller's own tenant, read-only ------------------------------------------------- + listHostings: () => request('/api/hostings') + } +} + +export type ApusApiClient = ReturnType diff --git a/ui/app/utils/apiErrors.ts b/ui/app/utils/apiErrors.ts new file mode 100644 index 0000000..4c53c77 --- /dev/null +++ b/ui/app/utils/apiErrors.ts @@ -0,0 +1,48 @@ +/** + * Uniform error type for every failure `ApusApiClient` can raise -- HTTP error responses, + * network failures, and failed SSE stream opens alike, so a caller can catch one type instead + * of juggling `fetch` rejections and HTTP status branches separately. + * + * `status` mirrors what the api module actually sends (see + * api/src/main/java/net/onelitefeather/apus/api/rest/support/*ExceptionHandler.java): + * - `400` -- {@link BadRequestExceptionHandler}, body is `{"message": "..."}}`, surfaced as-is. + * - `401` -- Micronaut Security's own default response for a missing/invalid/expired token; + * the api module adds no custom body for this case. + * - `403` -- {@link ForbiddenExceptionHandler}, no body at all. + * - `404` -- {@link NotFoundExceptionHandler}, no body at all -- also what a resource in a + * *different* tenant's namespace returns (see the relevant controllers' Javadoc: this is + * deliberate, not a client bug). + * - `0` -- no HTTP response was received at all (network failure, CORS, aborted request); see + * {@link networkError}. + */ +export class ApusApiError extends Error { + readonly status: number + readonly body: unknown + /** The underlying `fetch` rejection, when `status` is `0`. Not named `cause`: that name is + * `Error`'s own standard property (ES2022) and this is deliberately a distinct field. */ + readonly networkError: unknown + + constructor(options: { status: number; message: string; body?: unknown; cause?: unknown }) { + super(options.message) + this.name = 'ApusApiError' + this.status = options.status + this.body = options.body + this.networkError = options.cause + } +} + +/** Default, human-readable message per status when the response carried no usable body. */ +export function defaultMessageForStatus(status: number): string { + switch (status) { + case 400: + return 'The request was rejected as invalid.' + case 401: + return 'Not authenticated.' + case 403: + return 'Not permitted.' + case 404: + return 'Not found.' + default: + return `Request failed with status ${status}.` + } +} diff --git a/ui/app/utils/apiTypes.ts b/ui/app/utils/apiTypes.ts new file mode 100644 index 0000000..d53f6eb --- /dev/null +++ b/ui/app/utils/apiTypes.ts @@ -0,0 +1,237 @@ +/** + * Wire types for the `api` module's REST/SSE surface (design spec §11.1). Each type here is a + * direct field-for-field mirror of the Java response/request record it names in its comment -- + * read those files, do not guess at shape. Micronaut Serde serialises record components under + * their declared name with no naming strategy configured, so JSON keys equal the Java field + * names verbatim (camelCase both sides). + * + * These are *response* shapes as the API actually returns them -- several deliberately omit + * fields a naive mirror of the underlying custom resource would include (Secret names, job + * names, CR bookkeeping). See each Java file's own Javadoc for why; do not "complete" these + * types with fields the API does not send. + */ + +/** api/src/main/java/net/onelitefeather/apus/api/rest/support/ConditionResponse.java */ +export interface ConditionResponse { + type: string + status: string + reason: string + message: string +} + +// --------------------------------------------------------------------------------------------- +// Tenants -- GET/POST /api/tenants, platform-admin only (design spec §10.3, §11.1) +// --------------------------------------------------------------------------------------------- + +/** api/src/main/java/net/onelitefeather/apus/api/rest/tenant/TenantResponse.java */ +export interface TenantResponse { + name: string + displayName: string + storage: TenantStorageResponse + allowedHostingDomains: string[] + namespace: string + objectStoreUser: string + storageUsedBytes: number | null + conditions: ConditionResponse[] +} + +/** `TenantResponse.StorageResponse` -- never carries Ceph credentials, quota only. */ +export interface TenantStorageResponse { + quota: string | null + maxObjects: number | null +} + +/** api/src/main/java/net/onelitefeather/apus/api/rest/tenant/CreateTenantRequest.java */ +export interface CreateTenantRequest { + name: string + displayName?: string | null + storageQuota?: string | null + maxObjects?: number | null + allowedHostingDomains?: string[] | null +} + +/** + * api/src/main/java/net/onelitefeather/apus/api/rest/tenant/UpdateTenantRequest.java -- + * `PATCH /api/tenants/{name}`. Partial-update semantics: an omitted/`null` field leaves the + * current value untouched. Unlike `CreateTenantRequest`, there is no `displayName` here -- the + * endpoint only ever changes quota/domains (see that record's own Javadoc). + */ +export interface UpdateTenantRequest { + storageQuota?: string | null + maxObjects?: number | null + allowedHostingDomains?: string[] | null +} + +// --------------------------------------------------------------------------------------------- +// World sources -- GET/POST /api/sources, caller's own tenant (design spec §10.3, §11.1) +// --------------------------------------------------------------------------------------------- + +/** api/src/main/java/net/onelitefeather/apus/api/rest/worldsource/WorldSourceResponse.java */ +export interface WorldSourceResponse { + name: string + type: string + poll: string | null + worlds: WorldSelectorResponse[] + keepVersions: number + lastSeenVersion: string | null + latestBundle: WorldSourceBundleResponse | null + lastPollTime: string | null + conditions: ConditionResponse[] +} + +export interface WorldSelectorResponse { + name: string + layout: string | null + minecraftVersion: string | null +} + +/** Which bundle version this source last produced -- path and version only. */ +export interface WorldSourceBundleResponse { + path: string + version: string +} + +/** api/src/main/java/net/onelitefeather/apus/api/rest/worldsource/CreateWorldSourceRequest.java */ +export interface CreateWorldSourceRequest { + name: string + type: 's3' | 'pterodactyl' | 'upload' | 'push' + s3?: CreateWorldSourceS3Request | null + pterodactyl?: CreateWorldSourcePterodactylRequest | null + poll?: string | null + worlds?: WorldSelectorRequest[] | null + keepVersions?: number | null +} + +export interface CreateWorldSourceS3Request { + endpoint: string + bucket: string + prefix?: string | null + credentialsSecretName?: string | null +} + +export interface CreateWorldSourcePterodactylRequest { + panelUrl: string + serverId: string + credentialsSecretName?: string | null + select?: string | null +} + +export interface WorldSelectorRequest { + name: string + layout?: string | null + minecraftVersion?: string | null +} + +// --------------------------------------------------------------------------------------------- +// Maps -- GET /api/maps, GET /api/maps/{id}, POST /api/maps/{id}/render (design spec §10.3, §11.1) +// --------------------------------------------------------------------------------------------- + +/** api/src/main/java/net/onelitefeather/apus/api/rest/map/BlueMapMapResponse.java */ +export interface BlueMapMapResponse { + name: string + source: BlueMapMapSourceResponse + trigger: BlueMapMapTriggerResponse + bluemap: BlueMapMapSettingsResponse + shards: number + historyLimit: number + purgeOnDelete: boolean + bucket: BlueMapMapBucketResponse + latestRender: BlueMapMapLatestRenderResponse + conditions: ConditionResponse[] +} + +export interface BlueMapMapSourceResponse { + sourceRef: string | null + world: string | null + dimension: string | null +} + +export interface BlueMapMapTriggerResponse { + onNewBundle: boolean + schedule: string | null + concurrencyPolicy: string | null +} + +export interface BlueMapMapSettingsResponse { + version: string | null + minecraftVersion: string | null +} + +/** Bucket name and endpoint only -- never the Secret name holding its credentials. */ +export interface BlueMapMapBucketResponse { + name: string | null + endpoint: string | null +} + +export interface BlueMapMapLatestRenderResponse { + name: string | null + phase: string | null +} + +/** api/src/main/java/net/onelitefeather/apus/api/rest/map/TriggerRenderRequest.java */ +export interface TriggerRenderRequest { + force: boolean +} + +// --------------------------------------------------------------------------------------------- +// Renders -- GET /api/renders, GET /api/renders/{id}, plus SSE /events and /logs +// --------------------------------------------------------------------------------------------- + +/** api/src/main/java/net/onelitefeather/apus/api/rest/render/BlueMapRenderResponse.java */ +export interface BlueMapRenderResponse { + name: string + mapRef: string | null + force: boolean + phase: string | null + progress: BlueMapRenderProgressResponse + startTime: string | null + completionTime: string | null + conditions: ConditionResponse[] +} + +export interface BlueMapRenderProgressResponse { + percent: number + currentMap: string | null + etaSeconds: number + degraded: boolean +} + +/** + * SSE payload for `GET /api/renders/{id}/events` -- + * api/src/main/java/net/onelitefeather/apus/api/events/RenderProgress.java. A distinct, smaller + * type from {@link BlueMapRenderResponse}: the live stream is phase + progress only, not the + * full render resource. + */ +export interface RenderProgressEvent { + phase: string | null + percent: number + currentMap: string | null + etaSeconds: number + degraded: boolean +} + +/** + * api/src/main/java/net/onelitefeather/apus/api/rest/render/ClusterRenderResponse.java -- + * `GET /api/renders/cluster`, `platform-admin` only. Wraps the ordinary render response with + * which tenant it belongs to, since the platform dashboard's cluster-wide view has no tenant of + * its own to scope by. + */ +export interface ClusterRenderResponse { + tenant: string + render: BlueMapRenderResponse +} + +// --------------------------------------------------------------------------------------------- +// Hostings -- GET /api/hostings, read-only, caller's own tenant +// --------------------------------------------------------------------------------------------- + +/** api/src/main/java/net/onelitefeather/apus/api/rest/hosting/BlueMapHostingResponse.java */ +export interface BlueMapHostingResponse { + name: string + maps: (string | null)[] + hostname: string | null + url: string | null + ready: boolean + replicas: number + conditions: ConditionResponse[] +} diff --git a/ui/app/utils/domainValidation.ts b/ui/app/utils/domainValidation.ts new file mode 100644 index 0000000..ff83f65 --- /dev/null +++ b/ui/app/utils/domainValidation.ts @@ -0,0 +1,99 @@ +/** + * Validation for `Tenant.spec.hosting.allowedDomains` entries (design spec §11.2: "Domain- + * Freigaben"; operator/src/main/java/net/onelitefeather/apus/operator/api/TenantSpec.java's + * `Hosting.allowedDomains`). Pure TypeScript, no Nuxt/Vue dependency -- unit-tested in + * tests/unit/platform/domainValidation.spec.ts. + * + * IMPORTANT -- read before relaxing any rule here: this list is the only thing that stops one + * tenant's `BlueMapHosting` from claiming another tenant's hostname -- exactly the hole Phase 3 + * closed (`BlueMapHostingReconciler`, see `Hosting`'s own Javadoc: "An empty allowedDomains is + * deliberately treated as 'no hosting permitted yet', not 'anything goes'"). Rejecting a bare + * `*` is the single most important rule in this file, not a nice-to-have -- it would grant a + * tenant every hostname on the platform. + */ + +export interface DomainValidationResult { + readonly valid: boolean + readonly error: string | null +} + +const VALID: DomainValidationResult = { valid: true, error: null } + +function invalid(error: string): DomainValidationResult { + return { valid: false, error } +} + +/** One DNS label: letters/digits, hyphens allowed except leading/trailing, max 63 characters. */ +const LABEL_PATTERN = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/ + +/** + * Validates a single `allowedDomains` entry. Accepts a plain hostname (`maps.example.net`) or a + * single leading wildcard label (`*.friends.example.net`, matching what `TenantSpec.Hosting`'s + * Javadoc documents as supported) -- never a bare `*`, and never a wildcard anywhere but the + * leading label. + */ +export function validateAllowedDomain(input: string): DomainValidationResult { + const value = input.trim() + + if (value.length === 0) { + return invalid('Domain must not be empty.') + } + if (value === '*') { + return invalid( + 'A bare "*" would let this tenant claim every hostname on the platform -- use a specific ' + + 'domain, or a single leading wildcard label like "*.example.net", instead.' + ) + } + if (/\s/.test(value)) { + return invalid('Domain must not contain whitespace.') + } + if (value.includes('://') || value.includes('/') || value.includes(':')) { + return invalid('Enter a hostname only, without a scheme, path, or port.') + } + + const labels = value.split('.') + if (labels.some((label) => label.length === 0)) { + return invalid('Domain must not contain empty labels (e.g. two dots in a row, or a leading/trailing dot).') + } + + const [firstLabel, ...restLabels] = labels + const isWildcard = firstLabel === '*' + if (isWildcard && restLabels.length === 0) { + return invalid('A wildcard needs a concrete domain to scope it, e.g. "*.example.net".') + } + + const labelsToValidate = isWildcard ? restLabels : labels + for (const label of labelsToValidate) { + if (label === '*') { + return invalid('Only a single leading "*" label is allowed, e.g. "*.example.net".') + } + if (label.length > 63) { + return invalid(`"${label}" is too long -- domain labels are limited to 63 characters.`) + } + if (!LABEL_PATTERN.test(label)) { + return invalid(`"${label}" is not a valid domain label.`) + } + } + + return VALID +} + +/** + * Validates a whole `allowedDomains` list: every entry via {@link validateAllowedDomain}, plus + * no case-insensitive duplicates. An empty list is valid -- see this module's own Javadoc on + * why that means "hosting not yet allowed" rather than an error state. + */ +export function validateAllowedDomains(inputs: readonly string[]): DomainValidationResult { + const seen = new Set() + for (const raw of inputs) { + const result = validateAllowedDomain(raw) + if (!result.valid) return result + + const normalized = raw.trim().toLowerCase() + if (seen.has(normalized)) { + return invalid(`"${raw.trim()}" is listed more than once.`) + } + seen.add(normalized) + } + return VALID +} diff --git a/ui/app/utils/formatTimestamp.ts b/ui/app/utils/formatTimestamp.ts new file mode 100644 index 0000000..2c6e222 --- /dev/null +++ b/ui/app/utils/formatTimestamp.ts @@ -0,0 +1,12 @@ +/** + * Formats an ISO-8601 timestamp (or `null`) for display -- shared across the tenant dashboard's + * tables so "when did this last happen" reads consistently. Pure presentation (locale-dependent + * `Intl` formatting), not unit-tested per this task's brief ("Tests: für das, was Logik trägt... + * nicht für reine Darstellung"). + */ +export function formatTimestamp(value: string | null): string { + if (!value) return 'never' + const date = new Date(value) + if (Number.isNaN(date.getTime())) return value + return date.toLocaleString() +} diff --git a/ui/app/utils/jwt.ts b/ui/app/utils/jwt.ts new file mode 100644 index 0000000..7e4df1c --- /dev/null +++ b/ui/app/utils/jwt.ts @@ -0,0 +1,42 @@ +/** + * Decodes a JWT's payload (second segment) into its claims, without verifying the signature. + * + * This is deliberately *not* validation. The api module is the only party that verifies a + * token's signature and issuer (see api/src/main/resources/application.yml -- Micronaut + * Security validates against `APUS_JWT_JWKS_URI`/`APUS_JWT_ISSUER` on every request). This + * helper only reads claims already sitting in a token the broker issued to us, purely so the UI + * can decide what to show (see app/utils/role.ts). Never use its output for anything that needs + * to be trustworthy -- the API re-checks everything regardless. + * + * Works both in the browser (atob) and under Node/Vitest (Buffer fallback), and decodes the + * base64url payload as UTF-8 so non-ASCII claim values (e.g. a tenant display name) survive. + */ +export function decodeJwtPayload(token: string): Record { + const segments = token.split('.') + const payloadSegment = segments[1] + if (segments.length < 2 || !payloadSegment) { + throw new Error('not a JWT: expected at least a header and payload segment') + } + + const base64 = base64UrlToBase64(payloadSegment) + const binary = typeof atob === 'function' ? atob(base64) : bufferAtob(base64) + const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0)) + const json = new TextDecoder('utf-8').decode(bytes) + + const parsed: unknown = JSON.parse(json) + if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) { + throw new Error('not a JWT: payload is not a JSON object') + } + return parsed as Record +} + +function base64UrlToBase64(value: string): string { + const normalized = value.replaceAll('-', '+').replaceAll('_', '/') + const paddingNeeded = (4 - (normalized.length % 4)) % 4 + return normalized + '='.repeat(paddingNeeded) +} + +// Node-only fallback (no `atob` global): used under Vitest, never in a browser build. +function bufferAtob(base64: string): string { + return Buffer.from(base64, 'base64').toString('binary') +} diff --git a/ui/app/utils/renderProgress.ts b/ui/app/utils/renderProgress.ts new file mode 100644 index 0000000..6b09176 --- /dev/null +++ b/ui/app/utils/renderProgress.ts @@ -0,0 +1,85 @@ +/** + * Pure formatting/decision logic for render progress display (design spec §11.2: "Renders... + * für den laufenden Render Fortschritt in Prozent mit geschätzter Restzeit, live"). + * + * Framework-free so it stays unit-testable without mounting a component -- see + * tests/unit/tenant/renderProgress.spec.ts. + * + * The api module sends `-1` for `percent`/`etaSeconds` together with `degraded: true` when its + * progress *measurement* has degraded (design spec: this can happen without the render itself + * being at risk) -- see `BlueMapRenderProgressResponse`/`RenderProgressEvent` in + * app/utils/apiTypes.ts. The one binding rule here: never turn an unknown value into a fabricated + * number (a bar frozen at 0%, an invented ETA) -- report it as unknown instead. + */ +import type { RenderProgressEvent } from './apiTypes' + +/** Mirrors `RenderPhases.TERMINAL` (api module, api/src/main/java/.../events/RenderPhases.java) + * exactly -- the only two phases after which a render's progress stream will not change again. */ +const TERMINAL_PHASES: ReadonlySet = new Set(['Succeeded', 'Failed']) + +/** Whether `phase` is terminal, mirroring `RenderPhases.isTerminal` on the api module. */ +export function isRenderTerminal(phase: string | null | undefined): boolean { + return phase != null && TERMINAL_PHASES.has(phase) +} + +/** The subset of `BlueMapRenderProgressResponse`/`RenderProgressEvent` this module needs. */ +export interface RenderProgressSnapshot { + phase: string | null + percent: number + etaSeconds: number + degraded: boolean +} + +/** A `RenderProgressEvent` (SSE payload) is already a valid snapshot -- same shape. */ +export type RenderProgressSseSnapshot = RenderProgressEvent + +/** Ready-to-render form of a {@link RenderProgressSnapshot}: no `-1` sentinels left for a + * template to accidentally display. */ +export interface RenderProgressDisplay { + /** `false` when the api module reports `percent < 0` -- show this honestly, never as 0%. */ + readonly percentKnown: boolean + /** Clamped to [0, 100] when known; `null` when not -- feed straight to a progress bar. */ + readonly percent: number | null + /** `false` when the api module reports `etaSeconds < 0`. */ + readonly etaKnown: boolean + /** Human-readable remaining time (e.g. `"2h 15m"`), or `null` when unknown. */ + readonly etaLabel: string | null + /** Whether the *measurement* has degraded -- render may still be healthy, see module doc. */ + readonly degraded: boolean + readonly terminal: boolean +} + +/** Turns a raw snapshot into display-ready values -- the one place `-1` gets interpreted. */ +export function describeRenderProgress(snapshot: RenderProgressSnapshot): RenderProgressDisplay { + const percentKnown = snapshot.percent >= 0 + const etaKnown = snapshot.etaSeconds >= 0 + return { + percentKnown, + percent: percentKnown ? Math.min(100, Math.max(0, snapshot.percent)) : null, + etaKnown, + etaLabel: etaKnown ? formatDuration(snapshot.etaSeconds) : null, + degraded: snapshot.degraded, + terminal: isRenderTerminal(snapshot.phase) + } +} + +/** + * Formats a non-negative duration in seconds as a short human-readable label. Callers are + * expected to have already checked the value is known (see {@link describeRenderProgress}) -- + * this function has no "unknown" case of its own, on purpose, so that decision cannot be made + * twice in two different ways. + */ +export function formatDuration(totalSeconds: number): string { + const seconds = Math.max(0, Math.round(totalSeconds)) + const hours = Math.floor(seconds / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + const remainingSeconds = seconds % 60 + + if (hours > 0) { + return `${hours}h ${minutes}m` + } + if (minutes > 0) { + return `${minutes}m ${remainingSeconds}s` + } + return `${remainingSeconds}s` +} diff --git a/ui/app/utils/role.ts b/ui/app/utils/role.ts new file mode 100644 index 0000000..37e4bf5 --- /dev/null +++ b/ui/app/utils/role.ts @@ -0,0 +1,101 @@ +/** + * UI-side role helpers, mirroring the server-side model in + * `api/src/main/java/net/onelitefeather/apus/api/security/{Role,ApusPrincipal}.java` and + * `api/src/main/java/net/onelitefeather/apus/api/rest/support/TenantAccess.java`. + * + * IMPORTANT -- read before using any of this: these helpers exist purely so the UI can decide + * what to *show* (design spec §11.2: "Zwei Ebenen, getrennt über die Rolle im Token"). They + * enforce nothing. Every one of these checks is re-done, authoritatively, by the api module on + * every request (design spec §10.3: "Das Backend ist der Durchsetzungspunkt"). Hiding a button + * here only hides something the API would have refused anyway -- it must never be the *only* + * thing standing between a user and an action. Do not add logic here that a reviewer could + * mistake for an access-control boundary. + */ + +/** The four roles from design spec §10.3. Order matches the table there. */ +export const ROLES = ['platform-admin', 'tenant-owner', 'tenant-operator', 'tenant-viewer'] as const + +export type Role = (typeof ROLES)[number] + +const ROLE_SET: ReadonlySet = new Set(ROLES) + +/** Mirrors `Role.fromClaim`'s exact-match, case-insensitive, no-separator-tolerance behaviour. */ +export function isRole(value: string): value is Role { + return ROLE_SET.has(value) +} + +/** + * Claim name Micronaut Security's JWT roles resolution reads by default -- unconfigured in + * api/src/main/resources/application.yml (no `micronaut.security.token.roles-claim-name` + * override), so the framework default `"roles"` claim applies. This is what + * `authentication.getRoles()` resolves in `PrincipalResolver`; if that ever changes there, it + * must change here too. + */ +const ROLES_CLAIM = 'roles' + +/** + * Matches `PrincipalResolver.TENANT_CLAIM` exactly (api module, `support/PrincipalResolver.java`) + * -- the organisation claim design spec §10.3 says determines the tenant. + */ +const TENANT_CLAIM = 'organization' + +/** Who the UI is rendering for, decoded from the access token's claims. See the module Javadoc. */ +export interface ApusUiPrincipal { + /** The token's `sub` claim, or `null` if absent -- for display only. */ + readonly subject: string | null + /** The `organization` claim, or `null` if absent/blank -- mirrors `ApusPrincipal.tenant()`. */ + readonly tenant: string | null + /** Recognised roles only; unrecognised claim entries are dropped, never rejected. */ + readonly roles: readonly Role[] +} + +/** + * Builds an {@link ApusUiPrincipal} from a decoded token payload (see app/utils/jwt.ts). + * Unrecognised role claim entries are silently dropped -- mirroring `Role.fromClaim` returning + * `Optional.empty()` for a role the broker knows about but Apus does not (yet), rather than + * failing the whole token. + */ +export function parsePrincipal(claims: Record): ApusUiPrincipal { + const subject = typeof claims.sub === 'string' ? claims.sub : null + + const tenantClaim = claims[TENANT_CLAIM] + const tenant = typeof tenantClaim === 'string' && tenantClaim.trim().length > 0 ? tenantClaim : null + + const rawRoles = claims[ROLES_CLAIM] + const roles: Role[] = Array.isArray(rawRoles) + ? rawRoles + .filter((entry): entry is string => typeof entry === 'string') + .map((entry) => entry.trim().toLowerCase()) + .filter(isRole) + : [] + + return { subject, tenant, roles } +} + +/** Whether the platform-level dashboard should be offered at all (design spec §11.2). */ +export function isPlatformAdmin(principal: ApusUiPrincipal | null | undefined): boolean { + return principal?.roles.includes('platform-admin') ?? false +} + +/** + * Whether the tenant dashboard should offer write actions (create/trigger) -- + * mirrors `ApusPrincipal.canWrite()`. Deliberately excludes `platform-admin`, same as the + * server: that role's write access is to platform resources, not a tenant's own. + */ +export function canWriteTenant(principal: ApusUiPrincipal | null | undefined): boolean { + if (!principal) return false + return principal.roles.includes('tenant-owner') || principal.roles.includes('tenant-operator') +} + +/** + * Whether the tenant dashboard should be shown at all -- mirrors `TenantAccess.canRead()`: + * any of the three tenant-level roles. + */ +export function canReadTenant(principal: ApusUiPrincipal | null | undefined): boolean { + if (!principal) return false + return ( + principal.roles.includes('tenant-owner') + || principal.roles.includes('tenant-operator') + || principal.roles.includes('tenant-viewer') + ) +} diff --git a/ui/app/utils/sse.ts b/ui/app/utils/sse.ts new file mode 100644 index 0000000..ec58045 --- /dev/null +++ b/ui/app/utils/sse.ts @@ -0,0 +1,59 @@ +/** + * Minimal server-sent-events framer over a raw `ReadableStreamDefaultReader`. + * + * Why not `EventSource`: `EventSource` cannot set an `Authorization` header, and the api + * module's SSE endpoints (`GET /api/renders/{id}/events`, `.../logs`, see + * api/src/main/java/net/onelitefeather/apus/api/events/RenderStreamController.java) are behind + * the same bearer-JWT auth as everything else -- there is no query-parameter token reader + * configured in api/src/main/resources/application.yml. So the client opens the stream with + * `fetch` (which can set the header) and frames it itself; see `streamSse` in apiClient.ts for + * the fetch + auth-header side of this. + * + * Only handles the subset of the SSE wire format Micronaut's `Event.of(value)` actually emits: + * one or more `data:` lines per event, separated by a blank line. `event:`/`id:`/`retry:` lines + * and comments (`:`-prefixed) are intentionally not parsed -- the api module does not send them + * for these two endpoints, and speculatively supporting them would be untested code. + */ +export async function* parseSseStream( + reader: ReadableStreamDefaultReader +): AsyncGenerator { + const decoder = new TextDecoder('utf-8') + let buffer = '' + + while (true) { + const { done, value } = await reader.read() + if (done) break + buffer += decoder.decode(value, { stream: true }) + + let separatorIndex = buffer.indexOf('\n\n') + while (separatorIndex !== -1) { + const rawEvent = buffer.slice(0, separatorIndex) + buffer = buffer.slice(separatorIndex + 2) + const data = extractData(rawEvent) + if (data !== null) { + yield data + } + separatorIndex = buffer.indexOf('\n\n') + } + } + + // A final event without a trailing blank line (stream closed right after it) is still a + // complete event -- flush it rather than silently dropping the last message. + const trailing = extractData(buffer) + if (trailing !== null) { + yield trailing + } +} + +function extractData(rawEvent: string): string | null { + const dataLines = rawEvent + .split('\n') + .filter((line) => line.startsWith('data:')) + .map((line) => line.slice('data:'.length).replace(/^ /, '')) + + if (dataLines.length === 0) { + return null + } + // Per the SSE spec, multiple `data:` lines in one event join with `\n`. + return dataLines.join('\n') +} diff --git a/ui/app/utils/sseController.ts b/ui/app/utils/sseController.ts new file mode 100644 index 0000000..14b637c --- /dev/null +++ b/ui/app/utils/sseController.ts @@ -0,0 +1,59 @@ +/** + * Lifecycle wiring shared by every live SSE view on the tenant dashboard (render progress, + * render logs -- design spec §11.2: "Schließe die Ereignisströme wieder, wenn eine Ansicht + * verlassen wird oder der Render terminal ist"). Deliberately framework-free, so the cleanup + * behaviour is unit-testable without mounting a component -- see + * tests/unit/tenant/sseController.spec.ts. The Vue components in `components/tenant/` only call + * `openSseController` from `onMounted` and its returned `stop()` from `onUnmounted`. + */ +import type { SseHandlers } from './apiClient' +import { isRenderTerminal } from './renderProgress' + +export interface SseController { + /** Aborts the underlying stream. Safe to call more than once (`AbortController.abort()` is + * idempotent) and safe to call after the stream already closed itself. */ + stop: () => void +} + +/** + * Starts one `ApusApiClient` SSE method (`streamRenderEvents`/`streamRenderLogs`) and returns a + * handle to close it. `open` is the exact shape both client methods share: given handlers and an + * `AbortSignal`, return the promise that resolves once the stream ends. + */ +export function openSseController( + open: (handlers: SseHandlers, signal: AbortSignal) => Promise, + handlers: SseHandlers +): SseController { + const controller = new AbortController() + + open(handlers, controller.signal).catch(() => { + // A rejection here means the stream failed to open or broke mid-stream; `apiClient.ts`'s + // `streamSse` already routed that same error to `handlers.onError` before rethrowing it (or, + // if we called `stop()` ourselves, it's the expected abort). Either way, nothing further to + // do -- this catch exists only to keep that rejection from becoming an unhandled promise. + }) + + return { + stop: () => controller.abort() + } +} + +/** + * Wraps `handlers.onMessage` so the stream is stopped the moment a terminal render phase is + * observed, instead of relying solely on the api module closing its end (which it does too, see + * `RenderStreamController`'s Javadoc -- this is defence in depth, not a workaround for a gap). + */ +export function withAutoStopOnTerminal( + handlers: SseHandlers, + stop: () => void +): SseHandlers { + return { + ...handlers, + onMessage: (event: T) => { + handlers.onMessage(event) + if (isRenderTerminal(event.phase)) { + stop() + } + } + } +} diff --git a/ui/app/utils/storageUsage.ts b/ui/app/utils/storageUsage.ts new file mode 100644 index 0000000..ba5ee72 --- /dev/null +++ b/ui/app/utils/storageUsage.ts @@ -0,0 +1,170 @@ +/** + * Storage usage math for the platform dashboard (design spec §11.2: "Mandanten, Quotas mit + * Verbrauchsanzeige"). Pure TypeScript, no Nuxt/Vue dependency, so it is directly unit-testable + * -- see tests/unit/platform/storageUsage.spec.ts. + * + * IMPORTANT -- read before changing thresholds or wording here: the quota is enforced by Ceph + * (RGW), not by Apus or this UI (operator/src/main/java/net/onelitefeather/apus/operator/api/ + * TenantSpec.java's `StorageQuota` Javadoc: "Hard storage limit, enforced by Ceph rather than by + * this operator"). Nothing in this module, or in any component that uses it, may present usage + * as something the platform-admin can push past the limit from here -- it is an observation of + * `Tenant.status.storageUsedBytes`, not a control. What this module *is* for: making it obvious + * when a tenant is close to its limit, because uploads start failing once it is reached (design + * spec §12: "Speicherlimit erreicht -> RGW-Fehler -> Condition StorageQuotaExceeded, kein + * Retry"). + */ + +const QUANTITY_PATTERN = /^(\d+(?:\.\d+)?)\s*([a-zA-Z]*)$/ + +/** + * Byte multiplier for a Kubernetes resource quantity suffix -- binary (IEC: `Ki`..`Ei`) and + * decimal (SI: `k`/`K`..`E`) alike, plus the empty string for a plain byte count. `null` for an + * unrecognised suffix. A plain `if`/`else` chain rather than a lookup object so the result stays + * a definite `number`, not `number | undefined`, under this project's `noUncheckedIndexedAccess`. + */ +function unitMultiplier(unit: string): number | null { + if (unit.length === 0) return 1 + if (unit === 'Ki') return 2 ** 10 + if (unit === 'Mi') return 2 ** 20 + if (unit === 'Gi') return 2 ** 30 + if (unit === 'Ti') return 2 ** 40 + if (unit === 'Pi') return 2 ** 50 + if (unit === 'Ei') return 2 ** 60 + if (unit === 'k' || unit === 'K') return 1e3 + if (unit === 'M') return 1e6 + if (unit === 'G') return 1e9 + if (unit === 'T') return 1e12 + if (unit === 'P') return 1e15 + if (unit === 'E') return 1e18 + return null +} + +/** + * Parses a Kubernetes-style resource quantity string (`TenantResponse.storage.quota`, e.g. + * `"100Gi"` -- see `TenantSpec.StorageQuota` on the operator side) into a byte count. + * + * Returns `null` for anything unparseable -- a quota the UI cannot make sense of must not be + * silently treated as "0" or "unlimited"; callers surface that as "unknown", same as no usage + * being reported yet. + */ +export function parseQuotaBytes(quota: string | null | undefined): number | null { + if (quota == null) return null + const trimmed = quota.trim() + if (trimmed.length === 0) return null + + const match = QUANTITY_PATTERN.exec(trimmed) + if (!match) return null + + const numeric = match[1] + const unit = match[2] + if (numeric === undefined || unit === undefined) return null + + const value = Number(numeric) + if (!Number.isFinite(value)) return null + + const multiplier = unitMultiplier(unit) + if (multiplier === null) return null + + return value * multiplier +} + +const BYTE_UNIT_NAMES = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] + +/** Formats a non-negative byte count as a human-readable IEC size, e.g. `"12.34 GiB"`. */ +export function formatBytes(bytes: number): string { + if (!Number.isFinite(bytes) || bytes <= 0) return '0 B' + + const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), BYTE_UNIT_NAMES.length - 1) + const value = bytes / 1024 ** exponent + const formatted = exponent === 0 ? String(value) : value.toFixed(2) + return `${formatted} ${BYTE_UNIT_NAMES[exponent]}` +} + +/** + * `'unknown'` -- usage or quota could not be determined (e.g. `status.storageUsedBytes` has not + * been reported yet, see `describeStorageUsage`'s "no usage known" edge case). + * `'ok'` / `'warning'` / `'critical'` -- below, approaching, and just under the quota. + * `'over'` -- reported usage is at or above the quota. This is a stale-metrics or edge-timing + * observation, not a contradiction: Ceph already refuses further writes at this point (see + * this module's own Javadoc), so the UI shows it plainly rather than clamping it to 100%. + */ +export type StorageUsageLevel = 'unknown' | 'ok' | 'warning' | 'critical' | 'over' + +export interface StorageUsageSummary { + readonly usedBytes: number | null + readonly quotaBytes: number | null + /** Fraction of quota consumed (e.g. `0.42` for 42%); `null` when usage or quota is unknown. */ + readonly ratio: number | null + readonly level: StorageUsageLevel + /** Human-readable usage, or an explanatory placeholder when unknown. */ + readonly usedLabel: string + /** Human-readable quota, or the raw (unparseable) string when it could not be interpreted. */ + readonly quotaLabel: string +} + +/** At or above this fraction of quota, usage is flagged as approaching the limit. */ +const WARNING_RATIO = 0.8 +/** At or above this fraction of quota, usage is flagged as critically close to the limit. */ +const CRITICAL_RATIO = 0.95 + +/** + * Builds a display-ready summary of one tenant's storage usage against its quota. Handles the + * two edge cases that matter most for an operator glancing at the dashboard: no usage reported + * yet (`usedBytes` is `null` -- the tenant may be brand new, or the operator has not synced a + * status yet) and usage at or beyond the quota (see `StorageUsageLevel`'s `'over'` case). + */ +export function describeStorageUsage( + usedBytes: number | null | undefined, + quota: string | null | undefined +): StorageUsageSummary { + const quotaBytes = parseQuotaBytes(quota) + const used = usedBytes ?? null + + if (used === null || quotaBytes === null || quotaBytes <= 0) { + return { + usedBytes: used, + quotaBytes, + ratio: null, + level: 'unknown', + usedLabel: used === null ? 'Not yet reported' : formatBytes(used), + quotaLabel: quotaBytes === null ? (quota?.trim() || 'Not set') : formatBytes(quotaBytes) + } + } + + const ratio = used / quotaBytes + let level: StorageUsageLevel + if (ratio >= 1) { + level = 'over' + } else if (ratio >= CRITICAL_RATIO) { + level = 'critical' + } else if (ratio >= WARNING_RATIO) { + level = 'warning' + } else { + level = 'ok' + } + + return { + usedBytes: used, + quotaBytes, + ratio, + level, + usedLabel: formatBytes(used), + quotaLabel: formatBytes(quotaBytes) + } +} + +/** Maps a {@link StorageUsageLevel} to a Nuxt UI color token, for progress bars and badges. */ +export function storageUsageColor(level: StorageUsageLevel): 'neutral' | 'success' | 'warning' | 'error' { + switch (level) { + case 'ok': + return 'success' + case 'warning': + return 'warning' + case 'critical': + case 'over': + return 'error' + case 'unknown': + default: + return 'neutral' + } +} diff --git a/ui/eslint.config.mjs b/ui/eslint.config.mjs new file mode 100644 index 0000000..e355c42 --- /dev/null +++ b/ui/eslint.config.mjs @@ -0,0 +1,31 @@ +// @ts-check +import vuejsAccessibility from 'eslint-plugin-vuejs-accessibility' +import withNuxt from './.nuxt/eslint.config.mjs' + +// Accessibility is checked via eslint-plugin-vuejs-accessibility, same as launchpad +// (design spec §11.2, house standard). +const a11yConfigs = vuejsAccessibility.configs['flat/recommended'].map(config => ({ + ...config, + files: ['**/*.vue'], + rules: { + ...config.rules, + // Labels associated via `for`/`id` are valid; do not also require nesting. + 'vuejs-accessibility/label-has-for': [ + 'error', + { required: { some: ['nesting', 'id'] }, allowChildren: false } + ] + } +})) + +export default withNuxt(...a11yConfigs, { + rules: { + 'linebreak-style': ['error', 'unix'], + 'no-trailing-spaces': 'error' + } +}, { + files: ['tests/**/*.ts'], + rules: { + // Test doubles/fixtures legitimately reach for `any` more often than app code. + '@typescript-eslint/no-explicit-any': 'off' + } +}) diff --git a/ui/nuxt.config.ts b/ui/nuxt.config.ts new file mode 100644 index 0000000..901db82 --- /dev/null +++ b/ui/nuxt.config.ts @@ -0,0 +1,39 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +// +// Apus UI is a pure SPA (design spec §11.2): `ssr: false`, no server-rendered routes, no +// backend-for-frontend session. It is built as static assets (`nuxt generate` under the hood +// via `nuxt build` + `ssr: false`) and served from a plain webserver container -- there is no +// Nitro server available at runtime to lean on for anything (see ui/README.md "Why no +// server-side session"). That absence is why auth (see app/composables/useAuth.ts) is a +// client-only, public OIDC client rather than a confidential one behind a session cookie. +export default defineNuxtConfig({ + compatibilityDate: '2026-08-09', + devtools: { enabled: true }, + ssr: false, + modules: [ + '@nuxt/ui', + '@vueuse/nuxt', + '@nuxt/eslint' + ], + css: ['~/assets/css/main.css'], + runtimeConfig: { + public: { + // Base URL of the `api` module (design spec §11.1). No default -- an empty value would + // silently point every request at the SPA's own origin. + apiBaseUrl: '', + // Must match `APUS_JWT_ISSUER` on the `api` module -- see that module's + // application.yml. Which broker sits here is intentionally undecided (design spec §15). + oidcIssuer: '', + // The public (no client secret) OIDC client registered for this SPA at the broker. + oidcClientId: '' + } + }, + app: { + head: { + title: 'Apus' + } + }, + typescript: { + typeCheck: false + } +}) diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..4b54deb --- /dev/null +++ b/ui/package.json @@ -0,0 +1,43 @@ +{ + "name": "@onelitefeather/apus-ui", + "version": "0.1.0", + "description": "Apus web UI -- platform and tenant dashboards over the api module's REST/SSE surface", + "private": true, + "type": "module", + "engines": { + "node": "^22.12.0 || ^24.11.0 || >=26.0.0" + }, + "packageManager": "pnpm@11.20.0", + "scripts": { + "dev": "nuxt dev", + "build": "nuxt build", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "typecheck": "vue-tsc --noEmit -p tsconfig.json", + "test": "vitest run -c vitest.config.ts && vitest run -c vitest.nuxt.config.ts", + "test:watch": "vitest -c vitest.config.ts" + }, + "dependencies": { + "oidc-client-ts": "3.5.0" + }, + "devDependencies": { + "@nuxt/eslint": "1.17.0", + "@nuxt/test-utils": "4.1.0", + "@nuxt/ui": "4.10.0", + "@types/node": "26.2.0", + "@vue/test-utils": "2.4.11", + "@vueuse/nuxt": "14.4.0", + "eslint": "10.8.1", + "eslint-plugin-vuejs-accessibility": "2.5.0", + "happy-dom": "20.11.2", + "nuxt": "4.5.2", + "tailwindcss": "4.3.3", + "typescript": "6.0.3", + "vitest": "4.1.10", + "vue": "3.5.41", + "vue-tsc": "3.3.9" + } +} diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml new file mode 100644 index 0000000..9bd29c9 --- /dev/null +++ b/ui/pnpm-lock.yaml @@ -0,0 +1,11123 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + oidc-client-ts: + specifier: 3.5.0 + version: 3.5.0 + devDependencies: + '@nuxt/eslint': + specifier: 1.17.0 + version: 1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.41)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(typescript@6.0.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/test-utils': + specifier: 4.1.0 + version: 4.1.0(@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(happy-dom@20.11.2)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vitest@4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@nuxt/ui': + specifier: 4.10.0 + version: 4.10.0(f4346459f3b2557ba8fb68083f75b24a) + '@types/node': + specifier: 26.2.0 + version: 26.2.0 + '@vue/test-utils': + specifier: 2.4.11 + version: 2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)) + '@vueuse/nuxt': + specifier: 14.4.0 + version: 14.4.0(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0))(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vue@3.5.41(typescript@6.0.3)) + eslint: + specifier: 10.8.1 + version: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-plugin-vuejs-accessibility: + specifier: 2.5.0 + version: 2.5.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(globals@17.9.0)(supports-color@10.2.2) + happy-dom: + specifier: 20.11.2 + version: 20.11.2 + nuxt: + specifier: 4.5.2 + version: 4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0) + tailwindcss: + specifier: 4.3.3 + version: 4.3.3 + typescript: + specifier: 6.0.3 + version: 6.0.3 + vitest: + specifier: 4.1.10 + version: 4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + vue: + specifier: 3.5.41 + version: 3.5.41(typescript@6.0.3) + vue-tsc: + specifier: 3.3.9 + version: 3.3.9(typescript@6.0.3) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@antfu/install-pkg@2.0.1': + resolution: {integrity: sha512-iCKVQcIC0e3oDxEfs3SHQGW+ovhBMZmS1TE+bTk50rVyMCBmCfClv7Qi3HQKlumYwvjb/iIMeWCW2i67q6kFfQ==} + + '@apidevtools/json-schema-ref-parser@14.2.1': + resolution: {integrity: sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==} + engines: {node: '>= 20'} + peerDependencies: + '@types/json-schema': ^7.0.15 + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-annotate-as-pure@7.29.7': + resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.29.7': + resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.29.7': + resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.29.7': + resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.29.7': + resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.29.7': + resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + + '@babel/plugin-syntax-jsx@7.29.7': + resolution: {integrity: sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.29.7': + resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.29.7': + resolution: {integrity: sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@bomb.sh/tab@0.0.19': + resolution: {integrity: sha512-dTRfo9Q9B+lbLG3JCu8a/AGQSfD2XXcFcnakQzVjSOX+VvR/s9zpsH8TlqV3iHqazniRn1Ypwd1hcRlXcu/4BA==} + hasBin: true + peerDependencies: + cac: ^6.7.14 + citty: ^0.1.6 || ^0.2.0 + commander: ^13.1.0 || ^14.0.0 || ^15.0.0 + peerDependenciesMeta: + cac: + optional: true + citty: + optional: true + commander: + optional: true + + '@capsizecss/unpack@4.0.1': + resolution: {integrity: sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==} + engines: {node: '>=18'} + + '@clack/core@1.4.3': + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.7.0': + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} + engines: {node: '>= 20.12.0'} + + '@cloudflare/kv-asset-handler@0.4.2': + resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} + engines: {node: '>=18.0.0'} + + '@colordx/core@5.5.0': + resolution: {integrity: sha512-3PxTH8itZzltK0U9jTwVVnjLXvnDYuq3m+QXsHkENxWiPRh4WaoLcs1SQjqgZ55kS+QyirpH5BVwzP2gMVG6EQ==} + + '@dxup/nuxt@0.5.6': + resolution: {integrity: sha512-uZjAFoocWtWHr7YP9jm6FqwI8kjX2QN9bjcncoZt0GS+zExIAP3Ewv6EqEUvVP7w9pjZE+T19QxLHeoacN/MNg==} + + '@dxup/unimport@0.1.2': + resolution: {integrity: sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@es-joy/jsdoccomment@0.91.0': + resolution: {integrity: sha512-vgqlMGNNhZxwDYbUNIHj3Hskb4R28iqdXx90ufHyt/NeuTQkeqjTDslAs9I0/GCAfbxP5BpH5WsL1R1fht5Lxg==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@es-joy/resolve.exports@1.2.0': + resolution: {integrity: sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==} + engines: {node: '>=10'} + + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/compat@2.1.0': + resolution: {integrity: sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^8.40 || 9 || 10 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.5.5': + resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-inspector@3.2.0': + resolution: {integrity: sha512-kylJhcii8eDOiRFPANNUHOyDebBIOt+nqYXt8q6W9FbhYzFJAXjLzJz6KFNzY0WvIyOBKdbSQdwdPNrkMh05tg==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + eslint: ^8.50.0 || ^9.0.0 || ^10.0.0 + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/css-tree@4.0.5': + resolution: {integrity: sha512-iPmijIAq4hlIJB86PYmY/fcZORHtjphSqICDbwuw32A/JmkhZQ/K/6TjHE03zqf3n5yABpVcbRAMG8Mi9ojy8g==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/js@10.0.1': + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@floating-ui/vue@1.1.11': + resolution: {integrity: sha512-HzHKCNVxnGS35r9fCHBc3+uCnjw9IWIlCPL683cGgM9Kgj2BiAl8x1mS7vtvP6F9S/e/q4O6MApwSHj8hNLGfw==} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@iconify/collections@1.0.720': + resolution: {integrity: sha512-19NFSBxT9QJhm1Lc+qwt1vSpbTS5wvxeaeKXhreiZLtKwpJkXHm47MDzFRu6qvYuRgfH6QP7Ao36IeRRadjgfQ==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.4': + resolution: {integrity: sha512-b1S7B1k9ohZ+iNTi2ATxbRYG9fTrJmUT0rc46bvVnNxqNRGW7dyo/vRREwyniI5IRN2RSJHDcm+s3BjWrSAjHw==} + + '@iconify/vue@5.0.1': + resolution: {integrity: sha512-aumwwooJlFJ5H5qYWB6ZTAyM0C8hpfcSVLB9/a3qnH1GGvIJ+FEbpEs4s/HfErYe/M5qZeLjwmESR5fFm3lXEw==} + peerDependencies: + vue: '>=3.0.0' + + '@internationalized/date@3.12.3': + resolution: {integrity: sha512-fuLX+3ZKLsxI73y8b01EG/WjHb6gE6weCqlfawPO27kBWGMh9G1yH6Csv1uU7/cac9H2GHmOMt6CjmuQ1aia4Q==} + + '@internationalized/number@3.6.7': + resolution: {integrity: sha512-3ji1fcrT+FPAK86UqEhB/psHixYo6niWPJtt7+qRaYFynt/BaJG8GhAPimtWUpEiVSTq8ZM8L5psMxGquiB/Vg==} + + '@ioredis/commands@1.10.0': + resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@mapbox/node-pre-gyp@2.0.3': + resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} + engines: {node: '>=18'} + hasBin: true + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} + engines: {node: ^22.20 || ^24.12 || >=25} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@napi-rs/wasm-runtime@1.2.2': + resolution: {integrity: sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.3 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.3 + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nuxt/cli@3.37.0': + resolution: {integrity: sha512-Zj9NwHjEBzVrgezsgMFjpMhNqwNgROk9DzNi/dyfk1mCbXIRigV11br2xOl0Satek30bmv7oZAfMtCnDe6Ip0Q==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@nuxt/schema': ^4.4.6 + peerDependenciesMeta: + '@nuxt/schema': + optional: true + + '@nuxt/devalue@2.0.2': + resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} + + '@nuxt/devtools-kit@2.7.0': + resolution: {integrity: sha512-MIJdah6CF6YOW2GhfKnb8Sivu6HpcQheqdjOlZqShBr+1DyjtKQbAKSCAyKPaoIzZP4QOo2SmTFV6aN8jBeEIQ==} + peerDependencies: + vite: '>=6.0' + + '@nuxt/devtools-kit@3.4.1': + resolution: {integrity: sha512-6ltPm2yUW8GvDdf3VJna7+flLi+ej7xRfSr+S4ovevKt/CuPf9EqYOn1jW7Kw/U1MXt/71zkn+/O2vu3G6O9Hg==} + peerDependencies: + vite: '>=6.0' + + '@nuxt/devtools-wizard@3.4.1': + resolution: {integrity: sha512-taGeuTnkHsZVjgD9r6NXvvHaBzB2j4mCgOmlmkz3ntsqgh1SJfmsD11Tmtl7FVAxJS8Wuvuzgt0GyTlADBW9Wg==} + hasBin: true + + '@nuxt/devtools@3.4.1': + resolution: {integrity: sha512-20zZs6k/zAdi+PM7s1BwxE3hanZ+R1OGi5DWCKPyzSnhUUeeNebvWNgec7Rwnx6iKLkJfK4WFIZ+FL2QurG/ZQ==} + hasBin: true + peerDependencies: + '@vitejs/devtools': '*' + vite: '>=6.0' + peerDependenciesMeta: + '@vitejs/devtools': + optional: true + + '@nuxt/eslint-config@1.17.0': + resolution: {integrity: sha512-5lHecnGvi7RxGsR3Amvnl47bxb3F4wFD9KQgbbmhd6prz3OAAbgQio9EK88tPyNHt7+dxIFFOnCH6TJNl/QbqQ==} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + eslint-plugin-format: '*' + peerDependenciesMeta: + eslint-plugin-format: + optional: true + + '@nuxt/eslint-plugin@1.17.0': + resolution: {integrity: sha512-h/fn4K09tA5tvdLj9Zlu5mb3TOVO2zLAetCsfJ1/LLVm2XWtgDVhfSB+Sm93cF1rCGxahmHZd4RJz2nAsWTDvg==} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + '@nuxt/eslint@1.17.0': + resolution: {integrity: sha512-54aD2xJvI2QJnHvQwN22hEgE/izF5ez+diPE7yLCJskKQ0tqPrNJCcRjBtuFQmQMQjTfHESsfuFdLfwMGUz8bw==} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + eslint-webpack-plugin: ^4.1.0 + vite-plugin-eslint2: ^5.0.0 + peerDependenciesMeta: + eslint-webpack-plugin: + optional: true + vite-plugin-eslint2: + optional: true + + '@nuxt/fonts@0.14.0': + resolution: {integrity: sha512-4uXQl9fa5F4ibdgU8zomoOcyMdnwgdem+Pi8JEqeDYI5yPR32Kam6HnuRr47dTb97CstaepAvXPWQUUHMtjsFQ==} + + '@nuxt/icon@2.4.1': + resolution: {integrity: sha512-fOY3kiT6OoL4bWXVmMLc1VgoCm1PxIGSBmsSaLO090NEgtd1ub441dZ7MEoOD5UIilWzba1kCWdwJcAkGCOwLg==} + + '@nuxt/kit@3.21.11': + resolution: {integrity: sha512-0Xi3tgwN77w43Q8GCPIrvWmF1J7Peehkts44E0uKNIml9lB8WoUn8YxyUjxBv47XtVR86NWoWALAT+/IEMHJEA==} + engines: {node: '>=18.12.0'} + + '@nuxt/kit@4.5.2': + resolution: {integrity: sha512-l66LU9DcJYjmNwqwAj2I5UGRrUbnG2DOKGChnN70zIGtn0eq/z87gi/FRgha6eMb9/FmB1PFHgtx6PWVml1C2Q==} + engines: {node: '>=18.12.0'} + + '@nuxt/nitro-server@4.5.2': + resolution: {integrity: sha512-sx/vtT8D1WIRUOMuKQz/9z8nZb7jgVWc6HWwlkXKDjYZ84otPFtYCozKqhXWv6xf3JxJvge/RUAOwh9Z7P4nQQ==} + engines: {node: ^22.19.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@babel/plugin-proposal-decorators': ^7.25.0 || ^8.0.0 + '@babel/plugin-syntax-typescript': ^7.25.0 || ^8.0.0 + '@rollup/plugin-babel': ^6.0.0 || ^7.0.0 + nuxt: ^4.5.2 + peerDependenciesMeta: + '@babel/plugin-proposal-decorators': + optional: true + '@babel/plugin-syntax-typescript': + optional: true + '@rollup/plugin-babel': + optional: true + + '@nuxt/schema@4.5.2': + resolution: {integrity: sha512-h9g1kt9O2iU9nX6HDFu9gvwtpn+8oSJX0RSTWRBnEx/Pkz+WlOHtjuS0SbkTAXw5aT1+H1GysWVwNTjJfBY/0w==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/telemetry@2.8.0': + resolution: {integrity: sha512-zAwXY24KYvpLTmiV+osagd2EHkfs5IF+7oDZYTQoit5r0kPlwaCNlzHp5I/wUAWT4LBw6lG8gZ6bWidAdv/erQ==} + engines: {node: '>=18.12.0'} + hasBin: true + peerDependencies: + '@nuxt/kit': '>=3.0.0' + + '@nuxt/test-utils@4.1.0': + resolution: {integrity: sha512-B0CipGKVVY5qbLMXJqYPYdalNzE9VFzybEAOqHGFHPDqv/8RFRe+/F3lJJigtLFroxaBDMMyrhLcmgKIXBv8og==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@cucumber/cucumber': '>=11.0.0' + '@jest/globals': '>=30.0.0' + '@playwright/test': ^1.43.1 + '@testing-library/vue': ^8.0.1 + '@vitest/ui': '*' + '@vue/test-utils': ^2.4.2 + h3-next: '>=2.0.1-rc.22' + happy-dom: '>=20.0.11' + jsdom: '>=27.4.0' + playwright-core: ^1.43.1 + vitest: ^4.0.2 + peerDependenciesMeta: + '@cucumber/cucumber': + optional: true + '@jest/globals': + optional: true + '@playwright/test': + optional: true + '@testing-library/vue': + optional: true + '@vitest/ui': + optional: true + '@vue/test-utils': + optional: true + h3-next: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright-core: + optional: true + vitest: + optional: true + + '@nuxt/ui@4.10.0': + resolution: {integrity: sha512-f6eFtHZ958XIVnbpGz7OeVRjuEXdmQWgNKWBppNlh/lP790KDi8IXTZ6lndJ72lpp7hC8Wo2BbSL9zo9fwywWQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@inertiajs/vue3': ^2.0.7 || ^3.0.0 + '@internationalized/date': ^3.0.0 + '@internationalized/number': ^3.0.0 + '@nuxt/content': ^3.0.0 + '@tiptap/core': ^3 + '@tiptap/extension-bubble-menu': ^3 + '@tiptap/extension-code': ^3 + '@tiptap/extension-collaboration': ^3 + '@tiptap/extension-drag-handle': ^3 + '@tiptap/extension-drag-handle-vue-3': ^3 + '@tiptap/extension-floating-menu': ^3 + '@tiptap/extension-horizontal-rule': ^3 + '@tiptap/extension-image': ^3 + '@tiptap/extension-mention': ^3 + '@tiptap/extension-node-range': ^3 + '@tiptap/extension-placeholder': ^3 + '@tiptap/markdown': ^3 + '@tiptap/pm': ^3 + '@tiptap/starter-kit': ^3 + '@tiptap/suggestion': ^3 + '@tiptap/vue-3': ^3 + ai: ^6 || ^7 + joi: ^18.0.0 + superstruct: ^2.0.0 + tailwindcss: ^4.0.0 + typescript: ^5.6.3 || ^6.0.0 + valibot: ^1.0.0 + vue-router: ^4.5.0 || ^5.0.0 + yup: ^1.7.0 + zod: ^3.24.0 || ^4.0.0 + peerDependenciesMeta: + '@inertiajs/vue3': + optional: true + '@internationalized/date': + optional: true + '@internationalized/number': + optional: true + '@nuxt/content': + optional: true + ai: + optional: true + joi: + optional: true + superstruct: + optional: true + valibot: + optional: true + vue-router: + optional: true + yup: + optional: true + zod: + optional: true + + '@nuxt/vite-builder@4.5.2': + resolution: {integrity: sha512-fC8KUs5F1VpSEjTIjmx5pdflciMlp3FDCubx3AXElvRPLtBAPmyB69kmqVFjRnVQ8+vRHNyI7iBHUg9Se8srLA==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@babel/plugin-proposal-decorators': ^7.25.0 || ^8.0.0 + '@babel/plugin-syntax-jsx': ^7.25.0 || ^8.0.0 + nuxt: 4.5.2 + rolldown: ^1.0.0 + rollup-plugin-visualizer: ^6.0.0 || ^7.0.1 + vue: ^3.3.4 + peerDependenciesMeta: + '@babel/plugin-proposal-decorators': + optional: true + '@babel/plugin-syntax-jsx': + optional: true + rolldown: + optional: true + rollup-plugin-visualizer: + optional: true + + '@nuxtjs/color-mode@4.0.1': + resolution: {integrity: sha512-eiA7hWXi5zNHaYKyJFCGF6i0wFZtuvR7KDXZ6jiSvwxjCpRFwphrw0MOSmNfArTSSsT1wpW+/2H92cejeVfUlg==} + + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + + '@oxc-project/types@0.143.0': + resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} + + '@parcel/watcher-wasm@2.6.0': + resolution: {integrity: sha512-dtjbDxKSDPQ8AmA+pS4OFaHE1FKrjtGpLGBxw85uKFkRorjNbvDM/aFPgqosu40wprbp1xw2ZSxIKqghCUHe2w==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.7.0': + resolution: {integrity: sha512-0UTYalzk2t6S4rA2uHOz5bSSW2CHdv4vggJI6Alg90yvl0UgXs6XSXpH96OH+bRkX4J/06djv29pqXJ0lq5Kag==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + + '@rolldown/binding-android-arm64@1.2.3': + resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.3': + resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.3': + resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.3': + resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.3': + resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.3': + resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.3': + resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.3': + resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.3': + resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.3': + resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.3': + resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.3': + resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.3': + resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rollup/plugin-alias@6.0.0': + resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} + engines: {node: '>=20.19.0'} + peerDependencies: + rollup: '>=4.0.0' + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@29.0.3': + resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-inject@5.0.5': + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-terser@1.0.0': + resolution: {integrity: sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.62.4': + resolution: {integrity: sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.62.4': + resolution: {integrity: sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.62.4': + resolution: {integrity: sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.62.4': + resolution: {integrity: sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.62.4': + resolution: {integrity: sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.62.4': + resolution: {integrity: sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.62.4': + resolution: {integrity: sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.62.4': + resolution: {integrity: sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.62.4': + resolution: {integrity: sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.62.4': + resolution: {integrity: sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.62.4': + resolution: {integrity: sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.62.4': + resolution: {integrity: sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.62.4': + resolution: {integrity: sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.62.4': + resolution: {integrity: sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.62.4': + resolution: {integrity: sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.62.4': + resolution: {integrity: sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.62.4': + resolution: {integrity: sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.62.4': + resolution: {integrity: sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.62.4': + resolution: {integrity: sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.62.4': + resolution: {integrity: sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.62.4': + resolution: {integrity: sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.62.4': + resolution: {integrity: sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.62.4': + resolution: {integrity: sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.62.4': + resolution: {integrity: sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.62.4': + resolution: {integrity: sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==} + cpu: [x64] + os: [win32] + + '@simple-git/args-pathspec@1.0.3': + resolution: {integrity: sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==} + + '@simple-git/argv-parser@1.1.1': + resolution: {integrity: sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==} + + '@sindresorhus/base62@1.0.0': + resolution: {integrity: sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==} + engines: {node: '>=18'} + + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@speed-highlight/core@1.2.23': + resolution: {integrity: sha512-iRoq6i6JDJP6Mt2A5JaPvzw0pgYHH6k92ij+yXiTrB7T2y9N789aWE3EHWj/5ztlJBokcCBja3iYLVdu5wgnkg==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@stylistic/eslint-plugin@5.10.0': + resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} + + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} + engines: {node: '>= 20'} + + '@tailwindcss/postcss@4.3.3': + resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==} + + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@tanstack/table-core@8.21.3': + resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} + engines: {node: '>=12'} + + '@tanstack/virtual-core@3.17.7': + resolution: {integrity: sha512-bp+v10y65sp2H7WpWfIMyxTNfl8ZVfxFTLRjPIFRryi6FV/J33z4IS53WO4pTk36KlvJ4iLiQz+oaydDC1xbcA==} + + '@tanstack/vue-table@8.21.3': + resolution: {integrity: sha512-rusRyd77c5tDPloPskctMyPLFEQUeBzxdQ+2Eow4F7gDPlPOB1UnnhzfpdvqZ8ZyX2rRNGmqNnQWm87OI2OQPw==} + engines: {node: '>=12'} + peerDependencies: + vue: '>=3.2' + + '@tanstack/vue-virtual@3.13.35': + resolution: {integrity: sha512-lOfSPvgPdlaH6Qy+CyIc3XpycitaSQ9GECndGpTuDiu+uDA1am+90yWXwzDSd/20ZM196ggWJLS+Qb6WjVd/OA==} + peerDependencies: + vue: ^2.7.0 || ^3.0.0 + + '@tiptap/core@3.29.2': + resolution: {integrity: sha512-oKUkiPUB7noilVYxI9lNzUD4rX17sHub+PYjMfHMWHG9A3nvIy+FdePIVIIhThKWF7ijhr3eIqHY51Bn+GAFtw==} + peerDependencies: + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-blockquote@3.29.2': + resolution: {integrity: sha512-ca4OzKDh0yaxg2+Z56bC2QnWsNsFp2YMRfVig1PDXyMVFMNJpLcnhxgq/9btn+xYAlYrj8RymOeCTYREOR6Zjg==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-bold@3.29.2': + resolution: {integrity: sha512-elYbGxJsYnBb4leqrcjdIJuiG380BcOgN+UUzvOv+qEjfGVzHodFOMBl3qnmD6urYHNu5/qQK2S0qSSRXKCLNQ==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-bubble-menu@3.29.2': + resolution: {integrity: sha512-kzcWarcpr031rZu+R3Hzut5uxb3Qj/xxMDEYZIQ3uiq1yb5vEMXj8/SIyWautk6Nu8Rr1leV3rGdR4NzhzyFAA==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-bullet-list@3.29.2': + resolution: {integrity: sha512-3bWcCUPbCHv0XttlMdnAtXLNYWx2pblByMgxmGsaP9FU0QnslGXty6A6gHCqI33ygRg1vrA6U5Wtpwbi5aKu5g==} + peerDependencies: + '@tiptap/extension-list': 3.29.2 + + '@tiptap/extension-code-block@3.29.2': + resolution: {integrity: sha512-w153ct8g6dLiPTdXQ6SOIMxX4SEo5Q50AmjdEEEcJ7ZcYUcde/ScSskLHfOYmyt5ZFAiyEwr121+pux+p3/oAQ==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-code@3.29.2': + resolution: {integrity: sha512-c6W5UGuB7WNLpYocsgRzpO2OOTI4QjaI9jjHRMuty9z+s9DtaYM/HrRLNwVh6MopkHb+i/89Wkv8gCS34fftig==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-collaboration@3.29.2': + resolution: {integrity: sha512-KVKwIofMzraf0MxCXUkYd6fNmz0oGKaHDkjhNT6HGHrVzTFDJlZTwHHwSndQS2xKGmZbhWe8C32hvUrFsZXTPw==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + '@tiptap/y-tiptap': ^3.0.7 + yjs: ^13 + + '@tiptap/extension-document@3.29.2': + resolution: {integrity: sha512-YUamvefLnsqu6124GavVTI7nqcFlQJ12ROB0oSwG69eSBZYNjg1tIs05LFrBxkwf4Xgqd6YzfJ9+FeG428RvzQ==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-drag-handle-vue-3@3.29.2': + resolution: {integrity: sha512-4u2CraVeMEeq2Xyi/9YmFBhL/uE/Lb5IViWKNfOM4PmnPDAgAj6hXA1s/QIdBKNIE6ohWCQRfAKX+b5Ff5LStQ==} + peerDependencies: + '@tiptap/extension-drag-handle': 3.29.2 + '@tiptap/pm': 3.29.2 + '@tiptap/vue-3': 3.29.2 + vue: ^3.0.0 + + '@tiptap/extension-drag-handle@3.29.2': + resolution: {integrity: sha512-5Y5ElfRnrWIr9IRODzGkqLgIIbdUXNstbs7hWskXQWTg532TJfMpZmQbQRv7th39IcH0uusT7Vs/QlFKXzKVkA==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/extension-collaboration': 3.29.2 + '@tiptap/extension-node-range': 3.29.2 + '@tiptap/pm': 3.29.2 + '@tiptap/y-tiptap': ^3.0.7 + + '@tiptap/extension-dropcursor@3.29.2': + resolution: {integrity: sha512-KKno7cU9r1HdR48CRrsDu69/1UjZdoslq/UcE+Kx+tdhAv/aljXMkRSNzGMrBNOBDmHRgS1+58zm21WQWdQzwA==} + peerDependencies: + '@tiptap/extensions': 3.29.2 + + '@tiptap/extension-floating-menu@3.29.2': + resolution: {integrity: sha512-CBTq4Xs5aGWr65uFCIkKBms796OhmirWf/ax//iJ4fl9IfwqjwFuc2vQs9PmuwpKn9ctDHo2sMTtvyeCvIt5LQ==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-gapcursor@3.29.2': + resolution: {integrity: sha512-8Q39UR4/Tit759IeW9xZIe3NMwN11GsuA3FLheDyyGn7RrW02HD3HhUDlazE54Ki4HoosjFmChPlN4Ik2ubdRQ==} + peerDependencies: + '@tiptap/extensions': 3.29.2 + + '@tiptap/extension-hard-break@3.29.2': + resolution: {integrity: sha512-eUW3LN3fq8rXnjEUeI3D2QONYdLsU3yYQm4jxlErs2h4cfwrFjgf19VSUFVmm6LrFbbQ0OnDVPeVLL6iOwDw2w==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-heading@3.29.2': + resolution: {integrity: sha512-6W4aIy70Mh7BNlbG9zZ5FBLhJhU2UUEzgZJ/jwYSCcB30o8McLxJSEjhtoHiX8R78Ah2/JzBGvIe5olZlbeE4A==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-horizontal-rule@3.29.2': + resolution: {integrity: sha512-8/ZPzbB9X85Mc9/7xVLZupQKBr2UVcQTGr512xtqMW+XkCQRHCph46tRo828YE13IMWI5fWn/FaNCqXG9cULSw==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-image@3.29.2': + resolution: {integrity: sha512-F+S4iru247mNVZdkNwNDZHeb281DkjsBJinaOGsOyJTvXY+KU5Uq7vY1LQTn493dTfU48Z0yMBUXwJffCT92Mg==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-italic@3.29.2': + resolution: {integrity: sha512-iH63V/5wsaMnY4Jz0+meaAGhaec4AiOzOduzl6ZZr5IyGhZ1kthyW84ELt0dyLI3hNceAUhaNWc+I7+vX0aoXA==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-link@3.29.2': + resolution: {integrity: sha512-DcVer5SqrexKCEP6Ip1UPxJUMvcRCCItSv0wxoGytanrimBh2smvcg6X0DWnjlsi5H0updhyl+atYCmmQXUIXA==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-list-item@3.29.2': + resolution: {integrity: sha512-s8vBVHHFT0Qpu7CzAZ7S1kYmSiVaDvUNvMNcZUWnxj6VPfiwmx0eXd9FsjePrRCMoM5tFmPnhFTHDxY3D/eZeQ==} + peerDependencies: + '@tiptap/extension-list': 3.29.2 + + '@tiptap/extension-list-keymap@3.29.2': + resolution: {integrity: sha512-R+3k8OLnxdCH7Xy9ieOwUt5m2Je74u8mikothGmsYVO2Zyq48fIbmZ+X6RBPCu7DBOI2FIUhHEFbKQeDWvDNmA==} + peerDependencies: + '@tiptap/extension-list': 3.29.2 + + '@tiptap/extension-list@3.29.2': + resolution: {integrity: sha512-WPZ9BHAPT6QeIm1vdVkuoOWvy9a8/EZeJwV2VhU8LXyTAttvzyj4rsbbHyJWvYWlUSTt/QF2AZ2zhKo7u1w3/A==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-mention@3.29.2': + resolution: {integrity: sha512-WF8ugDa2IRbgyRW+PffPYg8ZI+Qp9azvIsNoyuf+VSg5Vp7ze2TuJXUTObSckyiN5Ann8bDNM9Hbu3TdoI0DFQ==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + '@tiptap/suggestion': 3.29.2 + + '@tiptap/extension-node-range@3.29.2': + resolution: {integrity: sha512-7ipYCrGZvnOL0vR4E69m8PSKDg49hH5n8nVFRej3cRn/xAdAl+ytJmrLSE+SLPvw6TN44NWk3iug23IjOu3Nbw==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-ordered-list@3.29.2': + resolution: {integrity: sha512-ndCunC+UsYOpkOtL7vGnDz21UNa45WUlcO9wMT1fbuYow2QnRhsuMlCWENXI52YPPARWuQ0RDgN7q6TaxPERBg==} + peerDependencies: + '@tiptap/extension-list': 3.29.2 + + '@tiptap/extension-paragraph@3.29.2': + resolution: {integrity: sha512-7qJj5YTr11vvjNgjDN1ypOfwTovc0QOCYcit/rskeuVgnmQZOZQzC/BbyKLLG7UGnpRLemU/mEGbW9pAqjAXkQ==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-placeholder@3.29.2': + resolution: {integrity: sha512-/BlpPIq2JZk6zLaeYVOXazi6dmd0iRriTymNEnFn1doManN1y5HED9LsMeb/AhNhauL5AgmcHgpvAjbsN9k4SA==} + peerDependencies: + '@tiptap/extensions': 3.29.2 + + '@tiptap/extension-strike@3.29.2': + resolution: {integrity: sha512-aEvLAbddUQZ+FukCreV3q4G2HfNI+odE7E9U+wbq6XsSWKyo8/pDu1muz+TFKNre4blSMOQ3JQmw5UeHDKy+fg==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-text@3.29.2': + resolution: {integrity: sha512-Ubko45JWWHe8glBt2PiGNF8hcbys/JNalFhiR7Y1X4iOOtAxAKJJxh3+eq+//NTlGuBPdWGp7zw8EEUp7anjKA==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extension-underline@3.29.2': + resolution: {integrity: sha512-K7XwH/xS/5AIREWQ00VTEf/W5U0olp7j6wwit7cdd/8nHv6h6AGr1+iEApHKoLXWQZLfGQKzJlT9W61LAl+fHA==} + peerDependencies: + '@tiptap/core': 3.29.2 + + '@tiptap/extensions@3.29.2': + resolution: {integrity: sha512-BCz+FCAChSYtUe4BFj97HEO+nSK+J7GxbJgZG4Hg7DT/gI+hRyeNndU8efiQAx3WGdzsFi3UxRpcF1tTQM7iMQ==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/markdown@3.29.2': + resolution: {integrity: sha512-Knf9YqG3fxOyFuS3pe3eapDz0ya9eqPGzmyMSd5PuHNmR9/Ir6i5qk5+Md6bCPgDNjYskztNm7DoBXPfbXbO/w==} + peerDependencies: + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/pm@3.29.2': + resolution: {integrity: sha512-GCOme7xHaS+DSoaA4CDcAD3l6JyBlvZhvCyfsy2Vp6j8tEoBkZWio7soYVosmlyn7zq8/64VeFZP5s47yfG7fQ==} + + '@tiptap/starter-kit@3.29.2': + resolution: {integrity: sha512-oTu0tysiqk4zgjEtxRHjAQgxUKaAevZwueOWwSWubHdokqp7SpcbE5n9USJv89HKuTUDm3GjnQH6q8HNn/2DsA==} + + '@tiptap/suggestion@3.29.2': + resolution: {integrity: sha512-ZEhRm0gnRCwCScR9IrnIBhm9sr6U8vpR9oeznYk3hiedZ48zsgohqvgoIYpWcwYWrT2Pb0NrfhCT8IuSzdJHzQ==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + + '@tiptap/vue-3@3.29.2': + resolution: {integrity: sha512-rLX+V+HXbsVlk+My8mslvbnbVXZiQZHYtbOiRgxugsqZ9SK1mr1FpgZ/ZNcotJAjecT8FJmPa45ccDnVu66eGA==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.29.2 + '@tiptap/pm': 3.29.2 + vue: ^3.0.0 + + '@tiptap/y-tiptap@3.0.8': + resolution: {integrity: sha512-+kndlSuoUK9sKVRuxbAHXNrbDvyydnG/Y0NFU9XXqaSkI9IRcrjpOf1RGd7NrC9jJXquDqZS96wOQf6eUpP9Dg==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + prosemirror-model: ^1.7.1 + prosemirror-state: ^1.2.3 + prosemirror-view: ^1.9.10 + y-protocols: ^1.0.1 + yjs: ^13.5.38 + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@26.2.0': + resolution: {integrity: sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@typescript-eslint/eslint-plugin@8.66.0': + resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.66.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.66.0': + resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.66.0': + resolution: {integrity: sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.66.0': + resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.66.0': + resolution: {integrity: sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.66.0': + resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.66.0': + resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.66.0': + resolution: {integrity: sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.66.0': + resolution: {integrity: sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.66.0': + resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unhead/bundler@3.3.1': + resolution: {integrity: sha512-F9gEgqpUKqHFzOv+7Pgm3TbmXhUdLX+WjZiPAK/huLDzblzZmvAUE9vRDymWaOST7jqGT/tPKkwl2kqbgb3nPw==} + peerDependencies: + '@unhead/cli': ^3.3.1 + '@vitejs/devtools-kit': ^0.4.1 + esbuild: '>=0.17.0' + lightningcss: '>=1.20.0' + oxc-parser: '>=0.98.0' + rolldown: '>=1.0.0' + unhead: ^3.3.1 + vite: '>=6.4.2' + webpack: '>=5.0.0' + peerDependenciesMeta: + '@unhead/cli': + optional: true + '@vitejs/devtools-kit': + optional: true + esbuild: + optional: true + lightningcss: + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + vite: + optional: true + webpack: + optional: true + + '@unhead/vue@2.1.17': + resolution: {integrity: sha512-pnC8x9HLV3qQXdvWfylUEU25uhfCAy3ly9nmpQz84j9py818DRfU8jOsQ5wjdWtxyU1vX/fW2udfm4jtxUK8Bg==} + peerDependencies: + vue: '>=3.5.18' + + '@unhead/vue@3.3.1': + resolution: {integrity: sha512-iS+eiE1NehbV/eF7wzR7UUuUVTv8fIphFOCekQvEMuPqfKPCB8f3wf7sgPgUngYX6mdgM6PmkGmaOQgTBxqwbw==} + peerDependencies: + vite: '>=6.4.2' + vue: '>=3.5.18' + webpack: '>=5.0.0' + peerDependenciesMeta: + vite: + optional: true + webpack: + optional: true + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.12.2': + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.12.2': + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} + cpu: [arm64] + os: [openharmony] + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} + cpu: [x64] + os: [win32] + + '@vercel/nft@1.10.2': + resolution: {integrity: sha512-w+WyX5Ulmj4dtTZrxaulqrjaLZHSbnPzx75SJsTNYmotKsqn1JlLnDJa+lz5hn90HJofhl/2MAtw0mCrgM3qYw==} + engines: {node: '>=20'} + hasBin: true + + '@vitejs/plugin-vue-jsx@5.1.6': + resolution: {integrity: sha512-YXvi4as2clxt6DFw5+a0tTA97ntiQXm/raR8ofNj3aNwwdlVGTiG2gp7EvfZW17P50acL/9bP0ccF4XnqNmlgA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@6.0.8': + resolution: {integrity: sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.2.25 + + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} + + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} + + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} + + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} + + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} + + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} + + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} + + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} + + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue-macros/common@3.1.4': + resolution: {integrity: sha512-/5Fv+6DgIcM9ajY05ZmKBv+LMX1M9A0X+IUwDRVdt67ciw8OV9bvG2r34p3RiEadlsQybjhKPRKNXDC8Bp23cw==} + engines: {node: '>=20.19.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + + '@vue/babel-helper-vue-transform-on@2.0.1': + resolution: {integrity: sha512-uZ66EaFbnnZSYqYEyplWvn46GhZ1KuYSThdT68p+am7MgBNbQ3hphTL9L+xSIsWkdktwhPYLwPgVWqo96jDdRA==} + + '@vue/babel-plugin-jsx@2.0.1': + resolution: {integrity: sha512-a8CaLQjD/s4PVdhrLD/zT574ZNPnZBOY+IhdtKWRB4HRZ0I2tXBi5ne7d9eCfaYwp5gU5+4KIyFTV1W1YL9xZA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@2.0.1': + resolution: {integrity: sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.41': + resolution: {integrity: sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==} + + '@vue/compiler-dom@3.5.41': + resolution: {integrity: sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==} + + '@vue/compiler-sfc@3.5.41': + resolution: {integrity: sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==} + + '@vue/compiler-ssr@3.5.41': + resolution: {integrity: sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==} + + '@vue/devtools-api@8.2.1': + resolution: {integrity: sha512-6u4vXBlIBAC1wMplIZgpyPn7uh/s4Bf6F5bMzvLv+EdJ0aHs/+4B7Ygv864EStQSjRbsRzTko/kUG1A1IejQ3A==} + + '@vue/devtools-core@8.2.1': + resolution: {integrity: sha512-s/VfAY9oDTb/kFEWmy461jaFde2MIV1RO/gi1vwM+PAZBZ/Pc2Ndu3BNBdZUze8QDUuyYvElbEEGA83syjJfzA==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@8.2.1': + resolution: {integrity: sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==} + + '@vue/devtools-shared@8.2.1': + resolution: {integrity: sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==} + + '@vue/language-core@3.3.9': + resolution: {integrity: sha512-in/68oAa4BCtVY6n/nkuhLIkV8DHYd2UivedJ6cMZ6UYtlq9jaoaSNUBHYCVO44z3nKg7MdE5OBoHKt5SxeBKQ==} + + '@vue/reactivity@3.5.41': + resolution: {integrity: sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==} + + '@vue/runtime-core@3.5.41': + resolution: {integrity: sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==} + + '@vue/runtime-dom@3.5.41': + resolution: {integrity: sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==} + + '@vue/server-renderer@3.5.41': + resolution: {integrity: sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==} + + '@vue/shared@3.5.41': + resolution: {integrity: sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==} + + '@vue/test-utils@2.4.11': + resolution: {integrity: sha512-GDqaqZsA6m2E5vNzej0aYiIb6BX8xV9pNSbbbXKOfEYwg7ZNblVX8suyqmUBThq8VIrgAJNxn+z72hVtUeiWHA==} + peerDependencies: + '@vue/compiler-dom': 3.x + '@vue/server-renderer': 3.x + vue: 3.x + peerDependenciesMeta: + '@vue/server-renderer': + optional: true + + '@vueuse/core@10.11.1': + resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} + + '@vueuse/core@14.4.0': + resolution: {integrity: sha512-X4WHz1HlCzCBoYXesUkifzzWBAcZgXG8Fi5iNPQg/epdzOB3gu8Fawj3hvuwYR1nGcXGnvxwYYcUC/71++svtQ==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/integrations@14.4.0': + resolution: {integrity: sha512-oJz9qTgczvA7L1nXQFRU7h8tQbOCoiceqvMMhT9XYMyOGTqLJ2rEa09PON+nD2t48sZUfeOmg4eaWJXV4sZb/w==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 || ^8 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 || ^8 + vue: ^3.5.0 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@10.11.1': + resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} + + '@vueuse/metadata@14.4.0': + resolution: {integrity: sha512-swx/255R6JyHZFJhx845iz5CRWDZdCfvkZOpACWc5+c5WHcG24mv8gUT1WIdFQaHt6dq79rvILd9QnCWiyVm9g==} + + '@vueuse/nuxt@14.4.0': + resolution: {integrity: sha512-97At9ad6UvEB73vH1/h2yYTRZM7uPchzo7s2jRLwKWWHRZXGdzTn8AtpSwZVIAaXJTDcpiqzo9Inhd8v50mkMg==} + peerDependencies: + nuxt: ^3.0.0 || ^4.0.0-0 || ^5.0.0-0 + vue: ^3.5.0 + + '@vueuse/shared@10.11.1': + resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + + '@vueuse/shared@14.4.0': + resolution: {integrity: sha512-JRgY90Sz8DDtPMsaDflvPMp9xYk69JZAmbuDvAquUVXKr2gEjqtzGNTTthLfckH0BzBqvnu31gb4a8TGLRe79g==} + peerDependencies: + vue: ^3.5.0 + + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + alien-signals@3.2.1: + resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} + engines: {node: '>=14'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + + are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} + engines: {node: '>=20.19.0'} + + ast-walker-scope@0.9.0: + resolution: {integrity: sha512-IJdzo2vLiElBxKzwS36VsCue/62d6IdWjnPB2v3nuPKeWGynp6FF/CYoLa5i/3jXH/z97ZDdsXz6abpgM6w07A==} + engines: {node: '>=20.19.0'} + + async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + autoprefixer@10.5.4: + resolution: {integrity: sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + b4a@1.8.1: + resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + bare-events@2.9.1: + resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.8.0: + resolution: {integrity: sha512-fM+MhCvdQhZ7NV6S95a07gPSqjIYKn6mFaXfx266wN3ajZGl/+1AzH+ubkXQ0fFZvOe2nk9VHkzdYkQE5zMV3Q==} + engines: {bare: '>=1.28.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-path@3.1.1: + resolution: {integrity: sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==} + + bare-stream@2.13.3: + resolution: {integrity: sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==} + peerDependencies: + bare-abort-controller: '*' + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.5.1: + resolution: {integrity: sha512-cD5ciQuKlx+eumTCfqbfiL+fhQm+dHbVNB/cX4+d+I/nx4JsVop9VoFEPAs5RJ6I84QR6bZIBjpd2kjDOYeWcg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.11.12: + resolution: {integrity: sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==} + engines: {node: '>=6.0.0'} + hasBin: true + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + + birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@2.1.4: + resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} + + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.7: + resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-image-size@0.6.4: + resolution: {integrity: sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==} + engines: {node: '>=4.0'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builtin-modules@5.3.0: + resolution: {integrity: sha512-hMQUl2bUFG339QygPM97E+mc8OY1IAchORZxm4a/frcYwKzozMzRVDBwHW0NjOqGElLm2O37AVQE8ikxlZHrMQ==} + engines: {node: '>=18.20'} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + c12@3.3.4: + resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true + + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + + caniuse-api@4.0.0: + resolution: {integrity: sha512-B0hQ1OLyJuHTQSOWXvwibWqM6DCoqJdvBA6X1S/53bd4XU7LJ1yurIPlrsouol3mw1jh9pGI4ivubSpmJeIqCA==} + + caniuse-lite@1.0.30001809: + resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + citty@0.2.2: + resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + cluster-key-slot@1.1.1: + resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} + engines: {node: '>=0.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colortranslator@5.0.0: + resolution: {integrity: sha512-Z3UPUKasUVDFCDYAjP2fmlVRf1jFHJv1izAmPjiOa0OCIw1W7iC8PZ2GsoDa8uZv+mKyWopxxStT9q05+27h7w==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + comment-parser@1.4.7: + resolution: {integrity: sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==} + engines: {node: '>= 12.0.0'} + + comment-parser@1.4.8: + resolution: {integrity: sha512-rKZTGo4fzKYna8UcL0isTg5wkBNla7bxTypLwZQXjIdi++IdP1OJ41rI5Mti3/jltkPujbu4i9LIARYA+zpotQ==} + engines: {node: '>= 12.0.0'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compatx@0.2.0: + resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} + + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie-es@2.0.1: + resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} + + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + + core-js-compat@3.50.0: + resolution: {integrity: sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==} + engines: {node: '>=6.4.0'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + + croner@10.0.1: + resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} + engines: {node: '>=18.0'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crossws@0.4.10: + resolution: {integrity: sha512-pz3oubH/dt12KjqsUB0IuXW4nwRDQ583iDsP4555Cpdqx0NoU7pGlWBcayyFI8f/l/idRpgjMEfwuOxSWJYlIA==} + peerDependencies: + srvx: '>=0.11.5' + peerDependenciesMeta: + srvx: + optional: true + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@8.0.4: + resolution: {integrity: sha512-WUn2NmdLD0FlUI8XdQrlfDjVNGLOI3cxaw7Y6msbfxn4G2vJByuO6M73Wo5B9Rd0Ap36SQhG7wsOXAMnVdC2eQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + cssnano-utils@6.0.2: + resolution: {integrity: sha512-AqysikWP69dOKAP/UMvUYrlZ1gvvQu0/eMFVUKLhH+ZM23dUAKXC31xKvNyL9It2UMF2uDmK4XotBeO9vSBKzg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + cssnano@8.0.4: + resolution: {integrity: sha512-m6epEvKkzysdXamdK4BU9S6lQzx+syY+5Qm4f2dbpxlewBtEYOKi2v2iIr1jLsjuAr3V1WjRp6hXFPH1BEDirw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + db0@0.3.4: + resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devalue@5.9.0: + resolution: {integrity: sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==} + + devframe@0.8.2: + resolution: {integrity: sha512-oodQXEQnrvufA1so/E058Z3SG3bk9AlUE5+NIAsyx5ZJH9P/oX6WMxjC0bs5PPwtKbS7pBHjxja2AD8EwGE8/Q==} + hasBin: true + peerDependencies: + '@modelcontextprotocol/client': ^2.0.0 + '@modelcontextprotocol/server': ^2.0.0 + cac: ^7.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/client': + optional: true + '@modelcontextprotocol/server': + optional: true + cac: + optional: true + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-prop@10.2.0: + resolution: {integrity: sha512-BTJ9aZYL3vCfZlZOBLy9v8TUqWGQ0pzFnygKwFZt5udj6viBoFIBviKPUoZLDCPn1FoXffv6McQFDenrm5Krfw==} + engines: {node: '>=20'} + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + editorconfig@1.0.7: + resolution: {integrity: sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==} + engines: {node: '>=14'} + hasBin: true + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.402: + resolution: {integrity: sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==} + + embla-carousel-auto-height@8.6.0: + resolution: {integrity: sha512-/HrJQOEM6aol/oF33gd2QlINcXy3e19fJWvHDuHWp2bpyTa+2dm9tVVJak30m2Qy6QyQ6Fc8DkImtv7pxWOJUQ==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-auto-scroll@8.6.0: + resolution: {integrity: sha512-WT9fWhNXFpbQ6kP+aS07oF5IHYLZ1Dx4DkwgCY8Hv2ZyYd2KMCPfMV1q/cA3wFGuLO7GMgKiySLX90/pQkcOdQ==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-autoplay@8.6.0: + resolution: {integrity: sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-class-names@8.6.0: + resolution: {integrity: sha512-l1hm1+7GxQ+zwdU2sea/LhD946on7XO2qk3Xq2XWSwBaWfdgchXdK567yzLtYSHn4sWYdiX+x4nnaj+saKnJkw==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-fade@8.6.0: + resolution: {integrity: sha512-qaYsx5mwCz72ZrjlsXgs1nKejSrW+UhkbOMwLgfRT7w2LtdEB03nPRI06GHuHv5ac2USvbEiX2/nAHctcDwvpg==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-vue@8.6.0: + resolution: {integrity: sha512-v8UO5UsyLocZnu/LbfQA7Dn2QHuZKurJY93VUmZYP//QRWoCWOsionmvLLAlibkET3pGPs7++03VhJKbWD7vhQ==} + peerDependencies: + vue: ^3.2.37 + + embla-carousel-wheel-gestures@8.1.0: + resolution: {integrity: sha512-J68jkYrxbWDmXOm2n2YHl+uMEXzkGSKjWmjaEgL9xVvPb3HqVmg6rJSKfI3sqIDVvm7mkeTy87wtG/5263XqHQ==} + engines: {node: '>=10'} + peerDependencies: + embla-carousel: ^8.0.0 || ~8.0.0-rc03 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.24.5: + resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + error-stack-parser-es@2.0.1: + resolution: {integrity: sha512-J36ntO+rMQVRuR/umlmxmfLi4TpWwtmTnHoJoXTiC2xDNazs0VDPKcX6pbhZMDd2HFtH9isMBJXMdbki+A++Pg==} + + errx@0.1.2: + resolution: {integrity: sha512-chfpPHmCerdo/rXr/nNvPZRkV4WwDRwzwnsJ0Uzz3tVi8Z41tDctRjduYy1138ii77AFlts1qvWtX3g/Acg91Q==} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.3.1: + resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} + + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-config-flat-gitignore@2.3.0: + resolution: {integrity: sha512-bg4ZLGgoARg1naWfsINUUb/52Ksw/K22K+T16D38Y8v+/sGwwIYrGvH/JBjOin+RQtxxC9tzNNiy4shnGtGyyQ==} + peerDependencies: + eslint: ^9.5.0 || ^10.0.0 + + eslint-flat-config-utils@3.2.0: + resolution: {integrity: sha512-PHgo1X5uqIorJONLVD9BIaOSdoYFD3z/AeJljdqDPlWVRpeCYkDbK9k0AXoYVqqNJr6FEYIEr5Rm2TSktLQcHw==} + + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + + eslint-merge-processors@2.0.0: + resolution: {integrity: sha512-sUuhSf3IrJdGooquEUB5TNpGNpBoQccbnaLHsb1XkBLUPPqCNivCpY05ZcpCOiV9uHwO2yxXEWVczVclzMxYlA==} + peerDependencies: + eslint: '*' + + eslint-plugin-import-lite@0.6.0: + resolution: {integrity: sha512-80vevx2A7i3H7n1/6pqDO8cc5wRz6OwLDvIyVl9UflBV1N1f46e9Ihzi65IOLYoSxM6YykK2fTw1xm0Ixx6aTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + eslint-plugin-import-x@4.17.1: + resolution: {integrity: sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true + + eslint-plugin-jsdoc@63.3.3: + resolution: {integrity: sha512-xI4IeVRzRFA2DGHrPLIxF3U+oJHU3FE+P9Zb27fVs5dPHgfcpoAs0PyCbznVhK7pwR+9BPUztFeXSgpw/CL4Yg==} + engines: {node: ^22.13.0 || >=24} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + + eslint-plugin-regexp@3.1.1: + resolution: {integrity: sha512-MxR5nqoQCtVWmJwia0D2+NlXX1xzdpkslsVOZLEYQ4PQWEaL65PCZXURxaBc3lPnkNFpNxzMIRmYVxdl8giXRA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: '>=9.38.0' + + eslint-plugin-unicorn@73.0.0: + resolution: {integrity: sha512-V0YatLe9nkGhXEXKe2Qljb1EY0sJHwDV0HUF1NKFwtsHh/fU7qGHDgv+6fchzZcgU2/7noHo2gdjnmo0P2uDPw==} + engines: {node: '>=22'} + peerDependencies: + eslint: '>=10.4' + + eslint-plugin-vue@10.10.0: + resolution: {integrity: sha512-dL9x9rBHqqNcByWiLOHK6L0SB97V82/NC0cZRn9cXPjM7pCuWlpQQP9bFH4vjBv80ej1ZpzAkuD8zWH1o9bZbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + vue-eslint-parser: ^10.3.0 + peerDependenciesMeta: + '@stylistic/eslint-plugin': + optional: true + '@typescript-eslint/parser': + optional: true + + eslint-plugin-vuejs-accessibility@2.5.0: + resolution: {integrity: sha512-oZ2fL4tS91Cm/ezH3BueNP+FtpbbeS627OSqqgp9/lsN//glmoPcLBT6D53xwGocLtyBybaT99tX4ThBh8+ytA==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + globals: '>= 13.12.1' + + eslint-processor-vue-blocks@2.0.0: + resolution: {integrity: sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==} + peerDependencies: + '@vue/compiler-sfc': ^3.3.0 + eslint: '>=9.0.0' + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-typegen@2.3.1: + resolution: {integrity: sha512-zVdh8rThBvv2o5T/K524Fr5iy1Jo0q09rHL7y7FbOhgMB177T2gw+shxfC4ChCEqdq6/y6LJA4j8Fbr/Xls9aw==} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.8.1: + resolution: {integrity: sha512-wqA7W2jbsC/BnV9Iv1UZpKVFkO1AdNoSmYW8NWG4HNOBbkAMvIqDZ27pI2f07dqn583NcIC44ckjAcOXDL1QbQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} + + exsolve@1.1.1: + resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} + + fake-indexeddb@6.2.5: + resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} + engines: {node: '>=18'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-npm-meta@2.2.0: + resolution: {integrity: sha512-99jPl8JkCSCa4VlboNU1XuL98ijm74Pm9CGo6H4BoMVoVh1uhguQcvwLgXDT8Vkl2qj/UEQ0J9gD8beHjTFk1w==} + hasBin: true + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@8.0.0: + resolution: {integrity: sha512-JGG8pvDi2C+JxidYdIwQDyS/CgcrIdh18cvgxcBge3wSHRQOrooMD3GlFBcmMJAN9M42SAZjDp5zv1dglJjwww==} + engines: {node: '>=20'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + + fnv1a-64@0.1.2: + resolution: {integrity: sha512-mJbcILTPybAR1jdOwt/lVv8N2cffeJFFP+gVbSAwLEx1ujXH27RpPd8Rokec/KX9c76UYIB6Co+H4lQzxPnJfA==} + + fontaine@0.8.0: + resolution: {integrity: sha512-eek1GbzOdWIj9FyQH/emqW1aEdfC3lYRCHepzwlFCm5T77fBSRSyNRKE6/antF1/B1M+SfJXVRQTY9GAr7lnDg==} + engines: {node: '>=18.12.0'} + + fontkitten@1.0.3: + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} + engines: {node: '>=20'} + + fontless@0.2.1: + resolution: {integrity: sha512-mUWZ8w91/mw2KEcZ6gHNoNNmsAq9Wiw2IypIux5lM03nhXm+WSloXGUNuRETNTLqZexMgpt7Aj/v63qqrsWraQ==} + engines: {node: '>=18.12.0'} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + framer-motion@12.43.0: + resolution: {integrity: sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} + + fuse.js@7.5.0: + resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==} + engines: {node: '>=10'} + + fzf@0.5.2: + resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} + + generic-names@4.0.0: + resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} + + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-tsconfig@4.14.1: + resolution: {integrity: sha512-Dz/6HxkrxgNehhxLVeyv8sad9UzF2xBVeaKBQNDfJ5XiSXmp2gTR0eO0RWiT2NCKS5aGP9jjkOMggTN90qU50A==} + + giget@3.3.1: + resolution: {integrity: sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg==} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + globals@17.9.0: + resolution: {integrity: sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==} + engines: {node: '>=18'} + + globby@16.2.3: + resolution: {integrity: sha512-VZX7TV7jmd/pn71vdnLKtgwy1IWqc3KjI9x1/UtPkwoKk5fKrNLY30ltDe3cAM5xruIN7YuuaulFt133jRrKZg==} + engines: {node: '>=20'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + h3@2.0.1-rc.26: + resolution: {integrity: sha512-GDxlvDsKxgjRvG5UBRJYyGJTMWLV30CJ4cV+e7QCTgftDHihrvio1fVPbNembhEr6J4WNm8IWy3fookgyTweLw==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.9 + peerDependenciesMeta: + crossws: + optional: true + + happy-dom@20.11.2: + resolution: {integrity: sha512-7MB+bJLkxu3SowAfBJbjW+c55kNz5tkR45gu2qzrxznezhLeN5YIlJbwUgSzlGc+qWoZ8Ykg71H5ezz69xixrw==} + engines: {node: '>=20.0.0'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + httpxy@0.5.5: + resolution: {integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + identifier-regex@1.1.0: + resolution: {integrity: sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA==} + engines: {node: '>=18'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + engines: {node: '>= 4'} + + image-meta@0.2.2: + resolution: {integrity: sha512-3MOLanc3sb3LNGWQl1RlQlNWURE5g32aUphrDyFeCsxBTk08iE3VNe4CwsUZ0Qs1X+EfX0+r29Sxdpza4B+yRA==} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + impound@1.1.6: + resolution: {integrity: sha512-ugavDQkE74SGrBjagNIwNVHNBxX14mmfQnTm4jFGzOoWwYsgihqV698BNr5xwRY9quKK4rEg8bc6ECltllMr+w==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ioredis@5.11.1: + resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==} + engines: {node: '>=12.22.0'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-builtin-module@5.0.0: + resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} + engines: {node: '>=18.20'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-identifier@1.1.0: + resolution: {integrity: sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==} + engines: {node: '>=18'} + + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + + isomorphic.js@0.2.5: + resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.8: + resolution: {integrity: sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + + jsdoc-type-pratt-parser@7.3.0: + resolution: {integrity: sha512-DoyJXo7x/n48M3NsGOs9QnEws0ft0tV3YsSgvWMNxz2hZtz+Q6fpqUD96lVYX4a+jcEkzHeFNDJOn68TzXfbdA==} + engines: {node: '>=20.0.0'} + + jsdoc-type-pratt-parser@8.0.0: + resolution: {integrity: sha512-uQu/fXVqVaMg6gM8/E5G5+eygVcZ1NV0Z51CvqhNa2bDWxvHMl484ETr6vph4oPyC+KUcbP/w2W2pewfCiR9aQ==} + engines: {node: '>=20.0.0'} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-to-typescript-lite@15.0.0: + resolution: {integrity: sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + knitwork@1.3.0: + resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} + + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lib0@0.2.117: + resolution: {integrity: sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw==} + engines: {node: '>=16'} + hasBin: true + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + linkifyjs@4.3.3: + resolution: {integrity: sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==} + + listhen@1.10.1: + resolution: {integrity: sha512-6nt/86SkqUQSLW1ofz8MxC6RhRMqOl3ONISe6qqvJ3xj09aJWQx6DhgSZpugs3PX4PXdOas/WD6A9jx6J2N19A==} + hasBin: true + peerDependencies: + '@parcel/watcher': ^2.5.6 + peerDependenciesMeta: + '@parcel/watcher': + optional: true + + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} + engines: {node: '>= 12.13.0'} + + local-pkg@1.2.1: + resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} + engines: {node: '>=14'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@8.0.0: + resolution: {integrity: sha512-XT9ewWAC43tiAV7xDAPflMkG0qOPn2QjHqlgX8FOqmWa/rxnyYDulF9T0F7tRy1u+TVTmK/M//6VIOye+2zDXg==} + engines: {node: '>=20'} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-regexp@0.10.0: + resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} + + magic-string-ast@1.0.3: + resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} + engines: {node: '>=20.19.0'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magic-string@1.1.0: + resolution: {integrity: sha512-kS3VHe0nEPST2saQV4Rbkchcd3UBRkVTQHo1D3h/ZTwFDhai/mfKkmtPAtD129EOI7K3HlHIsFOt0WrI2/oU9g==} + + magicast@0.5.4: + resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} + + make-asynchronous@1.1.0: + resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} + engines: {node: '>=18'} + + marked@17.0.6: + resolution: {integrity: sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA==} + engines: {node: '>= 20'} + hasBin: true + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + mdn-data@2.29.0: + resolution: {integrity: sha512-pVxQFCcaYUEAH853+v7yoI/qzhxXSq1bTb9obMYGYAN1c3Hen+XDCEvr296XhstrwlSTNgOR7mCSD4JPjbJe5A==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@4.1.0: + resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} + engines: {node: '>=16'} + hasBin: true + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + mocked-exports@0.1.1: + resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} + + motion-dom@12.43.0: + resolution: {integrity: sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag==} + + motion-utils@12.39.0: + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} + + motion-v@2.3.0: + resolution: {integrity: sha512-J0CCfXtICCni9RjotDUBOs57xNpYI9yyBSohEOxaRHrmjwOtlw291fhRu/mdgEdSasys96R028YDDOAtWBbRaA==} + peerDependencies: + '@vueuse/core': '>=10.0.0' + vue: '>=3.0.0' + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanotar@0.3.0: + resolution: {integrity: sha512-Kv2JYYiCzt16Kt5QwAc9BFG89xfPNBx+oQL4GQXD9nLqPkZBiNaqaCWtwnbk/q7UVsTYevvM1b0UF8zmEI4pCg==} + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + nitropack@2.13.4: + resolution: {integrity: sha512-tX7bT6zxNeMwkc6hxHiZeUoTOjVrcjoh1Z3cmxOlodIqjl4HISgqfGOmkWSayky3Nv9Z5+KQH52F8nmXJY5AAA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + xml2js: ^0.6.2 + peerDependenciesMeta: + xml2js: + optional: true + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-forge@1.4.0: + resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} + engines: {node: '>= 6.13.0'} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.5: + resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==} + + node-releases@2.0.53: + resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} + engines: {node: '>=18'} + + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nostics@1.2.0: + resolution: {integrity: sha512-FGqEfhQjrvo1lL8KFifdTQiNwwQHJxC1jtYE1Rc54qF/jxONUNL+kC9gS1krX8Q65PgrQ5fCqH/I4NhWBvdSqg==} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nuxt@4.5.2: + resolution: {integrity: sha512-tR3fcqeHlHmmkLMpIg3V7Y+1ltr302lW8djMw/iy+myfo7QSSz+BVJDuQhg5j73b9oteSyBfOKTDYTgvMtj6TA==} + engines: {node: ^22.19.0 || ^24.11.0 || >=26.0.0} + hasBin: true + peerDependencies: + '@parcel/watcher': ^2.1.0 + '@types/node': '>=18.12.0' + rolldown: ~1.2.1 + peerDependenciesMeta: + '@parcel/watcher': + optional: true + '@types/node': + optional: true + + nypm@0.6.9: + resolution: {integrity: sha512-zxlE2yvSWZWmHcNdT3+5zV2lrCogeE9YOklHrR3dFjqutq5wO7GFDYLFDRXLsYnJzwvy/im9fYoxePvS0VTW0w==} + engines: {node: '>=18'} + hasBin: true + + object-deep-merge@2.0.1: + resolution: {integrity: sha512-aKttDKcU3pyZqKcCkDhsMn70WmZFG2JGDQLP9EcLyTSIFQRCPWLAmBZRLJnrVUrhPG1jETEEbfdgbNtJf1LyMg==} + + object-identity@0.2.3: + resolution: {integrity: sha512-2J8Joz2Tf7aaylhqFvIUJHNgpuGR38Hh75Voq9GzTbStBxJUaOtN0K1aOd3cV5qp+ij1pMqRbPrGCGMOyX303w==} + + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} + engines: {node: '>=12.20.0'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ofetch@2.0.0-alpha.3: + resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + oidc-client-ts@3.5.0: + resolution: {integrity: sha512-l2q8l9CTCTOlbX+AnK4p3M+4CEpKpyQhle6blQkdFhm0IsBqsxm15bYaSa11G7pWdsYr6epdsRZxJpCyCRbT8A==} + engines: {node: '>=18'} + + on-change@6.0.2: + resolution: {integrity: sha512-08+12qcOVEA0fS9g/VxKS27HaT94nRutUT77J2dr8zv/unzXopvhBuF8tNLWsoLQ5IgrQ6eptGeGqUYat82U1w==} + engines: {node: '>=20'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + + oxc-walker@1.1.1: + resolution: {integrity: sha512-Hwd7dq28zu/Er99+bpWp16CGwFrhyalJh0W3JOB7XpPvgWo3MqMi2ksWGKuzzA9zt50mJ2pIUwR5lpAdZ9ACNQ==} + peerDependencies: + '@oxc-project/types': '>=0.98.0' + oxc-parser: '>=0.98.0' + rolldown: '>=1.0.0' + peerDependenciesMeta: + '@oxc-project/types': + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@1.8.0: + resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + + parse-imports-exports@0.2.4: + resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} + + parse-statements@1.0.11: + resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.1: + resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@8.0.2: + resolution: {integrity: sha512-3puH3etbn8GPaJuF8OybCdUW6PJO0KU9ZnsaA/1VG9HU0Wdrf94dOTQkbQnA8/qkYdPjwHzcWvzUGXIeawBa0w==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-convert-values@8.0.2: + resolution: {integrity: sha512-KA6VVp93xASmDI0HWgRQ7938XR20hZEVL525YCbcTVsuxn4BNxs+ge4wLNow+ay+uqPuy3uEh51zhjfI92uN4w==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-discard-comments@8.0.2: + resolution: {integrity: sha512-tQk36szZkG9ngZM9bKrUp3hM2SxdclYJVnMtAMKyi0RqY7IQpx67TJ3+0thRMV47niKBw9Y/1auGkBeCfPC97A==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-discard-duplicates@8.0.2: + resolution: {integrity: sha512-Y2IDdRqvnpzsOH5ZLcJnvh/Eiye8O3r6uO7oFTe3YuFfrat3xQRDPjTVohRmi8RWuOIq2rGjva1n4Adus4pljw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-discard-empty@8.0.2: + resolution: {integrity: sha512-fGHTnqg2S4fBudyd+tCE+qT57R4YRUaYLannCrKYsE8u/rCMGCBMPwIM4jcNWJLP5vMEBitGrXa5mGB7VKA+Eg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-discard-overridden@8.0.2: + resolution: {integrity: sha512-a9Dvv5ccOI7P94oCaeytj4FCSsHiXyH8KwXQorU/GJWDRvwFMY9yUs4uPKSG2HBSGtR49xo3ieml6F1EQCJtZA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-merge-longhand@8.0.2: + resolution: {integrity: sha512-iN1JQ21vKd3ZdbHmj69lqOwaWiFvxlXVQ5EeH/sw5M3TqI1sFR28G4yleAcNkMwB55E6qGRRVR3lem+ZJazmoQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-merge-rules@8.0.2: + resolution: {integrity: sha512-ipELN1m3k/GLGD+wmYHtiEVE2TMW5OKm4CgSRqYDeDz1ZX89AbeUCoeos0dUdTcpMilSa+zIRwvD78U3Uv/1BA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-minify-font-values@8.0.2: + resolution: {integrity: sha512-T6oURfdYH/BtXLLN/biomuY1hSYSGbfRyLyxQ+7+VCRw7Zj1ROpRwHpaX2PP/rpmT/0yHaGIVUNShmanvm3PXw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-minify-gradients@8.0.2: + resolution: {integrity: sha512-s49jAcFm5eF7GLLU0+28e4mQc/vISBMtu+1gQbq/Uf7+w155G8nbItaQp5NYY7QsYerpj2qvtNkYN25gZWWYdw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-minify-params@8.0.2: + resolution: {integrity: sha512-ifaU795JsBddkffWbTOXl8ubUyBqpNiLS8xjqKmE/Sw9AOpjWG2uFPfpEv3AZPXWNkWJf8kGvW9wLHImEUJUkA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-minify-selectors@8.0.3: + resolution: {integrity: sha512-3WchKL9xoA80/jNkRcimRGIc9mP6sHPQUY/1WzV+GbF69I/upieyaKzZcIdQzf9cBmCJ6vjxi+NrKqCojoOb7Q==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-charset@8.0.2: + resolution: {integrity: sha512-iy3/b+gX+dHfbNZq/4rfThbMAqxhneBJEhS71y5toliav5rLowkZ6g0ZJGymXRZytDOt/u+fRSFkNJLkRPYaug==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-display-values@8.0.2: + resolution: {integrity: sha512-T6Az9mgc7FUWvI6mK0uOsItT6csep7fdLtDSRC2XBMTCvrQmtYiz86T5hEM6sfAkZVVhfrALPhdPxJWVoNAktw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-positions@8.0.2: + resolution: {integrity: sha512-BBg188AxYLC86LDEnkbQTcdnZugP2vDwYQQDV+Htju2gpTqM2a3o/oQ91/h9+j0277InjNgrI7l1LDDRrlWQ5w==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-repeat-style@8.0.2: + resolution: {integrity: sha512-6mbVJzuogwcAHMd6MMpmAMcc3BkleOcY2xazCp+HCMiod78tx7rdOrufTrPYGjBLaTjkgNUr8KCkLHj8mfH6WQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-string@8.0.2: + resolution: {integrity: sha512-8UK2KJSChlv7V12QgWTWtbRzzZcki/f21e8egMlFHTE9rEBCCyLo60rcY3mh77cDZhrBSIfKM9ciOsU6249nbA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-timing-functions@8.0.2: + resolution: {integrity: sha512-C2OyYiEMKjCxA0m+QJ5SeMf12OenIIGqrXEuWizEunZZP+s5TRq1aT8naxqr/8rytSRqD4SwH4mywc9G44u4cw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-unicode@8.0.2: + resolution: {integrity: sha512-ttWq9oM88gSPpfspoZB49r/lv1fvjOadi79E/4BxGVt0rughnNDdTnDLmWj+epOjS6iKhmse3kbNcISR6Jl+3A==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-url@8.0.2: + resolution: {integrity: sha512-PvSiaJOQpP0AW5GSHrWZXupfhUgLUtS1MubJX+wPwh6RZZP6CHnZQy/S8uX2vvHMd57qIZ44Sb/37rFMiAWPfA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-normalize-whitespace@8.0.2: + resolution: {integrity: sha512-Fipz8bjy96XPmtMPsqbGw3fypbS+aOHJfpTzfQY9z0lDYFqqGIqYWwrfsi2ZOv7B86pY81vQGJ6mSHWvTXDV7g==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-ordered-values@8.0.2: + resolution: {integrity: sha512-LBqMGd6Bam4TVp9dKui01o0prWtsGfPP+WtENunNs3L9oi+t75uPyEmzzaimxinmGgeiFLix9xLI0FfD+qedjw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-reduce-initial@8.0.2: + resolution: {integrity: sha512-+612lhSpyp1g4ZU0zQKwmdHnAi8LevMpzvQuP2RVhq+EUWqAwwUMk03OQEfzy+es9OSdRTuy5ugnFeEeOiIe2A==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-reduce-transforms@8.0.2: + resolution: {integrity: sha512-7D2vDXJ2HBNQpbiw5dY9UyLfBRCGRBjV0ChMqHdHghFsjAH3hIIUgb/rE+e77LFiT8VjXUK2fZh3omG4R96n8A==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-selector-parser@7.1.5: + resolution: {integrity: sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==} + engines: {node: '>=4'} + + postcss-svgo@8.0.3: + resolution: {integrity: sha512-ADG8YNtwE5bcqvxw1gU0X7FkgdvinZZxWKHSCMwayX7gPl4XRmBMyiC84Ukal5bPS9Nk/2tI7siJwqxIN4/grg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-unique-selectors@8.0.2: + resolution: {integrity: sha512-cIftRB4rW3UCqnQjFAS6WlUzragjsU2AtMzWDdDQKTMjgPh1rO8qYgnoYqkUgRXKnxd3902laOWbkkYO/GYEHw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.26: + resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + engines: {node: ^10 || ^12 || >=14} + + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + pretty-bytes@7.1.1: + resolution: {integrity: sha512-X+vn9z8nOFZQlxOLmfJ0iKDdMD7jYTsTW12OAlCpdoE3Igik6L37pugIZi+N3usuyp5McfgKPWi12q3zvHLeGQ==} + engines: {node: '>=20'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + prosemirror-changeset@2.4.1: + resolution: {integrity: sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==} + + prosemirror-commands@1.7.2: + resolution: {integrity: sha512-q6Q6szxqdu9Xd6EcdKsqXghu5nQdZTpB4Q9yd04WRc7/jt763e/rT60Owh0L1GYY+T46o5rD+9lEN36dZS43tw==} + + prosemirror-dropcursor@1.8.3: + resolution: {integrity: sha512-FoYbsJR8gK+DGlqhNoE29Loa38eIZPzQRIb1VMaDNBoo4OLP6vVof/jR8qFY/6XvUd6Dhug8MDCHl2a/h8RTfQ==} + + prosemirror-gapcursor@1.4.1: + resolution: {integrity: sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==} + + prosemirror-history@1.5.0: + resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + + prosemirror-inputrules@1.5.1: + resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-model@1.25.11: + resolution: {integrity: sha512-QWg9RhnpLlogAmp3p96uEFrE5txQpFynd4vhBAELkwgOCWQs/X0yCzB3/hrHqiPwf91RG5KyWq6553zs9JqIOQ==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + + prosemirror-tables@1.8.5: + resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} + + prosemirror-transform@1.12.0: + resolution: {integrity: sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==} + + prosemirror-view@1.42.2: + resolution: {integrity: sha512-Pdg0l5kXm8aLDquFAnQFTCITg0q44sLqBlHlpsVLD9segdOao8TOfQdAhCrCXyVgPSRr6UDDROOIWA3bIrN9YQ==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quote-js-string@0.1.0: + resolution: {integrity: sha512-Y3NoRtprEEZQD8RfxMCfS0ZTqc4e+i18OrXEXAvpM6TfC/3y+0L5rNbZiSnbBBEkDfFzbpd8o+cE8q3/anjMGA==} + engines: {node: '>=22'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + rc9@3.0.1: + resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regjsparser@0.13.2: + resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} + hasBin: true + + reka-ui@2.10.1: + resolution: {integrity: sha512-drcOQ4rQtDYAcGCsyQBqQg8QQ+H3B+zDaMJU0h8KPEPMa7g9BHu3zcOi4OB39XJSWizceFoNO0Z9tctSGLOXqg==} + peerDependencies: + vue: '>= 3.4.0' + + reserved-identifiers@1.2.0: + resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} + engines: {node: '>=18'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown-string@0.3.1: + resolution: {integrity: sha512-dv8GOXkYqUQdI0rsXB8hmzO95pKWSuX2eg5/JSJa9czfEVIFuKNR7ZJDfat8LlmD35RAhWY+evS7/wXXqFDfSg==} + engines: {node: '>=20.19.0'} + peerDependencies: + rolldown: '*' + peerDependenciesMeta: + rolldown: + optional: true + + rolldown@1.2.3: + resolution: {integrity: sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup-plugin-visualizer@7.0.1: + resolution: {integrity: sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==} + engines: {node: '>=22'} + hasBin: true + peerDependencies: + rolldown: 1.x || ^1.0.0-beta || ^1.0.0-rc + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup@4.62.4: + resolution: {integrity: sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + + rou3@0.9.1: + resolution: {integrity: sha512-z/sSmzvtwMDDnxsPVhfWMuG6F6mbmhFDXoVqLmMfbpDD9qfV3GDmSQpf0+W296/ZDIpW2wcMmBfpVFzcnOi/nA==} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} + engines: {node: '>=11.0.0'} + + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serialize-javascript@7.0.7: + resolution: {integrity: sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g==} + engines: {node: '>=20.0.0'} + + seroval@1.6.2: + resolution: {integrity: sha512-mPT+SD2TrlB6wvte1KkYOYUkubaTbd6pZ/6Kk3C9nxzrHmCZyhxOO7XGAeL7f+yLKZglzGtM9odUVvg/EhO+vQ==} + engines: {node: '>=10'} + + serve-placeholder@2.0.2: + resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.10.0: + resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-git@3.36.0: + resolution: {integrity: sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + smob@1.6.2: + resolution: {integrity: sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==} + engines: {node: '>=20.0.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@5.0.0: + resolution: {integrity: sha512-vngmw3Rgn+o2arXNbnZaj5UtOEBuWBfvaI+Wc8GFfykIhA5/vdK9/Sp/XkLv63dykz2rxKDvKEHupF5P0FORcQ==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + + srvx@0.11.22: + resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==} + engines: {node: '>=20.16.0'} + hasBin: true + + srvx@0.12.5: + resolution: {integrity: sha512-IuvtDNQg5EIwv3c6dleyau7u8hCyGQ7D6+V/QM799Aud07z0wCUcurKLTRfyG33C8oUY+UWcVBFkfHMcbtmRLA==} + engines: {node: '>=20.16.0'} + hasBin: true + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} + + streamx@2.28.0: + resolution: {integrity: sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.2.2: + resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} + engines: {node: '>=20'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} + + strip-literal@4.0.0: + resolution: {integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==} + + structured-clone-es@2.0.1: + resolution: {integrity: sha512-10ZL5r77LhknxlP1FBiCW+VdnuWOEFLdSS2SKtjyEV+L4qP1hUEIMIZW94LC3jKxRmT/Dj7KkD1mqh/IY6lhKQ==} + + stylehacks@8.0.2: + resolution: {integrity: sha512-3d5vjQODiMc4VwED1w24fAYSfeAjdIRLy88cJQ9NAYkZr/6ozCVbusda5N+0kXsfGWW3pizUgYK2TOZxiU0cSQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.25 + + super-regex@1.1.0: + resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} + engines: {node: '>=18'} + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@4.0.2: + resolution: {integrity: sha512-ekx94z1rRc5LDi6oSUaeRnYhd0UOJxdtQCL2rF8xpWxD3TPAsISWOrxezqGovqS38GRZOdpDfvQe3ts6F7nsng==} + engines: {node: '>=16'} + hasBin: true + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tailwind-merge@3.6.0: + resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} + + tailwind-variants@3.3.1: + resolution: {integrity: sha512-4pAvwUtM4HKBiRZftncAbpn6V9Hhwoa5Fl7O2u5zbp7Z5Cvu+/o/6+176WY3WCEES209543quG8zFIcXCsc5Jw==} + engines: {node: '>=16.9.x', pnpm: '>=7.x'} + peerDependencies: + tailwind-merge: '>=3.0.0' + tailwindcss: '*' + peerDependenciesMeta: + tailwind-merge: + optional: true + tailwindcss: + optional: true + + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tar-stream@3.2.0: + resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} + + tar@7.5.22: + resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} + engines: {node: '>=18'} + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} + + terser@5.49.2: + resolution: {integrity: sha512-rGbJiKeQ4WDe3EXlDAIaQcwftVfv2Q8o1awFNfvXolJYKkb1AuZY1RTOmqx4LJXZENbWZA7eIsYGHuEzHsi1nQ==} + engines: {node: '>=10'} + hasBin: true + + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + + time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyclip@0.1.15: + resolution: {integrity: sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==} + engines: {node: ^16.14.0 || >= 17.3.0} + + tinyexec@1.3.0: + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.1: + resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} + engines: {node: '>=14.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-valid-identifier@1.0.0: + resolution: {integrity: sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==} + engines: {node: '>=20'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-fest@5.8.0: + resolution: {integrity: sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==} + engines: {node: '>=20'} + + type-level-regexp@0.1.17: + resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + ultrahtml@1.7.0: + resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + unctx@2.5.0: + resolution: {integrity: sha512-p+Rz9x0R7X+CYDkT+Xg8/GhpcShTlU8n+cf9OtOEf7zEQsNcCZO1dPKNRDqvUTaq+P32PMMkxWHwfrxkqfqAYg==} + + unctx@3.0.0: + resolution: {integrity: sha512-DoXdZVeyi2jyEsn86i8MO5RTItm1kffUkH9/+DQORn3Q688AMOy2551CIl6AdGL2UpwD675wtbNOl75wIQN/uA==} + peerDependencies: + magic-string: '>=0.30.21' + oxc-parser: '>=0.140.0' + rolldown: ^1.1.5 + unplugin: ^3.3.0 + peerDependenciesMeta: + magic-string: + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + unplugin: + optional: true + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + undici@8.10.0: + resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} + engines: {node: '>=22.19.0'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + + unhead@2.1.17: + resolution: {integrity: sha512-HLMKXOszRhAPBrr6VlqCeVeJq2kbC4kXwzGLEZvvojPLWNYTJw22xG7Bfwhsvs31+IBet3Wl8ADg9dwYdyphfQ==} + + unhead@3.3.1: + resolution: {integrity: sha512-eqHlbLyuvIXw898WopQmosTml4PdYW5ZhXDom/sf7ysAqQB9uvYrw2/dNvbrmkJTufSkmNmgGCjoQcvoT2mS/A==} + peerDependencies: + vite: '>=6.4.2' + peerDependenciesMeta: + vite: + optional: true + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + + unifont@0.7.4: + resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} + + unimport@6.4.0: + resolution: {integrity: sha512-JJOOuNMFq8b4ZPBKwQUxEcba4MplskDzYI1Lvrf8rJfWphZTWvPNXWa493qsPngHUmub89w6C7j+SeLWTE/UIQ==} + engines: {node: '>=18.12.0'} + peerDependencies: + oxc-parser: '*' + rolldown: ^1.0.0 + peerDependenciesMeta: + oxc-parser: + optional: true + rolldown: + optional: true + + unplugin-auto-import@21.1.0: + resolution: {integrity: sha512-EzrSqWIBulEqCuP7idADXH+tVKYrbwKlR5+r/lOWik0o+Ksny1kitmtryHGNSv7puzzORlcIwT/x2JStiszlHA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@nuxt/kit': ^4.0.0 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-utils@0.3.2: + resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==} + engines: {node: '>=20.19.0'} + + unplugin-vue-components@32.1.0: + resolution: {integrity: sha512-YiUkSxuRjab18XFOrX5VsIxXzccrfmHVGsGeJgSgklb829DQmCy9E4vvDUE4tuvZZdxyFJZX0Oc4TPnnxiiMyg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@nuxt/kit': ^3.2.2 || ^4.0.0 + vue: ^3.0.0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + unplugin@3.3.0: + resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + + unrouting@0.2.2: + resolution: {integrity: sha512-EoCab68s1o9AWFq9fjKsMEsmjKrPO11SAsvopikks2eEm/KLXgZMCof4cgpVgdy0Vz71OFBJw6DoDqu1oOSFGw==} + + unrs-resolver@1.12.2: + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + untun@0.2.2: + resolution: {integrity: sha512-+NnOJcSiEtYsVgJmXUzQbJeRAFXJC4yPJYuh6kF9B0Rm6zunXcs/3GZOTllyocSbUDIxD6Bj7e/4ATw7sph1Sw==} + hasBin: true + + untyped@2.0.0: + resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} + hasBin: true + + unwasm@0.5.3: + resolution: {integrity: sha512-keBgTSfp3r6+s9ZcSma+0chwxQdmLbB5+dAD9vjtB21UTMYuKAxHXCU1K2CbCtnP09EaWeRvACnXk0EJtUx+hw==} + + update-browserslist-db@1.3.0: + resolution: {integrity: sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uqr@0.1.3: + resolution: {integrity: sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vaul-vue@0.4.1: + resolution: {integrity: sha512-A6jOWOZX5yvyo1qMn7IveoWN91mJI5L3BUKsIwkg6qrTGgHs1Sb1JF/vyLJgnbN1rH4OOOxFbtqL9A46bOyGUQ==} + peerDependencies: + reka-ui: ^2.0.0 + vue: ^3.3.0 + + verkit@0.3.2: + resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==} + engines: {node: '>=18.12.0'} + + vite-dev-rpc@2.0.0: + resolution: {integrity: sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 || ^8.0.0 + + vite-hot-client@2.2.0: + resolution: {integrity: sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0 + + vite-node@6.0.0: + resolution: {integrity: sha512-oj4PVrT+pDh6GYf5wfUXkcZyekYS8kKPfLPXVl8qe324Ec6l4K2DUKNadRbZ3LQl0qGcDz+PyOo7ZAh00Y+JjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + vite-plugin-checker@0.14.5: + resolution: {integrity: sha512-c9lQ92eisUO+F7Fd93aelojmiOS+NQpPgQ1XR2LTQHox1/laZf4yAoQj+L3RA9Vgh10e2nFd9b8r2LLyYZsbpA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@biomejs/biome': '>=2.4.12' + eslint: '>=9.39.4' + meow: ^13.2.0 || ^14.0.0 + optionator: ^0.9.4 + oxlint: '>=1' + stylelint: '>=16.26.1' + typescript: '*' + vite: '>=5.4.21' + vue-tsc: ~2.2.10 || ^3.0.0 + peerDependenciesMeta: + '@biomejs/biome': + optional: true + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + oxlint: + optional: true + stylelint: + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + vite-plugin-inspect@11.4.1: + resolution: {integrity: sha512-ShOFe2PURXGvRS5OrgmOLZOCwDTD7dEBVt0tMpFPKb9AsvqXKCRGM8QgKrUbRbJYFXScHvDPpGRd28rYidC0tA==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 || ^7.0.0-0 || ^8.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-tracer@1.4.0: + resolution: {integrity: sha512-0tQCjCqZWVSK6UeRW9S4ABbf47lKQ68zvrT2FNvZmiL+alDydCVyH/T3Jlfbdc3T3C2Iuyyl5aVsMbF8IQIoxA==} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vue: ^3.5.0 + + vite@8.2.1: + resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.4.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest-environment-nuxt@2.0.0: + resolution: {integrity: sha512-zEGFRiCAaRR3fHnqISHKMNTRvCzkQEI1XyFeqNgR2IBD0oYkfZ1rUHwi7C+h3Cns3KPykfB0av1B3MtLEbChDw==} + + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-bundle-renderer@2.3.1: + resolution: {integrity: sha512-7F4LNMopUw5RgYWo4zCmVUHCc6aQRC6dCKHUYkM/n+fux4AUGdL1x6m5A515WWyFysRRN7cx3hBzVqoisfRfzw==} + + vue-component-type-helpers@3.3.9: + resolution: {integrity: sha512-3c/UfMe0SqyEfcGTyH7mfshHagJ9QTCbppCb0/uGpHZpFug7+If3GeGZN7I0YheKEExemx3xldQPoO7PQSOLQg==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-devtools-stub@0.1.0: + resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} + + vue-eslint-parser@10.4.1: + resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + + vue-router@5.2.0: + resolution: {integrity: sha512-QAC5i0LEb1GLG0LXDQmHu8L7FX12j0KwU/JTKmLQUJMrn04gQdKP6Du+p0QwpHb3iy71vBlqnHQ8WAfOSAWhqw==} + peerDependencies: + '@pinia/colada': '>=0.21.2' + '@vue/compiler-sfc': ^3.5.34 || ^4.0.0 + pinia: ^3.0.4 || ^4.0.2 + vite: ^7.3.0 || ^8.0.0 + vue: ^3.5.34 || ^4.0.0 + peerDependenciesMeta: + '@pinia/colada': + optional: true + '@vue/compiler-sfc': + optional: true + pinia: + optional: true + vite: + optional: true + + vue-tsc@3.3.9: + resolution: {integrity: sha512-TS3Y1ux/IRoE8OCP2PpACAeOseuIs0UvWrcr7u+w3PmfY+SlCfEf8zjrBgnQksHUgLpthi5vHlffcQTQTdPBZA==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.41: + resolution: {integrity: sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + wheel-gestures@2.2.48: + resolution: {integrity: sha512-f+Gy33Oa5Z14XY9679Zze+7VFhbsQfBFXodnU2x589l4kxGM9L5Y8zETTmcMR5pWOPQyRv4Z0lNax6xCO0NSlA==} + engines: {node: '>=18'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + y-protocols@1.0.7: + resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + yjs: ^13.0.0 + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.1.0: + resolution: {integrity: sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yjs@13.6.32: + resolution: {integrity: sha512-lfiJIIC4Xayt5ItynE407ehlE03pCjeOc4hkR4yxxvvNJ4kuiN25B0g+Qp8XagYz361LLL7DCzR5bvFJ81QKtQ==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.1: + resolution: {integrity: sha512-mxW3qiSnl+GRxXsaUMzv2Mbada1Y8CDltET9UxejDQe6DBYlSekghl5U5K0ReAikcHDi0G1vKZEmmo/NWAGKLA==} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.8.0 + tinyexec: 1.3.0 + + '@antfu/install-pkg@2.0.1': + dependencies: + package-manager-detector: 1.8.0 + tinyexec: 1.3.0 + + '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': + dependencies: + '@types/json-schema': 7.0.15 + js-yaml: 4.3.1 + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7(supports-color@10.2.2)': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8(supports-color@10.2.2) + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@10.2.2) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/generator@8.0.0': + dependencies: + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.29.7': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.28.7 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7(supports-color@10.2.2) + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7(supports-color@10.2.2) + '@babel/traverse': 7.29.8(supports-color@10.2.2) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-member-expression-to-functions@7.29.7(supports-color@10.2.2)': + dependencies: + '@babel/traverse': 7.29.8(supports-color@10.2.2) + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.29.7(supports-color@10.2.2)': + dependencies: + '@babel/traverse': 7.29.8(supports-color@10.2.2) + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-module-imports': 7.29.7(supports-color@10.2.2) + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.8(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.29.7': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-plugin-utils@7.29.7': {} + + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-member-expression-to-functions': 7.29.7(supports-color@10.2.2) + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/traverse': 7.29.8(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.29.7(supports-color@10.2.2)': + dependencies: + '@babel/traverse': 7.29.8(supports-color@10.2.2) + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-string-parser@8.0.0': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-identifier@8.0.4': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + + '@babel/parser@7.29.8': + dependencies: + '@babel/types': 7.29.8 + + '@babel/parser@8.0.4': + dependencies: + '@babel/types': 8.0.4 + + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-transform-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7(supports-color@10.2.2) + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + + '@babel/traverse@7.29.8(supports-color@10.2.2)': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@babel/types@8.0.4': + dependencies: + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 + + '@bomb.sh/tab@0.0.19(cac@7.0.0)(citty@0.2.2)': + optionalDependencies: + cac: 7.0.0 + citty: 0.2.2 + + '@capsizecss/unpack@4.0.1': + dependencies: + fontkitten: 1.0.3 + + '@clack/core@1.4.3': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.7.0': + dependencies: + '@clack/core': 1.4.3 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@cloudflare/kv-asset-handler@0.4.2': {} + + '@colordx/core@5.5.0': {} + + '@dxup/nuxt@0.5.6(esbuild@0.28.1)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@dxup/unimport': 0.1.2 + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@vue/compiler-dom': 3.5.41 + chokidar: 5.0.0 + knitwork: 1.3.0 + magic-string: 1.1.0 + pathe: 2.0.3 + tinyglobby: 0.2.17 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - magicast + - oxc-parser + - rolldown + - rollup + - unloader + - vite + - webpack + + '@dxup/unimport@0.1.2': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@es-joy/jsdoccomment@0.91.0': + dependencies: + '@types/estree': 1.0.9 + '@typescript-eslint/types': 8.66.0 + comment-parser: 1.4.7 + esquery: 1.7.0 + jsdoc-type-pratt-parser: 8.0.0 + + '@es-joy/resolve.exports@1.2.0': {} + + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/aix-ppc64@0.28.1': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.28.1': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-arm@0.28.1': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/android-x64@0.28.1': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.28.1': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.28.1': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.28.1': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.28.1': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.28.1': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-arm@0.28.1': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.28.1': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.28.1': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.28.1': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.28.1': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.28.1': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.28.1': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/linux-x64@0.28.1': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.28.1': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.28.1': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.28.1': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.28.1': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.28.1': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.28.1': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.28.1': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.28.1': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + + '@esbuild/win32-x64@0.28.1': + optional: true + + '@eslint-community/eslint-utils@4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))': + dependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/compat@2.1.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))': + dependencies: + '@eslint/core': 1.2.1 + optionalDependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + + '@eslint/config-array@0.23.5(supports-color@10.2.2)': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3(supports-color@10.2.2) + minimatch: 10.2.6 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.5.5': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/config-helpers@0.7.0': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/config-inspector@3.2.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(srvx@0.11.22)': + dependencies: + ansis: 4.3.1 + cac: 7.0.0 + chokidar: 5.0.0 + devframe: 0.8.2(cac@7.0.0)(srvx@0.11.22) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + jiti: 2.7.0 + tinyglobby: 0.2.17 + transitivePeerDependencies: + - '@modelcontextprotocol/client' + - '@modelcontextprotocol/server' + - srvx + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/css-tree@4.0.5': + dependencies: + mdn-data: 2.29.0 + source-map-js: 1.2.1 + + '@eslint/js@10.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))': + optionalDependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.7.2': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/utils@0.2.12': {} + + '@floating-ui/vue@1.1.11(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@floating-ui/dom': 1.8.0 + '@floating-ui/utils': 0.2.12 + vue-demi: 0.14.10(vue@3.5.41(typescript@6.0.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@iconify/collections@1.0.720': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.4': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + import-meta-resolve: 4.2.0 + + '@iconify/vue@5.0.1(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@iconify/types': 2.0.0 + vue: 3.5.41(typescript@6.0.3) + + '@internationalized/date@3.12.3': + dependencies: + '@swc/helpers': 0.5.23 + + '@internationalized/number@3.6.7': + dependencies: + '@swc/helpers': 0.5.23 + + '@ioredis/commands@1.10.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@kwsites/file-exists@1.1.1(supports-color@10.2.2)': + dependencies: + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@mapbox/node-pre-gyp@2.0.3(supports-color@10.2.2)': + dependencies: + consola: 3.4.2 + detect-libc: 2.1.2 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + node-fetch: 2.7.0 + nopt: 8.1.0 + semver: 7.8.5 + tar: 7.5.22 + transitivePeerDependencies: + - encoding + - supports-color + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + optional: true + + '@napi-rs/wasm-runtime@1.2.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nuxt/cli@3.37.0(@nuxt/schema@4.5.2)(cac@7.0.0)(magicast@0.5.4)(supports-color@10.2.2)': + dependencies: + '@bomb.sh/tab': 0.0.19(cac@7.0.0)(citty@0.2.2) + '@clack/prompts': 1.7.0 + c12: 3.3.4(magicast@0.5.4) + citty: 0.2.2 + confbox: 0.2.4 + consola: 3.4.2 + debug: 4.4.3(supports-color@10.2.2) + defu: 6.1.7 + exsolve: 1.1.1 + fuse.js: 7.5.0 + fzf: 0.5.2 + giget: 3.3.1 + jiti: 2.7.0 + listhen: 1.10.1(srvx@0.11.22) + nypm: 0.6.9 + ofetch: 1.5.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.1 + scule: 1.3.0 + semver: 7.8.5 + srvx: 0.11.22 + std-env: 4.2.0 + tinyclip: 0.1.15 + tinyexec: 1.3.0 + ufo: 1.6.4 + youch: 4.1.1 + optionalDependencies: + '@nuxt/schema': 4.5.2 + transitivePeerDependencies: + - '@parcel/watcher' + - cac + - commander + - magicast + - supports-color + + '@nuxt/devalue@2.0.2': {} + + '@nuxt/devtools-kit@2.7.0(magicast@0.5.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@nuxt/kit': 3.21.11(magicast@0.5.4) + execa: 8.0.1 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - magicast + + '@nuxt/devtools-kit@3.4.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@nuxt/kit': 4.5.2(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + execa: 8.0.1 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-kit@3.4.1(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + execa: 8.0.1 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-wizard@3.4.1': + dependencies: + '@clack/prompts': 1.7.0 + consola: 3.4.2 + diff: 8.0.4 + execa: 8.0.1 + magicast: 0.5.4 + pathe: 2.0.3 + pkg-types: 2.3.1 + semver: 7.8.5 + + '@nuxt/devtools@3.4.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@nuxt/devtools-kit': 3.4.1(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/devtools-wizard': 3.4.1 + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@vue/devtools-core': 8.2.1(vue@3.5.41(typescript@6.0.3)) + '@vue/devtools-kit': 8.2.1 + birpc: 4.0.0 + consola: 3.4.2 + destr: 2.0.5 + error-stack-parser-es: 2.0.1 + execa: 8.0.1 + fast-npm-meta: 2.2.0 + get-port-please: 3.2.0 + hookable: 6.1.1 + image-meta: 0.2.2 + is-installed-globally: 1.0.0 + launch-editor: 2.14.1 + local-pkg: 1.2.1 + magicast: 0.5.4 + nypm: 0.6.9 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.1 + semver: 7.8.5 + simple-git: 3.36.0(supports-color@10.2.2) + sirv: 3.0.2 + structured-clone-es: 2.0.1 + tinyglobby: 0.2.17 + unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)) + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vite-plugin-inspect: 11.4.1(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + vite-plugin-vue-tracer: 1.4.0(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + which: 6.0.1 + ws: 8.21.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - idb-keyval + - ioredis + - magic-string + - oxc-parser + - rolldown + - supports-color + - unplugin + - uploadthing + - utf-8-validate + - vue + + '@nuxt/eslint-config@1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.41)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@antfu/install-pkg': 2.0.1 + '@clack/prompts': 1.7.0 + '@eslint/js': 10.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@nuxt/eslint-plugin': 1.17.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@stylistic/eslint-plugin': 5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@typescript-eslint/eslint-plugin': 8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-config-flat-gitignore: 2.3.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint-flat-config-utils: 3.2.0 + eslint-merge-processors: 2.0.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint-plugin-import-lite: 0.6.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint-plugin-import-x: 4.17.1(@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) + eslint-plugin-jsdoc: 63.3.3(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) + eslint-plugin-regexp: 3.1.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint-plugin-unicorn: 73.0.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint-plugin-vue: 10.10.0(@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)))(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(vue-eslint-parser@10.4.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.41)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + globals: 17.9.0 + local-pkg: 1.2.1 + pathe: 2.0.3 + vue-eslint-parser: 10.4.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) + transitivePeerDependencies: + - '@typescript-eslint/utils' + - '@vue/compiler-sfc' + - eslint-import-resolver-node + - supports-color + - typescript + + '@nuxt/eslint-plugin@1.17.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + - typescript + + '@nuxt/eslint@1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.41)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(typescript@6.0.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@eslint/config-inspector': 3.2.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(srvx@0.11.22) + '@nuxt/devtools-kit': 3.4.1(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/eslint-config': 1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.41)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@nuxt/eslint-plugin': 1.17.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + chokidar: 5.0.0 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-flat-config-utils: 3.2.0 + eslint-typegen: 2.3.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + find-up: 8.0.0 + get-port-please: 3.2.0 + mlly: 1.8.2 + pathe: 2.0.3 + unimport: 6.4.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + transitivePeerDependencies: + - '@farmfe/core' + - '@modelcontextprotocol/client' + - '@modelcontextprotocol/server' + - '@rspack/core' + - '@typescript-eslint/utils' + - '@vue/compiler-sfc' + - bun-types-no-globals + - esbuild + - eslint-import-resolver-node + - eslint-plugin-format + - magic-string + - magicast + - oxc-parser + - rolldown + - rollup + - srvx + - supports-color + - typescript + - unloader + - unplugin + - vite + - webpack + + '@nuxt/fonts@0.14.0(db0@0.3.4)(esbuild@0.28.1)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@nuxt/devtools-kit': 3.4.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/kit': 4.5.2(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + consola: 3.4.2 + defu: 6.1.7 + fontless: 0.2.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + h3: 1.15.11 + magic-regexp: 0.10.0 + ofetch: 1.5.1 + pathe: 2.0.3 + sirv: 3.0.2 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unifont: 0.7.4 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@farmfe/core' + - '@netlify/blobs' + - '@planetscale/database' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bun-types-no-globals + - db0 + - esbuild + - idb-keyval + - ioredis + - magic-string + - magicast + - oxc-parser + - rolldown + - rollup + - unloader + - uploadthing + - vite + - webpack + + '@nuxt/icon@2.4.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@iconify/collections': 1.0.720 + '@iconify/types': 2.0.0 + '@iconify/utils': 3.1.4 + '@iconify/vue': 5.0.1(vue@3.5.41(typescript@6.0.3)) + '@nuxt/devtools-kit': 3.4.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/kit': 4.5.2(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + consola: 3.4.2 + local-pkg: 1.2.1 + mlly: 1.8.2 + ohash: 2.0.11 + picomatch: 4.0.5 + std-env: 4.2.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + - vite + - vue + + '@nuxt/kit@3.21.11(magicast@0.5.4)': + dependencies: + c12: 3.3.4(magicast@0.5.4) + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.1.2 + exsolve: 1.1.1 + ignore: 7.0.6 + jiti: 2.7.0 + klona: 2.0.6 + knitwork: 1.3.0 + mlly: 1.8.2 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.3.1 + rc9: 3.0.1 + scule: 1.3.0 + semver: 7.8.5 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unctx: 2.5.0 + untyped: 2.0.0 + transitivePeerDependencies: + - magicast + + '@nuxt/kit@4.5.2(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))': + dependencies: + c12: 3.3.4(magicast@0.5.4) + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.1.2 + exsolve: 1.1.1 + ignore: 7.0.6 + jiti: 2.7.0 + klona: 2.0.6 + mlly: 1.8.2 + nostics: 1.2.0 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.3.1 + rc9: 3.0.1 + scule: 1.3.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unctx: 3.0.0(magic-string@0.30.21)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + untyped: 2.0.0 + verkit: 0.3.2 + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + + '@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))': + dependencies: + c12: 3.3.4(magicast@0.5.4) + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.1.2 + exsolve: 1.1.1 + ignore: 7.0.6 + jiti: 2.7.0 + klona: 2.0.6 + mlly: 1.8.2 + nostics: 1.2.0 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.3.1 + rc9: 3.0.1 + scule: 1.3.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unctx: 3.0.0(magic-string@1.1.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + untyped: 2.0.0 + verkit: 0.3.2 + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + + '@nuxt/nitro-server@4.5.2(467e40c8b12fd96d762b2d5481a36d99)': + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@unhead/vue': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + '@vue/shared': 3.5.41 + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + devalue: 5.9.0 + errx: 0.1.2 + escape-string-regexp: 5.0.0 + exsolve: 1.1.1 + h3: 1.15.11 + impound: 1.1.6(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + klona: 2.0.6 + mocked-exports: 0.1.1 + nitropack: 2.13.4(rolldown@1.2.3)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + nostics: 1.2.0 + nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0) + nypm: 0.6.9 + ohash: 2.0.11 + pathe: 2.0.3 + rou3: 0.9.1 + std-env: 4.2.0 + ufo: 1.6.4 + unctx: 3.0.0(magic-string@1.1.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)) + vue: 3.5.41(typescript@6.0.3) + vue-bundle-renderer: 2.3.1 + vue-devtools-stub: 0.1.0 + optionalDependencies: + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@libsql/client' + - '@netlify/blobs' + - '@oxc-project/types' + - '@parcel/watcher' + - '@planetscale/database' + - '@rspack/core' + - '@unhead/cli' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools-kit' + - aws4fetch + - bare-abort-controller + - bare-buffer + - better-sqlite3 + - bun-types-no-globals + - db0 + - drizzle-orm + - encoding + - esbuild + - idb-keyval + - ioredis + - lightningcss + - magic-string + - magicast + - mysql2 + - oxc-parser + - react-native-b4a + - rolldown + - rollup + - sqlite3 + - srvx + - supports-color + - typescript + - unloader + - unplugin + - uploadthing + - vite + - webpack + - xml2js + + '@nuxt/schema@4.5.2': + dependencies: + '@vue/shared': 3.5.41 + defu: 6.1.7 + nostics: 1.2.0 + pathe: 2.0.3 + pkg-types: 2.3.1 + std-env: 4.2.0 + + '@nuxt/telemetry@2.8.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))': + dependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + citty: 0.2.2 + consola: 3.4.2 + ofetch: 2.0.0-alpha.3 + rc9: 3.0.1 + std-env: 4.2.0 + + '@nuxt/test-utils@4.1.0(@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(happy-dom@20.11.2)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vitest@4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))': + dependencies: + '@clack/prompts': 1.7.0 + '@nuxt/devtools-kit': 2.7.0(magicast@0.5.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/kit': 3.21.11(magicast@0.5.4) + c12: 3.3.4(magicast@0.5.4) + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + estree-walker: 3.0.3 + exsolve: 1.1.1 + fake-indexeddb: 6.2.5 + get-port-please: 3.2.0 + h3: 1.15.11 + local-pkg: 1.2.1 + magic-string: 1.1.0 + node-fetch-native: 1.6.7 + node-mock-http: 1.0.5 + nypm: 0.6.9 + ofetch: 1.5.1 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + radix3: 1.1.2 + scule: 1.3.0 + std-env: 4.2.0 + tinyexec: 1.3.0 + ufo: 1.6.4 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + vitest-environment-nuxt: 2.0.0(@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(happy-dom@20.11.2)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vitest@4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + vue: 3.5.41(typescript@6.0.3) + optionalDependencies: + '@vue/test-utils': 2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)) + happy-dom: 20.11.2 + vitest: 4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - magicast + - rolldown + - rollup + - typescript + - unloader + - vite + - webpack + + '@nuxt/ui@4.10.0(f4346459f3b2557ba8fb68083f75b24a)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@iconify/vue': 5.0.1(vue@3.5.41(typescript@6.0.3)) + '@nuxt/fonts': 0.14.0(db0@0.3.4)(esbuild@0.28.1)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/icon': 2.4.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + '@nuxt/kit': 4.5.2(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@nuxt/schema': 4.5.2 + '@nuxtjs/color-mode': 4.0.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@standard-schema/spec': 1.1.0 + '@tailwindcss/postcss': 4.3.3 + '@tailwindcss/vite': 4.3.3(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@tanstack/vue-table': 8.21.3(vue@3.5.41(typescript@6.0.3)) + '@tanstack/vue-virtual': 3.13.35(vue@3.5.41(typescript@6.0.3)) + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/extension-bubble-menu': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-code': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-collaboration': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32) + '@tiptap/extension-drag-handle': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/extension-collaboration@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32))(@tiptap/extension-node-range@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)) + '@tiptap/extension-drag-handle-vue-3': 3.29.2(@tiptap/extension-drag-handle@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/extension-collaboration@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32))(@tiptap/extension-node-range@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)))(@tiptap/pm@3.29.2)(@tiptap/vue-3@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(vue@3.5.41(typescript@6.0.3)))(vue@3.5.41(typescript@6.0.3)) + '@tiptap/extension-floating-menu': 3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-horizontal-rule': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-image': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-mention': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/suggestion@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-node-range': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-placeholder': 3.29.2(@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/markdown': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + '@tiptap/starter-kit': 3.29.2 + '@tiptap/suggestion': 3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/vue-3': 3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(vue@3.5.41(typescript@6.0.3)) + '@unhead/vue': 2.1.17(vue@3.5.41(typescript@6.0.3)) + '@vueuse/core': 14.4.0(vue@3.5.41(typescript@6.0.3)) + '@vueuse/integrations': 14.4.0(change-case@5.4.4)(fuse.js@7.5.0)(jwt-decode@4.0.0)(vue@3.5.41(typescript@6.0.3)) + '@vueuse/shared': 14.4.0(vue@3.5.41(typescript@6.0.3)) + colortranslator: 5.0.0 + consola: 3.4.2 + defu: 6.1.7 + embla-carousel-auto-height: 8.6.0(embla-carousel@8.6.0) + embla-carousel-auto-scroll: 8.6.0(embla-carousel@8.6.0) + embla-carousel-autoplay: 8.6.0(embla-carousel@8.6.0) + embla-carousel-class-names: 8.6.0(embla-carousel@8.6.0) + embla-carousel-fade: 8.6.0(embla-carousel@8.6.0) + embla-carousel-vue: 8.6.0(vue@3.5.41(typescript@6.0.3)) + embla-carousel-wheel-gestures: 8.1.0(embla-carousel@8.6.0) + fuse.js: 7.5.0 + hookable: 6.1.1 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.2 + motion-v: 2.3.0(@vueuse/core@14.4.0(vue@3.5.41(typescript@6.0.3)))(vue@3.5.41(typescript@6.0.3)) + ohash: 2.0.11 + pathe: 2.0.3 + reka-ui: 2.10.1(vue@3.5.41(typescript@6.0.3)) + scule: 1.3.0 + tailwind-merge: 3.6.0 + tailwind-variants: 3.3.1(tailwind-merge@3.6.0)(tailwindcss@4.3.3) + tailwindcss: 4.3.3 + tinyglobby: 0.2.17 + typescript: 6.0.3 + ufo: 1.6.4 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-auto-import: 21.1.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))(@vueuse/core@14.4.0(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-vue-components: 32.1.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + vaul-vue: 0.4.1(reka-ui@2.10.1(vue@3.5.41(typescript@6.0.3)))(vue@3.5.41(typescript@6.0.3)) + vue-component-type-helpers: 3.3.9 + optionalDependencies: + '@internationalized/date': 3.12.3 + '@internationalized/number': 3.6.7 + vue-router: 5.2.0(@vue/compiler-sfc@3.5.41)(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@emotion/is-prop-valid' + - '@farmfe/core' + - '@netlify/blobs' + - '@planetscale/database' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vue/composition-api' + - async-validator + - aws4fetch + - axios + - bun-types-no-globals + - change-case + - db0 + - drauu + - embla-carousel + - esbuild + - focus-trap + - idb-keyval + - ioredis + - jwt-decode + - magicast + - nprogress + - oxc-parser + - qrcode + - react + - react-dom + - rolldown + - rollup + - sortablejs + - universal-cookie + - unloader + - uploadthing + - vite + - vue + - webpack + + '@nuxt/vite-builder@4.5.2(55748b195e817d1cd0e6036ca1cd0f8f)': + dependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@vitejs/plugin-vue': 6.0.8(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + '@vitejs/plugin-vue-jsx': 5.1.6(supports-color@10.2.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + autoprefixer: 10.5.4(postcss@8.5.26) + consola: 3.4.2 + cssnano: 8.0.4(postcss@8.5.26) + defu: 6.1.7 + escape-string-regexp: 5.0.0 + exsolve: 1.1.1 + generic-names: 4.0.0 + get-port-please: 3.2.0 + jiti: 2.7.0 + js-tokens: 10.0.0 + knitwork: 1.3.0 + mlly: 1.8.2 + mocked-exports: 0.1.1 + nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0) + nypm: 0.6.9 + pathe: 2.0.3 + pkg-types: 2.3.1 + postcss: 8.5.26 + rolldown-string: 0.3.1(rolldown@1.2.3) + seroval: 1.6.2 + std-env: 4.2.0 + ufo: 1.6.4 + unenv: 2.0.0-rc.24 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vite-node: 6.0.0(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vite-plugin-checker: 0.14.5(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(optionator@0.9.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) + vue-bundle-renderer: 2.3.1 + optionalDependencies: + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) + rolldown: 1.2.3 + rollup-plugin-visualizer: 7.0.1(rolldown@1.2.3)(rollup@4.62.4) + transitivePeerDependencies: + - '@biomejs/biome' + - '@types/node' + - '@vitejs/devtools' + - esbuild + - eslint + - less + - magic-string + - magicast + - meow + - optionator + - oxc-parser + - oxlint + - sass + - sass-embedded + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - unplugin + - vue-tsc + - yaml + + '@nuxtjs/color-mode@4.0.1(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))': + dependencies: + '@nuxt/kit': 4.5.2(magic-string@0.30.21)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + exsolve: 1.1.1 + pathe: 2.0.3 + pkg-types: 2.3.1 + semver: 7.8.5 + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + + '@one-ini/wasm@0.1.1': {} + + '@oxc-project/types@0.143.0': {} + + '@parcel/watcher-wasm@2.6.0': + dependencies: + is-glob: 4.0.3 + picomatch: 4.0.5 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.29': {} + + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.7.0': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + + '@rolldown/binding-android-arm64@1.2.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.3': + optional: true + + '@rolldown/binding-darwin-x64@1.2.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.3': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.3': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@rollup/plugin-alias@6.0.0(rollup@4.62.4)': + optionalDependencies: + rollup: 4.62.4 + + '@rollup/plugin-commonjs@29.0.3(rollup@4.62.4)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@4.0.5) + is-reference: 1.2.1 + magic-string: 0.30.21 + picomatch: 4.0.5 + optionalDependencies: + rollup: 4.62.4 + + '@rollup/plugin-inject@5.0.5(rollup@4.62.4)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + estree-walker: 2.0.2 + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.62.4 + + '@rollup/plugin-json@6.1.0(rollup@4.62.4)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + optionalDependencies: + rollup: 4.62.4 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.4)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.12 + optionalDependencies: + rollup: 4.62.4 + + '@rollup/plugin-replace@6.0.3(rollup@4.62.4)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.62.4 + + '@rollup/plugin-terser@1.0.0(rollup@4.62.4)': + dependencies: + serialize-javascript: 7.0.7 + smob: 1.6.2 + terser: 5.49.2 + optionalDependencies: + rollup: 4.62.4 + + '@rollup/pluginutils@5.4.0(rollup@4.62.4)': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.5 + optionalDependencies: + rollup: 4.62.4 + + '@rollup/rollup-android-arm-eabi@4.62.4': + optional: true + + '@rollup/rollup-android-arm64@4.62.4': + optional: true + + '@rollup/rollup-darwin-arm64@4.62.4': + optional: true + + '@rollup/rollup-darwin-x64@4.62.4': + optional: true + + '@rollup/rollup-freebsd-arm64@4.62.4': + optional: true + + '@rollup/rollup-freebsd-x64@4.62.4': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.62.4': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.62.4': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.62.4': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.62.4': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.62.4': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.62.4': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.62.4': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.62.4': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.62.4': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.62.4': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.62.4': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.62.4': + optional: true + + '@rollup/rollup-linux-x64-musl@4.62.4': + optional: true + + '@rollup/rollup-openbsd-x64@4.62.4': + optional: true + + '@rollup/rollup-openharmony-arm64@4.62.4': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.62.4': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.62.4': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.62.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.62.4': + optional: true + + '@simple-git/args-pathspec@1.0.3': {} + + '@simple-git/argv-parser@1.1.1': + dependencies: + '@simple-git/args-pathspec': 1.0.3 + + '@sindresorhus/base62@1.0.0': {} + + '@sindresorhus/is@7.2.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@speed-highlight/core@1.2.23': {} + + '@standard-schema/spec@1.1.0': {} + + '@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@typescript-eslint/types': 8.66.0 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + estraverse: 5.3.0 + picomatch: 4.0.5 + + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.3.3': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.24.5 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.3.3 + + '@tailwindcss/oxide-android-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide@4.3.3': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/postcss@4.3.3': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + postcss: 8.5.26 + tailwindcss: 4.3.3 + + '@tailwindcss/vite@4.3.3(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + + '@tanstack/table-core@8.21.3': {} + + '@tanstack/virtual-core@3.17.7': {} + + '@tanstack/vue-table@8.21.3(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@tanstack/table-core': 8.21.3 + vue: 3.5.41(typescript@6.0.3) + + '@tanstack/vue-virtual@3.13.35(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@tanstack/virtual-core': 3.17.7 + vue: 3.5.41(typescript@6.0.3) + + '@tiptap/core@3.29.2(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-blockquote@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-bold@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-bubble-menu@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-bullet-list@3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extension-list': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-code-block@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-code@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-collaboration@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + '@tiptap/y-tiptap': 3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) + yjs: 13.6.32 + + '@tiptap/extension-document@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-drag-handle-vue-3@3.29.2(@tiptap/extension-drag-handle@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/extension-collaboration@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32))(@tiptap/extension-node-range@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)))(@tiptap/pm@3.29.2)(@tiptap/vue-3@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(vue@3.5.41(typescript@6.0.3)))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@tiptap/extension-drag-handle': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/extension-collaboration@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32))(@tiptap/extension-node-range@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)) + '@tiptap/pm': 3.29.2 + '@tiptap/vue-3': 3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(vue@3.5.41(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) + + '@tiptap/extension-drag-handle@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/extension-collaboration@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32))(@tiptap/extension-node-range@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/extension-collaboration': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32) + '@tiptap/extension-node-range': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + '@tiptap/y-tiptap': 3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) + + '@tiptap/extension-dropcursor@3.29.2(@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extensions': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-floating-menu@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-gapcursor@3.29.2(@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extensions': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-hard-break@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-heading@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-horizontal-rule@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-image@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-italic@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-link@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + linkifyjs: 4.3.3 + + '@tiptap/extension-list-item@3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extension-list': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-list-keymap@3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extension-list': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-mention@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(@tiptap/suggestion@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + '@tiptap/suggestion': 3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-node-range@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/extension-ordered-list@3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extension-list': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-paragraph@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-placeholder@3.29.2(@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/extensions': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/extension-strike@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-text@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extension-underline@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + + '@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/markdown@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + marked: 17.0.6 + + '@tiptap/pm@3.29.2': + dependencies: + prosemirror-changeset: 2.4.1 + prosemirror-commands: 1.7.2 + prosemirror-dropcursor: 1.8.3 + prosemirror-gapcursor: 1.4.1 + prosemirror-history: 1.5.0 + prosemirror-inputrules: 1.5.1 + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.11 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.4 + prosemirror-tables: 1.8.5 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.42.2 + + '@tiptap/starter-kit@3.29.2': + dependencies: + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/extension-blockquote': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-bold': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-bullet-list': 3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-code': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-code-block': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-document': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-dropcursor': 3.29.2(@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-gapcursor': 3.29.2(@tiptap/extensions@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-hard-break': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-heading': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-horizontal-rule': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-italic': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-link': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-list': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-list-item': 3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-list-keymap': 3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-ordered-list': 3.29.2(@tiptap/extension-list@3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)) + '@tiptap/extension-paragraph': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-strike': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-text': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extension-underline': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2)) + '@tiptap/extensions': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/suggestion@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + + '@tiptap/vue-3@3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2)(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.29.2(@tiptap/pm@3.29.2) + '@tiptap/pm': 3.29.2 + vue: 3.5.41(typescript@6.0.3) + optionalDependencies: + '@tiptap/extension-bubble-menu': 3.29.2(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + '@tiptap/extension-floating-menu': 3.29.2(@floating-ui/dom@1.8.0)(@tiptap/core@3.29.2(@tiptap/pm@3.29.2))(@tiptap/pm@3.29.2) + + '@tiptap/y-tiptap@3.0.8(prosemirror-model@1.25.11)(prosemirror-state@1.4.4)(prosemirror-view@1.42.2)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)': + dependencies: + lib0: 0.2.117 + prosemirror-model: 1.25.11 + prosemirror-state: 1.4.4 + prosemirror-view: 1.42.2 + y-protocols: 1.0.7(yjs@13.6.32) + yjs: 13.6.32 + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.9': {} + + '@types/jsesc@2.5.1': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@26.2.0': + dependencies: + undici-types: 8.3.0 + + '@types/resolve@1.20.2': {} + + '@types/web-bluetooth@0.0.20': {} + + '@types/web-bluetooth@0.0.21': {} + + '@types/whatwg-mimetype@3.0.2': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 26.2.0 + + '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.66.0 + '@typescript-eslint/type-utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.66.0 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + ignore: 7.0.6 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.66.0 + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/typescript-estree': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.66.0 + debug: 4.4.3(supports-color@10.2.2) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.66.0(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) + '@typescript-eslint/types': 8.66.0 + debug: 4.4.3(supports-color@10.2.2) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.66.0': + dependencies: + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/visitor-keys': 8.66.0 + + '@typescript-eslint/tsconfig-utils@8.66.0(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 + + '@typescript-eslint/type-utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/typescript-estree': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + debug: 4.4.3(supports-color@10.2.2) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.66.0': {} + + '@typescript-eslint/typescript-estree@8.66.0(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/project-service': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/visitor-keys': 8.66.0 + debug: 4.4.3(supports-color@10.2.2) + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@typescript-eslint/scope-manager': 8.66.0 + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/typescript-estree': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.66.0': + dependencies: + '@typescript-eslint/types': 8.66.0 + eslint-visitor-keys: 5.0.1 + + '@unhead/bundler@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(rolldown@1.2.3)(rollup@4.62.4)(unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + magic-string: 1.1.0 + oxc-walker: 1.1.1(@oxc-project/types@0.143.0)(rolldown@1.2.3) + unhead: 3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + optionalDependencies: + esbuild: 0.28.1 + lightningcss: 1.33.0 + rolldown: 1.2.3 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@oxc-project/types' + - '@rspack/core' + - bun-types-no-globals + - rollup + - unloader + + '@unhead/vue@2.1.17(vue@3.5.41(typescript@6.0.3))': + dependencies: + hookable: 6.1.1 + unhead: 2.1.17 + vue: 3.5.41(typescript@6.0.3) + + '@unhead/vue@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@unhead/bundler': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(rolldown@1.2.3)(rollup@4.62.4)(unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + hookable: 6.1.1 + unhead: 3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + vue: 3.5.41(typescript@6.0.3) + optionalDependencies: + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@oxc-project/types' + - '@rspack/core' + - '@unhead/cli' + - '@vitejs/devtools-kit' + - bun-types-no-globals + - esbuild + - lightningcss + - oxc-parser + - rolldown + - rollup + - unloader + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + optional: true + + '@vercel/nft@1.10.2(rollup@4.62.4)(supports-color@10.2.2)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.3(supports-color@10.2.2) + '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + acorn: 8.18.0 + acorn-import-attributes: 1.9.5(acorn@8.18.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 13.0.6 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.5 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vitejs/plugin-vue-jsx@5.1.6(supports-color@10.2.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) + '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@rolldown/pluginutils': 1.0.1 + '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vue: 3.5.41(typescript@6.0.3) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@6.0.8(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vue: 3.5.41(typescript@6.0.3) + + '@vitest/expect@4.1.10': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + chai: 6.2.2 + tinyrainbow: 3.1.1 + + '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + + '@vitest/pretty-format@4.1.10': + dependencies: + tinyrainbow: 3.1.1 + + '@vitest/runner@4.1.10': + dependencies: + '@vitest/utils': 4.1.10 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.10': {} + + '@vitest/utils@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.1 + + '@volar/language-core@2.4.28': + dependencies: + '@volar/source-map': 2.4.28 + + '@volar/source-map@2.4.28': {} + + '@volar/typescript@2.4.28(typescript@6.0.3)': + dependencies: + '@volar/language-core': 2.4.28 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + optionalDependencies: + typescript: 6.0.3 + + '@vue-macros/common@3.1.4(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@vue/compiler-sfc': 3.5.41 + ast-kit: 2.2.0 + local-pkg: 1.2.1 + magic-string-ast: 1.0.3 + unplugin-utils: 0.3.2 + optionalDependencies: + vue: 3.5.41(typescript@6.0.3) + + '@vue/babel-helper-vue-transform-on@2.0.1': {} + + '@vue/babel-plugin-jsx@2.0.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + '@babel/helper-module-imports': 7.29.7(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2)) + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8(supports-color@10.2.2) + '@babel/types': 7.29.8 + '@vue/babel-helper-vue-transform-on': 2.0.1 + '@vue/babel-plugin-resolve-type': 2.0.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@vue/shared': 3.5.41 + optionalDependencies: + '@babel/core': 7.29.7(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@2.0.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-module-imports': 7.29.7(supports-color@10.2.2) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/parser': 7.29.8 + '@vue/compiler-sfc': 3.5.41 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.41': + dependencies: + '@babel/parser': 7.29.8 + '@vue/shared': 3.5.41 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.41': + dependencies: + '@vue/compiler-core': 3.5.41 + '@vue/shared': 3.5.41 + + '@vue/compiler-sfc@3.5.41': + dependencies: + '@babel/parser': 7.29.8 + '@vue/compiler-core': 3.5.41 + '@vue/compiler-dom': 3.5.41 + '@vue/compiler-ssr': 3.5.41 + '@vue/shared': 3.5.41 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.26 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.41': + dependencies: + '@vue/compiler-dom': 3.5.41 + '@vue/shared': 3.5.41 + + '@vue/devtools-api@8.2.1': + dependencies: + '@vue/devtools-kit': 8.2.1 + + '@vue/devtools-core@8.2.1(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@vue/devtools-kit': 8.2.1 + '@vue/devtools-shared': 8.2.1 + vue: 3.5.41(typescript@6.0.3) + + '@vue/devtools-kit@8.2.1': + dependencies: + '@vue/devtools-shared': 8.2.1 + birpc: 2.9.0 + hookable: 5.5.3 + perfect-debounce: 2.1.0 + + '@vue/devtools-shared@8.2.1': {} + + '@vue/language-core@3.3.9': + dependencies: + '@volar/language-core': 2.4.28 + '@vue/compiler-dom': 3.5.41 + '@vue/shared': 3.5.41 + alien-signals: 3.2.1 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.5 + + '@vue/reactivity@3.5.41': + dependencies: + '@vue/shared': 3.5.41 + + '@vue/runtime-core@3.5.41': + dependencies: + '@vue/reactivity': 3.5.41 + '@vue/shared': 3.5.41 + + '@vue/runtime-dom@3.5.41': + dependencies: + '@vue/reactivity': 3.5.41 + '@vue/runtime-core': 3.5.41 + '@vue/shared': 3.5.41 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.41': + dependencies: + '@vue/compiler-ssr': 3.5.41 + '@vue/runtime-dom': 3.5.41 + '@vue/shared': 3.5.41 + + '@vue/shared@3.5.41': {} + + '@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@vue/compiler-dom': 3.5.41 + js-beautify: 1.15.4 + vue: 3.5.41(typescript@6.0.3) + vue-component-type-helpers: 3.3.9 + optionalDependencies: + '@vue/server-renderer': 3.5.41 + + '@vueuse/core@10.11.1(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.11.1 + '@vueuse/shared': 10.11.1(vue@3.5.41(typescript@6.0.3)) + vue-demi: 0.14.10(vue@3.5.41(typescript@6.0.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/core@14.4.0(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.4.0 + '@vueuse/shared': 14.4.0(vue@3.5.41(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) + + '@vueuse/integrations@14.4.0(change-case@5.4.4)(fuse.js@7.5.0)(jwt-decode@4.0.0)(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@vueuse/core': 14.4.0(vue@3.5.41(typescript@6.0.3)) + '@vueuse/shared': 14.4.0(vue@3.5.41(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) + optionalDependencies: + change-case: 5.4.4 + fuse.js: 7.5.0 + jwt-decode: 4.0.0 + + '@vueuse/metadata@10.11.1': {} + + '@vueuse/metadata@14.4.0': {} + + '@vueuse/nuxt@14.4.0(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0))(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vue@3.5.41(typescript@6.0.3))': + dependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@vueuse/core': 14.4.0(vue@3.5.41(typescript@6.0.3)) + '@vueuse/metadata': 14.4.0 + local-pkg: 1.2.1 + nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0) + vue: 3.5.41(typescript@6.0.3) + transitivePeerDependencies: + - magic-string + - magicast + - oxc-parser + - rolldown + - unplugin + + '@vueuse/shared@10.11.1(vue@3.5.41(typescript@6.0.3))': + dependencies: + vue-demi: 0.14.10(vue@3.5.41(typescript@6.0.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/shared@14.4.0(vue@3.5.41(typescript@6.0.3))': + dependencies: + vue: 3.5.41(typescript@6.0.3) + + abbrev@2.0.0: {} + + abbrev@3.0.1: {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + acorn-import-attributes@1.9.5(acorn@8.18.0): + dependencies: + acorn: 8.18.0 + + acorn-jsx@5.3.2(acorn@8.18.0): + dependencies: + acorn: 8.18.0 + + acorn@8.18.0: {} + + agent-base@7.1.4: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + alien-signals@3.2.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + ansis@4.3.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.18.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.2.0 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + are-docs-informative@0.0.2: {} + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + aria-query@5.3.2: {} + + assertion-error@2.0.1: {} + + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.29.8 + pathe: 2.0.3 + + ast-walker-scope@0.9.0: + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + ast-kit: 2.2.0 + + async-sema@3.1.1: {} + + async@3.2.6: {} + + autoprefixer@10.5.4(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + caniuse-lite: 1.0.30001809 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + b4a@1.8.1: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + bare-events@2.9.1: {} + + bare-fs@4.8.0: + dependencies: + bare-events: 2.9.1 + bare-path: 3.1.1 + bare-stream: 2.13.3(bare-events@2.9.1) + bare-url: 2.5.1 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-path@3.1.1: {} + + bare-stream@2.13.3(bare-events@2.9.1): + dependencies: + b4a: 1.8.1 + streamx: 2.28.0 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.9.1 + transitivePeerDependencies: + - react-native-b4a + + bare-url@2.5.1: + dependencies: + bare-path: 3.1.1 + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.11.12: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + birpc@2.9.0: {} + + birpc@4.0.0: {} + + boolbase@1.0.0: {} + + brace-expansion@2.1.4: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.9: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.7: + dependencies: + baseline-browser-mapping: 2.11.12 + caniuse-lite: 1.0.30001809 + electron-to-chromium: 1.5.402 + node-releases: 2.0.53 + update-browserslist-db: 1.3.0(browserslist@4.28.7) + + buffer-crc32@1.0.0: {} + + buffer-from@1.1.2: {} + + buffer-image-size@0.6.4: + dependencies: + '@types/node': 26.2.0 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtin-modules@5.3.0: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + c12@3.3.4(magicast@0.5.4): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.4.2 + exsolve: 1.1.1 + giget: 3.3.1 + jiti: 2.7.0 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.1 + rc9: 3.0.1 + optionalDependencies: + magicast: 0.5.4 + + cac@7.0.0: {} + + caniuse-api@4.0.0: + dependencies: + browserslist: 4.28.7 + caniuse-lite: 1.0.30001809 + + caniuse-lite@1.0.30001809: {} + + chai@6.2.2: {} + + change-case@5.4.4: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + chownr@3.0.0: {} + + ci-info@4.4.0: {} + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + citty@0.2.2: {} + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + cluster-key-slot@1.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colortranslator@5.0.0: {} + + commander@10.0.1: {} + + commander@11.1.0: {} + + commander@2.20.3: {} + + comment-parser@1.4.7: {} + + comment-parser@1.4.8: {} + + commondir@1.0.1: {} + + compatx@0.2.0: {} + + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + consola@3.4.2: {} + + convert-hrtime@5.0.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.3: {} + + cookie-es@2.0.1: {} + + cookie-es@3.1.1: {} + + core-js-compat@3.50.0: + dependencies: + browserslist: 4.28.7 + + core-util-is@1.0.3: {} + + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + + croner@10.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crossws@0.4.10(srvx@0.11.22): + optionalDependencies: + srvx: 0.11.22 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@8.0.4(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + cssnano-utils: 6.0.2(postcss@8.5.26) + postcss: 8.5.26 + postcss-calc: 10.1.1(postcss@8.5.26) + postcss-colormin: 8.0.2(postcss@8.5.26) + postcss-convert-values: 8.0.2(postcss@8.5.26) + postcss-discard-comments: 8.0.2(postcss@8.5.26) + postcss-discard-duplicates: 8.0.2(postcss@8.5.26) + postcss-discard-empty: 8.0.2(postcss@8.5.26) + postcss-discard-overridden: 8.0.2(postcss@8.5.26) + postcss-merge-longhand: 8.0.2(postcss@8.5.26) + postcss-merge-rules: 8.0.2(postcss@8.5.26) + postcss-minify-font-values: 8.0.2(postcss@8.5.26) + postcss-minify-gradients: 8.0.2(postcss@8.5.26) + postcss-minify-params: 8.0.2(postcss@8.5.26) + postcss-minify-selectors: 8.0.3(postcss@8.5.26) + postcss-normalize-charset: 8.0.2(postcss@8.5.26) + postcss-normalize-display-values: 8.0.2(postcss@8.5.26) + postcss-normalize-positions: 8.0.2(postcss@8.5.26) + postcss-normalize-repeat-style: 8.0.2(postcss@8.5.26) + postcss-normalize-string: 8.0.2(postcss@8.5.26) + postcss-normalize-timing-functions: 8.0.2(postcss@8.5.26) + postcss-normalize-unicode: 8.0.2(postcss@8.5.26) + postcss-normalize-url: 8.0.2(postcss@8.5.26) + postcss-normalize-whitespace: 8.0.2(postcss@8.5.26) + postcss-ordered-values: 8.0.2(postcss@8.5.26) + postcss-reduce-initial: 8.0.2(postcss@8.5.26) + postcss-reduce-transforms: 8.0.2(postcss@8.5.26) + postcss-svgo: 8.0.3(postcss@8.5.26) + postcss-unique-selectors: 8.0.2(postcss@8.5.26) + + cssnano-utils@6.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + + cssnano@8.0.4(postcss@8.5.26): + dependencies: + cssnano-preset-default: 8.0.4(postcss@8.5.26) + lilconfig: 3.1.3 + postcss: 8.5.26 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.2.3: {} + + db0@0.3.4: {} + + debug@4.4.3(supports-color@10.2.2): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + defu@6.1.7: {} + + denque@2.1.0: {} + + depd@2.0.0: {} + + destr@2.0.5: {} + + detect-indent@7.0.2: {} + + detect-libc@2.1.2: {} + + devalue@5.9.0: {} + + devframe@0.8.2(cac@7.0.0)(srvx@0.11.22): + dependencies: + '@standard-schema/spec': 1.1.0 + birpc: 4.0.0 + crossws: 0.4.10(srvx@0.11.22) + destr: 2.0.5 + h3: 2.0.1-rc.26(crossws@0.4.10(srvx@0.11.22)) + mrmime: 2.0.1 + nostics: 1.2.0 + pathe: 2.0.3 + ufo: 1.6.4 + optionalDependencies: + cac: 7.0.0 + transitivePeerDependencies: + - srvx + + diff@8.0.4: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-prop@10.2.0: + dependencies: + type-fest: 5.8.0 + + dotenv@17.4.2: {} + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + editorconfig@1.0.7: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.9 + semver: 7.8.5 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.402: {} + + embla-carousel-auto-height@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-auto-scroll@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-autoplay@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-class-names@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-fade@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-vue@8.6.0(vue@3.5.41(typescript@6.0.3)): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + vue: 3.5.41(typescript@6.0.3) + + embla-carousel-wheel-gestures@8.1.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + wheel-gestures: 2.2.48 + + embla-carousel@8.6.0: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.24.5: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + entities@4.5.0: {} + + entities@7.0.1: {} + + error-stack-parser-es@1.0.5: {} + + error-stack-parser-es@2.0.1: {} + + errx@0.1.2: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.3.1: {} + + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-config-flat-gitignore@2.3.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + '@eslint/compat': 2.1.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + + eslint-flat-config-utils@3.2.0: + dependencies: + '@eslint/config-helpers': 0.5.5 + pathe: 2.0.3 + + eslint-import-context@0.1.9(unrs-resolver@1.12.2): + dependencies: + get-tsconfig: 4.14.1 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.12.2 + + eslint-merge-processors@2.0.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + + eslint-plugin-import-lite@0.6.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + + eslint-plugin-import-x@4.17.1(@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2): + dependencies: + '@typescript-eslint/types': 8.66.0 + comment-parser: 1.4.8 + debug: 4.4.3(supports-color@10.2.2) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-import-context: 0.1.9(unrs-resolver@1.12.2) + is-glob: 4.0.3 + minimatch: 10.2.6 + semver: 7.8.5 + stable-hash-x: 0.2.0 + unrs-resolver: 1.12.2 + optionalDependencies: + '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + transitivePeerDependencies: + - supports-color + + eslint-plugin-jsdoc@63.3.3(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2): + dependencies: + '@es-joy/jsdoccomment': 0.91.0 + '@es-joy/resolve.exports': 1.2.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.7 + debug: 4.4.3(supports-color@10.2.2) + escape-string-regexp: 4.0.0 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + espree: 11.2.0 + esquery: 1.7.0 + html-entities: 2.6.0 + object-deep-merge: 2.0.1 + parse-imports-exports: 0.2.4 + semver: 7.8.5 + spdx-expression-parse: 5.0.0 + to-valid-identifier: 1.0.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-regexp@3.1.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@eslint-community/regexpp': 4.12.2 + comment-parser: 1.4.8 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + jsdoc-type-pratt-parser: 7.3.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 + + eslint-plugin-unicorn@73.0.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@eslint/css-tree': 4.0.5 + browserslist: 4.28.7 + change-case: 5.4.4 + ci-info: 4.4.0 + core-js-compat: 3.50.0 + detect-indent: 7.0.2 + entities: 4.5.0 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + find-up-simple: 1.0.1 + globals: 17.9.0 + indent-string: 5.0.0 + is-builtin-module: 5.0.0 + is-identifier: 1.1.0 + pluralize: 8.0.0 + quote-js-string: 0.1.0 + regjsparser: 0.13.2 + reserved-identifiers: 1.2.0 + semver: 7.8.5 + strip-indent: 4.1.1 + yaml: 2.9.0 + + eslint-plugin-vue@10.10.0(@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)))(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(vue-eslint-parser@10.4.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 7.1.5 + semver: 7.8.5 + vue-eslint-parser: 10.4.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) + xml-name-validator: 5.0.0 + optionalDependencies: + '@stylistic/eslint-plugin': 5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + + eslint-plugin-vuejs-accessibility@2.5.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(globals@17.9.0)(supports-color@10.2.2): + dependencies: + aria-query: 5.3.2 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + globals: 17.9.0 + vue-eslint-parser: 10.4.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.41)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + '@vue/compiler-sfc': 3.5.41 + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-typegen@2.3.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)): + dependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + json-schema-to-typescript-lite: 15.0.0 + ohash: 2.0.11 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5(supports-color@10.2.2) + '@eslint/config-helpers': 0.7.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.2 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@10.2.2) + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.6 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) + eslint-visitor-keys: 4.2.1 + + espree@11.2.0: + dependencies: + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) + eslint-visitor-keys: 5.0.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.9.1 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: {} + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + expect-type@1.4.0: {} + + exsolve@1.1.1: {} + + fake-indexeddb@6.2.5: {} + + fast-deep-equal@3.1.3: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-npm-meta@2.2.0: + dependencies: + cac: 7.0.0 + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + file-uri-to-path@1.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.1: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@8.0.0: + dependencies: + locate-path: 8.0.0 + unicorn-magic: 0.3.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.4 + keyv: 4.5.4 + + flatted@3.4.4: {} + + fnv1a-64@0.1.2: {} + + fontaine@0.8.0: + dependencies: + '@capsizecss/unpack': 4.0.1 + css-tree: 3.2.1 + magic-regexp: 0.10.0 + magic-string: 0.30.21 + pathe: 2.0.3 + ufo: 1.6.4 + unplugin: 2.3.11 + + fontkitten@1.0.3: + dependencies: + tiny-inflate: 1.0.3 + + fontless@0.2.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + consola: 3.4.2 + css-tree: 3.2.1 + defu: 6.1.7 + esbuild: 0.27.7 + fontaine: 0.8.0 + jiti: 2.7.0 + lightningcss: 1.33.0 + magic-string: 0.30.21 + ohash: 2.0.11 + pathe: 2.0.3 + ufo: 1.6.4 + unifont: 0.7.4 + unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)) + optionalDependencies: + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - uploadthing + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fraction.js@5.3.4: {} + + framer-motion@12.43.0: + dependencies: + motion-dom: 12.43.0 + motion-utils: 12.39.0 + tslib: 2.8.1 + + fresh@2.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function-timeout@1.0.2: {} + + fuse.js@7.5.0: {} + + fzf@0.5.2: {} + + generic-names@4.0.0: + dependencies: + loader-utils: 3.3.1 + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.6.0: {} + + get-port-please@3.2.0: {} + + get-stream@8.0.1: {} + + get-tsconfig@4.14.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + giget@3.3.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@13.0.6: + dependencies: + minimatch: 10.2.6 + minipass: 7.1.3 + path-scurry: 2.0.2 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + globals@17.9.0: {} + + globby@16.2.3: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.6 + is-path-inside: 4.0.0 + slash: 5.1.0 + unicorn-magic: 0.4.0 + + graceful-fs@4.2.11: {} + + gzip-size@7.0.0: + dependencies: + duplexer: 0.1.2 + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.5 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + h3@2.0.1-rc.26(crossws@0.4.10(srvx@0.11.22)): + dependencies: + rou3: 0.9.1 + srvx: 0.12.5 + optionalDependencies: + crossws: 0.4.10(srvx@0.11.22) + + happy-dom@20.11.2: + dependencies: + '@types/node': 26.2.0 + '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + buffer-image-size: 0.6.4 + entities: 7.0.1 + whatwg-mimetype: 3.0.0 + ws: 8.21.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hey-listen@1.0.8: {} + + hookable@5.5.3: {} + + hookable@6.1.1: {} + + html-entities@2.6.0: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-shutdown@1.2.2: {} + + https-proxy-agent@7.0.6(supports-color@10.2.2): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + httpxy@0.5.5: {} + + human-signals@5.0.0: {} + + identifier-regex@1.1.0: + dependencies: + reserved-identifiers: 1.2.0 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.6: {} + + image-meta@0.2.2: {} + + import-meta-resolve@4.2.0: {} + + impound@1.1.6(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + es-module-lexer: 2.3.1 + pathe: 2.0.3 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-utils: 0.3.2 + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - vite + - webpack + + imurmurhash@0.1.4: {} + + indent-string@5.0.0: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + ioredis@5.11.1(supports-color@10.2.2): + dependencies: + '@ioredis/commands': 1.10.0 + cluster-key-slot: 1.1.1 + debug: 4.4.3(supports-color@10.2.2) + denque: 2.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + + iron-webcrypto@1.2.1: {} + + is-builtin-module@5.0.0: + dependencies: + builtin-modules: 5.3.0 + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.4 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-identifier@1.1.0: + dependencies: + identifier-regex: 1.1.0 + super-regex: 1.1.0 + + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-module@1.0.0: {} + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.9 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isexe@4.0.0: {} + + isomorphic.js@0.2.5: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@2.7.0: {} + + js-beautify@1.15.4: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.7 + glob: 10.5.0 + js-cookie: 3.0.8 + nopt: 7.2.1 + + js-cookie@3.0.8: {} + + js-tokens@10.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + + jsdoc-type-pratt-parser@7.3.0: {} + + jsdoc-type-pratt-parser@8.0.0: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-to-typescript-lite@15.0.0: + dependencies: + '@apidevtools/json-schema-ref-parser': 14.2.1(@types/json-schema@7.0.15) + '@types/json-schema': 7.0.15 + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jwt-decode@4.0.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + klona@2.0.6: {} + + knitwork@1.3.0: {} + + launch-editor@2.14.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.10.0 + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lib0@0.2.117: + dependencies: + isomorphic.js: 0.2.5 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + 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 + + lilconfig@3.1.3: {} + + linkifyjs@4.3.3: {} + + listhen@1.10.1(srvx@0.11.22): + dependencies: + '@parcel/watcher-wasm': 2.6.0 + citty: 0.2.2 + consola: 3.4.2 + crossws: 0.4.10(srvx@0.11.22) + defu: 6.1.7 + get-port-please: 3.2.0 + h3: 1.15.11 + http-shutdown: 1.2.2 + jiti: 2.7.0 + node-forge: 1.4.0 + pathe: 2.0.3 + std-env: 4.2.0 + tinyclip: 0.1.15 + ufo: 1.6.4 + untun: 0.2.2 + uqr: 0.1.3 + transitivePeerDependencies: + - srvx + + loader-utils@3.3.1: {} + + local-pkg@1.2.1: + dependencies: + mlly: 1.8.2 + pkg-types: 2.3.1 + quansync: 0.2.11 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@8.0.0: + dependencies: + p-locate: 6.0.0 + + lodash@4.18.1: {} + + lru-cache@10.4.3: {} + + lru-cache@11.5.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-regexp@0.10.0: + dependencies: + estree-walker: 3.0.3 + magic-string: 0.30.21 + mlly: 1.8.2 + regexp-tree: 0.1.27 + type-level-regexp: 0.1.17 + ufo: 1.6.4 + unplugin: 2.3.11 + + magic-string-ast@1.0.3: + dependencies: + magic-string: 0.30.21 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magic-string@1.1.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.4: + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + source-map-js: 1.2.1 + + make-asynchronous@1.1.0: + dependencies: + p-event: 6.0.1 + type-fest: 4.41.0 + web-worker: 1.5.0 + + marked@17.0.6: {} + + mdn-data@2.0.28: {} + + mdn-data@2.27.1: {} + + mdn-data@2.29.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@4.1.0: {} + + mimic-fn@4.0.0: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.9 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.4 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.4 + + minipass@7.1.3: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + + mlly@1.8.2: + dependencies: + acorn: 8.18.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + + mocked-exports@0.1.1: {} + + motion-dom@12.43.0: + dependencies: + motion-utils: 12.39.0 + + motion-utils@12.39.0: {} + + motion-v@2.3.0(@vueuse/core@14.4.0(vue@3.5.41(typescript@6.0.3)))(vue@3.5.41(typescript@6.0.3)): + dependencies: + '@vueuse/core': 14.4.0(vue@3.5.41(typescript@6.0.3)) + framer-motion: 12.43.0 + hey-listen: 1.0.8 + motion-dom: 12.43.0 + motion-utils: 12.39.0 + vue: 3.5.41(typescript@6.0.3) + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - react + - react-dom + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.18: {} + + nanotar@0.3.0: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + nitropack@2.13.4(rolldown@1.2.3)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.2 + '@rollup/plugin-alias': 6.0.0(rollup@4.62.4) + '@rollup/plugin-commonjs': 29.0.3(rollup@4.62.4) + '@rollup/plugin-inject': 5.0.5(rollup@4.62.4) + '@rollup/plugin-json': 6.1.0(rollup@4.62.4) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.62.4) + '@rollup/plugin-replace': 6.0.3(rollup@4.62.4) + '@rollup/plugin-terser': 1.0.0(rollup@4.62.4) + '@vercel/nft': 1.10.2(rollup@4.62.4)(supports-color@10.2.2) + archiver: 7.0.1 + c12: 3.3.4(magicast@0.5.4) + chokidar: 5.0.0 + citty: 0.2.2 + compatx: 0.2.0 + confbox: 0.2.4 + consola: 3.4.2 + cookie-es: 2.0.1 + croner: 10.0.1 + crossws: 0.3.5 + db0: 0.3.4 + defu: 6.1.7 + destr: 2.0.5 + dot-prop: 10.2.0 + esbuild: 0.28.1 + escape-string-regexp: 5.0.0 + etag: 1.8.1 + exsolve: 1.1.1 + globby: 16.2.3 + gzip-size: 7.0.0 + h3: 1.15.11 + hookable: 5.5.3 + httpxy: 0.5.5 + ioredis: 5.11.1(supports-color@10.2.2) + jiti: 2.7.0 + klona: 2.0.6 + knitwork: 1.3.0 + listhen: 1.10.1(srvx@0.11.22) + magic-string: 0.30.21 + magicast: 0.5.4 + mime: 4.1.0 + mlly: 1.8.2 + node-fetch-native: 1.6.7 + node-mock-http: 1.0.5 + ofetch: 1.5.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.1 + pretty-bytes: 7.1.1 + radix3: 1.1.2 + rollup: 4.62.4 + rollup-plugin-visualizer: 7.0.1(rolldown@1.2.3)(rollup@4.62.4) + scule: 1.3.0 + semver: 7.8.5 + serve-placeholder: 2.0.2 + serve-static: 2.2.1(supports-color@10.2.2) + source-map: 0.7.6 + std-env: 4.2.0 + ufo: 1.6.4 + ultrahtml: 1.7.0 + uncrypto: 0.1.3 + unctx: 2.5.0 + unenv: 2.0.0-rc.24 + unimport: 6.4.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-utils: 0.3.2 + unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)) + untyped: 2.0.0 + unwasm: 0.5.3 + youch: 4.1.1 + youch-core: 0.3.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@libsql/client' + - '@netlify/blobs' + - '@parcel/watcher' + - '@planetscale/database' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bare-abort-controller + - bare-buffer + - better-sqlite3 + - bun-types-no-globals + - drizzle-orm + - encoding + - idb-keyval + - mysql2 + - oxc-parser + - react-native-b4a + - rolldown + - sqlite3 + - srvx + - supports-color + - unloader + - uploadthing + - vite + - webpack + + node-fetch-native@1.6.7: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-forge@1.4.0: {} + + node-gyp-build@4.8.4: {} + + node-mock-http@1.0.5: {} + + node-releases@2.0.53: {} + + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + normalize-path@3.0.0: {} + + nostics@1.2.0: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nuxt@4.5.2(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@types/node@26.2.0)(@vue/compiler-sfc@3.5.41)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.1)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.49.2)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3))(yaml@2.9.0): + dependencies: + '@dxup/nuxt': 0.5.6(esbuild@0.28.1)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@nuxt/cli': 3.37.0(@nuxt/schema@4.5.2)(cac@7.0.0)(magicast@0.5.4)(supports-color@10.2.2) + '@nuxt/devtools': 3.4.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@nuxt/nitro-server': 4.5.2(467e40c8b12fd96d762b2d5481a36d99) + '@nuxt/schema': 4.5.2 + '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)))) + '@nuxt/vite-builder': 4.5.2(55748b195e817d1cd0e6036ca1cd0f8f) + '@unhead/vue': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + '@vue/shared': 3.5.41 + chokidar: 5.0.0 + compatx: 0.2.0 + consola: 3.4.2 + cookie-es: 3.1.1 + defu: 6.1.7 + devalue: 5.9.0 + errx: 0.1.2 + escape-string-regexp: 5.0.0 + exsolve: 1.1.1 + fnv1a-64: 0.1.2 + hookable: 6.1.1 + ignore: 7.0.6 + impound: 1.1.6(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + jiti: 2.7.0 + klona: 2.0.6 + knitwork: 1.3.0 + magic-string: 1.1.0 + mlly: 1.8.2 + nanotar: 0.3.0 + nostics: 1.2.0 + nypm: 0.6.9 + object-identity: 0.2.3 + ofetch: 1.5.1 + ohash: 2.0.11 + on-change: 6.0.2 + oxc-walker: 1.1.1(@oxc-project/types@0.143.0)(rolldown@1.2.3) + pathe: 2.0.3 + perfect-debounce: 2.1.0 + picomatch: 4.0.5 + pkg-types: 2.3.1 + rolldown: 1.2.3 + rolldown-string: 0.3.1(rolldown@1.2.3) + rou3: 0.9.1 + scule: 1.3.0 + std-env: 4.2.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + ultrahtml: 1.7.0 + uncrypto: 0.1.3 + unctx: 3.0.0(magic-string@1.1.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + undici: 8.10.0 + unhead: 3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unimport: 6.4.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unrouting: 0.2.2 + untyped: 2.0.0 + verkit: 0.3.2 + vue: 3.5.41(typescript@6.0.3) + vue-component-type-helpers: 3.3.9 + vue-router: 5.2.0(@vue/compiler-sfc@3.5.41)(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)) + optionalDependencies: + '@types/node': 26.2.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@babel/plugin-proposal-decorators' + - '@babel/plugin-syntax-jsx' + - '@babel/plugin-syntax-typescript' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@libsql/client' + - '@netlify/blobs' + - '@oxc-project/types' + - '@pinia/colada' + - '@planetscale/database' + - '@rollup/plugin-babel' + - '@rspack/core' + - '@unhead/cli' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools' + - '@vitejs/devtools-kit' + - '@vue/compiler-sfc' + - aws4fetch + - bare-abort-controller + - bare-buffer + - better-sqlite3 + - bufferutil + - bun-types-no-globals + - cac + - commander + - db0 + - drizzle-orm + - encoding + - esbuild + - eslint + - idb-keyval + - ioredis + - less + - lightningcss + - magicast + - meow + - mysql2 + - optionator + - oxc-parser + - oxlint + - pinia + - react-native-b4a + - rollup + - rollup-plugin-visualizer + - sass + - sass-embedded + - sqlite3 + - srvx + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - unloader + - uploadthing + - utf-8-validate + - vite + - vue-tsc + - webpack + - xml2js + - yaml + + nypm@0.6.9: + dependencies: + citty: 0.2.2 + pathe: 2.0.3 + tinyexec: 1.3.0 + + object-deep-merge@2.0.1: {} + + object-identity@0.2.3: {} + + obug@2.1.4: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + ofetch@2.0.0-alpha.3: {} + + ohash@2.0.11: {} + + oidc-client-ts@3.5.0: + dependencies: + jwt-decode: 4.0.0 + + on-change@6.0.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + orderedmap@2.1.1: {} + + oxc-walker@1.1.1(@oxc-project/types@0.143.0)(rolldown@1.2.3): + optionalDependencies: + '@oxc-project/types': 0.143.0 + rolldown: 1.2.3 + + p-event@6.0.1: + dependencies: + p-timeout: 6.1.4 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-timeout@6.1.4: {} + + package-json-from-dist@1.0.1: {} + + package-manager-detector@1.8.0: {} + + parse-imports-exports@0.2.4: + dependencies: + parse-statements: 1.0.11 + + parse-statements@1.0.11: {} + + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-scurry@2.0.2: + dependencies: + lru-cache: 11.5.2 + minipass: 7.1.3 + + pathe@2.0.3: {} + + perfect-debounce@2.1.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.5: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkg-types@2.3.1: + dependencies: + confbox: 0.2.4 + exsolve: 1.1.1 + pathe: 2.0.3 + + pluralize@8.0.0: {} + + postcss-calc@10.1.1(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-selector-parser: 7.1.5 + postcss-value-parser: 4.2.0 + + postcss-colormin@8.0.2(postcss@8.5.26): + dependencies: + '@colordx/core': 5.5.0 + browserslist: 4.28.7 + caniuse-api: 4.0.0 + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-convert-values@8.0.2(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-selector-parser: 7.1.5 + + postcss-discard-duplicates@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + + postcss-discard-empty@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + + postcss-discard-overridden@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + + postcss-merge-longhand@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + stylehacks: 8.0.2(postcss@8.5.26) + + postcss-merge-rules@8.0.2(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + caniuse-api: 4.0.0 + cssnano-utils: 6.0.2(postcss@8.5.26) + postcss: 8.5.26 + postcss-selector-parser: 7.1.5 + + postcss-minify-font-values@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@8.0.2(postcss@8.5.26): + dependencies: + '@colordx/core': 5.5.0 + cssnano-utils: 6.0.2(postcss@8.5.26) + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-minify-params@8.0.2(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + cssnano-utils: 6.0.2(postcss@8.5.26) + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@8.0.3(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + caniuse-api: 4.0.0 + cssesc: 3.0.0 + postcss: 8.5.26 + postcss-selector-parser: 7.1.5 + + postcss-normalize-charset@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + + postcss-normalize-display-values@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@8.0.2(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@8.0.2(postcss@8.5.26): + dependencies: + cssnano-utils: 6.0.2(postcss@8.5.26) + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@8.0.2(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + caniuse-api: 4.0.0 + postcss: 8.5.26 + + postcss-reduce-transforms@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@7.1.5: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@8.0.3(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-value-parser: 4.2.0 + svgo: 4.0.2 + + postcss-unique-selectors@8.0.2(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-selector-parser: 7.1.5 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.26: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + powershell-utils@0.1.0: {} + + prelude-ls@1.2.1: {} + + pretty-bytes@7.1.1: {} + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + prosemirror-changeset@2.4.1: + dependencies: + prosemirror-transform: 1.12.0 + + prosemirror-commands@1.7.2: + dependencies: + prosemirror-model: 1.25.11 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + prosemirror-dropcursor@1.8.3: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.42.2 + + prosemirror-gapcursor@1.4.1: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.11 + prosemirror-state: 1.4.4 + prosemirror-view: 1.42.2 + + prosemirror-history@1.5.0: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.42.2 + rope-sequence: 1.3.4 + + prosemirror-inputrules@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.4 + w3c-keyname: 2.2.8 + + prosemirror-model@1.25.11: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.11 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + prosemirror-state@1.4.4: + dependencies: + prosemirror-model: 1.25.11 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.42.2 + + prosemirror-tables@1.8.5: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.11 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.42.2 + + prosemirror-transform@1.12.0: + dependencies: + prosemirror-model: 1.25.11 + + prosemirror-view@1.42.2: + dependencies: + prosemirror-model: 1.25.11 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + proto-list@1.2.4: {} + + punycode@2.3.1: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + quote-js-string@0.1.0: {} + + radix3@1.1.2: {} + + range-parser@1.3.0: {} + + rc9@3.0.1: + dependencies: + defu: 6.1.7 + destr: 2.0.5 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + + readdirp@5.1.1: {} + + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + refa@0.12.1: + dependencies: + '@eslint-community/regexpp': 4.12.2 + + regexp-ast-analysis@0.7.1: + dependencies: + '@eslint-community/regexpp': 4.12.2 + refa: 0.12.1 + + regexp-tree@0.1.27: {} + + regjsparser@0.13.2: + dependencies: + jsesc: 3.1.0 + + reka-ui@2.10.1(vue@3.5.41(typescript@6.0.3)): + dependencies: + '@floating-ui/dom': 1.8.0 + '@floating-ui/vue': 1.1.11(vue@3.5.41(typescript@6.0.3)) + '@internationalized/date': 3.12.3 + '@internationalized/number': 3.6.7 + '@tanstack/vue-virtual': 3.13.35(vue@3.5.41(typescript@6.0.3)) + '@vueuse/core': 14.4.0(vue@3.5.41(typescript@6.0.3)) + '@vueuse/shared': 14.4.0(vue@3.5.41(typescript@6.0.3)) + aria-hidden: 1.2.6 + defu: 6.1.7 + ohash: 2.0.11 + vue: 3.5.41(typescript@6.0.3) + transitivePeerDependencies: + - '@vue/composition-api' + + reserved-identifiers@1.2.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + retry@0.12.0: {} + + reusify@1.1.0: {} + + rolldown-string@0.3.1(rolldown@1.2.3): + dependencies: + magic-string: 1.1.0 + optionalDependencies: + rolldown: 1.2.3 + + rolldown@1.2.3: + dependencies: + '@oxc-project/types': 0.143.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.2.3 + '@rolldown/binding-darwin-arm64': 1.2.3 + '@rolldown/binding-darwin-x64': 1.2.3 + '@rolldown/binding-freebsd-x64': 1.2.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.3 + '@rolldown/binding-linux-arm64-gnu': 1.2.3 + '@rolldown/binding-linux-arm64-musl': 1.2.3 + '@rolldown/binding-linux-ppc64-gnu': 1.2.3 + '@rolldown/binding-linux-s390x-gnu': 1.2.3 + '@rolldown/binding-linux-x64-gnu': 1.2.3 + '@rolldown/binding-linux-x64-musl': 1.2.3 + '@rolldown/binding-openharmony-arm64': 1.2.3 + '@rolldown/binding-win32-arm64-msvc': 1.2.3 + '@rolldown/binding-win32-x64-msvc': 1.2.3 + + rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4): + dependencies: + open: 11.0.0 + picomatch: 4.0.5 + source-map: 0.7.6 + yargs: 18.1.0 + optionalDependencies: + rolldown: 1.2.3 + rollup: 4.62.4 + + rollup@4.62.4: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@napi-rs/lzma-linux-x64-gnu': 1.5.1 + '@rollup/rollup-android-arm-eabi': 4.62.4 + '@rollup/rollup-android-arm64': 4.62.4 + '@rollup/rollup-darwin-arm64': 4.62.4 + '@rollup/rollup-darwin-x64': 4.62.4 + '@rollup/rollup-freebsd-arm64': 4.62.4 + '@rollup/rollup-freebsd-x64': 4.62.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.4 + '@rollup/rollup-linux-arm-musleabihf': 4.62.4 + '@rollup/rollup-linux-arm64-gnu': 4.62.4 + '@rollup/rollup-linux-arm64-musl': 4.62.4 + '@rollup/rollup-linux-loong64-gnu': 4.62.4 + '@rollup/rollup-linux-loong64-musl': 4.62.4 + '@rollup/rollup-linux-ppc64-gnu': 4.62.4 + '@rollup/rollup-linux-ppc64-musl': 4.62.4 + '@rollup/rollup-linux-riscv64-gnu': 4.62.4 + '@rollup/rollup-linux-riscv64-musl': 4.62.4 + '@rollup/rollup-linux-s390x-gnu': 4.62.4 + '@rollup/rollup-linux-x64-gnu': 4.62.4 + '@rollup/rollup-linux-x64-musl': 4.62.4 + '@rollup/rollup-openbsd-x64': 4.62.4 + '@rollup/rollup-openharmony-arm64': 4.62.4 + '@rollup/rollup-win32-arm64-msvc': 4.62.4 + '@rollup/rollup-win32-ia32-msvc': 4.62.4 + '@rollup/rollup-win32-x64-gnu': 4.62.4 + '@rollup/rollup-win32-x64-msvc': 4.62.4 + fsevents: 2.3.3 + + rope-sequence@1.3.4: {} + + rou3@0.9.1: {} + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + sax@1.6.1: {} + + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.12.2 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + + scule@1.3.0: {} + + semver@6.3.1: {} + + semver@7.8.5: {} + + send@1.2.1(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@7.0.7: {} + + seroval@1.6.2: {} + + serve-placeholder@2.0.2: + dependencies: + defu: 6.1.7 + + serve-static@2.2.1(supports-color@10.2.2): + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.10.0: {} + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-git@3.36.0(supports-color@10.2.2): + dependencies: + '@kwsites/file-exists': 1.1.1(supports-color@10.2.2) + '@kwsites/promise-deferred': 1.1.1 + '@simple-git/args-pathspec': 1.0.3 + '@simple-git/argv-parser': 1.1.1 + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + slash@5.1.0: {} + + smob@1.6.2: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@5.0.0: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + srvx@0.11.22: {} + + srvx@0.12.5: {} + + stable-hash-x@0.2.0: {} + + stackback@0.0.2: {} + + standard-as-callback@2.1.0: {} + + statuses@2.0.2: {} + + std-env@4.2.0: {} + + streamx@2.28.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string-width@8.2.2: + dependencies: + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-final-newline@3.0.0: {} + + strip-indent@4.1.1: {} + + strip-literal@4.0.0: + dependencies: + js-tokens: 10.0.0 + + structured-clone-es@2.0.1: {} + + stylehacks@8.0.2(postcss@8.5.26): + dependencies: + browserslist: 4.28.7 + postcss: 8.5.26 + postcss-selector-parser: 7.1.5 + + super-regex@1.1.0: + dependencies: + function-timeout: 1.0.2 + make-asynchronous: 1.1.0 + time-span: 5.1.0 + + supports-color@10.2.2: {} + + supports-preserve-symlinks-flag@1.0.0: {} + + svgo@4.0.2: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.2.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.1 + + tagged-tag@1.0.0: {} + + tailwind-merge@3.6.0: {} + + tailwind-variants@3.3.1(tailwind-merge@3.6.0)(tailwindcss@4.3.3): + optionalDependencies: + tailwind-merge: 3.6.0 + tailwindcss: 4.3.3 + + tailwindcss@4.3.3: {} + + tapable@2.3.3: {} + + tar-stream@3.2.0: + dependencies: + b4a: 1.8.1 + bare-fs: 4.8.0 + fast-fifo: 1.3.2 + streamx: 2.28.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + tar@7.5.22: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + + teex@1.0.1: + dependencies: + streamx: 2.28.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + terser@5.49.2: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.18.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + text-decoder@1.2.7: + dependencies: + b4a: 1.8.1 + transitivePeerDependencies: + - react-native-b4a + + time-span@5.1.0: + dependencies: + convert-hrtime: 5.0.0 + + tiny-inflate@1.0.3: {} + + tiny-invariant@1.3.3: {} + + tinybench@2.9.0: {} + + tinyclip@0.1.15: {} + + tinyexec@1.3.0: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + tinyrainbow@3.1.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-valid-identifier@1.0.0: + dependencies: + '@sindresorhus/base62': 1.0.0 + reserved-identifiers: 1.2.0 + + toidentifier@1.0.1: {} + + totalist@3.0.1: {} + + tr46@0.0.3: {} + + ts-api-utils@2.5.0(typescript@6.0.3): + dependencies: + typescript: 6.0.3 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@4.41.0: {} + + type-fest@5.8.0: + dependencies: + tagged-tag: 1.0.0 + + type-level-regexp@0.1.17: {} + + typescript@6.0.3: {} + + ufo@1.6.4: {} + + ultrahtml@1.7.0: {} + + uncrypto@0.1.3: {} + + unctx@2.5.0: + dependencies: + acorn: 8.18.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + unplugin: 2.3.11 + + unctx@3.0.0(magic-string@0.30.21)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))): + optionalDependencies: + magic-string: 0.30.21 + rolldown: 1.2.3 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + + unctx@3.0.0(magic-string@1.1.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))): + optionalDependencies: + magic-string: 1.1.0 + rolldown: 1.2.3 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + + undici-types@8.3.0: {} + + undici@8.10.0: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unhead@2.1.17: + dependencies: + hookable: 6.1.1 + + unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + hookable: 6.1.1 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + optionalDependencies: + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - webpack + + unicorn-magic@0.3.0: {} + + unicorn-magic@0.4.0: {} + + unifont@0.7.4: + dependencies: + css-tree: 3.2.1 + ofetch: 1.5.1 + ohash: 2.0.11 + + unimport@6.4.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + acorn: 8.18.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.2.1 + magic-string: 1.1.0 + mlly: 1.8.2 + pathe: 2.0.3 + picomatch: 4.0.5 + pkg-types: 2.3.1 + scule: 1.3.0 + strip-literal: 4.0.0 + tinyglobby: 0.2.17 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-utils: 0.3.2 + optionalDependencies: + rolldown: 1.2.3 + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rollup + - unloader + - vite + - webpack + + unplugin-auto-import@21.1.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))(@vueuse/core@14.4.0(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + local-pkg: 1.2.1 + magic-string: 1.1.0 + picomatch: 4.0.5 + unimport: 6.4.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-utils: 0.3.2 + optionalDependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + '@vueuse/core': 14.4.0(vue@3.5.41(typescript@6.0.3)) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - oxc-parser + - rolldown + - rollup + - unloader + - vite + - webpack + + unplugin-utils@0.3.2: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.5 + + unplugin-vue-components@32.1.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)): + dependencies: + chokidar: 5.0.0 + local-pkg: 1.2.1 + magic-string: 0.30.21 + mlly: 1.8.2 + obug: 2.1.4 + picomatch: 4.0.5 + tinyglobby: 0.2.17 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-utils: 0.3.2 + vue: 3.5.41(typescript@6.0.3) + optionalDependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - vite + - webpack + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.18.0 + picomatch: 4.0.5 + webpack-virtual-modules: 0.6.2 + + unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.5 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.28.1 + rolldown: 1.2.3 + rollup: 4.62.4 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + + unrouting@0.2.2: + dependencies: + escape-string-regexp: 5.0.0 + ufo: 1.6.4 + + unrs-resolver@1.12.2: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.12.2 + '@unrs/resolver-binding-android-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-x64': 1.12.2 + '@unrs/resolver-binding-freebsd-x64': 1.12.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 + + unstorage@1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.2 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + db0: 0.3.4 + ioredis: 5.11.1(supports-color@10.2.2) + + untun@0.2.2: {} + + untyped@2.0.0: + dependencies: + citty: 0.1.6 + defu: 6.1.7 + jiti: 2.7.0 + knitwork: 1.3.0 + scule: 1.3.0 + + unwasm@0.5.3: + dependencies: + exsolve: 1.1.1 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.2 + pathe: 2.0.3 + pkg-types: 2.3.1 + + update-browserslist-db@1.3.0(browserslist@4.28.7): + dependencies: + browserslist: 4.28.7 + escalade: 3.2.0 + picocolors: 1.1.1 + + uqr@0.1.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vaul-vue@0.4.1(reka-ui@2.10.1(vue@3.5.41(typescript@6.0.3)))(vue@3.5.41(typescript@6.0.3)): + dependencies: + '@vueuse/core': 10.11.1(vue@3.5.41(typescript@6.0.3)) + reka-ui: 2.10.1(vue@3.5.41(typescript@6.0.3)) + vue: 3.5.41(typescript@6.0.3) + transitivePeerDependencies: + - '@vue/composition-api' + + verkit@0.3.2: {} + + vite-dev-rpc@2.0.0(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + birpc: 4.0.0 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vite-hot-client: 2.2.0(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + + vite-hot-client@2.2.0(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + + vite-node@6.0.0(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0): + dependencies: + cac: 7.0.0 + es-module-lexer: 2.3.1 + obug: 2.1.4 + pathe: 2.0.3 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@types/node' + - '@vitejs/devtools' + - esbuild + - jiti + - less + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vite-plugin-checker@0.14.5(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(optionator@0.9.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue-tsc@3.3.9(typescript@6.0.3)): + dependencies: + '@babel/code-frame': 7.29.7 + chokidar: 5.0.0 + npm-run-path: 6.0.0 + picocolors: 1.1.1 + picomatch: 4.0.5 + proper-lockfile: 4.1.2 + tiny-invariant: 1.3.3 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + optionalDependencies: + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + optionator: 0.9.4 + typescript: 6.0.3 + vue-tsc: 3.3.9(typescript@6.0.3) + + vite-plugin-inspect@11.4.1(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))))(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + ansis: 4.3.1 + error-stack-parser-es: 1.0.5 + obug: 2.1.4 + ohash: 2.0.11 + open: 11.0.0 + perfect-debounce: 2.1.0 + sirv: 3.0.2 + unplugin-utils: 0.3.2 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vite-dev-rpc: 2.0.0(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + optionalDependencies: + '@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + + vite-plugin-vue-tracer@1.4.0(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)): + dependencies: + estree-walker: 3.0.3 + exsolve: 1.1.1 + magic-string: 0.30.21 + pathe: 2.0.3 + source-map-js: 1.2.1 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + vue: 3.5.41(typescript@6.0.3) + + vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.5 + postcss: 8.5.26 + rolldown: 1.2.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.2.0 + esbuild: 0.28.1 + fsevents: 2.3.3 + jiti: 2.7.0 + terser: 5.49.2 + yaml: 2.9.0 + + vitest-environment-nuxt@2.0.0(@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(happy-dom@20.11.2)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vitest@4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))): + dependencies: + '@nuxt/test-utils': 4.1.0(@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@6.0.3)))(esbuild@0.28.1)(happy-dom@20.11.2)(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@6.0.3)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vitest@4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))) + transitivePeerDependencies: + - '@cucumber/cucumber' + - '@farmfe/core' + - '@jest/globals' + - '@playwright/test' + - '@rspack/core' + - '@testing-library/vue' + - '@vitest/ui' + - '@vue/test-utils' + - bun-types-no-globals + - esbuild + - h3-next + - happy-dom + - jsdom + - magicast + - playwright-core + - rolldown + - rollup + - typescript + - unloader + - vite + - vitest + - webpack + + vitest@4.1.10(@types/node@26.2.0)(happy-dom@20.11.2)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.3.1 + expect-type: 1.4.0 + magic-string: 0.30.21 + obug: 2.1.4 + pathe: 2.0.3 + picomatch: 4.0.5 + std-env: 4.2.0 + tinybench: 2.9.0 + tinyexec: 1.3.0 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.1 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 26.2.0 + happy-dom: 20.11.2 + transitivePeerDependencies: + - msw + + vscode-uri@3.1.0: {} + + vue-bundle-renderer@2.3.1: + dependencies: + ufo: 1.6.4 + + vue-component-type-helpers@3.3.9: {} + + vue-demi@0.14.10(vue@3.5.41(typescript@6.0.3)): + dependencies: + vue: 3.5.41(typescript@6.0.3) + + vue-devtools-stub@0.1.0: {} + + vue-eslint-parser@10.4.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + eslint: 10.8.1(jiti@2.7.0)(supports-color@10.2.2) + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + semver: 7.8.5 + transitivePeerDependencies: + - supports-color + + vue-router@5.2.0(@vue/compiler-sfc@3.5.41)(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3)): + dependencies: + '@babel/generator': 8.0.0 + '@vue-macros/common': 3.1.4(vue@3.5.41(typescript@6.0.3)) + '@vue/devtools-api': 8.2.1 + ast-walker-scope: 0.9.0 + chokidar: 5.0.0 + json5: 2.2.3 + local-pkg: 1.2.1 + magic-string: 0.30.21 + mlly: 1.8.2 + muggle-string: 0.4.1 + nostics: 1.2.0 + pathe: 2.0.3 + picomatch: 4.0.5 + scule: 1.3.0 + tinyglobby: 0.2.17 + unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0)) + unplugin-utils: 0.3.2 + vue: 3.5.41(typescript@6.0.3) + yaml: 2.9.0 + optionalDependencies: + '@vue/compiler-sfc': 3.5.41 + vite: 8.2.1(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.2)(yaml@2.9.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - webpack + + vue-tsc@3.3.9(typescript@6.0.3): + dependencies: + '@volar/typescript': 2.4.28(typescript@6.0.3) + '@vue/language-core': 3.3.9 + typescript: 6.0.3 + + vue@3.5.41(typescript@6.0.3): + dependencies: + '@vue/compiler-dom': 3.5.41 + '@vue/compiler-sfc': 3.5.41 + '@vue/runtime-dom': 3.5.41 + '@vue/server-renderer': 3.5.41 + '@vue/shared': 3.5.41 + optionalDependencies: + typescript: 6.0.3 + + w3c-keyname@2.2.8: {} + + web-worker@1.5.0: {} + + webidl-conversions@3.0.1: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-mimetype@3.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + wheel-gestures@2.2.48: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@6.0.1: + dependencies: + isexe: 4.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + ws@8.21.3: {} + + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + + xml-name-validator@5.0.0: {} + + y-protocols@1.0.7(yjs@13.6.32): + dependencies: + lib0: 0.2.117 + yjs: 13.6.32 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@5.0.0: {} + + yaml@2.9.0: {} + + yargs-parser@22.0.0: {} + + yargs@18.1.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.2.2 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + yjs@13.6.32: + dependencies: + lib0: 0.2.117 + + yocto-queue@0.1.0: {} + + yocto-queue@1.2.2: {} + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.1: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.7.0 + '@speed-highlight/core': 1.2.23 + cookie-es: 3.1.1 + youch-core: 0.3.3 + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 diff --git a/ui/pnpm-workspace.yaml b/ui/pnpm-workspace.yaml new file mode 100644 index 0000000..10e4abb --- /dev/null +++ b/ui/pnpm-workspace.yaml @@ -0,0 +1,4 @@ +allowBuilds: + esbuild: true + unrs-resolver: true + vue-demi: true diff --git a/ui/tests/nuxt/defaultLayout.nuxt.spec.ts b/ui/tests/nuxt/defaultLayout.nuxt.spec.ts new file mode 100644 index 0000000..7d4d90b --- /dev/null +++ b/ui/tests/nuxt/defaultLayout.nuxt.spec.ts @@ -0,0 +1,50 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { mountSuspended } from '@nuxt/test-utils/runtime' +import DefaultLayout from '~/layouts/default.vue' + +/** + * A real render, through Nuxt's own component auto-registration -- not a typecheck. This is + * the belt that catches what `vue-tsc --noEmit` and `nuxt build` both silently let through: + * a template referencing a component under its bare filename (``) instead of the + * directory-prefixed name Nuxt actually registers it under (`LayoutAppHeader`, since + * `app/components/layout/AppHeader.vue` sits one directory below `app/components/`). An + * unresolved tag compiles fine and renders as an empty custom element at runtime -- neither + * static check flags it, only mounting the real tree does. + * + * `default.vue` was exactly this bug (``), and `AppHeader.vue` itself carried the + * same mistake one level down (`` instead of ``) -- both fixed + * alongside this test. If either regresses, this test fails on two independent signals: the + * header/nav content goes missing from the rendered output, and Vue's own + * "Failed to resolve component" dev warning fires. + */ +describe('layouts/default.vue', () => { + afterEach(() => { + vi.restoreAllMocks() + }) + + it('resolves and renders AppHeader and AppNav, not just an empty custom element', async () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + const wrapper = await mountSuspended(DefaultLayout, { + slots: { default: () => 'tenant dashboard content' } + }) + + // AppHeader.vue's own template content -- only present if `` actually + // resolved and rendered its subtree (which itself only renders if `` inside + // *it* resolved too). + expect(wrapper.text()).toContain('Apus') + expect(wrapper.find('header').exists()).toBe(true) + + // AppNav.vue's own content, nested two levels deep (default.vue -> AppHeader -> AppNav). + expect(wrapper.find('nav[aria-label="Main"]').exists()).toBe(true) + expect(wrapper.text()).toContain('Account') + + // The layout's own slot content, proving the layout itself rendered past the header. + expect(wrapper.text()).toContain('tenant dashboard content') + + const failedToResolve = warnSpy.mock.calls.some((call) => + call.some((arg) => typeof arg === 'string' && arg.includes('Failed to resolve component')) + ) + expect(failedToResolve).toBe(false) + }) +}) diff --git a/ui/tests/unit/apiClient.spec.ts b/ui/tests/unit/apiClient.spec.ts new file mode 100644 index 0000000..bd98295 --- /dev/null +++ b/ui/tests/unit/apiClient.spec.ts @@ -0,0 +1,291 @@ +import { describe, expect, it, vi } from 'vitest' +import { createApusApiClient, type FetchLike } from '../../app/utils/apiClient' +import { ApusApiError } from '../../app/utils/apiErrors' +import type { TenantResponse } from '../../app/utils/apiTypes' + +const BASE_URL = 'https://api.apus.example.net' + +function jsonResponse(status: number, body: unknown): Response { + return { + ok: status >= 200 && status < 300, + status, + text: async () => JSON.stringify(body) + } as Response +} + +function emptyResponse(status: number): Response { + return { + ok: status >= 200 && status < 300, + status, + text: async () => '' + } as Response +} + +function sseResponse(chunks: string[]): Response { + const encoder = new TextEncoder() + const body = new ReadableStream({ + start(controller) { + for (const chunk of chunks) controller.enqueue(encoder.encode(chunk)) + controller.close() + } + }) + return { ok: true, status: 200, body } as unknown as Response +} + +describe('createApusApiClient / request handling', () => { + it('sends a bearer token and Accept header on a GET request', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, [])) + const client = createApusApiClient({ + baseUrl: BASE_URL, + getAccessToken: () => 'the-token', + fetchImpl + }) + + await client.listTenants() + + expect(fetchImpl).toHaveBeenCalledOnce() + const [url, init] = fetchImpl.mock.calls[0] + expect(url).toBe(`${BASE_URL}/api/tenants`) + const headers = new Headers(init?.headers) + expect(headers.get('Authorization')).toBe('Bearer the-token') + expect(headers.get('Accept')).toBe('application/json') + }) + + it('sends no Authorization header when there is no token', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, [])) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.listTenants() + + const headers = new Headers(fetchImpl.mock.calls[0][1]?.headers) + expect(headers.has('Authorization')).toBe(false) + }) + + it('supports an async getAccessToken', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, [])) + const client = createApusApiClient({ + baseUrl: BASE_URL, + getAccessToken: async () => 'async-token', + fetchImpl + }) + + await client.listTenants() + + const headers = new Headers(fetchImpl.mock.calls[0][1]?.headers) + expect(headers.get('Authorization')).toBe('Bearer async-token') + }) + + it('parses a successful JSON response', async () => { + const tenant: TenantResponse = { + name: 'friends-server', + displayName: 'Friends Server', + storage: { quota: '500Gi', maxObjects: 5_000_000 }, + allowedHostingDomains: ['*.friends.example.net'], + namespace: 'bluemap-friends-server', + objectStoreUser: 'apus-friends-server', + storageUsedBytes: 228_730_548_224, + conditions: [] + } + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, [tenant])) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await expect(client.listTenants()).resolves.toEqual([tenant]) + }) + + it('POSTs a JSON body with a Content-Type header', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(201, { name: 'new-tenant' })) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.createTenant({ name: 'new-tenant' }) + + const [url, init] = fetchImpl.mock.calls[0] + expect(url).toBe(`${BASE_URL}/api/tenants`) + expect(init?.method).toBe('POST') + expect(init?.body).toBe(JSON.stringify({ name: 'new-tenant' })) + expect(new Headers(init?.headers).get('Content-Type')).toBe('application/json') + }) + + it('triggers a render with no body and no Content-Type header when force is omitted', async () => { + const fetchImpl = vi.fn().mockResolvedValue( + jsonResponse(201, { name: 'r1', mapRef: 'survival-overworld', force: false }) + ) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.triggerRender('survival-overworld') + + const [url, init] = fetchImpl.mock.calls[0] + expect(url).toBe(`${BASE_URL}/api/maps/survival-overworld/render`) + expect(init?.body).toBeUndefined() + expect(new Headers(init?.headers).has('Content-Type')).toBe(false) + }) + + it('PATCHes a JSON body against the tenant path for updateTenant', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, { name: 'acme' })) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.updateTenant('acme', { storageQuota: '500Gi' }) + + const [url, init] = fetchImpl.mock.calls[0] + expect(url).toBe(`${BASE_URL}/api/tenants/acme`) + expect(init?.method).toBe('PATCH') + expect(init?.body).toBe(JSON.stringify({ storageQuota: '500Gi' })) + expect(new Headers(init?.headers).get('Content-Type')).toBe('application/json') + }) + + it('URL-encodes the tenant name for updateTenant', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, {})) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.updateTenant('needs encoding/slash', {}) + + expect(fetchImpl.mock.calls[0][0]).toBe(`${BASE_URL}/api/tenants/needs%20encoding%2Fslash`) + }) + + it('fetches the cluster-wide render view from /api/renders/cluster', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, [])) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.listClusterRenders() + + expect(fetchImpl.mock.calls[0][0]).toBe(`${BASE_URL}/api/renders/cluster`) + }) + + it('URL-encodes path parameters', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, {})) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await client.getMap('needs encoding/slash') + + expect(fetchImpl.mock.calls[0][0]).toBe(`${BASE_URL}/api/maps/needs%20encoding%2Fslash`) + }) + + it('treats 204 No Content as a successful empty result', async () => { + const fetchImpl = vi.fn().mockResolvedValue(emptyResponse(204)) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + await expect(client.listTenants()).resolves.toBeUndefined() + }) + + it('strips a trailing slash from baseUrl', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(200, [])) + const client = createApusApiClient({ baseUrl: `${BASE_URL}/`, getAccessToken: () => null, fetchImpl }) + + await client.listTenants() + + expect(fetchImpl.mock.calls[0][0]).toBe(`${BASE_URL}/api/tenants`) + }) +}) + +describe('createApusApiClient / error handling', () => { + it('surfaces the message from a 400 error body (BadRequestExceptionHandler)', async () => { + const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(400, { message: 'name must not be blank' })) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const error = await client.createTenant({ name: '' }).catch((e: unknown) => e) + + expect(error).toBeInstanceOf(ApusApiError) + expect((error as ApusApiError).status).toBe(400) + expect((error as ApusApiError).message).toBe('name must not be blank') + }) + + it('falls back to a default message for a 403 with no body (ForbiddenExceptionHandler)', async () => { + const fetchImpl = vi.fn().mockResolvedValue(emptyResponse(403)) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const error = await client.listSources().catch((e: unknown) => e) + + expect(error).toBeInstanceOf(ApusApiError) + expect((error as ApusApiError).status).toBe(403) + expect((error as ApusApiError).message).toBe('Not permitted.') + }) + + it('falls back to a default message for a 404 with no body (NotFoundExceptionHandler)', async () => { + const fetchImpl = vi.fn().mockResolvedValue(emptyResponse(404)) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const error = await client.getRender('missing').catch((e: unknown) => e) + + expect(error).toBeInstanceOf(ApusApiError) + expect((error as ApusApiError).status).toBe(404) + expect((error as ApusApiError).message).toBe('Not found.') + }) + + it('maps a fetch/network failure to a status-0 ApusApiError instead of rejecting raw', async () => { + const cause = new TypeError('Failed to fetch') + const fetchImpl = vi.fn().mockRejectedValue(cause) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const error = await client.listTenants().catch((e: unknown) => e) + + expect(error).toBeInstanceOf(ApusApiError) + expect((error as ApusApiError).status).toBe(0) + expect((error as ApusApiError).networkError).toBe(cause) + }) + + it('does not throw when an error body is present but not JSON', async () => { + const fetchImpl = vi.fn().mockResolvedValue({ + ok: false, + status: 500, + text: async () => 'Internal Server Error' + } as Response) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const error = await client.listTenants().catch((e: unknown) => e) + + expect(error).toBeInstanceOf(ApusApiError) + expect((error as ApusApiError).status).toBe(500) + expect((error as ApusApiError).message).toBe('Request failed with status 500.') + }) +}) + +describe('createApusApiClient / SSE streams', () => { + it('parses each render progress event as JSON and calls onClose at stream end', async () => { + const fetchImpl = vi.fn().mockResolvedValue( + sseResponse(['data: {"phase":"Rendering","percent":10}\n\n', 'data: {"phase":"Succeeded","percent":100}\n\n']) + ) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => 'tok', fetchImpl }) + + const received: unknown[] = [] + let closed = false + await client.streamRenderEvents('r1', { + onMessage: (event) => received.push(event), + onClose: () => { + closed = true + } + }) + + expect(received).toEqual([ + { phase: 'Rendering', percent: 10 }, + { phase: 'Succeeded', percent: 100 } + ]) + expect(closed).toBe(true) + expect(fetchImpl.mock.calls[0][0]).toBe(`${BASE_URL}/api/renders/r1/events`) + const headers = new Headers(fetchImpl.mock.calls[0][1]?.headers) + expect(headers.get('Authorization')).toBe('Bearer tok') + expect(headers.get('Accept')).toBe('text/event-stream') + }) + + it('delivers log lines as raw strings, not JSON-parsed', async () => { + const fetchImpl = vi.fn().mockResolvedValue( + sseResponse(['data: [INFO] starting render\n\n', 'data: [INFO] updating map \'overworld\': 35%\n\n']) + ) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const lines: string[] = [] + await client.streamRenderLogs('r1', { onMessage: (line) => lines.push(line) }) + + expect(lines).toEqual(['[INFO] starting render', '[INFO] updating map \'overworld\': 35%']) + }) + + it('rejects with an ApusApiError when the stream fails to open', async () => { + const fetchImpl = vi.fn().mockResolvedValue(emptyResponse(404)) + const client = createApusApiClient({ baseUrl: BASE_URL, getAccessToken: () => null, fetchImpl }) + + const error = await client + .streamRenderEvents('missing', { onMessage: () => {} }) + .catch((e: unknown) => e) + + expect(error).toBeInstanceOf(ApusApiError) + expect((error as ApusApiError).status).toBe(404) + }) +}) diff --git a/ui/tests/unit/jwt.spec.ts b/ui/tests/unit/jwt.spec.ts new file mode 100644 index 0000000..d9cd947 --- /dev/null +++ b/ui/tests/unit/jwt.spec.ts @@ -0,0 +1,51 @@ +import { describe, expect, it } from 'vitest' +import { decodeJwtPayload } from '../../app/utils/jwt' + +/** Base64url-encodes a claims object into a fake (unsigned) JWT for testing the decoder alone. */ +function fakeJwt(claims: Record): string { + const header = base64Url(JSON.stringify({ alg: 'none', typ: 'JWT' })) + const payload = base64Url(JSON.stringify(claims)) + return `${header}.${payload}.signature` +} + +function base64Url(json: string): string { + const bytes = new TextEncoder().encode(json) + const binary = Array.from(bytes, (byte) => String.fromCharCode(byte)).join('') + return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '') +} + +describe('decodeJwtPayload', () => { + it('decodes claims from a well-formed token', () => { + const token = fakeJwt({ sub: 'user-1', organization: 'friends-server', roles: ['tenant-owner'] }) + + expect(decodeJwtPayload(token)).toEqual({ + sub: 'user-1', + organization: 'friends-server', + roles: ['tenant-owner'] + }) + }) + + it('decodes non-ASCII claim values correctly', () => { + const token = fakeJwt({ name: 'Jörg Müller' }) + + expect(decodeJwtPayload(token)).toEqual({ name: 'Jörg Müller' }) + }) + + it('decodes an unpadded base64url payload (no trailing =)', () => { + // A payload whose base64 length is not a multiple of 4 requires the decoder to re-pad it. + const token = fakeJwt({ a: 1 }) + expect(token.split('.')[1].length % 4).not.toBe(0) + + expect(decodeJwtPayload(token)).toEqual({ a: 1 }) + }) + + it('rejects a string with fewer than two segments', () => { + expect(() => decodeJwtPayload('not-a-jwt')).toThrow(/at least a header and payload/) + }) + + it('rejects a payload that is not a JSON object', () => { + const notAnObject = `${base64Url('{}')}.${base64Url('[1,2,3]')}.sig` + + expect(() => decodeJwtPayload(notAnObject)).toThrow(/not a JSON object/) + }) +}) diff --git a/ui/tests/unit/platform/domainValidation.spec.ts b/ui/tests/unit/platform/domainValidation.spec.ts new file mode 100644 index 0000000..e794390 --- /dev/null +++ b/ui/tests/unit/platform/domainValidation.spec.ts @@ -0,0 +1,95 @@ +import { describe, expect, it } from 'vitest' +import { validateAllowedDomain, validateAllowedDomains } from '../../../app/utils/domainValidation' + +describe('validateAllowedDomain', () => { + it('accepts a plain hostname', () => { + expect(validateAllowedDomain('maps.friends.example.net')).toEqual({ valid: true, error: null }) + }) + + it('accepts a single leading wildcard label', () => { + expect(validateAllowedDomain('*.friends.example.net')).toEqual({ valid: true, error: null }) + }) + + it('trims surrounding whitespace before validating', () => { + expect(validateAllowedDomain(' maps.example.net ')).toEqual({ valid: true, error: null }) + }) + + it('rejects an empty or blank entry', () => { + expect(validateAllowedDomain('').valid).toBe(false) + expect(validateAllowedDomain(' ').valid).toBe(false) + }) + + it('rejects a bare "*" with an explanation of what it would grant', () => { + // The one rule this module exists for: a bare "*" would let this tenant claim every + // hostname on the platform -- exactly the hole Phase 3 closed. + const result = validateAllowedDomain('*') + + expect(result.valid).toBe(false) + expect(result.error).toMatch(/every hostname/) + }) + + it('rejects a wildcard that is not the leading label', () => { + expect(validateAllowedDomain('sub.*.example.net').valid).toBe(false) + expect(validateAllowedDomain('example.*').valid).toBe(false) + }) + + it('rejects a lone wildcard with no domain to scope it', () => { + expect(validateAllowedDomain('*.').valid).toBe(false) + }) + + it('rejects whitespace inside the value', () => { + expect(validateAllowedDomain('maps example.net').valid).toBe(false) + }) + + it('rejects a value carrying a scheme, path, or port', () => { + expect(validateAllowedDomain('https://maps.example.net').valid).toBe(false) + expect(validateAllowedDomain('maps.example.net/path').valid).toBe(false) + expect(validateAllowedDomain('maps.example.net:8080').valid).toBe(false) + }) + + it('rejects empty labels from consecutive or leading/trailing dots', () => { + expect(validateAllowedDomain('maps..example.net').valid).toBe(false) + expect(validateAllowedDomain('.maps.example.net').valid).toBe(false) + expect(validateAllowedDomain('maps.example.net.').valid).toBe(false) + }) + + it('rejects a label starting or ending with a hyphen', () => { + expect(validateAllowedDomain('-maps.example.net').valid).toBe(false) + expect(validateAllowedDomain('maps-.example.net').valid).toBe(false) + }) + + it('rejects a label over 63 characters', () => { + const tooLong = 'a'.repeat(64) + expect(validateAllowedDomain(`${tooLong}.example.net`).valid).toBe(false) + }) + + it('accepts a single-label hostname', () => { + expect(validateAllowedDomain('localhost')).toEqual({ valid: true, error: null }) + }) +}) + +describe('validateAllowedDomains', () => { + it('accepts an empty list', () => { + // Per TenantSpec.Hosting's Javadoc: empty means "hosting not yet allowed", a valid state, + // not an error. + expect(validateAllowedDomains([])).toEqual({ valid: true, error: null }) + }) + + it('accepts a list of distinct valid domains', () => { + expect(validateAllowedDomains(['maps.a.example.net', '*.b.example.net'])).toEqual({ valid: true, error: null }) + }) + + it('rejects the list as soon as one entry is invalid', () => { + const result = validateAllowedDomains(['maps.example.net', '*']) + + expect(result.valid).toBe(false) + expect(result.error).toMatch(/every hostname/) + }) + + it('rejects case-insensitive duplicates', () => { + const result = validateAllowedDomains(['Maps.Example.Net', 'maps.example.net']) + + expect(result.valid).toBe(false) + expect(result.error).toMatch(/more than once/) + }) +}) diff --git a/ui/tests/unit/platform/storageUsage.spec.ts b/ui/tests/unit/platform/storageUsage.spec.ts new file mode 100644 index 0000000..b30bb42 --- /dev/null +++ b/ui/tests/unit/platform/storageUsage.spec.ts @@ -0,0 +1,126 @@ +import { describe, expect, it } from 'vitest' +import { + describeStorageUsage, + formatBytes, + parseQuotaBytes, + storageUsageColor +} from '../../../app/utils/storageUsage' + +describe('parseQuotaBytes', () => { + it('parses binary (IEC) suffixes', () => { + expect(parseQuotaBytes('100Gi')).toBe(100 * 2 ** 30) + expect(parseQuotaBytes('1Ki')).toBe(2 ** 10) + expect(parseQuotaBytes('2Ti')).toBe(2 * 2 ** 40) + }) + + it('parses decimal (SI) suffixes', () => { + expect(parseQuotaBytes('5M')).toBe(5 * 1e6) + expect(parseQuotaBytes('1k')).toBe(1e3) + }) + + it('parses a plain number as bytes', () => { + expect(parseQuotaBytes('2048')).toBe(2048) + }) + + it('parses fractional quantities', () => { + expect(parseQuotaBytes('1.5Gi')).toBe(1.5 * 2 ** 30) + }) + + it('returns null for null, undefined, or blank input', () => { + expect(parseQuotaBytes(null)).toBeNull() + expect(parseQuotaBytes(undefined)).toBeNull() + expect(parseQuotaBytes(' ')).toBeNull() + }) + + it('returns null for an unrecognised suffix', () => { + expect(parseQuotaBytes('100Xi')).toBeNull() + }) + + it('returns null for non-numeric input', () => { + expect(parseQuotaBytes('not-a-quantity')).toBeNull() + }) +}) + +describe('formatBytes', () => { + it('formats zero and negative input as "0 B"', () => { + expect(formatBytes(0)).toBe('0 B') + expect(formatBytes(-5)).toBe('0 B') + }) + + it('formats sub-kibibyte values in bytes', () => { + expect(formatBytes(512)).toBe('512 B') + }) + + it('picks the largest unit that keeps the value >= 1', () => { + expect(formatBytes(2 ** 30)).toBe('1.00 GiB') + expect(formatBytes(1.5 * 2 ** 30)).toBe('1.50 GiB') + }) +}) + +describe('describeStorageUsage', () => { + it('reports "unknown" when no usage has been observed yet', () => { + // Edge case called out in the task brief: a brand-new tenant, or one whose operator has + // not synced a status yet. + const summary = describeStorageUsage(null, '100Gi') + + expect(summary.level).toBe('unknown') + expect(summary.ratio).toBeNull() + expect(summary.usedLabel).toBe('Not yet reported') + expect(summary.quotaLabel).toBe('100.00 GiB') + }) + + it('reports "unknown" when the quota cannot be parsed', () => { + const summary = describeStorageUsage(1024, 'not-a-quantity') + + expect(summary.level).toBe('unknown') + expect(summary.ratio).toBeNull() + expect(summary.quotaLabel).toBe('not-a-quantity') + }) + + it('reports "unknown" when the quota is null', () => { + const summary = describeStorageUsage(1024, null) + + expect(summary.level).toBe('unknown') + expect(summary.quotaLabel).toBe('Not set') + }) + + it('reports "ok" comfortably below the warning threshold', () => { + const summary = describeStorageUsage(10 * 2 ** 30, '100Gi') + + expect(summary.level).toBe('ok') + expect(summary.ratio).toBeCloseTo(0.1) + }) + + it('reports "warning" at 80% and above', () => { + const summary = describeStorageUsage(80 * 2 ** 30, '100Gi') + + expect(summary.level).toBe('warning') + }) + + it('reports "critical" at 95% and above', () => { + const summary = describeStorageUsage(95 * 2 ** 30, '100Gi') + + expect(summary.level).toBe('critical') + }) + + it('reports "over" when usage is at or beyond the quota', () => { + // Edge case called out in the task brief: Ceph enforces the limit, not this UI, so the + // dashboard must be able to show usage that has reached or (per stale metrics) exceeded it. + const atLimit = describeStorageUsage(100 * 2 ** 30, '100Gi') + const beyondLimit = describeStorageUsage(120 * 2 ** 30, '100Gi') + + expect(atLimit.level).toBe('over') + expect(beyondLimit.level).toBe('over') + expect(beyondLimit.ratio).toBeCloseTo(1.2) + }) +}) + +describe('storageUsageColor', () => { + it('maps each level to the expected color token', () => { + expect(storageUsageColor('unknown')).toBe('neutral') + expect(storageUsageColor('ok')).toBe('success') + expect(storageUsageColor('warning')).toBe('warning') + expect(storageUsageColor('critical')).toBe('error') + expect(storageUsageColor('over')).toBe('error') + }) +}) diff --git a/ui/tests/unit/role.spec.ts b/ui/tests/unit/role.spec.ts new file mode 100644 index 0000000..e3e2f0f --- /dev/null +++ b/ui/tests/unit/role.spec.ts @@ -0,0 +1,134 @@ +import { describe, expect, it } from 'vitest' +import { + canReadTenant, + canWriteTenant, + isPlatformAdmin, + isRole, + parsePrincipal, + type ApusUiPrincipal +} from '../../app/utils/role' + +describe('parsePrincipal', () => { + it('reads subject, tenant and recognised roles from token claims', () => { + const principal = parsePrincipal({ + sub: 'user-1', + organization: 'friends-server', + roles: ['tenant-owner', 'tenant-operator'] + }) + + expect(principal).toEqual({ + subject: 'user-1', + tenant: 'friends-server', + roles: ['tenant-owner', 'tenant-operator'] + }) + }) + + it('silently drops roles the broker sends that Apus does not recognise', () => { + // Mirrors Role.fromClaim on the api module: one unrecognised entry must not reject the + // whole token, only that entry. + const principal = parsePrincipal({ sub: 'user-1', roles: ['tenant-viewer', 'some-future-role'] }) + + expect(principal.roles).toEqual(['tenant-viewer']) + }) + + it('normalises role casing and whitespace the same way Role.fromClaim does', () => { + const principal = parsePrincipal({ sub: 'user-1', roles: [' Tenant-Owner ', 'PLATFORM-ADMIN'] }) + + expect(principal.roles).toEqual(['tenant-owner', 'platform-admin']) + }) + + it('maps a missing organization claim to null, never a default tenant', () => { + const principal = parsePrincipal({ sub: 'user-1' }) + + expect(principal.tenant).toBeNull() + }) + + it('maps a blank organization claim to null', () => { + // Mirrors ApusPrincipal's compact constructor: blank -> null, not an empty-string tenant. + const principal = parsePrincipal({ sub: 'user-1', organization: ' ' }) + + expect(principal.tenant).toBeNull() + }) + + it('maps a missing subject claim to null rather than throwing', () => { + const principal = parsePrincipal({ organization: 'friends-server' }) + + expect(principal.subject).toBeNull() + }) + + it('ignores a non-array roles claim instead of throwing', () => { + const principal = parsePrincipal({ sub: 'user-1', roles: 'tenant-owner' }) + + expect(principal.roles).toEqual([]) + }) +}) + +describe('isRole', () => { + it('accepts exactly the four spec roles', () => { + expect(isRole('platform-admin')).toBe(true) + expect(isRole('tenant-owner')).toBe(true) + expect(isRole('tenant-operator')).toBe(true) + expect(isRole('tenant-viewer')).toBe(true) + }) + + it('rejects near-miss spellings (no separator tolerance)', () => { + expect(isRole('platform_admin')).toBe(false) + expect(isRole('admin')).toBe(false) + expect(isRole('')).toBe(false) + }) +}) + +function principalWith(roles: ApusUiPrincipal['roles']): ApusUiPrincipal { + return { subject: 'user-1', tenant: 'friends-server', roles } +} + +describe('isPlatformAdmin', () => { + it('is true only for platform-admin', () => { + expect(isPlatformAdmin(principalWith(['platform-admin']))).toBe(true) + expect(isPlatformAdmin(principalWith(['tenant-owner']))).toBe(false) + }) + + it('is false for null/undefined principal (unauthenticated)', () => { + expect(isPlatformAdmin(null)).toBe(false) + expect(isPlatformAdmin(undefined)).toBe(false) + }) +}) + +describe('canWriteTenant', () => { + it('is true for tenant-owner and tenant-operator', () => { + expect(canWriteTenant(principalWith(['tenant-owner']))).toBe(true) + expect(canWriteTenant(principalWith(['tenant-operator']))).toBe(true) + }) + + it('is false for tenant-viewer', () => { + expect(canWriteTenant(principalWith(['tenant-viewer']))).toBe(false) + }) + + it('excludes platform-admin, mirroring ApusPrincipal.canWrite() on the api module', () => { + // A platform-admin's write access is to platform resources (tenants, quotas), not to a + // tenant's own sources/maps/renders -- see ApusPrincipal.canWrite()'s Javadoc. + expect(canWriteTenant(principalWith(['platform-admin']))).toBe(false) + }) + + it('is false without a principal', () => { + expect(canWriteTenant(null)).toBe(false) + }) +}) + +describe('canReadTenant', () => { + it('is true for any of the three tenant roles', () => { + expect(canReadTenant(principalWith(['tenant-owner']))).toBe(true) + expect(canReadTenant(principalWith(['tenant-operator']))).toBe(true) + expect(canReadTenant(principalWith(['tenant-viewer']))).toBe(true) + }) + + it('is false for platform-admin alone, mirroring TenantAccess.canRead()', () => { + // A narrow-scope caller with no tenant role fails this gate even with a tenant claim + // present -- see TenantAccess's Javadoc on service tokens for the same rule server-side. + expect(canReadTenant(principalWith(['platform-admin']))).toBe(false) + }) + + it('is false with no roles at all', () => { + expect(canReadTenant(principalWith([]))).toBe(false) + }) +}) diff --git a/ui/tests/unit/sse.spec.ts b/ui/tests/unit/sse.spec.ts new file mode 100644 index 0000000..6aa7bab --- /dev/null +++ b/ui/tests/unit/sse.spec.ts @@ -0,0 +1,72 @@ +import { describe, expect, it } from 'vitest' +import { parseSseStream } from '../../app/utils/sse' + +/** Builds a `ReadableStreamDefaultReader` that yields the given raw text chunks, in order. */ +function readerFromChunks(chunks: string[]): ReadableStreamDefaultReader { + const encoder = new TextEncoder() + const stream = new ReadableStream({ + start(controller) { + for (const chunk of chunks) { + controller.enqueue(encoder.encode(chunk)) + } + controller.close() + } + }) + return stream.getReader() +} + +async function collect(reader: ReadableStreamDefaultReader): Promise { + const events: string[] = [] + for await (const event of parseSseStream(reader)) { + events.push(event) + } + return events +} + +describe('parseSseStream', () => { + it('yields the data payload of a single event', async () => { + const events = await collect(readerFromChunks(['data: {"percent":50}\n\n'])) + + expect(events).toEqual(['{"percent":50}']) + }) + + it('yields multiple events from one chunk', async () => { + const events = await collect( + readerFromChunks(['data: one\n\ndata: two\n\ndata: three\n\n']) + ) + + expect(events).toEqual(['one', 'two', 'three']) + }) + + it('reassembles an event split across multiple chunks', async () => { + const events = await collect( + readerFromChunks(['data: {"perc', 'ent":50}\n', '\n']) + ) + + expect(events).toEqual(['{"percent":50}']) + }) + + it('joins multiple data: lines within one event with a newline, per the SSE spec', async () => { + const events = await collect(readerFromChunks(['data: line one\ndata: line two\n\n'])) + + expect(events).toEqual(['line one\nline two']) + }) + + it('flushes a trailing event that has no final blank line', async () => { + const events = await collect(readerFromChunks(['data: only one, no trailing blank line'])) + + expect(events).toEqual(['only one, no trailing blank line']) + }) + + it('ignores an event with no data: line at all', async () => { + const events = await collect(readerFromChunks([': this is a comment, not data\n\ndata: real\n\n'])) + + expect(events).toEqual(['real']) + }) + + it('produces nothing for an empty stream', async () => { + const events = await collect(readerFromChunks([])) + + expect(events).toEqual([]) + }) +}) diff --git a/ui/tests/unit/tenant/renderProgress.spec.ts b/ui/tests/unit/tenant/renderProgress.spec.ts new file mode 100644 index 0000000..e319abd --- /dev/null +++ b/ui/tests/unit/tenant/renderProgress.spec.ts @@ -0,0 +1,91 @@ +import { describe, expect, it } from 'vitest' +import { describeRenderProgress, formatDuration, isRenderTerminal } from '../../../app/utils/renderProgress' + +describe('isRenderTerminal', () => { + it('is true for Succeeded and Failed', () => { + expect(isRenderTerminal('Succeeded')).toBe(true) + expect(isRenderTerminal('Failed')).toBe(true) + }) + + it('is false for in-progress phases', () => { + expect(isRenderTerminal('Pending')).toBe(false) + expect(isRenderTerminal('Syncing')).toBe(false) + expect(isRenderTerminal('Rendering')).toBe(false) + expect(isRenderTerminal('Finalizing')).toBe(false) + }) + + it('is false for null/undefined rather than throwing', () => { + expect(isRenderTerminal(null)).toBe(false) + expect(isRenderTerminal(undefined)).toBe(false) + }) +}) + +describe('formatDuration', () => { + it('formats sub-minute durations as seconds only', () => { + expect(formatDuration(0)).toBe('0s') + expect(formatDuration(45)).toBe('45s') + }) + + it('formats sub-hour durations as minutes and seconds', () => { + expect(formatDuration(65)).toBe('1m 5s') + expect(formatDuration(600)).toBe('10m 0s') + }) + + it('formats durations of an hour or more as hours and minutes, dropping seconds', () => { + expect(formatDuration(3600)).toBe('1h 0m') + expect(formatDuration(8130)).toBe('2h 15m') + }) + + it('rounds to the nearest second', () => { + expect(formatDuration(44.6)).toBe('45s') + }) + + it('clamps a negative input to zero rather than producing a negative label', () => { + expect(formatDuration(-5)).toBe('0s') + }) +}) + +describe('describeRenderProgress', () => { + it('reports a known percent and eta as-is when non-negative', () => { + const display = describeRenderProgress({ phase: 'Rendering', percent: 42, etaSeconds: 90, degraded: false }) + + expect(display.percentKnown).toBe(true) + expect(display.percent).toBe(42) + expect(display.etaKnown).toBe(true) + expect(display.etaLabel).toBe('1m 30s') + expect(display.degraded).toBe(false) + expect(display.terminal).toBe(false) + }) + + it('reports percent/eta as unknown -- never a fabricated 0 or invented eta -- when the api sends -1', () => { + const display = describeRenderProgress({ phase: 'Rendering', percent: -1, etaSeconds: -1, degraded: true }) + + expect(display.percentKnown).toBe(false) + expect(display.percent).toBeNull() + expect(display.etaKnown).toBe(false) + expect(display.etaLabel).toBeNull() + expect(display.degraded).toBe(true) + }) + + it('clamps an out-of-range percent into [0, 100] rather than passing it straight to a progress bar', () => { + expect(describeRenderProgress({ phase: null, percent: 150, etaSeconds: 0, degraded: false }).percent).toBe(100) + expect(describeRenderProgress({ phase: null, percent: 0, etaSeconds: 0, degraded: false }).percent).toBe(0) + }) + + it('treats percent/eta unknown and degraded as independent signals', () => { + // A measurement can degrade on just one of the two values -- both are checked separately, + // not inferred from `degraded` alone. + const display = describeRenderProgress({ phase: 'Rendering', percent: 60, etaSeconds: -1, degraded: true }) + + expect(display.percentKnown).toBe(true) + expect(display.percent).toBe(60) + expect(display.etaKnown).toBe(false) + expect(display.degraded).toBe(true) + }) + + it('flags terminal phases', () => { + expect(describeRenderProgress({ phase: 'Succeeded', percent: 100, etaSeconds: 0, degraded: false }).terminal).toBe(true) + expect(describeRenderProgress({ phase: 'Failed', percent: -1, etaSeconds: -1, degraded: true }).terminal).toBe(true) + expect(describeRenderProgress({ phase: 'Rendering', percent: 50, etaSeconds: 10, degraded: false }).terminal).toBe(false) + }) +}) diff --git a/ui/tests/unit/tenant/sseController.spec.ts b/ui/tests/unit/tenant/sseController.spec.ts new file mode 100644 index 0000000..2799861 --- /dev/null +++ b/ui/tests/unit/tenant/sseController.spec.ts @@ -0,0 +1,87 @@ +import { describe, expect, it, vi } from 'vitest' +import { openSseController, withAutoStopOnTerminal } from '../../../app/utils/sseController' +import type { SseHandlers } from '../../../app/utils/apiClient' + +describe('openSseController', () => { + it('calls open with the handlers and a fresh, not-yet-aborted signal', () => { + const open = vi.fn().mockResolvedValue(undefined) + const handlers: SseHandlers = { onMessage: vi.fn() } + + openSseController(open, handlers) + + expect(open).toHaveBeenCalledTimes(1) + const [passedHandlers, signal] = open.mock.calls[0] as [SseHandlers, AbortSignal] + expect(passedHandlers).toBe(handlers) + expect(signal.aborted).toBe(false) + }) + + it('aborts the signal passed to open() when stop() is called', () => { + const open = vi.fn().mockResolvedValue(undefined) + const controller = openSseController(open, { onMessage: vi.fn() }) + + const [, signal] = open.mock.calls[0] as [SseHandlers, AbortSignal] + expect(signal.aborted).toBe(false) + + controller.stop() + + expect(signal.aborted).toBe(true) + }) + + it('tolerates stop() being called more than once', () => { + const open = vi.fn().mockResolvedValue(undefined) + const controller = openSseController(open, { onMessage: vi.fn() }) + + expect(() => { + controller.stop() + controller.stop() + }).not.toThrow() + }) + + it('swallows a rejection from open() instead of producing an unhandled promise rejection', async () => { + const open = vi.fn().mockRejectedValue(new Error('stream failed')) + + expect(() => openSseController(open, { onMessage: vi.fn() })).not.toThrow() + // Let the rejected promise's microtask settle; if the catch in openSseController were + // missing, vitest would report an unhandled rejection for this test. + await new Promise((resolve) => setTimeout(resolve, 0)) + }) +}) + +describe('withAutoStopOnTerminal', () => { + it('always forwards the event to the wrapped onMessage', () => { + const onMessage = vi.fn() + const stop = vi.fn() + const wrapped = withAutoStopOnTerminal({ onMessage }, stop) + + wrapped.onMessage({ phase: 'Rendering' }) + + expect(onMessage).toHaveBeenCalledWith({ phase: 'Rendering' }) + }) + + it('does not stop the stream for a non-terminal phase', () => { + const stop = vi.fn() + const wrapped = withAutoStopOnTerminal({ onMessage: vi.fn() }, stop) + + wrapped.onMessage({ phase: 'Rendering' }) + + expect(stop).not.toHaveBeenCalled() + }) + + it('stops the stream once a terminal phase is observed', () => { + const stop = vi.fn() + const wrapped = withAutoStopOnTerminal({ onMessage: vi.fn() }, stop) + + wrapped.onMessage({ phase: 'Succeeded' }) + + expect(stop).toHaveBeenCalledTimes(1) + }) + + it('preserves onError/onClose from the wrapped handlers unchanged', () => { + const onError = vi.fn() + const onClose = vi.fn() + const wrapped = withAutoStopOnTerminal({ onMessage: vi.fn(), onError, onClose }, vi.fn()) + + expect(wrapped.onError).toBe(onError) + expect(wrapped.onClose).toBe(onClose) + }) +}) diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..a746f2a --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/ui/vitest.config.ts b/ui/vitest.config.ts new file mode 100644 index 0000000..713cf43 --- /dev/null +++ b/ui/vitest.config.ts @@ -0,0 +1,18 @@ +import { fileURLToPath } from 'node:url' +import { defineConfig } from 'vitest/config' + +// Deliberately not `@nuxt/test-utils`' Nuxt-aware runner: everything under test (app/utils/*) +// is plain, framework-agnostic TypeScript with no Nuxt auto-imports or runtime dependency -- +// see ui/README.md "Why plain Vitest". A `happy-dom` environment is enough for the DOM globals +// (atob, TextDecoder, ReadableStream) the API client and JWT helpers touch. +export default defineConfig({ + resolve: { + alias: { + '~': fileURLToPath(new URL('./app', import.meta.url)) + } + }, + test: { + environment: 'happy-dom', + include: ['tests/unit/**/*.spec.ts'] + } +}) diff --git a/ui/vitest.nuxt.config.ts b/ui/vitest.nuxt.config.ts new file mode 100644 index 0000000..04bdc5d --- /dev/null +++ b/ui/vitest.nuxt.config.ts @@ -0,0 +1,14 @@ +import { defineVitestConfig } from '@nuxt/test-utils/config' + +// Separate from vitest.config.ts on purpose (see that file's own comment on "why plain +// Vitest" for app/utils/*): this config boots an actual Nuxt app context (auto-imports, +// component auto-registration with the real directory-prefixed names, plugins) so that a +// component referencing e.g. `` where Nuxt only ever registered +// `LayoutAppHeader` fails the test the same way it fails at runtime -- a plain `vue-tsc` +// typecheck or `nuxt build` does not catch this (see tests/nuxt/defaultLayout.nuxt.spec.ts). +export default defineVitestConfig({ + test: { + environment: 'nuxt', + include: ['tests/nuxt/**/*.spec.ts'] + } +})