diff --git a/.github/workflows/ci-docs-versions.yml b/.github/workflows/ci-docs-versions.yml new file mode 100644 index 00000000..54b3b021 --- /dev/null +++ b/.github/workflows/ci-docs-versions.yml @@ -0,0 +1,37 @@ +name: docs versions + +on: + push: + branches: + - master + paths: + - ".github/workflows/ci-docs-versions.yml" + - "scripts/check-documented-versions.sh" + - "site/content/docs/getting-started/installation/index.md" + - "backend/go.mod" + - "frontend/apps/remark42/package.json" + - "frontend/.nvmrc" + pull_request: + paths: + - ".github/workflows/ci-docs-versions.yml" + - "scripts/check-documented-versions.sh" + - "site/content/docs/getting-started/installation/index.md" + - "backend/go.mod" + - "frontend/apps/remark42/package.json" + - "frontend/.nvmrc" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check: + name: Documented versions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Check documented versions against the repository + run: ./scripts/check-documented-versions.sh diff --git a/.github/workflows/ci-frontend.yml b/.github/workflows/ci-frontend.yml index 86940565..0a6888fd 100644 --- a/.github/workflows/ci-frontend.yml +++ b/.github/workflows/ci-frontend.yml @@ -41,11 +41,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Translations check run: pnpm translation-check @@ -77,11 +77,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Run type check run: pnpm type-check @@ -113,11 +113,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Run linters run: pnpm lint @@ -177,11 +177,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Test & Coverage run: pnpm coverage diff --git a/.github/workflows/ci-site.yml b/.github/workflows/ci-site.yml index 361be584..9f887f40 100644 --- a/.github/workflows/ci-site.yml +++ b/.github/workflows/ci-site.yml @@ -9,10 +9,14 @@ on: paths: - ".github/workflows/ci-site.yml" - "site/**" + - "!**/CLAUDE.md" + - "!site/README.md" pull_request: paths: - ".github/workflows/ci-site.yml" - "site/**" + - "!**/CLAUDE.md" + - "!site/README.md" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index d977a08e..224a3fe5 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -10,6 +10,7 @@ on: - "e2e/**" - "compose-e2e-test.yml" - "Dockerfile" + - "!**.md" pull_request: branches: [master] @@ -20,6 +21,7 @@ on: - "e2e/**" - "compose-e2e-test.yml" - "Dockerfile" + - "!**.md" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bd7a7908..b7ed4194 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,10 +12,10 @@ on: - "scripts/**" - "backend/**" - "frontend/**" + - "!backend/**.md" + - "!frontend/**.md" - "README.md" - "LICENSE" - - "CLAUDE.md" - - "site/content/docs/getting-started/installation/index.md" permissions: contents: read @@ -47,7 +47,7 @@ jobs: with: node-version: 24 cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: test and build backend run: | @@ -67,7 +67,7 @@ jobs: - name: install frontend dependencies run: pnpm install --frozen-lockfile - working-directory: frontend + working-directory: frontend/apps/remark42 env: CI: "true" @@ -123,11 +123,11 @@ jobs: with: node-version: 24 cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: install frontend dependencies run: pnpm install --frozen-lockfile - working-directory: frontend + working-directory: frontend/apps/remark42 env: CI: "true" diff --git a/CLAUDE.md b/CLAUDE.md index 08abb1f7..a0c754ed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,13 +10,13 @@ - Run single test: `cd backend/app && go test -run TestName ./path/to/package` - **IMPORTANT**: Run example tests: `cd backend/_example/memory_store && go test -race ./... && go build -race ./...` - **Frontend**: - - Development: `cd frontend && pnpm dev:app` - - Tests: `cd frontend && pnpm test` + - Development: `cd frontend/apps/remark42 && pnpm dev` + - Tests: `cd frontend/apps/remark42 && pnpm test` - **End-to-end**: `make e2e` drives the widget in a real browser; see `e2e/README.md`. Build-tagged, so `go test ./...` never runs it. - **Lint**: - Backend: `cd backend && golangci-lint run` - **IMPORTANT**: Example lint: `cd backend/_example/memory_store && golangci-lint run --config ../../.golangci.yml` - - Frontend: `cd frontend && pnpm lint` + - Frontend: `cd frontend/apps/remark42 && pnpm lint` - **Before committing**: Always run tests and linter on both main backend AND examples - **Go module changes**: - **Any** change to `backend/go.mod` or `backend/go.sum` requires `go mod tidy` in `backend/_example/memory_store` in the same commit. That covers dependency bumps, adding or removing a dependency, and changing the `go` directive, not only version updates. diff --git a/Dockerfile b/Dockerfile index 0215ba03..6d338f85 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,13 @@ FROM --platform=$BUILDPLATFORM node:24-alpine AS frontend-deps ARG SKIP_FRONTEND_TEST ARG SKIP_FRONTEND_BUILD +# the manifest's prepare script installs husky hooks, which needs a git repository the build +# context does not have. husky itself skips on CI, and this is the same flag the build stage sets +ENV CI=true -WORKDIR /srv/frontend/ +WORKDIR /srv/frontend/apps/remark42/ -COPY ./frontend/package.json ./frontend/pnpm-lock.yaml ./frontend/pnpm-workspace.yaml /srv/frontend/ -COPY ./frontend/apps/remark42/package.json /srv/frontend/apps/remark42/ +COPY ./frontend/apps/remark42/package.json ./frontend/apps/remark42/pnpm-lock.yaml /srv/frontend/apps/remark42/ RUN \ if [[ -z "$SKIP_FRONTEND_BUILD" || -z "$SKIP_FRONTEND_TEST" ]]; then \ diff --git a/docs/backlog/public-widget-contract-docs-and-types.md b/docs/backlog/public-widget-contract-docs-and-types.md new file mode 100644 index 00000000..39df3b8c --- /dev/null +++ b/docs/backlog/public-widget-contract-docs-and-types.md @@ -0,0 +1,58 @@ +--- +worth: yes +where: site/content/docs/configuration/frontend/_index.md, frontend/apps/remark42/app/typings/global.d.ts +added: 2026-08-21 +--- +# The public embed contract has no reference page and no shippable type declaration + +Discussion #1714 asked for a description of `window.REMARK42` and TypeScript types, in December 2023. +The contract was written out in a reply on 2026-08-20, but a discussion comment is not documentation, +and the two halves of the request are still open. + +## The docs half + +The pieces exist and are scattered. `configuration/frontend/_index.md:81` documents `changeTheme` only, +in a section about theming. `configuration/frontend/spa.md` shows `createInstance`, `destroy` and the +`REMARK42::ready` event, but as a single-page-app recipe rather than as a reference. The Astro and +Gatsby manuals repeat fragments again. There is no page that states the surface once. + +Three behaviours are documented nowhere and will bite anyone building against it, all in `app/embed.ts`: + +- `createInstance` throws rather than returning an error in three cases: no element with id `remark42`, + `window.remark_config` undefined, or `site_id` unset +- those checks read the **global** `window.remark_config`, while the rest of the function reads the + object passed as the argument, so passing a config does not remove the need for a valid global +- `createInstance` reuses a direct-child iframe carrying `data-remark42-iframe` rather than creating one, + and the config passed to that second call is ignored, so calling it again without a `destroy` silently + does nothing. The reuse also leaves the first instance's `message`, `hashchange` and `click` listeners + installed, so each call adds another set + +Also undocumented: the embed script creates an instance *before* dispatching `REMARK42::ready`, so the +event means the global is safe to touch rather than that nothing is mounted; and `__colors__` reaches +the iframe through `window.name` (`templates/iframe.ejs:42-44`) rather than the URL, so it is read once +at boot and is not a runtime API. + +## The types half, and the open decision + +`app/typings/global.d.ts` is internal: it imports `jest-fetch-mock` and `common/types`, so it cannot be +shipped as-is. A public declaration would be a standalone file with `Theme`, `RemarkConfig` and the +`window.REMARK42` surface and no internal imports. That part is easy. + +**How it reaches a consumer is not decided.** `tsc` picks up types from `node_modules`, and npm is the +direction we have just moved away from: #1715 declined packaging the widgets and #2172 removed +`@remark42/api`. Options, in the order I would rank them: + +1. Publish the file on the site as a copy-paste block, with no package. Zero infrastructure, works + today, and consumers paste it into their own `global.d.ts`. This is what the Astro and Gatsby + manuals need, since both currently declare `REMARK42: any` and `remark_config: any` + (`integration-with-astro/index.md:150`, `integration-with-gatsby/index.md:109`), which is our own + documentation admitting the gap. +2. A types-only npm package. Note this does not contradict #1715: that was declined because shipping + *widget code* through npm puts the widget in the host origin and breaks OAuth. A package containing + no runtime code has none of that problem. It does add a publish step and a version to keep in sync. + +Option 1 clears the reported need. Option 2 only pays off if we want `npm i -D` ergonomics, which is a +separate call. + +Whatever is chosen, fixing the two integration manuals to stop using `any` is the visible win, and +#1714 should get the pull request linked when it lands, as promised there. diff --git a/docs/plans/2026-08-19-frontend-simplification.md b/docs/plans/2026-08-19-frontend-simplification.md new file mode 100644 index 00000000..eee4258b --- /dev/null +++ b/docs/plans/2026-08-19-frontend-simplification.md @@ -0,0 +1,561 @@ +# Frontend direction: two viable paths, and what has to be true for either + +Written 2026-08-19, revised 2026-08-22. Every file reference below was re-checked against master +`a82dc8d3` plus #2196, #2197 and #2198, which are treated here as landed: they change the e2e net, +the manifest layout, the fallback page, the asset path and the instance URL, and costing either +direction against the state before them would be costing a world that no longer exists. + +## Overview + +- The widget's measured cost was the **toolchain and the React compatibility alias**, not Preact + itself. The alias is now gone, so what remains is the toolchain +- Two paths are genuinely viable: **incremental simplification** (keep Preact, finish collapsing the + toolchain) or the **server-rendered rewrite** of #825. This document sets out to cost both rather + than to recommend against one, and it half succeeds: Path A is costed, Path B is not, because two + of its inputs are still open. What language the retained client code is written in, and whether a + scoped XSRF exemption can make the document render authenticated, both change the figure + materially. The "months" estimate below is therefore a placeholder rather than a finding, and + should not be quoted as though the comparison had been made +- Server rendering is not architecturally blocked. Authenticated *fragments* work; the initial + *document* render is anonymous in every configuration, and that is forced rather than chosen +- Whichever path is taken, two standing requirements constrain it, and three pieces of work are + worth doing first regardless. One of those three is now done + +## Standing requirements + +Not tasks. Tests any proposal has to pass. + +### R1: Remark42 must be hostable on a domain other than the site embedding it + +This is a product requirement rather than a constraint to respect in passing, and it is the one +users report against most. The target arrangement is remark42 serving from its own name, say +`remark42.example.com`, with comments appearing on a different site entirely, say `food.com`. It is +documented in `site/content/docs/manuals/separate-domain/index.md`, so operators follow it and then +find that authentication behaves differently from the same-domain case. + +**Acceptance criteria.** A reader on `food.com` can sign in with any configured provider, post, +reload the page, and still be signed in, on a browser that blocks unpartitioned third-party cookies. +Nothing short of the reload proves it: the widget holds a token in memory for the life of a page, so +a test that signs in and posts without reloading passes while the persistence is entirely broken. + +**Where that stands.** The e2e suite covers the rendering half through +`TestCrossOrigin_WidgetRendersOnAnotherOrigin`, which proves the document loads on another origin +and reports itself through postMessage across the boundary, and `ALLOWED_HOSTS` refusal through +`TestCrossOrigin_DisallowedHostNeverReportsInited`. The authentication half is not covered and +cannot be until the e2e stack speaks https, because an embedded cookie needs `SameSite=None`, which +browsers accept only with `Secure`. + +`ALLOWED_HOSTS` sets the CSP `frame-ancestors` and `AUTH_SAME_SITE=none` lets auth cookies be set +from any embedding domain. OAuth is what visibly fails off-domain (discussion #1139). Telegram, +email and anonymous work where third-party cookies are still permitted, and stop working where they +are not: the server's cookies carry no `Partitioned`, and the header fallback is off by default, so +nothing saves them once the browser blocks unpartitioned third-party cookies. + +There is a second mechanism aimed squarely at this, `AUTH_SEND_JWT_HEADER`, which returns the token +in a response header so the client can present it without relying on an ambient cookie. #1877 was +opened by an operator who wanted exactly this for exactly this reason, and #1929 was merged as its +first half. Its persistence never worked on https: the client wrote its copy under a `__Host-` +prefix that neither the backend nor the widget's own reader ever asks for, and marked it +`SameSite=Strict`, which is never sent from a third-party frame. Both are corrected here, and the +frontend now marks its cookies `SameSite=None; Secure; Partitioned` when it detects a third-party +context. The server-set cookies still need the same treatment, and that is upstream work in +`go-pkgz/auth`. + +Constraints on any frontend design: + +- nothing may assume the widget and host page share an origin. Note `BASE_URL` comes from + `remark_config.host`, read into `BASE_URL` in `app/common/constants.config.ts`, so the iframe is + cross-site only when that host differs from the page host; both configurations exist in the wild +- treat third-party cookie loss as the direction of travel. Safari blocks third-party cookies + outright and honours only cookies explicitly marked `Partitioned`; its CHIPS support has been + switched on, off and on again across releases, so pin the current state before relying on a + version number. A design depending on `SameSite=None` surviving has an expiry date +- the endpoint is CHIPS (`SameSite=None; Secure; Partitioned`) or a token not relying on ambient + cookies. Neither is a flag flip, and the first cost is upstream rather than here: + `go-pkgz/auth/v2@v2.2.0` cannot emit `Partitioned` at all. Both cookies are hand-built in + `Service.Set` with only `HttpOnly`, `Path`, `Domain`, `MaxAge`, `Secure` and `SameSite`, and + `AUTH_SAME_SITE` in `cmd/server.go` offers `default`/`none`/`lax`/`strict` with no partitioned + axis, since `Partitioned` is a separate attribute. That is a PR to the library before anything in + this repo changes +- the popup-to-iframe handoff cannot be done in JS. The JWT cookie is `HttpOnly: true`, set in + `Service.Set`, so the top-level popup cannot read it to hand over, and the receiving end would not + work either: `setAuthCookie` in `cookies.ts` writes `SameSite: 'Strict'` under a `__Host-` prefix + with no `Partitioned`, and Strict is never sent from a third-party frame. The handoff has to be + server-mediated, a one-time code redeemed for a `Set-Cookie … Partitioned` issued from the + embedded context. Email and anonymous authenticate over XHR from inside the iframe, which keeps + them working while third-party cookies are permitted, but XHR does not create a partition by + itself, so they need `Partitioned` for the same reason OAuth does +- the failure mode is silent rather than an error, which is why #1139 reads as a hang. OAuth + completion is detected by polling: `oauthSignin` in `auth/auth.api.ts` opens the popup and, on + `visibilitychange` once `authWindow.closed`, calls `getUser()`, with nothing posted back from the + popup. When the cookie is not readable from the embedded context, `getUser()` returns null and the + flow re-polls every minute until the 5 minute deadline gives up, showing a waiting state + throughout. Until #2197 that deadline rejected without tearing the subscription down, so the retry + outlived it and polled for the life of the page; the reason it lasted is that the arrangement it + breaks in is the one nobody runs locally +- the documented escape hatch is the fallback page. When the widget detects a third-party context + with storage unavailable it offers a link to `${origin}/web/comments.html` (`auth-panel.tsx`, the + `IS_THIRD_PARTY` and `IS_STORAGE_AVAILABLE` checks in `app/common/constants.ts`). That page went + unbuilt from the January 2021 rewrite until #2197 restored the entry, so it 404'd for four years + in exactly R1's configuration. Any redesign has to keep emitting it, and nothing pins that yet: + the `documentedWebPaths` table in `e2e/webfiles_test.go` still has no entry for it, which is the + same absence that let it break in the first place +- fixing #1139 must not get harder + +### R2: The language must be selectable per page, and may stay fixed after load + +24 catalogs in `app/locales/`. Locale is read once from `remark_config.locale` (the `locale` export +in `app/common/settings.ts`) and resolved to one chunk by `loadLocale`. There is **no runtime +switcher** and no locale entry in the postMessage contract, so language cannot change during an +instance's life. + +That makes this a comfortable requirement: a site with three language versions embeds each page with +its own locale. Server-generated per-locale output satisfies it as well as the current client +catalog. + +Must survive: + +- `remark_config.locale` keeps selecting the language per instance +- all 24 languages keep working. Adding one is not catalog-only today: the language goes into + `tasks/supportedLocales.json`, and generation then rewrites `app/utils/loadLocale.ts` from it. + Preserve that registry-plus-generation shape or replace it deliberately +- the translation completeness check in `ci-frontend.yml` survives in some form +- `formatDate`/`formatTime` (`Comment` in `comment.tsx`, implemented over `Intl.DateTimeFormat` in + `common/intl.tsx`) keep resolving in the viewer's **timezone**. The locale is not the viewer's: + the provider gets the configured `locale` (`remark.tsx`, from `remark_config.locale` via the + `locale` export in `settings.ts`), which the server knows too. Only the timezone is genuinely + client-side, so the carve-out is timezone-local time rendering rather than a whole date-formatting + layer + +## Server rendering is not blocked, but the document render is anonymous by force + +SSR is sometimes assumed to be impossible here, on the grounds that the widget document is +cross-site and the auth cookie defaults to Lax. That reasoning does not hold: + +- **htmx fragments are XHR, not document navigations.** They are same-origin to the widget document, + so the server-set auth cookie rides along exactly as it does for today's API calls. What + `htmx:configRequest` has to attach is the `X-XSRF-TOKEN` header read from the JS-readable XSRF + cookie, attached by `request()` in `fetcher.ts`, and on **every** authenticated request rather + than only state-changing ones: `request()` attaches it unconditionally for get, put, post and + delete alike. There is no JS-held JWT to attach under default configuration: `activeJwtToken` in + `fetcher.ts` is filled only from an `X-JWT` response header, which the server sends only in + `SEND_JWT_HEADER` mode +- **`AUTH_SEND_JWT_HEADER` defaults to false** (`backend/app/cmd/server.go`). Auth is cookie-based + by default, so the header was never what made it work +- **The cross-domain auth limitation already exists**, is documented, and is #1139's subject. SSR + does not introduce it and does not make it worse +- **The `/web/` cache and rate limit are not a general blocker.** They apply to the current static + route, where `addFileServer` applies `rateLimiter` and `cacheControl`; dynamic HTML served from a + new route avoids that pair, and `/api/v1` open routes already run through `NoCache`. The open + routes do carry their own limiter, `rateLimiter(s.openRouteLimiter)`, so a new route escapes the + static cache, not rate limiting in general. Price which bucket it lands in: open routes allow 10 + req/s per IP (`openRouteLimiter` in `rest.go`) against 20/s for static `/web/`, applied by + `addFileServer`, and a fragment UI multiplies requests per interaction against the tighter one. + Under R1, with readers behind shared egress, that is the operative ceiling +- **`AUTH_SAME_SITE=none` already exists** and would let cookies accompany iframe navigations on + browsers that still allow third-party cookies. It is inert for the document render, though, for + the reason below: the cookie arrives and is then discarded + +The real constraint is not about cookie delivery at all. + +**The first document render is anonymous in the configuration remark42 ships, and changing that is a +security decision rather than a flag flip.** The auth library rejects any cookie-borne token whose +`X-XSRF-TOKEN` header does not match the JWT's `jti`, in `Service.Get` of `go-pkgz/auth/v2@v2.2.0`. +A document navigation, which is what an iframe `src` is, cannot carry a custom header, so the widget +document arrives anonymous even with `AUTH_SAME_SITE=none`, even with third-party cookies fully +permitted, and even with a perfectly delivered partitioned cookie. `authMiddleware.Trace` swallows +the error, which is why it is silent. + +What makes it the current behaviour rather than a law is `XSRFIgnoreMethods`, an option the library +exposes on `Opts` and threads into the JWT service. remark42 leaves it unset, so the default empty +list applies and the short circuit in `Service.Get` never fires for any method. Setting it would +make an authenticated document render possible. + +Do not reach for it globally, though. `GET /deleteme` deletes every comment a user has written, and +is a GET deliberately, so that the link in the confirmation email works when clicked. Exempting GET +from XSRF wholesale removes that protection from a destructive endpoint. Anything built on this has +to scope the exemption to the document route alone, and that route has to be provably side-effect +free. Cost that work rather than assuming either that the door is shut or that it is open. + +There is also a query-parameter path, and it is worse than the constraint: `Service.Get` accepts the +token from a query parameter, `?jwt=` rather than the library default `?token=` because remark42 +overrides `JWTQuery` in `cmd/server.go`, and because `fromCookie` stays false the XSRF check is +skipped entirely. That would put a live JWT into `Referer`, into history, and into the access log if +the route is one that logs bodies. It is unreachable in any case, since the JWT cookie is `HttpOnly: +true`, set in `Service.Set`, and no JS can read it to build the URL. + +So anonymous-first is what the current configuration gives, and the honest Path B position is that +making the document authenticated is a scoped piece of security work with its own cost. Until that +is costed, budget for anonymous-first: render anonymous, then hydrate the user state over XHR, which +does carry the header. Anonymous-first is also what a shared cache wants, though see the hydration +item in Path B for how much that is worth. + +## Verified facts + +Checked against the code at `a82dc8d3` and by independent reviewers. + +- 9 runtime dependencies against 61 devDependencies, and **68** override entries, all in the single + `frontend/apps/remark42/package.json` since #2197 removed the workspace root. Before this effort + started it was 15 against 83 across two manifests +- `pnpm audit` reports **no known vulnerabilities** as of 2026-08-20, after the override work. The + 23 it reported before that were all build or test tooling and none shipped, so the toolchain's + security cost is recurring maintenance rather than a standing exposure, and it is a weak argument + for Path B +- Frontend churn 67 commits in 24 months against 119 on the backend, merges excluded on both sides +- Preact appears in 53 non-test files, 57 counting typings and stubs, and not only for `h` and JSX + types: `Fragment` in 11, `Component` in 7, `render` in 1, `createRef` in 3, `createContext` in 2, + and `preact/hooks` in 19. **No file imports `preact/compat` any more**, no `react` or `react-dom` + entries remain in `package.json`, and the only `paths` entries in `tsconfig.json` point at preact + itself. `frontend/CLAUDE.md` carries a "Don't import preact/compat" section recording why +- Composer plus auth is **~2,400 non-test lines** (`comment-form/` 1,540, `auth/` 867), the most + stateful code in the repo, plus two custom-element packages and the polyfill they need +- The e2e suite is Go and playwright-go since #2180, and passed 60 tests while this was being + written, up from 7. Treat the exact figure as stale on sight; it is the only coverage that + survives a rewrite +- The unit suite is 46 files, 25 `*.test.*` plus 21 `*.spec.*`, and **426 cases**, as jest + enumerates them. Counting only `*.test.*` understates it by twenty files, which is the trap +- `en.json` is 180 keys with no ICU plural or select forms +- 136 non-test source files under `app/` excluding typings, mocks and stubs, 8,498 lines; 152 files + and 8,715 lines counting them +- `profile.ts` (139 lines) is only the iframe host; the view is `profile.tsx` (235) reusing + `Comment` (638) in `view="user"` mode +- `last-comments` renders into the **host page**, not an iframe, and side-loads its own stylesheet + (`last-comments.tsx`) +- `/find` already supports server pagination via `limit` and `offset_id` in `findCommentsCtrl`; only + the widget ignores them +- Client-only state: collapse persisted via `remark.tsx` and `store/thread/utils.ts`; hidden users + localStorage-only (`store/user/actions.ts`); votes optimistic via component state, with the store + patched only on success and errors merely clearing `loadingState` (`comment-votes.tsx`) +- Emoji rendering and the image proxy already run server-side in `CommentFormatter`, wired in + `cmd/server.go`, so neither is a Path B cost +- 8 `window.confirm` call sites gate delete, pin, verify, block and hide (six in `comment.tsx`, two + in `settings.tsx`). The iframe carries no `sandbox` attribute, so `allow-modals` is not the issue, + but cross-origin iframe dialogs have been targeted for removal once already (Chrome 92, rolled + back after breakage). #2024 proposes an inline replacement. Either path inherits all 8, and R1 is + exactly the configuration where it bites +- `CommentFormatter` in `formatter.go` runs chroma with `html.WithClasses(true)`, so highlight CSS + lives in the bundle; `Comment.Text` is pre-sanitised while `Orig` is explicitly unsafe, as + `store.Comment` documents +- `getLocalIdent` in `webpack.config.js` emits order-dependent ids via `incstr`, **in production + only**; development builds use readable `[name]__[local]_[hash:5]`, since `getLocalIdent` is + production-only. They are stable for an identical module order and churn on any add or reorder, so + no embedder has a CSS override surface that survives an upgrade + +## What the bundler still does + +The concrete "what is left" list, and what any no-npm proposal has to answer for. + +- transpiles TS and JSX for 136 to 152 source files, typed by `tsconfig.json`, compiled by the + preset list in `.babelrc.js` +- CSS modules for 29 `*.module.css` files, 2,219 lines, including 177 nested `&`, 4 `composes` and + 10 `:global` occurrences across 6 files, all handled by the CSS-modules rule in + `webpack.config.js`. One of the `composes` crosses a file boundary (`auth.module.css` composes + `input` from `components/input/input.module.css`), which has no plain-CSS equivalent and has to be + flattened rather than translated +- code-splits the 24 locale JSON catalogs (`app/utils/loadLocale.ts`, itself generated) and + `node-emoji` (the lazy import in `comment-form/text-expander.tsx`) +- runs postcss-preset-env against `defaults, not IE 11, not samsung 12` +- builds six `.ejs` templates through `HtmlWebpackPlugin`, the sixth being `comments.ejs`, the R1 + fallback page above +- resolves images through `file-loader`. The public path is derived at runtime from the URL the + bundle was loaded from since #2197; before that it was fixed to `/web/`, so a sub-path install of + the kind `site/content/docs/manuals/subdomain/index.md` documents fetched its provider icons from + the domain root. A build with no bundler has to derive every asset URL from `BASE_URL` itself, and + inherits that requirement rather than the fix +- strips `data-testid` through a local babel plugin, which nothing else replicates +- minifies JS and CSS +- supplies `REMARK_NODE`, `REMARK_URL` and `NODE_ENV` through `DefinePlugin`, read by `NODE_ID` and + `BASE_URL` in `constants.config.ts`, and by `last-comments.tsx`. `REMARK_URL` is the one that had + teeth: it was baked in as `{% REMARK_URL %}` and substituted by the release script, which left + every published binary serving a widget pointed at loopback. #2198 moved the substitution to serve + time in the Go file server, so a no-bundler build inherits a working mechanism rather than a + broken one + +Five CI jobs depend on npm and each needs a replacement or an accepted loss: `translations-check`, +`type-check`, `lint`, `size-limit` and `test`, all in `ci-frontend.yml`. + +### What is already out + +The widget build is the last npm consumer in the repository, which is worth stating because it was +not true a week ago. + +- **`site/`** has no `package.json` at all since #2179 moved it from eleventy to hugo. It is now a + Go static generator against `hugo.toml`, `layouts/` and `content/`, and is no longer a separate + npm decision deferred to later +- **`e2e/`** is a Go module since #2180. Note the caveat: `playwright-go` downloads a node runtime + and the playwright npm package as its browser driver at test time (`e2e-tests.yml` caches both). + That is a fetched runtime rather than a tracked dependency, so it survives whatever happens here +- **`@remark42/api`** and `frontend/packages/` are gone with #2172 +- **Three static assets** moved into `backend/app/webassets/assets` in #2181 and are embedded in the + Go binary, which is the working proof that the no-build serving path carries real files + +Since #2197 removed the workspace root there is one manifest and one lockfile, +`frontend/apps/remark42/package.json` and its `pnpm-lock.yaml`. `release.yml` still runs pnpm to +build the widget, and that step goes when the widget build does. + +## Do first, regardless of path + +### Task 1: Document and type the public contract + +Answers discussion #1714. It is a discussion rather than an issue, so no PR closes it; the same is +true of #1715 and #1383. Every third-party integration found in the wild uses `remark_config` plus +`window.REMARK42.createInstance()`, and none of it is documented. + +The contract was written out in a reply on #1714 on 2026-08-20, and +`docs/backlog/public-widget-contract-docs-and-types.md` records the remaining work. One decision is +open and belongs here rather than in the backlog note: **how a public `.d.ts` reaches a consumer** +now that npm is the direction being left. Publishing it on the site as a copy-paste block needs no +infrastructure; a types-only package does not contradict #1715, whose objection was that shipping +widget *code* through npm breaks OAuth, but it adds a publish step and a version to keep in sync. + +- [ ] Document `createInstance`, `destroy`, `changeTheme`, the `REMARK42::ready` event and every + `remark_config` field, including the two behaviours that bite: `createInstance` throws rather than + returning an error, and its guard clauses read the **global** config while the rest of the + function reads the argument, so passing a config does not remove the need for a valid global. A + second call also reuses the iframe and ignores the config passed to it. #2197 stopped that call + stacking a second listener set, but left the reuse itself alone, so what the contract should be is + still open: replace the instance atomically, or return the existing one and require `destroy` + before a configuration change +- [ ] Ship a `.d.ts`, after deciding how it is delivered +- [ ] Move the REST reference out of `site/content/docs/contributing/api` into the integration docs; + #1383 states the API is the supported path for custom frontends +- [ ] Document `__colors__` from `window.name` (`templates/iframe.ejs`), which works today and is + undocumented +- [ ] Fix the Astro and Gatsby manuals, which declare `REMARK42: any` and `remark_config: any` + +### Task 2: Extend the e2e suite + +**Done.** #2180 moved the suite to Go and playwright-go and took it from 7 tests to 22; #2196 took +it to 48. Every item this task originally listed is covered: vote and its failure path +(`vote_test.go`), edit inside and outside the deadline, delete and reply (`comment_test.go`), sort +change and collapse persistence (`thread_test.go`), anonymous and email auth (`auth_test.go`), the +profile iframe and last-comments (`widgets_test.go`). + +What remains uncovered is a different list, and it is the contract surface rather than the +behaviour: a cross-origin host page (every host page in the suite is served from the widget origin, +so R1 has no coverage at all), the `comments.html` fallback, `remark_config` fields (`url`, +`page_title`, hash deep links, `max_shown_comments`, the three `show_*_subscription` flags, +`__colors__`), the listener leak on a repeated `createInstance`, timezone-local date rendering, the +unknown-locale fallback, and the composer. + +### Task 3: Stable class names and a documented override stylesheet + +Closes #5, open since 2018. Server-rendered markup needs stable names anyway, and the current ids +churn per build so there is nothing to preserve, only something to start honouring. + +- [ ] Replace the `getLocalIdent` output with stable semantic names on the public surface +- [ ] Document the override point + +The surface that exists today is accidental rather than designed, but it is not small, and that +changes what Task 3 is. `auth.tsx` alone emits sixteen global names (`auth`, `auth-error`, +`auth-dropdown`, `auth-form`, `auth-form-title`, `auth-row`, `auth-tabs`, `auth-tabs-item`, +`auth-divider`, `auth-close-button`, `auth-token-textarea`, `auth-submit`, `auth-button`, +`auth-back-button`, `auth-input-username`, `auth-input-email`). Add `select`, `select_focused`, +`select_`, `select-arrow` and `select-element` (`select.tsx`), `sort-picker` +(`sort-picker.tsx`), `oauth-icon` (the `OAuth` component in `oauth.tsx`), bare `.dark`/`.light` on +the root wrapper, and `comment_highlighting`, applied imperatively in `root.tsx`. Six module files +reach these through `:global()`. + +So the first step is an inventory rather than a design: integrators may already be relying on any of +these, and they have to be treated as a contract to preserve rather than a blank sheet. Note also +that the hashed names are deterministic for an identical module order, so they churn on a reorder +rather than on every build; the problem is that nothing tells an integrator which of the two kinds +of name they are looking at. + +Two things make this more urgent than its age suggests. Production and development emit different +names, so a developer never sees what an integrator sees. And unit tests run through +`identity-obj-proxy`, mapped in `jest.config.mjs`, so no test observes a real class name and nothing +would catch a naming regression. + +`app/styles/custom-properties.css` is the one stylesheet already in the right shape for this: 80 +plain custom properties, no module scoping, nothing for the bundler to rename. + +**Ordering caution.** #2128 is rewriting this same CSS layer on the assumption that hashed class +names stay. Settling the direction here first avoids redoing that work. + +## Path A: incremental simplification + +Keep Preact. Remove what makes it expensive. + +- [x] Replace `react-redux`. Done in #2175: `app/store/context.tsx` is a small binding over preact + context, and the store's own logic was already plain `redux` plus `redux-thunk` +- [x] Replace `react-intl`. Done in #2176: `app/common/intl.tsx` is a 253-line binding over preact + context with 25 importers. Note what it does **not** implement, because it constrains R2: `{name}` + interpolation and paired `` rich text only, with no ICU plural, select, typed arguments or + apostrophe quoting. All 24 catalogs stay within that today +- [x] Delete the `react`/`react-dom` aliases, `@preact/compat` and the `paths` entries in + `tsconfig.json`. Done in #2176 +- [x] Collapse the compiler pipelines to one. Done in #2178: `ts-loader`, `@swc/jest`, `@swc/core` + and enzyme are gone, `babel-loader` is the only compiler, and `jest.config.mjs` hands the same + `.babelrc.js` to `babel-jest`. The same PR dropped the module/nomodule dual build, so output is + `[name].mjs` only and `.js` is a server-side alias (the alias comment in + `backend/app/rest/api/webfiles.go`) +- [ ] Evaluate **preact + htm over native ESM**, and treat the answer as likely no. It is not the + cheap item it looks: dropping the JSX transpile drops type-checked markup, since the `jsx: + react-jsx` and `jsxImportSource: preact` options in `tsconfig.json` is what types templates today + and `htm` tagged literals are opaque to `tsc`. Rewriting every `.tsx` with a type-safety + regression is the same objection the Rejected section uses against a vanilla rewrite. Unbundling + 136 or more source files plus 24 locale chunks into individually fetched modules also multiplies a + cold load's request count against the 20/s `/web/` bucket that `addFileServer` applies, and + because `cacheControl` sends `max-age=3600, no-cache` with an ETag even a warm cache revalidates + each one. It additionally collides with the legacy `.js` contract, which promises module-free + bytes + +**What actually happened**: the first four items landed within two days of this document being +written, on 21 August. Only the htm evaluation is open, which retires the original framing that this +path "spends the expensive `react-intl` card on the option that does not remove npm". That card is +already played, and it cost less than estimated. + +**The revised objection**: the devDependency target did not materialise. This document predicted a +fall from 82 to roughly 20; the figure after the collapse is 59. What survives is not compilation +but **gates and machinery**: eslint, stylelint, prettier, size-limit, `@formatjs/cli` and the +webpack plugin set. That reframes both paths. The remaining question is no longer how the code is +compiled, it is what verifies it. + +## Path B: server-rendered, #825 + +- [ ] Serve dynamic HTML from a **new route**, and not just outside `/web/`. It must also sit + outside `/api/v1`, because `apiCSPMiddleware` replaces the CSP on everything mounted there with + `default-src 'none'; sandbox; frame-ancestors 'none'`, from `rest/image_headers.go`, which would + sandbox the widget document and forbid framing it at all. The global `securityHeadersMiddleware` + is what supplies `frame-ancestors` from `ALLOWED_HOSTS`, so it is also R1's enforcement point. + Note its `form-action 'none'`: htmx uses XHR and is unaffected, but a progressive-enhancement + design built on real form submissions is blocked by the existing policy +- [ ] Render anonymous-first, then hydrate. Budget this as a **second full render of the tree**, not + a patch: user identity threads through every node. `prepVotes` in `store/service/service.go` sets + each comment's `Vote` from the requester and strips the voter map, `alterCommentCached` blanks + `User.IP` for non-admins, and on top sit the edit window, own-comment delete, admin controls and + hidden users. The backend already shows the shape: `/find` keys its cache on `URLKeyWithUser` + (`URLKeyWithUser`, used by `findCommentsCtrl`), one entry per user with a separate `admin!!` key. + An HTML cache fragments the same way, so the shared-cache benefit only pays for logged-out readers +- [ ] Attach the existing auth via `htmx:configRequest` on fragment requests +- [ ] Keep client-side: embed script, auth popups, composer, collapse and hidden-user state, + optimistic votes, and the **three subscription flows**. Email, Telegram and RSS + (`comment-form/__subscribe-by-email/`, `__subscribe-by-telegram/`, `__subscribe-by-rss/`) are each + multi-step and stateful (send code, enter code, confirm; QR plus poll), backing seven private + endpoints in `routes()` plus the `GET /qr/telegram` route +- [ ] Keep the height shim on every swap. The iframe has no intrinsic height; the parent sizes it + from `postMessage({height})` (`updateIframeHeight` in `utils/post-message.ts`, consumed in + `embed.ts`). The ResizeObserver that feeds it already exists (the `ResizeObserver` in `root.tsx`, + plus the dropdown one in `auth.hooks.ts`), so this is code to carry forward rather than write +- [ ] Serve the `?selfClose` stub from the new route. OAuth builds its return URL from the widget + document's own path (`oauth.tsx` builds `origin + pathname + '?selfClose'`) and `iframe.ejs` + closes the popup on arrival. Move the document and the return URL moves with it, so the new route + inherits the self-closing stub and must not cache that response +- [ ] Thread `?site=` through every fragment URL. `matchSiteID` rejects an empty `site` param on + every private and admin request, so a fragment that omits it gets a 403 rather than a 401 +- [ ] Join the public response cache's flush scopes. Comment and info responses are cached keyed by + `Scopes(siteID, URL)` and flushed on writes (`findCommentsCtrl` and `infoCtrl`); a dynamic HTML + route outside those scopes serves stale comments after every post +- [ ] Move i18n server-side except timezone-local `formatDate`/`formatTime`. This is a from-zero + build: `backend/app/templates` holds five templates today, four email plus one error page, and no + catalog machinery. Go's `text/template` has no plural support either, so the current no-ICU + position has to be stated as a rule or implemented on both sides +- [ ] Decide what happens to the two host-DOM scripts, `last-comments` (`last-comments.tsx`) and + `counter` (`counter.ts`), which write into the host page rather than into the iframe. Cross-origin + server rendering is available to them through CORS fragments (the backend runs `corsMiddleware()` + unless `ProxyCORS` is set, in `routes()`) or through an iframe, so this is a design choice, not a + blocker + +**Cost**: months to an opt-in parallel UI reads as a floor derived from the optimistic architecture, +and the optimistic architecture does not hold. Anonymous-first is forced rather than chosen, so the +fragment layer reproduces the entire authenticated tree rather than a delta; add the three +subscription flows and, if R1 is to be honoured, the upstream `Partitioned` work in `go-pkgz/auth`. +On one contributor the realistic figure is long enough that the plan's own warning applies to the +schedule and not only to the design. Deletes the entire npm toolchain. **Against it**: 2,400 lines +of the most stateful code get rewritten; a second HTML-fragment API surface becomes permanent +alongside the JSON one; and no comparable project does this (isso, utterances, waline and cusdis are +all client-rendered, giscus does SSR in JS, and comentario, the closest Go analogue, ships a +framework-free TS web component). + +The net that rewrite would run against is materially better than when this was written: sixty-odd +tests rather than seven, and still growing. It is still not a substitute for the 426 unit cases, +which is a separate item below. + +**The unresolved tension**: "deletes the entire npm toolchain" and "keep the composer, auth, votes, +collapse and the embed script client-side" pull against each other. That kept code is 2,400 lines of +TSX today and the composer leans on two custom-element packages and a polyfill. Without npm it +becomes hand-authored vanilla or htm modules, which is the same "unowned in-house framework" risk +the Rejected section uses to rule out a full vanilla rewrite, now applied to the most stateful code +in the repo. Path B is not costed until it says what the kept client code is written in. + +## What neither path has answered yet + +Missing from both costings, and each one can move the verdict. + +- **A definition of done for "no npm".** Which files and jobs actually go: the node stages in + `Dockerfile`, the five `ci-frontend.yml` jobs, the pnpm steps in `release.yml`, husky and + lint-staged. And what replaces each gate, or which loss is accepted +- **A browser-support floor.** the browserslist query in `.babelrc.js` targets `defaults, not IE 11, + not samsung 12` today. Without a transpiler that becomes the literal floor and source syntax ships + as written, which matters for native CSS nesting and JSON import attributes +- **A runtime-dependency inventory.** For each of `preact`, `redux`, `redux-thunk`, `clsx`, + `lodash-es/isEqual`, `node-emoji` and the three custom elements: is there a usable ESM build, what + is the licence, and is it vendored into `backend/app/webassets/assets` or dropped. The two the + plan itself proposes, `htm` for Path A and `htmx` for Path B, belong in the same inventory with + the same columns, plus what each costs the CSP. "Vendor the custom elements" understates them: + `markdown-toolbar` mutates textarea selections and `text-expander` emits its own events and lazily + loads the emoji data, so the tags rendering is not the same as the behaviour working +- **A security section.** Messages are still posted with `'*'` in both directions + (`postMessageToParent` and `postMessageToIframe` in `post-message.ts`), so both ends check the + sender rather than the target: #2197 made the parent ignore anything that did not come from a + frame it created, and the child side checks `isFromParent`. The child cannot do better, because + the host page is whatever site embeds the widget and `ALLOWED_HOSTS` is what constrains that, + server side through `frame-ancestors`. The parent can: it builds the iframe URL from `BASE_URL`, + so it knows the widget origin and could both pass that as `targetOrigin` instead of `'*'` and + compare `event.origin` alongside `event.source`. That hardening is available and not done. Beyond + the channel, `dangerouslySetInnerHTML` on comment text and preview (`comment.tsx` and + `comment-form.tsx`) relies entirely on server-side sanitisation in `store.Comment`, and any new + route needs its CSP decided +- **The integrator compatibility contract beyond the JS API.** The documented `/web` URLs pinned by + `documentedWebPaths` in `e2e/webfiles_test.go`, the `remark_config.components` loader, and the + legacy `.js` names, which must stay module-free. `/web` is also an overlay rather than one + directory: a `--web-root` file wins and only a missing name falls through to the embedded assets + (`webFileSystem` in `webfiles.go`, mounted by `addFileServer`), so moving a page between the two + sources silently changes whether an operator can override it +- **Translation tooling after node.** Only `@formatjs/cli` is genuinely npm-bound; the downstream + `tasks/*.js` scripts are dependency-free node over `extracted-messages/messages.json`. Note the + failure mode: extraction matches the identifiers `defineMessages`, `FormattedMessage` and + `intl.formatMessage` rather than an import source, so moving strings into Go templates extracts + zero keys with a zero exit code, after which `generateDictionary.js` deletes them from all 24 + catalogs +- **A replacement strategy for the 426 unit cases**, naming what e2e cannot reach: the store, the + fetcher, cookie handling and the intl parser. Two whole flows sit here rather than in the e2e net: + Telegram auth and subscription have no browser route at all, which the e2e suite's own backlog + note records, and RSS subscription is covered only for whether its control renders. Path B keeps + all three subscription flows, so it inherits all three gaps +- **Whether dependency-free node scripts are allowed to stay.** The goal bans the installed + dependency tree and the build and test machinery, but `tasks/checkTranslation.js` and its siblings + need only node built-ins. Nothing in the goal as stated decides whether they survive as scripts or + have to be ported to Go, and the answer changes the size of the i18n item +- **A build-output acceptance matrix.** Each generated HTML page, the dynamic catalogue and emoji + payloads, the copied images, the stripped `data-testid` attributes and the compressed size budgets + are today the emergent result of separate webpack rules and plugins rather than one replaceable + step. Without a statement of what the output must contain, a replacement cannot be checked against + anything +- **Size budgets and the dev loop.** `.size-limit.js` and `webpack-dev-server` both disappear with + npm; a Go test over the embedded FS covers the first, `make rundev` plus `--web-root` the second +- **Storage partitioning semantics.** Collapse, hidden users, sort, draft and email all live in + widget-origin `localStorage`, so on a multi-site install "persists across reload" becomes per top + site +- **Sequencing against #2128**, which rewrites the CSS layer on the assumption that hashed class + names stay. It is the one piece of work in flight that Task 3 collides with, and settling the + class-name direction first is what stops that work being redone + +## If Path B is chosen + +Ship it as an opt-in parallel UI (`remark_config.ui: 'v2'` on a separate endpoint), time-boxed, with +a stated date at which one of the two is deleted. With one active frontend contributor the realistic +failure is not picking the wrong stack, it is carrying two half-finished ones. + +## Rejected + +- **Full vanilla rewrite**: the render layer becomes an unowned in-house framework +- **lit / alpine / solid / petite-vue**: none removes more tooling than Path A, each trades a known + 3 kB library for a less-known one +- **Packaging widgets for npm (#1715)**: the widget must run in an iframe on the remark42 origin for + OAuth popups; importing it into a host bundle breaks auth. A types-only package is a separate + question and is not covered by that objection +- **`@remark42/api`**: removed in #2172. It had no OAuth method and no consumers. + `frontend/packages/` is gone with it, and #2197 removed the workspace root outright, leaving a + single manifest and lockfile under `frontend/apps/remark42` diff --git a/e2e/widgets_test.go b/e2e/widgets_test.go index f03edd4b..90f59352 100644 --- a/e2e/widgets_test.go +++ b/e2e/widgets_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "net/http" + neturl "net/url" "os" "path/filepath" "strconv" @@ -326,3 +327,83 @@ func TestWidgets_SimpleViewHidesTheEditingFurniture(t *testing.T) { }) } } + +// TestWidgets_CommentsPageOpensAThreadOnItsOwnOrigin covers /web/comments.html, which is where the +// widget sends a reader whose browser blocks third-party storage: the auth panel links it, and the +// page mounts the widget on the instance's own origin, where the storage is first-party. +// +// The page is built from templates/comments.ejs by HtmlWebpackPlugin, and the build stopped +// emitting it while the link went on pointing at it, so readers who followed it reached a 404. +// Nothing noticed, because it is the one page no other test opens. +func TestWidgets_CommentsPageOpensAThreadOnItsOwnOrigin(t *testing.T) { + thread := threadURL(t) + text := "cookie fallback " + runID + + poster := newPage(t) + posted := openURL(t, poster, thread) + signInAnon(t, poster, posted, "fallbackposter") + postComment(t, posted, text) + + page := newPage(t) + pauseForAuthLimit() + resp, err := page.Goto(fmt.Sprintf("%s/web/comments.html?site_id=remark&url=%s", + baseURL, neturl.QueryEscape(thread))) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, 200, resp.Status(), + "the page the auth panel links to when third-party storage is blocked is not served") + + // it reads the thread out of its own query string and mounts the widget itself, so reaching + // the comment proves the page was served, its inline script ran, and it asked for the right + // thread. a 200 alone would be satisfied by any page the server happened to return + frame := widget(t, page) + waitVisible(t, comment(frame, text)) +} + +// TestWidgets_CommentsPageRefusesInjectedMarkup covers the reflected injection the fallback page +// carried. It puts the url from its own query string into the title, and building that with +// innerHTML let a crafted url run script in a top-level document on the instance's own origin, +// which is where the reader's session lives; inside the widget frame the same payload would be +// far less use. The hole and the page arrived together, since it is only reachable at all now +// that the build emits it again +func TestWidgets_CommentsPageRefusesInjectedMarkup(t *testing.T) { + for _, tc := range []struct { + name, url string + }{ + {"markup", `">`}, + {"javascript scheme", "javascript:window.__xss=1"}, + } { + t.Run(tc.name, func(t *testing.T) { + page := newPage(t) + + pauseForAuthLimit() + // %20 and not +, which is what a browser produces and what the page's own parser + // reads back: it decodes with decodeURIComponent, which leaves a + as a plus + escaped := strings.ReplaceAll(neturl.QueryEscape(tc.url), "+", "%20") + _, err := page.Goto(fmt.Sprintf("%s/web/comments.html?site_id=remark&url=%s", baseURL, escaped)) + require.NoError(t, err) + waitVisible(t, page.Locator("#title")) + + // nothing the url asked for became an element + imgs, err := page.Locator("#title img").Count() + require.NoError(t, err) + assert.Zero(t, imgs, "the url reached the page as markup, so a crafted one runs script "+ + "on the instance's own origin") + + ran, err := page.Evaluate(`() => Boolean(window.__xss)`) + require.NoError(t, err) + assert.Equal(t, false, ran, "the injected script ran") + + // and the title still shows what it was given, so what changed is the escaping and + // not the feature + txt, err := page.Locator("#title").InnerText() + require.NoError(t, err) + assert.Contains(t, txt, tc.url, "the title should carry the url as text") + + // only http(s) reaches href, or the anchor itself becomes the payload + href, err := page.Locator("#title a").First().GetAttribute("href") + require.NoError(t, err) + assert.Empty(t, href, "a url the page will not navigate to should not become a link") + }) + } +} diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md index 365977c3..1b570561 100644 --- a/frontend/CLAUDE.md +++ b/frontend/CLAUDE.md @@ -8,7 +8,7 @@ CI staying green does **not** mean every pin is consistent — `.nvmrc` in parti - `Dockerfile` (production image) — `FROM node:X-alpine` and `npm i -g pnpm@X.Y.Z` - `frontend/.nvmrc` — not read by CI at all; only matters to a human running `nvm use` locally. This is the one that drifted unnoticed: it sat at `16` through the whole node-20 migration because nothing red ever pointed at it. -- Every `package.json`'s `packageManager` field (`frontend/package.json`, `frontend/apps/remark42/package.json`) and `frontend/apps/remark42/package.json`'s `engines` block +- `frontend/apps/remark42/package.json`, both its `packageManager` field and its `engines` block - `pnpm/action-setup@vN` blocks in `.github/workflows/ci-frontend.yml` (5) and `release.yml` (2) — pin `version:` to the **exact** patch (e.g. `10.10.0`), matching `packageManager`, not just the major. A floating major here is silent in CI (it just resolves to whatever the latest patch is at run time) but breaks the "Dockerfile and CI use the same pnpm" guarantee. - `node:` matrices in `.github/workflows/ci-frontend.yml` (every entry, not just the first) and the `node-version:` values in `release.yml` @@ -16,6 +16,16 @@ When bumping pnpm/node, also re-check `frontend/apps/remark42/package.json`'s `e `engines.node` states the major we support, currently `>=24`, which is the active LTS; 22 has dropped to maintenance. `@babel/core` 8 wants `^22.18 || >=24.11` and `size-limit` 13 wants `^22.18 || ^24 || >=26`, so 22 was the floor rather than the target. Individual dev dependencies can be stricter within that major (`undici` wants `>=20.18.1`); do not chase those patch floors into `engines` or the docs, or every lockfile refresh becomes a documentation change. +## One manifest, at `frontend/apps/remark42` + +`frontend/` holds no `package.json`, no lockfile and no `pnpm-workspace.yaml`. Everything pnpm reads +lives in `frontend/apps/remark42`: the dependencies, `packageManager`, `engines` and the +`pnpm.overrides` block. Install and run from there, not from `frontend/`. + +The directory nesting is kept because every path in the repository points at it, from the Dockerfile +and the workflows to the published contributing docs. `frontend/` still carries `.nvmrc`, `.husky` +and this file, none of which pnpm reads. + ## pnpm 10's stricter `node-linker` layout needs explicit pins One dep is pinned specifically because of pnpm 10's hoisting changes, not because of the dep itself: @@ -74,11 +84,11 @@ Keep both in step. If babel were left on the classic `pragma: 'h'` transform, a without `import { h }` would type-check and lint clean, then throw at runtime, because `eslint-config-preact` sets `react/react-in-jsx-scope` to 0 and the local config turns `no-undef` off. -## `@babel/core` is pinned to 8 for the whole workspace +## `@babel/core` is pinned to 8 for the whole dependency tree `@jest/transform` and `istanbul-lib-instrument` depend on `@babel/core` 7 outright, and a babel 8 preset loaded into a babel 7 core fails on the first `enum` it meets. The `pnpm.overrides` entry in -`frontend/package.json` is what stops that. `eslint-config-preact` is the one consumer that cannot +`frontend/apps/remark42/package.json` is what stops that. `eslint-config-preact` is the one consumer that cannot take it: its `@babel/eslint-parser` loads babel 7 syntax plugins that babel 8 rejects, so a second scoped override, `eslint-config-preact>@babel/core`, holds that subtree on 7. @@ -103,8 +113,8 @@ directory second, matching the backend's order, so links to them resolve on the `eslint.config.mjs` lives in `apps/remark42`, and eslint loads the config next to the directory it is *run from* rather than the one nearest the file being linted. Anything that invokes eslint has -to have `apps/remark42` as its working directory: the workspace-root `lint` script filters to the -app, `.husky/pre-commit` cd's into it, and an IDE integration needs +to have `apps/remark42` as its working directory: it is where every script runs, `.husky/pre-commit` +cd's into it, and an IDE integration needs `"eslint.workingDirectories": ["frontend/apps/remark42"]`. Rules that only exist under a plugin's flat-config export are spread in explicitly; the block that diff --git a/frontend/apps/remark42/app/common/cookies.https.test.ts b/frontend/apps/remark42/app/common/cookies.https.test.ts new file mode 100644 index 00000000..07f72b24 --- /dev/null +++ b/frontend/apps/remark42/app/common/cookies.https.test.ts @@ -0,0 +1,90 @@ +/** + * @jest-environment jsdom + * @jest-environment-options {"url": "https://remark42.example.com/web/iframe.html"} + */ + +/** + * The naming bug this guards against only appeared on https, because the prefix was applied from + * `window.location.protocol`. Every other suite here runs on the jsdom default of http, so the + * decoration never showed up and the defect reached production untouched. This file exists to run + * the same code on an https page, which is the only condition that reveals it. + */ + +function captureRaw() { + const written: string[] = []; + const original = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); + + Object.defineProperty(document, 'cookie', { + configurable: true, + get: () => '', + set: (v: string) => { + written.push(v); + }, + }); + + return { + written, + restore() { + delete (document as unknown as Record).cookie; + if (original) Object.defineProperty(Document.prototype, 'cookie', original); + }, + }; +} + +async function loadCookies(thirdParty: boolean) { + jest.resetModules(); + jest.doMock('./constants', () => ({ IS_THIRD_PARTY: thirdParty })); + + return import('./cookies'); +} + +afterEach(() => { + jest.dontMock('./constants'); +}); + +describe('auth cookies on an https page', () => { + it('writes the undecorated name the backend and the fetcher read', async () => { + const raw = captureRaw(); + const { setAuthCookie } = await loadCookies(false); + + setAuthCookie('JWT', 'token'); + setAuthCookie('XSRF-TOKEN', 'jti'); + + // the backend looks for JWT and `fetcher` reads XSRF-TOKEN. A __Host- prefix stores both + // under names neither of them asks for, and only here, on https + expect(raw.written[0]).toMatch(/^JWT=token/); + expect(raw.written[1]).toMatch(/^XSRF-TOKEN=jti/); + expect(raw.written.join('\n')).not.toContain('__Host-'); + + raw.restore(); + }); + + it('marks the cookie for third-party delivery when the page is on another origin', async () => { + const raw = captureRaw(); + const { setAuthCookie } = await loadCookies(true); + + setAuthCookie('JWT', 'token'); + + expect(raw.written[0]).toContain('sameSite=None'); + expect(raw.written[0]).toContain('secure'); + expect(raw.written[0]).toContain('partitioned'); + + raw.restore(); + }); + + it('clears under the same attributes, so the browser matches the cookie it set', async () => { + const raw = captureRaw(); + const { clearAuthCookie } = await loadCookies(true); + + clearAuthCookie('JWT'); + + expect(raw.written[0]).toMatch(/^JWT=;/); + expect(raw.written[0]).not.toContain('__Host-'); + expect(raw.written[0]).toContain('sameSite=None'); + expect(raw.written[0]).toContain('partitioned'); + + raw.restore(); + }); +}); + +export {}; diff --git a/frontend/apps/remark42/app/common/cookies.test.ts b/frontend/apps/remark42/app/common/cookies.test.ts new file mode 100644 index 00000000..bf3fd2bb --- /dev/null +++ b/frontend/apps/remark42/app/common/cookies.test.ts @@ -0,0 +1,137 @@ +/** + * These cookies exist to be read by someone else: the JWT by the backend, which looks for `JWT`, + * and the XSRF value by `fetcher`, which reads `XSRF-TOKEN`. So the name written and the + * attributes that decide delivery are the whole contract. + * + * `window.location` is not redefinable under jsdom, so the protocol-dependent half is covered by + * calling `authCookieOptions` directly rather than by faking an https page. + */ + +/** captures the strings assigned to document.cookie, which is where the attributes live */ +function captureCookieWrites() { + const written: string[] = []; + const original = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); + + Object.defineProperty(document, 'cookie', { + configurable: true, + get: () => written.join('; '), + set: (v: string) => { + written.push(v.split(';')[0]); + }, + }); + + return { + written, + restore() { + delete (document as unknown as Record).cookie; + if (original) Object.defineProperty(Document.prototype, 'cookie', original); + }, + }; +} + +/** raw assignments, attributes included, which the capture above deliberately strips for reads */ +function captureRaw() { + const written: string[] = []; + const original = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); + + Object.defineProperty(document, 'cookie', { + configurable: true, + get: () => '', + set: (v: string) => { + written.push(v); + }, + }); + + return { + written, + restore() { + delete (document as unknown as Record).cookie; + if (original) Object.defineProperty(Document.prototype, 'cookie', original); + }, + }; +} + +async function loadCookies(thirdParty: boolean) { + jest.resetModules(); + jest.doMock('./constants', () => ({ IS_THIRD_PARTY: thirdParty })); + + return import('./cookies'); +} + +afterEach(() => { + jest.dontMock('./constants'); +}); + +describe('authCookieOptions', () => { + it('keeps the cookie off cross-site requests when the widget shares its page origin', async () => { + const { authCookieOptions } = await loadCookies(false); + + expect(authCookieOptions(true)).toEqual({ path: '/', sameSite: 'Strict', secure: true }); + }); + + it('asks for delivery in a third-party frame when the page is on another origin', async () => { + const { authCookieOptions } = await loadCookies(true); + + // Strict is never sent from a third-party frame: SameSite is judged against the top-level + // site, not the request's own origin. None needs Secure, and Partitioned is what survives + // third-party cookie blocking + expect(authCookieOptions(true)).toEqual({ + path: '/', + sameSite: 'None', + secure: true, + partitioned: true, + }); + }); + + it('does not claim attributes it cannot honour over http', async () => { + const { authCookieOptions } = await loadCookies(true); + + // SameSite=None without Secure is rejected outright, which loses the cookie altogether + expect(authCookieOptions(false)).toEqual({ path: '/', sameSite: 'Strict', secure: false }); + }); +}); + +describe('setAuthCookie', () => { + it('writes the name it was given, undecorated', async () => { + const raw = captureRaw(); + const { setAuthCookie } = await loadCookies(false); + + setAuthCookie('XSRF-TOKEN', 'jti-value'); + + // a __Host- prefix stores the value under a name neither the backend nor the fetcher asks + // for, and only on https, so it is invisible until deployment + expect(raw.written[0]).toMatch(/^XSRF-TOKEN=jti-value/); + expect(raw.written[0]).not.toContain('__Host-'); + + raw.restore(); + }); + + it('round-trips through the reader that consumes it', async () => { + const capture = captureCookieWrites(); + const { setAuthCookie, getCookie } = await loadCookies(false); + + setAuthCookie('XSRF-TOKEN', 'jti-value'); + + expect(getCookie('XSRF-TOKEN')).toBe('jti-value'); + + capture.restore(); + }); +}); + +describe('clearAuthCookie', () => { + it('expires the cookie under the attributes it was set with', async () => { + const raw = captureRaw(); + const { clearAuthCookie } = await loadCookies(true); + + clearAuthCookie('JWT'); + + // a mismatched SameSite or Partitioned makes this a different cookie, and the original stays + expect(raw.written[0]).toMatch(/^JWT=;/); + expect(raw.written[0]).toContain('Thu, 01 Jan 1970'); + expect(raw.written[0]).toContain('sameSite=Strict'); + + raw.restore(); + }); +}); + +export {}; diff --git a/frontend/apps/remark42/app/common/cookies.ts b/frontend/apps/remark42/app/common/cookies.ts index 7ac4590b..23aa6608 100644 --- a/frontend/apps/remark42/app/common/cookies.ts +++ b/frontend/apps/remark42/app/common/cookies.ts @@ -1,3 +1,5 @@ +import { IS_THIRD_PARTY } from './constants'; + interface CookieOptions { /** * Either time in seconds, @@ -9,6 +11,12 @@ interface CookieOptions { domain?: string; secure?: boolean; sameSite?: 'Strict' | 'Lax' | 'None'; + /** + * CHIPS. Keys the cookie to the embedding top-level site as well as its own, which is the only + * form of third-party cookie browsers still accept. Requires Secure, and is meaningless without + * `sameSite: 'None'`. + */ + partitioned?: boolean; } export function setCookie(name: string, value: string, options: CookieOptions = {}) { @@ -39,48 +47,56 @@ export function setCookie(name: string, value: string, options: CookieOptions = } /** - * Sets a cookie with enhanced security options for authentication + * Attributes an auth cookie has to carry to be delivered in the context the widget is running in. + * + * The name is never decorated. These cookies exist to be read by someone else: the JWT by the + * backend, which looks for `JWT`, and the XSRF value by `fetcher`, which reads `XSRF-TOKEN`. A + * `__Host-` prefix would satisfy neither, and the security it buys is worth nothing on a cookie + * that no longer reaches its reader. + * + * `SameSite` follows the embedding. Strict is right when the widget and the page share an origin + * and keeps the cookie off cross-site requests entirely. It is fatal once they do not: a Strict + * cookie is never sent from a third-party frame, because `SameSite` is judged against the + * top-level site rather than the request's own origin. The separate-domain arrangement therefore + * needs `None`, which browsers only honour with `Secure`, plus `Partitioned` to survive + * third-party cookie blocking. + * + * Over http in a third-party frame there is no combination that works, and this returns the + * strict form rather than an unusable one. + */ +export function authCookieOptions(isSecure: boolean): CookieOptions { + if (IS_THIRD_PARTY && isSecure) { + return { path: '/', sameSite: 'None', secure: true, partitioned: true }; + } + + return { path: '/', sameSite: 'Strict', secure: isSecure }; +} + +/** + * Sets a cookie with the attributes its delivery context requires * @param name The name of the cookie * @param value The value to set * @param options Additional cookie options */ export function setAuthCookie(name: string, value: string, options: CookieOptions = {}) { const isSecure = window.location.protocol === 'https:'; - const cookiePrefix = isSecure ? '__Host-' : ''; - // Default options for auth cookies with strong security - const authOptions: CookieOptions = { - path: '/', - sameSite: 'Strict', - secure: isSecure, - ...options, - }; - - setCookie(`${cookiePrefix}${name}`, value, authOptions); + setCookie(name, value, { ...authCookieOptions(isSecure), ...options }); } /** - * Clears an authentication cookie by setting its expiration to the past + * Clears an authentication cookie by setting its expiration to the past. + * The attributes have to match the ones it was set with, or the browser treats it as a different + * cookie and leaves the original in place. * @param name The name of the cookie to clear */ export function clearAuthCookie(name: string) { const isSecure = window.location.protocol === 'https:'; - const cookiePrefix = isSecure ? '__Host-' : ''; - setCookie(`${cookiePrefix}${name}`, '', { - path: '/', - secure: isSecure, + setCookie(name, '', { + ...authCookieOptions(isSecure), expires: new Date(0), // Set to epoch time to expire immediately }); - - // Also try to clear the non-prefixed version to be thorough - if (cookiePrefix) { - setCookie(name, '', { - path: '/', - secure: isSecure, - expires: new Date(0), - }); - } } export function getCookie(name: string) { diff --git a/frontend/apps/remark42/app/components/auth/auth.api.spec.ts b/frontend/apps/remark42/app/components/auth/auth.api.spec.ts new file mode 100644 index 00000000..70f22d50 --- /dev/null +++ b/frontend/apps/remark42/app/components/auth/auth.api.spec.ts @@ -0,0 +1,118 @@ +import { oauthSignin } from './auth.api'; + +/** + * The OAuth flow has no message from the popup to listen for: the popup closes itself and the + * opener notices, so completion is detected by polling `getUser` whenever the document regains + * focus. That polling is what these tests are about. Cross-domain embedding is the case where + * the cookie never becomes readable and `getUser` therefore never stops returning null, so the + * retry has to be bounded by something other than success. + */ +describe('oauthSignin', () => { + const openedWindow = { closed: true } as Window; + + beforeEach(() => { + jest.useFakeTimers(); + jest.spyOn(window, 'open').mockReturnValue(openedWindow); + // the poll only fires while the document is focused and visible + jest.spyOn(document, 'hasFocus').mockReturnValue(true); + Object.defineProperty(document, 'hidden', { value: false, configurable: true }); + fetchMock.resetMocks(); + }); + + afterEach(() => { + jest.runOnlyPendingTimers(); + jest.useRealTimers(); + jest.restoreAllMocks(); + }); + + /** how many listeners the flow has attached and not removed */ + function listenerCount() { + return ( + (document.addEventListener as jest.Mock).mock.calls.length - + (document.removeEventListener as jest.Mock).mock.calls.length + ); + } + + it('stops polling once it gives up', async () => { + // an unauthenticated response is what a cross-domain embed gets indefinitely + fetchMock.mockResponse('', { status: 401 }); + const pending = oauthSignin('/auth/github/login'); + const rejected = expect(pending).rejects.toThrow(/authorization window/); + + // the poll is reachable only from the two listeners and from the retry it schedules itself, + // so without dispatching one of them no request is ever made and this test asserts nothing + window.dispatchEvent(new Event('focus')); + await jest.advanceTimersByTimeAsync(0); + expect(fetchMock.mock.calls.length).toBeGreaterThan(0); + + // it keeps retrying while getUser returns null + await jest.advanceTimersByTimeAsync(60 * 1000); + const whileRunning = fetchMock.mock.calls.length; + expect(whileRunning).toBeGreaterThan(1); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await rejected; + + const afterGivingUp = fetchMock.mock.calls.length; + // without the teardown the one-minute retry keeps rescheduling itself for the life of the + // page, against a route capped at 2 req/s + await jest.advanceTimersByTimeAsync(10 * 60 * 1000); + expect(fetchMock.mock.calls.length).toBe(afterGivingUp); + }); + + it('does not reschedule when getUser resolves after the deadline', async () => { + // the deadline can pass while a request is in flight. that resolution still runs the code + // after the await, and without a guard it schedules a fresh retry with nothing left to clear + let release: (v: Response) => void = () => undefined; + fetchMock.mockImplementation( + () => + new Promise((r) => { + release = r as (v: Response) => void; + }) + ); + + const pending = oauthSignin('/auth/github/login'); + const rejected = expect(pending).rejects.toThrow(/authorization window/); + + window.dispatchEvent(new Event('focus')); + await jest.advanceTimersByTimeAsync(0); + expect(fetchMock.mock.calls.length).toBe(1); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await rejected; + + // the in-flight request now comes back unauthenticated, after the flow already gave up + release(new Response('', { status: 401 })); + await jest.advanceTimersByTimeAsync(0); + + const afterGivingUp = fetchMock.mock.calls.length; + await jest.advanceTimersByTimeAsync(10 * 60 * 1000); + expect(fetchMock.mock.calls.length).toBe(afterGivingUp); + }); + + it('detaches its listeners once it gives up', async () => { + jest.spyOn(document, 'addEventListener'); + jest.spyOn(document, 'removeEventListener'); + fetchMock.mockResponse('', { status: 401 }); + + const pending = oauthSignin('/auth/github/login'); + const rejected = expect(pending).rejects.toThrow(); + expect(listenerCount()).toBeGreaterThan(0); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await rejected; + + expect(listenerCount()).toBe(0); + }); + + it('rejects with an error rather than undefined', async () => { + fetchMock.mockResponse('', { status: 401 }); + const pending = oauthSignin('/auth/github/login'); + // the caller stores whatever this rejects with as the error state, so rejecting with no + // argument puts undefined on screen + const assertion = expect(pending).rejects.toBeInstanceOf(Error); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await assertion; + }); +}); diff --git a/frontend/apps/remark42/app/components/auth/auth.api.ts b/frontend/apps/remark42/app/components/auth/auth.api.ts index e53e1783..03f3f6ed 100644 --- a/frontend/apps/remark42/app/components/auth/auth.api.ts +++ b/frontend/apps/remark42/app/components/auth/auth.api.ts @@ -42,12 +42,20 @@ export function oauthSignin(url: string): Promise { return Promise.resolve(null); } + subscribed = true; + return new Promise((resolve, reject) => { + // closure-local rather than the module-level `subscribed`, because a second oauthSignin can + // start while this one's getUser is still resolving and would clear a flag it does not own + let stopped = false; + function unsubscribe() { + stopped = true; document.removeEventListener('visibilitychange', handleWindowVisibilityChange); window.removeEventListener('focus', handleWindowVisibilityChange); subscribed = false; clearTimeout(timeout); + clearTimeout(giveUp); } async function handleWindowVisibilityChange() { @@ -57,6 +65,12 @@ export function oauthSignin(url: string): Promise { const user = await getUser(); + // the request was in flight when the deadline passed, so there is nothing left to clear the + // retry this would otherwise schedule + if (stopped) { + return; + } + clearTimeout(timeout); if (user === null) { @@ -72,9 +86,15 @@ export function oauthSignin(url: string): Promise { unsubscribe(); } - setTimeout( + // giving up has to tear the subscription down as well. the retry above reschedules itself + // for as long as getUser keeps returning null, which is the permanent state whenever the + // widget is embedded cross-domain and the cookie never becomes readable, so leaving the + // listeners attached leaves a poll of /auth/user running for the life of the page against + // a route limited to 2 req/s + const giveUp = setTimeout( () => { - reject(); + unsubscribe(); + reject(new Error('Timed out waiting for the authorization window')); }, 5 * 60 * 1000 ); diff --git a/frontend/apps/remark42/app/components/dropdown/dropdown.tsx b/frontend/apps/remark42/app/components/dropdown/dropdown.tsx index 1ca37537..f4a000cd 100644 --- a/frontend/apps/remark42/app/components/dropdown/dropdown.tsx +++ b/frontend/apps/remark42/app/components/dropdown/dropdown.tsx @@ -5,7 +5,7 @@ import clsx from 'clsx'; import type { Theme } from 'common/types'; import { sleep } from 'utils/sleep'; import { Button } from 'components/button'; -import { parseMessage } from 'utils/post-message'; +import { parseMessage, isFromParent } from 'utils/post-message'; import styles from './dropdown.module.css'; @@ -136,6 +136,10 @@ export class Dropdown extends Component { } receiveMessage(evt: MessageEvent) { + if (!isFromParent(evt)) { + return; + } + const data = parseMessage(evt); if (!data.clickOutside || !this.state.isActive) { diff --git a/frontend/apps/remark42/app/components/root/root.tsx b/frontend/apps/remark42/app/components/root/root.tsx index bab2bd83..43b88af8 100644 --- a/frontend/apps/remark42/app/components/root/root.tsx +++ b/frontend/apps/remark42/app/components/root/root.tsx @@ -34,7 +34,7 @@ import { ConnectedComment as Comment } from 'components/comment/connected-commen import { uploadImage, getPreview } from 'common/api'; import { isUserAnonymous } from 'utils/isUserAnonymous'; import { bindActions } from 'utils/actionBinder'; -import { postMessageToParent, parseMessage, updateIframeHeight } from 'utils/post-message'; +import { postMessageToParent, parseMessage, isFromParent, updateIframeHeight } from 'utils/post-message'; import { useActions } from 'hooks/useAction'; import { setCollapse } from 'store/thread/actions'; @@ -185,6 +185,10 @@ export class Root extends Component { }; onMessage = (event: MessageEvent) => { + if (!isFromParent(event)) { + return; + } + const data = parseMessage(event); if (data.signout === true) { diff --git a/frontend/apps/remark42/app/embed.test.ts b/frontend/apps/remark42/app/embed.test.ts index d7375d11..ff73e6d3 100644 --- a/frontend/apps/remark42/app/embed.test.ts +++ b/frontend/apps/remark42/app/embed.test.ts @@ -50,4 +50,82 @@ describe('embed', () => { expect(root.querySelectorAll('iframe')).toHaveLength(1); expect(root.querySelector(MARKED)).toBe(first); }); + + it('does not stack listeners when createInstance is called again', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + + // the second call reuses the iframe rather than building one, so without a teardown the first + // call's handlers stay attached and both react to every message + window.REMARK42.createInstance(window.remark_config); + window.REMARK42.createInstance(window.remark_config); + + let resizes = 0; + Object.defineProperty(iframe.style, 'height', { + set() { + resizes += 1; + }, + get: () => '', + configurable: true, + }); + + window.dispatchEvent(new MessageEvent('message', { data: { height: 500 }, source: iframe.contentWindow })); + + expect(resizes).toBe(1); + }); + + it('detaches every listener on destroy, however many instances were created', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + + window.REMARK42.createInstance(window.remark_config); + window.REMARK42.destroy!(); + + let resized = false; + Object.defineProperty(iframe.style, 'height', { + set() { + resized = true; + }, + get: () => '', + configurable: true, + }); + + window.dispatchEvent(new MessageEvent('message', { data: { height: 500 }, source: iframe.contentWindow })); + + expect(resized).toBe(false); + }); + + it('resizes for its own iframe', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + + window.dispatchEvent(new MessageEvent('message', { data: { height: 500 }, source: iframe.contentWindow })); + + expect(iframe.style.height).toBe('500px'); + }); + + it('ignores a message from a frame it does not own', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + iframe.style.height = '100px'; + + // every frame on a page can reach window.parent, an advertisement among them, and the handler + // resizes the widget, scrolls the page and opens the profile overlay + const foreign = document.createElement('iframe'); + document.body.appendChild(foreign); + const scrollTo = jest.spyOn(window, 'scrollTo').mockImplementation(() => undefined); + + window.dispatchEvent( + new MessageEvent('message', { + data: { height: 9000, scrollTo: 5000, profile: { id: 'anyone' } }, + source: foreign.contentWindow, + }) + ); + + expect(iframe.style.height).toBe('100px'); + expect(scrollTo).not.toHaveBeenCalled(); + expect(document.querySelectorAll('iframe')).toHaveLength(2); + + scrollTo.mockRestore(); + }); }); diff --git a/frontend/apps/remark42/app/embed.ts b/frontend/apps/remark42/app/embed.ts index 3fa5f8b5..3d229d0d 100644 --- a/frontend/apps/remark42/app/embed.ts +++ b/frontend/apps/remark42/app/embed.ts @@ -2,12 +2,18 @@ import { NODE_ID, COMMENT_NODE_CLASSNAME_PREFIX } from 'common/constants.config' import { parseMessage, postMessageToIframe } from 'utils/post-message'; import { createIframe } from 'utils/create-iframe'; import type { Theme } from 'common/types'; -import { closeProfile, openProfile } from 'profile'; +import { closeProfile, openProfile, ownsWindow } from 'profile'; // marks the iframe this module owns, so a second createInstance reuses it instead of adopting // whatever the integrator left in the root as a loading placeholder const IFRAME_MARKER = 'data-remark42-iframe'; +// detaches the listeners of whichever instance is current. every createInstance installs three of +// them plus a title observer, all closing over that call's iframe, while the call reuses an +// existing iframe rather than building one. Without this a second call leaves the first set +// attached for good, since destroy() can only reach the newest closure +let detachCurrentInstance: (() => void) | null = null; + if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { @@ -45,6 +51,10 @@ function createInstance(config: typeof window.remark_config) { root.appendChild(iframe); + // after the throwing validation above, so a rejected call leaves a working instance alone + detachCurrentInstance?.(); + detachCurrentInstance = detach; + window.addEventListener('message', handleReceiveMessage); window.addEventListener('hashchange', handleHashChange); document.addEventListener('click', postClickOutsideToIframe); @@ -61,6 +71,13 @@ function createInstance(config: typeof window.remark_config) { } function handleReceiveMessage(event: MessageEvent): void { + // only the frames this module created. window.parent is reachable by every frame on the page, + // an advertisement among them, and the handler below resizes the widget, scrolls the page and + // opens the profile overlay, so an unchecked sender can drive all three + if (event.source !== iframe.contentWindow && !ownsWindow(event.source)) { + return; + } + const data = parseMessage(event); if (typeof data.height === 'number') { @@ -125,7 +142,7 @@ function createInstance(config: typeof window.remark_config) { postMessageToIframe(iframe, { theme }); } - function destroy() { + function detach() { window.removeEventListener('message', handleReceiveMessage); window.removeEventListener('hashchange', handleHashChange); document.removeEventListener('click', postClickOutsideToIframe); @@ -136,6 +153,15 @@ function createInstance(config: typeof window.remark_config) { // to prevent attempts to send messages to detached frame titleObserver = null; } + } + + function destroy() { + detach(); + + // a later createInstance must not detach an instance that is already gone + if (detachCurrentInstance === detach) { + detachCurrentInstance = null; + } iframe.remove(); } diff --git a/frontend/apps/remark42/app/profile.ts b/frontend/apps/remark42/app/profile.ts index 3a96d104..1e251490 100644 --- a/frontend/apps/remark42/app/profile.ts +++ b/frontend/apps/remark42/app/profile.ts @@ -87,6 +87,13 @@ export function openProfile(params: Profile & Record) window.addEventListener('keydown', handleKeydown); } +// ownsWindow reports whether the message came from the profile frame this module created. The +// host page's listener has no other way to tell it apart: any frame on the page can post to the +// parent, and nothing about the message itself says where it came from +export function ownsWindow(source: MessageEventSource | null): boolean { + return source !== null && iframe !== null && source === iframe.contentWindow; +} + export function closeProfile() { window.removeEventListener('keydown', handleKeydown); animateDisappear().then(() => { diff --git a/frontend/apps/remark42/app/remark.tsx b/frontend/apps/remark42/app/remark.tsx index 3d4128d2..fbb7c025 100644 --- a/frontend/apps/remark42/app/remark.tsx +++ b/frontend/apps/remark42/app/remark.tsx @@ -4,7 +4,7 @@ import { Provider } from 'store/context'; import { IntlProvider } from 'common/intl'; import { loadLocale } from 'utils/loadLocale'; -import { parseMessage } from 'utils/post-message'; +import { parseMessage, isFromParent } from 'utils/post-message'; import { ConnectedRoot } from 'components/root'; import { Profile } from 'components/profile'; import { store } from 'store'; @@ -36,6 +36,10 @@ async function init(): Promise { node.innerHTML = ''; window.addEventListener('message', (evt) => { + if (!isFromParent(evt)) { + return; + } + const data = parseMessage(evt); if (data.theme === 'light') { diff --git a/frontend/apps/remark42/app/utils/post-message.test.ts b/frontend/apps/remark42/app/utils/post-message.test.ts new file mode 100644 index 00000000..c4029fbc --- /dev/null +++ b/frontend/apps/remark42/app/utils/post-message.test.ts @@ -0,0 +1,26 @@ +import { isFromParent } from './post-message'; + +/** + * The widget document acts on `signout` and `theme` straight out of a message, so the sender has to + * be the page embedding it. The origin cannot stand in for that check: the host is whatever site + * embeds the widget, and `ALLOWED_HOSTS` is enforced server side through `frame-ancestors`. + */ +describe('isFromParent', () => { + it('accepts the embedding page', () => { + expect(isFromParent(new MessageEvent('message', { source: window.parent }))).toBe(true); + }); + + it('rejects another frame on the page', () => { + const foreign = document.createElement('iframe'); + document.body.appendChild(foreign); + + expect(isFromParent(new MessageEvent('message', { source: foreign.contentWindow }))).toBe(false); + + foreign.remove(); + }); + + it('rejects a message carrying no sender', () => { + // an extension posting into the frame is the common case + expect(isFromParent(new MessageEvent('message', { data: { signout: true } }))).toBe(false); + }); +}); diff --git a/frontend/apps/remark42/app/utils/post-message.ts b/frontend/apps/remark42/app/utils/post-message.ts index bee61e21..a14099f9 100644 --- a/frontend/apps/remark42/app/utils/post-message.ts +++ b/frontend/apps/remark42/app/utils/post-message.ts @@ -49,6 +49,22 @@ export function postMessageToIframe(target: HTMLIFrameElement, data: ChildMessag return true; } +/** + * Whether a message reaching the widget document came from the page embedding it. + * + * The embed script is the only legitimate sender, and it always posts from the parent. Browser + * extensions post their own messages into the frame, and so can any window holding a reference to + * it, which matters because the child acts on `signout` and `theme`. The origin cannot be checked + * instead: the host page is whatever site embeds the widget, so there is no fixed value to compare + * against, and `ALLOWED_HOSTS` is enforced server side through `frame-ancestors` rather than here. + * + * A widget opened directly rather than embedded has `window.parent === window`, so its own messages + * still pass, which is what the counter and last-comments pages rely on. + */ +export function isFromParent(evt: MessageEvent): boolean { + return evt.source === window.parent; +} + /** * Parses data from post message that was received in iframe * diff --git a/frontend/apps/remark42/package.json b/frontend/apps/remark42/package.json index 7a3e7603..3247c4dc 100644 --- a/frontend/apps/remark42/package.json +++ b/frontend/apps/remark42/package.json @@ -19,7 +19,8 @@ "translation-check": "run-s translation:extract translation:check", "translation:extract": "formatjs extract --out-file=./extracted-messages/messages.json \"**/*.{ts,tsx}\" --ignore=\"**/*.d.ts\" --ignore=\"**/*.{test,spec}.{ts,tsx}\" --ignore=\"app/tests/**\" --ignore=\"app/__mocks__/**\" --ignore=\"app/__stubs__/**\"", "translation:generate": "node ./tasks/generateDictionary.js", - "translation:check": "node ./tasks/checkTranslation.js" + "translation:check": "node ./tasks/checkTranslation.js", + "prepare": "if [ -z \"$CI\" ]; then cd ../../.. && husky install frontend/.husky; else echo \"Skip Husky Hooks\"; fi" }, "engines": { "node": ">=24", @@ -71,12 +72,14 @@ "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "html-webpack-plugin": "^5.6.8", + "husky": "^8.0.1", "identity-obj-proxy": "^3.0.0", "incstr": "^1.2.3", "jest": "^30.4.2", "jest-environment-jsdom": "^30.4.1", "jest-fetch-mock": "^4.2.0", "jest-localstorage-mock": "^2.4.26", + "lint-staged": "^13.0.3", "mini-css-extract-plugin": "^2.10.2", "npm-run-all": "^4.1.5", "postcss": "^8.5.26", @@ -97,5 +100,77 @@ "webpack-bundle-analyzer": "^5.3.1", "webpack-cli": "^7.2.2", "webpack-dev-server": "^5.2.5" + }, + "pnpm": { + "overrides": { + "decode-uri-component@<0.2.1": ">=0.2.1", + "loader-utils@>=2.0.0 <2.0.3": ">=2.0.3 <3.0.0", + "loader-utils@>=2.0.0 <2.0.4": ">=2.0.4 <3.0.0", + "json5@<1.0.2": ">=1.0.2", + "json5@>=2.0.0 <2.2.2": ">=2.2.2", + "tough-cookie@<4.1.3": ">=4.1.3", + "micromatch@<4.0.8": ">=4.0.8", + "esbuild@<=0.24.2": ">=0.25.0", + "word-wrap@<1.2.4": ">=1.2.4", + "cookie@<0.7.0": ">=0.7.0", + "@babel/runtime-corejs3@<7.26.10": ">=7.26.10 <8.0.0", + "@babel/runtime@<7.26.10": ">=7.26.10 <8.0.0", + "@babel/helpers@<7.26.10": ">=7.26.10 <8.0.0", + "cross-spawn@<6.0.6": ">=6.0.6", + "cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5", + "tmp@<=0.2.3": ">=0.2.4", + "form-data@>=4.0.0 <4.0.4": ">=4.0.4", + "nanoid@>=4.0.0 <5.0.9": ">=5.0.9", + "glob@>=10.2.0 <10.5.0": ">=10.5.0 <11.0.0", + "diff@>=4.0.0 <4.0.4": ">=4.0.4", + "semver@>=2.0.0-alpha <5.7.2": ">=5.7.2", + "semver@>=7.0.0 <7.5.2": ">=7.5.2", + "semver@>=6.0.0 <6.3.1": ">=6.3.1", + "serialize-javascript@<=7.0.2": ">=7.0.3", + "flatted@<3.4.0": ">=3.4.0", + "flatted@<=3.4.1": ">=3.4.2", + "lodash-es@>=4.0.0 <=4.17.23": ">=4.18.0", + "lodash@>=4.0.0 <=4.17.23": ">=4.18.0", + "lodash-es@<=4.17.23": ">=4.18.0", + "lodash@<=4.17.23": ">=4.18.0", + "serialize-javascript@>=6.0.0 <6.0.2": ">=6.0.2", + "@xmldom/xmldom@<0.8.12": ">=0.8.12", + "@babel/traverse@<7.23.2": ">=7.23.2 <8.0.0", + "@xmldom/xmldom@<0.8.13": ">=0.8.13", + "@tootallnate/once@<2.0.1": ">=2.0.1", + "serialize-javascript@>=5.0.0 <7.0.5": ">=7.0.5", + "uuid@<11.1.1": ">=11.1.1", + "@babel/plugin-transform-modules-systemjs@>=7.12.0 <=7.29.3": ">=7.29.4 <8.0.0", + "lodash@>=4.0.0 <=4.17.22": ">=4.17.23", + "shell-quote@>=1.1.0 <=1.8.3": ">=1.8.4", + "tmp@<0.2.6": ">=0.2.6", + "form-data@>=4.0.0 <4.0.6": ">=4.0.6", + "launch-editor@<=2.14.0": ">=2.14.1", + "@babel/core@<=7.29.0": ">=7.29.6 <8.0.0", + "webpack-dev-server@<5.2.6": ">=5.2.6 <6.0.0", + "http-proxy-middleware@>=0.16.0 <2.0.10": ">=2.0.10 <3.0.0", + "yaml@>=1.0.0 <2.0.0": ">=1.10.3 <2.0.0", + "yaml@>=2.0.0 <3.0.0": ">=2.9.0 <3.0.0", + "js-yaml@>=3.0.0 <4.0.0": ">=3.15.1 <4.0.0", + "js-yaml@>=4.0.0 <5.0.0": ">=5.2.2 <6.0.0", + "minimatch@>=3.0.0 <4.0.0": ">=3.1.3 <4.0.0", + "minimatch@>=9.0.0 <10.0.0": ">=9.0.7 <10.0.0", + "ajv@>=8.0.0 <9.0.0": ">=8.18.0 <9.0.0", + "ws@>=7.0.0 <8.0.0": ">=7.5.11 <8.0.0", + "ws@>=8.0.0 <9.0.0": ">=8.21.0 <9.0.0", + "brace-expansion@>=1.0.0 <2.0.0": ">=1.1.18 <2.0.0", + "brace-expansion@>=2.0.0 <3.0.0": ">=2.0.2 <3.0.0", + "brace-expansion@>=4.0.0 <6.0.0": ">=5.0.9 <6.0.0", + "fast-uri": ">=4.1.2 <5.0.0", + "nanoid@>=3.0.0 <4.0.0": ">=3.3.18 <4.0.0", + "postcss@<8.5.23": ">=8.5.23 <9.0.0", + "svgo": ">=4.0.2 <5.0.0", + "undici@>=7.0.0 <8.0.0": ">=7.29.0 <8.0.0", + "body-parser@<1.20.6": ">=1.20.6 <2.0.0", + "preact": "10.29.8", + "@types/minimatch": "5.1.2", + "@babel/core": "^8.0.1", + "eslint-config-preact>@babel/core": "^7.29.7" + } } } diff --git a/frontend/pnpm-lock.yaml b/frontend/apps/remark42/pnpm-lock.yaml similarity index 86% rename from frontend/pnpm-lock.yaml rename to frontend/apps/remark42/pnpm-lock.yaml index 8908f4a2..a28ddbc1 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/apps/remark42/pnpm-lock.yaml @@ -77,15 +77,6 @@ overrides: importers: .: - devDependencies: - husky: - specifier: ^8.0.1 - version: 8.0.3 - lint-staged: - specifier: ^13.0.3 - version: 13.3.0 - - apps/remark42: dependencies: '@github/markdown-toolbar-element': specifier: ^2.2.3 @@ -135,7 +126,7 @@ importers: version: 13.0.3(size-limit@13.0.3) '@testing-library/jest-dom': specifier: ^7.0.1 - version: 7.0.1(@testing-library/dom@8.20.1)(vitest@4.1.9) + version: 7.0.1(@testing-library/dom@8.20.1) '@testing-library/preact': specifier: 3.2.4 version: 3.2.4(preact@10.29.8) @@ -204,7 +195,7 @@ importers: version: 6.10.2(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-prettier: specifier: ^5.5.6 - version: 5.5.6(@types/eslint@8.56.12)(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6) + version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6) file-loader: specifier: ^6.2.0 version: 6.2.0(webpack@5.109.2) @@ -214,6 +205,9 @@ importers: html-webpack-plugin: specifier: ^5.6.8 version: 5.6.8(webpack@5.109.2) + husky: + specifier: ^8.0.1 + version: 8.0.3 identity-obj-proxy: specifier: ^3.0.0 version: 3.0.0 @@ -222,7 +216,7 @@ importers: version: 1.2.3 jest: specifier: ^30.4.2 - version: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + version: 30.4.2(@types/node@26.2.0) jest-environment-jsdom: specifier: ^30.4.1 version: 30.4.1 @@ -232,6 +226,9 @@ importers: jest-localstorage-mock: specifier: ^2.4.26 version: 2.4.26 + lint-staged: + specifier: ^13.0.3 + version: 13.3.0 mini-css-extract-plugin: specifier: ^2.10.2 version: 2.10.2(webpack@5.109.2) @@ -282,7 +279,7 @@ importers: version: 5.9.3 webpack: specifier: ^5.109.2 - version: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + version: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) webpack-bundle-analyzer: specifier: ^5.3.1 version: 5.3.1 @@ -291,7 +288,7 @@ importers: version: 7.2.2(js-yaml@5.3.0)(json5@2.2.3)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.2) webpack-dev-server: specifier: '>=5.2.6 <6.0.0' - version: 5.2.6(tslib@2.8.1)(webpack-cli@7.2.2)(webpack@5.109.2) + version: 5.2.6(webpack-cli@7.2.2)(webpack@5.109.2) packages: @@ -332,10 +329,6 @@ packages: '@babel/core': ^8.0.1 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - '@babel/generator@7.29.7': - resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} - 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'} @@ -472,11 +465,6 @@ packages: resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@7.29.7': - resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.29.8': resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} @@ -1005,10 +993,6 @@ packages: resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/types@7.29.7': - resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.8': resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} @@ -1020,22 +1004,14 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@bcoe/v8-coverage@1.0.2': - resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} - engines: {node: '>=18'} - '@cacheable/memory@2.2.0': resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} '@cacheable/utils@2.5.0': resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} - '@colordx/core@5.5.0': - resolution: {integrity: sha512-3PxTH8itZzltK0U9jTwVVnjLXvnDYuq3m+QXsHkENxWiPRh4WaoLcs1SQjqgZ55kS+QyirpH5BVwzP2gMVG6EQ==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + '@colordx/core@5.6.0': + resolution: {integrity: sha512-EDlcg/Hmlj1WuFh/Os9YhA+A2aasB2XlgwFfGePUDuW7fVHC07HBi5AFIMx0Ct1eM8kHM9NRyOtZ0MuVYa8xvg==} '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} @@ -1048,8 +1024,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-calc@3.2.1': - resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} + '@csstools/css-calc@3.3.0': + resolution: {integrity: sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -1074,8 +1050,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.6': - resolution: {integrity: sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==} + '@csstools/css-syntax-patches-for-csstree@1.1.8': + resolution: {integrity: sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -1210,26 +1186,17 @@ packages: '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - '@emnapi/core@1.11.1': - resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - '@emnapi/runtime@1.11.1': - resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + '@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 @@ -1305,41 +1272,6 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@2.0.7': - resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - - '@inquirer/confirm@6.1.1': - resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@11.2.1': - resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@2.0.7': - resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - - '@inquirer/type@4.0.7': - resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1463,9 +1395,6 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@jsonjoy.com/base64@1.1.2': resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} engines: {node: '>=10.0'} @@ -1502,50 +1431,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.57.8': - resolution: {integrity: sha512-YzVbwggV9452VCeHgo0bjsTaUt1O7JE0XpEsPar93nn/+RAwXk0mb1Y+f5EDJ3TRtRCFe+Ck5RuojdfB4jeHVw==} + '@jsonjoy.com/fs-core@4.68.1': + resolution: {integrity: sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.57.8': - resolution: {integrity: sha512-vmClyvCQMxgqz7uamDiGtRfp4MjzOznk3pcQjCxlIwJcw7TWeyr+bF30hI0x8NxdtNOGMg1pHM74VDIXOeyjuw==} + '@jsonjoy.com/fs-fsa@4.68.1': + resolution: {integrity: sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.57.8': - resolution: {integrity: sha512-mxXSXw8zZwRVakcjLqR2I/psy4gURFSASZS10kKJ2kJw05GC2nXGroGrWVHxwgkxXgQLsFQnB74QaLzsxzdL/w==} + '@jsonjoy.com/fs-node-builtins@4.68.1': + resolution: {integrity: sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.57.8': - resolution: {integrity: sha512-AWZcT/4+H+iDl4XCukbXrarvwEgOrf/prFI5/7eg4ix9FxqVsZysIDJd1Kjd+AjlCeHKHJOaRqjLd5HiGSCJEw==} + '@jsonjoy.com/fs-node-to-fsa@4.68.1': + resolution: {integrity: sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.57.8': - resolution: {integrity: sha512-E/bJ7sQAb4pu9nbeJhbULU3WnqWrswte4N9Js/oHt7aHB746S8/XBqKlcbrqIgnD3095XluovNEZuu5ONT230g==} + '@jsonjoy.com/fs-node-utils@4.68.1': + resolution: {integrity: sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.57.8': - resolution: {integrity: sha512-IPEOlDYSnTDYpjQlQg2F8h+eqxKQN3sdbroI0WrteRiQZ462HzVpBo9ZZX485njz4nAacoe3fd4iDiIhk+k5Hg==} + '@jsonjoy.com/fs-node@4.68.1': + resolution: {integrity: sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.57.8': - resolution: {integrity: sha512-DfzhOBpmvNu5P/KSe4NNQaOnvNliTdcf0qrh/4EReErF/XUQXYkd0vZl/OiJCm/qjEEo8DWRstliw2/JNS84dA==} + '@jsonjoy.com/fs-print@4.68.1': + resolution: {integrity: sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.57.8': - resolution: {integrity: sha512-L+eqKaWOHLDaiMv1dh/EWQ4hA+o6xAhWSumTo3Teg7OM18jU/KE13/e8Mfal+eAZ/pSl4wIhKHcDiwapJzC8Wg==} + '@jsonjoy.com/fs-snapshot@4.68.1': + resolution: {integrity: sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -1604,15 +1533,12 @@ packages: '@mdn/browser-compat-data@6.1.5': resolution: {integrity: sha512-PzdZZzRhcXvKB0begee28n5lvwAcinGKYuLZOVxHAZm+n7y01ddEGfdS1ZXRuVcV+ndG6mSEAE8vgudom5UjYg==} - '@mswjs/interceptors@0.41.9': - resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} - engines: {node: '>=18'} - - '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + '@napi-rs/wasm-runtime@1.2.3': + resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -1633,50 +1559,45 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + '@peculiar/asn1-cms@2.9.4': + resolution: {integrity: sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==} + engines: {node: '>=14'} - '@open-draft/deferred-promise@3.0.0': - resolution: {integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==} + '@peculiar/asn1-csr@2.9.4': + resolution: {integrity: sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==} + engines: {node: '>=14'} - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + '@peculiar/asn1-ecc@2.9.4': + resolution: {integrity: sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==} + engines: {node: '>=14'} - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@peculiar/asn1-pfx@2.9.4': + resolution: {integrity: sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==} + engines: {node: '>=14'} - '@oxc-project/types@0.137.0': - resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} + '@peculiar/asn1-pkcs8@2.9.4': + resolution: {integrity: sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==} + engines: {node: '>=14'} - '@peculiar/asn1-cms@2.8.0': - resolution: {integrity: sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA==} + '@peculiar/asn1-pkcs9@2.9.4': + resolution: {integrity: sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==} + engines: {node: '>=14'} - '@peculiar/asn1-csr@2.8.0': - resolution: {integrity: sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg==} + '@peculiar/asn1-rsa@2.9.4': + resolution: {integrity: sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==} + engines: {node: '>=14'} - '@peculiar/asn1-ecc@2.8.0': - resolution: {integrity: sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ==} + '@peculiar/asn1-schema@2.9.4': + resolution: {integrity: sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==} + engines: {node: '>=14'} - '@peculiar/asn1-pfx@2.8.0': - resolution: {integrity: sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg==} + '@peculiar/asn1-x509-attr@2.9.4': + resolution: {integrity: sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==} + engines: {node: '>=14'} - '@peculiar/asn1-pkcs8@2.8.0': - resolution: {integrity: sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA==} - - '@peculiar/asn1-pkcs9@2.8.0': - resolution: {integrity: sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ==} - - '@peculiar/asn1-rsa@2.8.0': - resolution: {integrity: sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg==} - - '@peculiar/asn1-schema@2.8.0': - resolution: {integrity: sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==} - - '@peculiar/asn1-x509-attr@2.8.0': - resolution: {integrity: sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA==} - - '@peculiar/asn1-x509@2.8.0': - resolution: {integrity: sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg==} + '@peculiar/asn1-x509@2.9.4': + resolution: {integrity: sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==} + engines: {node: '>=14'} '@peculiar/utils@2.0.3': resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} @@ -1696,103 +1617,11 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@rolldown/binding-android-arm64@1.1.3': - resolution: {integrity: sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.1.3': - resolution: {integrity: sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.1.3': - resolution: {integrity: sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.1.3': - resolution: {integrity: sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.1.3': - resolution: {integrity: sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.1.3': - resolution: {integrity: sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-arm64-musl@1.1.3': - resolution: {integrity: sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-ppc64-gnu@1.1.3': - resolution: {integrity: sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - - '@rolldown/binding-linux-s390x-gnu@1.1.3': - resolution: {integrity: sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - - '@rolldown/binding-linux-x64-gnu@1.1.3': - resolution: {integrity: sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-linux-x64-musl@1.1.3': - resolution: {integrity: sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-openharmony-arm64@1.1.3': - resolution: {integrity: sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.1.3': - resolution: {integrity: sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.1.3': - resolution: {integrity: sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.1.3': - resolution: {integrity: sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@sinclair/typebox@0.34.49': - resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} + '@sinclair/typebox@0.34.52': + resolution: {integrity: sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==} '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} @@ -1810,96 +1639,6 @@ packages: peerDependencies: size-limit: 13.0.3 - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@swc/core-darwin-arm64@1.16.1': - resolution: {integrity: sha512-zlJblJ8ncErD43lKdxjbUaUskJQf+LxiPXYcWXD8/8ZMV+7uuAT+CwjciLXpyZBd5Pq/S726bMpeeAwSeL1hhg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - - '@swc/core-darwin-x64@1.16.1': - resolution: {integrity: sha512-IN0BmPWb0YAh/17mmlWB/HDBtTw2MfuW4hulf/tQAgTQBRH17l+z499bNJLK6LizSjqs0P7V+jU38Zj+vJC1DA==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - - '@swc/core-linux-arm-gnueabihf@1.16.1': - resolution: {integrity: sha512-EYgrx2YOCQ2Twz2S793kqNjPkpvYVUPzzR95bIb7by+VQcyaai4lZZ2iz/tZvcFVKSNcN3/JTKwx+aBn2ZL52A==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - - '@swc/core-linux-arm64-gnu@1.16.1': - resolution: {integrity: sha512-moyKm0YZlHdHohzm1YwgAyesqnE853rO0REMfJLFAova51wF9BNi+3ZW2PeS7Vqvn6HeJuepLpAHbBdZctxpHA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-arm64-musl@1.16.1': - resolution: {integrity: sha512-kKGBO9wdapiSzuf5ZzZ2fYtlu1BNSYtIIUxvH1ir/gcelTOREEHGDCLTDFx/2Knf878nU11A40z7LxwasEFxqA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-ppc64-gnu@1.16.1': - resolution: {integrity: sha512-nZ6qahtLxC3PM54cWOQZHxt4lTCF/3J4LIoWWzz6v7A+rLs8Dx54anYQf7mH3eIi8KlNpgKci/ie8ZSqFN8O7A==} - engines: {node: '>=10'} - cpu: [ppc64] - os: [linux] - - '@swc/core-linux-s390x-gnu@1.16.1': - resolution: {integrity: sha512-4ji5PNzhYq193Z4/4xUaSoNJza6iCkDJSzhetrbB6KOYxsr+kxtQr8ePWhMJUiMt6JUWtXaZ1PYT8FhtED+nGA==} - engines: {node: '>=10'} - cpu: [s390x] - os: [linux] - - '@swc/core-linux-x64-gnu@1.16.1': - resolution: {integrity: sha512-VJQxqrisHV+B394IgrOu8YsIIXZgffnf5tO+yc9Z/hoUpuZEvuQTjWwlnpZdpyD+0nx6LTD1/3k646JYm43yJA==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-linux-x64-musl@1.16.1': - resolution: {integrity: sha512-r9oV1mwxxsIGcLV1IQ/tw76MW3doatKze1QFWuC+a7QqJUkhY/bKTSVk6NpKKUGm2LDsE33Va8VqSClfA7vSiQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-win32-arm64-msvc@1.16.1': - resolution: {integrity: sha512-6huNRessoBLxWEqBm5zJXyCQ27TO7anvkdiuQ5MDO4CJni0nOXEqKtV9RllQ2TdyENKKsUMXVnIfW2hIXx/R5Q==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - - '@swc/core-win32-ia32-msvc@1.16.1': - resolution: {integrity: sha512-OVKJFUzphrGmsh+BGtcZDesx0YryV7/Yvy5XGgTqnrZfjnyfcr5uaqYQugCckdIlupc5Vs3XtDjRAj12z4ZPlw==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - - '@swc/core-win32-x64-msvc@1.16.1': - resolution: {integrity: sha512-Bt+VIhWYCGk4urklnkkteLUOeLv1VxigwTCeB/xC6rBZxY6IIKdDwCJf6on3E3SUGsIqmQS6QqtuJQc1VxF4Aw==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - - '@swc/core@1.16.1': - resolution: {integrity: sha512-nUaeu91O5QZKrQdaDCHd402ogUIoNOOjpkZNq0UomWK0G6gDaGmLhvddF1/3BXf5O8aLyo6ZPY/aMDWvaJQ/hg==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - - '@swc/types@0.1.28': - resolution: {integrity: sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==} - '@testing-library/dom@8.20.1': resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} engines: {node: '>=12'} @@ -1920,18 +1659,6 @@ packages: peerDependencies: preact: 10.29.8 - '@tsconfig/node10@1.0.12': - resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@tybys/wasm-util@0.10.3': resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} @@ -1956,36 +1683,21 @@ packages: '@types/bonjour@3.5.13': resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/eslint@8.56.12': - resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/express-serve-static-core@4.19.9': resolution: {integrity: sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg==} - '@types/express-serve-static-core@5.1.3': - resolution: {integrity: sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==} - '@types/express@4.17.25': resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - '@types/express@5.0.6': - resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} - '@types/gensync@1.0.5': resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} @@ -2028,8 +1740,8 @@ packages: '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} - '@types/lodash@4.17.24': - resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + '@types/lodash@4.17.25': + resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -2067,21 +1779,12 @@ packages: '@types/serve-static@1.15.10': resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - '@types/serve-static@2.2.0': - resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} - - '@types/set-cookie-parser@2.4.10': - resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==} - '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -2159,8 +1862,8 @@ packages: '@ungap/custom-elements@1.3.0': resolution: {integrity: sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==} - '@ungap/structured-clone@1.3.2': - resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==} + '@ungap/structured-clone@1.3.3': + resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==} '@unrs/resolver-binding-android-arm-eabi@1.12.2': resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} @@ -2272,44 +1975,6 @@ packages: cpu: [x64] os: [win32] - '@vitest/coverage-v8@4.1.9': - resolution: {integrity: sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==} - peerDependencies: - '@vitest/browser': 4.1.9 - vitest: 4.1.9 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@4.1.9': - resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} - - '@vitest/mocker@4.1.9': - resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} - 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.9': - resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} - - '@vitest/runner@4.1.9': - resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} - - '@vitest/snapshot@4.1.9': - resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} - - '@vitest/spy@4.1.9': - resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} - - '@vitest/utils@4.1.9': - resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} - '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -2374,8 +2039,8 @@ packages: resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} - acorn@8.17.0: - resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} engines: {node: '>=0.4.0'} hasBin: true @@ -2424,8 +2089,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -2448,9 +2113,6 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -2511,19 +2173,12 @@ packages: resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} engines: {node: '>=12.0.0'} - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - ast-metadata-inferer@0.8.1: resolution: {integrity: sha512-ht3Dm6Zr7SXv6t1Ra6gFo0+kLDglHGrEbYihTkcycrbHw7WCcuhBzPlJYHEsIpycaUwzsJHje+vUcxXUX4ztTA==} ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@1.0.4: - resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} - astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -2532,8 +2187,8 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - autoprefixer@10.5.2: - resolution: {integrity: sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==} + autoprefixer@10.5.4: + resolution: {integrity: sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -2543,8 +2198,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.12.1: - resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==} + axe-core@4.13.0: + resolution: {integrity: sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==} engines: {node: '>=4'} axobject-query@4.1.0: @@ -2602,8 +2257,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - baseline-browser-mapping@2.10.40: - resolution: {integrity: sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==} + baseline-browser-mapping@2.11.17: + resolution: {integrity: sha512-KAUDn1OSS0fmPlGO+NOUMRcOQ/b/shUBH3OgkG73mPgdf+JD/BQ6fHboGxNOxnUmlwcq+lLq3dTkayRPuSfXwg==} engines: {node: '>=6.0.0'} hasBin: true @@ -2621,8 +2276,8 @@ packages: resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - bonjour-service@1.4.2: - resolution: {integrity: sha512-lMskhnsW70yWHr4PhPeh2rvaIkLSaDpp+nmtbXBZaNKTXwxL73QOkW6HhbzqTImXjevn9TreGT4GACGBCGP9nQ==} + bonjour-service@1.4.4: + resolution: {integrity: sha512-jCZcVv7eoc4QesRscwEZtSROBen+6LpKAmBIsQYQrsAeVHLyMXWX/t6eIV5KiRZYNUBl8eVqImEEMQ8L5+c/Kw==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2641,8 +2296,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.4: - resolution: {integrity: sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==} + browserslist@4.28.8: + resolution: {integrity: sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2701,12 +2356,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001800: - resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} + caniuse-lite@1.0.30001809: + resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -2761,10 +2412,6 @@ packages: resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2797,8 +2444,8 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colord@2.9.3: - resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + colord@2.10.0: + resolution: {integrity: sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==} colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -2858,12 +2505,9 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + 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==} @@ -2886,9 +2530,6 @@ packages: typescript: optional: true - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-env@10.1.0: resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} engines: {node: '>=20'} @@ -2897,10 +2538,6 @@ packages: cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} - cross-spawn@6.0.6: - resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} - engines: {node: '>=4.8'} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -3107,8 +2744,8 @@ packages: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + default-browser@5.5.1: + resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==} engines: {node: '>=18'} define-data-property@1.1.4: @@ -3139,10 +2776,6 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -3150,10 +2783,6 @@ packages: detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - diff@4.0.4: - resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} - engines: {node: '>=0.3.1'} - dns-packet@5.6.1: resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} engines: {node: '>=6'} @@ -3214,8 +2843,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.382: - resolution: {integrity: sha512-8ETaWbV6SZOrno+G93Ffd9ENsMtetqdnqj4nlfxFW90Sm5GgnuV28Kf62hqQVD6VUgzm7qFQKsTsAPmeUiU3Ug==} + electron-to-chromium@1.5.412: + resolution: {integrity: sha512-z4rMe3esBzlzovKHj4gxJnsCGZRK5l4baUvm+gCGJBPE+gsyUMKsuU9tnEUtI1dOebXz1ytAPGjvXhmQ7rIPwA==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -3239,10 +2868,6 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - enhanced-resolve@5.24.1: - resolution: {integrity: sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw==} - engines: {node: '>=10.13.0'} - enhanced-resolve@5.24.5: resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} engines: {node: '>=10.13.0'} @@ -3289,12 +2914,12 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-iterator-helpers@1.3.3: - resolution: {integrity: sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==} + es-iterator-helpers@1.4.0: + resolution: {integrity: sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==} engines: {node: '>= 0.4'} - es-module-lexer@2.2.0: - resolution: {integrity: sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==} + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} es-object-atoms@1.1.2: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} @@ -3349,8 +2974,8 @@ packages: eslint-import-resolver-node@0.3.10: resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - eslint-module-utils@2.13.0: - resolution: {integrity: sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==} + eslint-module-utils@2.14.0: + resolution: {integrity: sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -3445,6 +3070,7 @@ packages: eslint@9.39.5: resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -3477,9 +3103,6 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - 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'} @@ -3510,10 +3133,6 @@ packages: resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} engines: {node: '>= 0.8.0'} - expect-type@1.4.0: - resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} - engines: {node: '>=12.0.0'} - expect@30.4.1: resolution: {integrity: sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -3538,18 +3157,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - 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-uri@4.1.2: resolution: {integrity: sha512-TyGmBcbDTZXcb2cj5MV89DrF42DKvb3y5DDUNh95iO+IMeAzMkVSxK1PZRrRIpc9yg8U2GhGdbofNa0LS/a4Bw==} - fast-wrap-ansi@0.2.2: - resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} - fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -3613,8 +3223,8 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} follow-redirects@1.16.0: resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} @@ -3777,10 +3387,6 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphql@16.14.2: - resolution: {integrity: sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} @@ -3830,9 +3436,6 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - headers-polyfill@5.0.1: - resolution: {integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==} - hookified@1.15.1: resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} @@ -3956,8 +3559,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} import-fresh@3.3.1: @@ -4005,8 +3608,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.4.0: - resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} + ipaddr.js@2.5.0: + resolution: {integrity: sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==} engines: {node: '>= 10'} is-arguments@1.2.0: @@ -4106,9 +3709,6 @@ packages: resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} engines: {node: '>=16'} - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -4478,76 +4078,6 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - 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-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - 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-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - 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] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - 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] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - 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@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -4627,8 +4157,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.1: - resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -4638,19 +4168,10 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magicast@0.5.3: - resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} - make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -4675,10 +4196,8 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memfs@4.57.8: - resolution: {integrity: sha512-bApYhn8BLpFAnAQmFfEl/NPN+8qx5Ar3V4Qt3ek23mVwBEElzV7c6XoPkb/PCG8ZFpowCEpHcPwMFTwHS7tSMA==} - peerDependencies: - tslib: '2' + memfs@4.68.1: + resolution: {integrity: sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw==} memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} @@ -4748,8 +4267,8 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} minimatch@3.1.5: @@ -4822,24 +4341,10 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.14.6: - resolution: {integrity: sha512-ALe+N10S72cyx94cMcy3Zs4HhXCj35sgeAL4c+WTvKi0zWnbd8/h0lcFqv0mb2P+aSgAdD7p9HzvA0DiUPxsyg==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true - mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} - 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} @@ -4867,9 +4372,6 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -4895,8 +4397,8 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.50: - resolution: {integrity: sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==} + node-releases@2.0.53: + resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} engines: {node: '>=18'} normalize-package-data@2.5.0: @@ -4964,8 +4466,8 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - obug@2.1.3: - resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} on-finished@2.4.1: @@ -4999,11 +4501,8 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + own-keys@1.0.2: + resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} p-limit@2.3.0: @@ -5073,10 +4572,6 @@ packages: path-is-inside@1.0.2: resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} - path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5095,9 +4590,6 @@ packages: path-to-regexp@0.1.13: resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -5106,9 +4598,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -5116,8 +4605,8 @@ packages: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pidtree@0.3.1: @@ -5543,8 +5032,8 @@ packages: resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==} engines: {node: '>=4'} - postcss-selector-parser@7.1.4: - resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} + postcss-selector-parser@7.1.5: + resolution: {integrity: sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==} engines: {node: '>=4'} postcss-svgo@7.1.3: @@ -5618,8 +5107,8 @@ packages: pvtsutils@1.3.6: resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + pvutils@1.2.0: + resolution: {integrity: sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==} engines: {node: '>=16.0.0'} qified@0.10.1: @@ -5774,9 +5263,6 @@ packages: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} - rettime@0.11.11: - resolution: {integrity: sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -5789,11 +5275,6 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rolldown@1.1.3: - resolution: {integrity: sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -5825,8 +5306,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} saxes@6.0.0: @@ -5848,10 +5329,6 @@ packages: resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} engines: {node: '>=18'} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -5877,9 +5354,6 @@ packages: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} - set-cookie-parser@3.1.1: - resolution: {integrity: sha512-vM9SUhjsUYs6UeJUmygc5Ofm5eQGe85riob5ju6XCgFGJI5PLV4nrDAQpQjd+LkFBpAkADn5BQQpZ9EUNkyLuA==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -5899,24 +5373,16 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} - shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.9.0: - resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} + shell-quote@1.10.0: + resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} engines: {node: '>= 0.4'} side-channel-list@1.0.1: @@ -5935,9 +5401,6 @@ packages: resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} 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==} @@ -6013,9 +5476,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -6024,16 +5484,10 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -6203,16 +5657,12 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - terser@5.48.0: - resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==} + terser@5.50.0: + resolution: {integrity: sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w==} engines: {node: '>=10'} hasBin: true @@ -6220,8 +5670,8 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} - thingies@2.6.0: - resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + thingies@2.6.1: + resolution: {integrity: sha512-cV/CMGTK3M4MlnJ/0At6ismOw/A0EEniDNScajjz/Br3c1sqE72YD01rGpPTKwd27wAxI5Pr+6+0w8yofzFRYw==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -6229,35 +5679,17 @@ packages: thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} - tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - engines: {node: '>=14.0.0'} - tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.5: - resolution: {integrity: sha512-pGrwzZDvPwKe+7NNUqAunb6rqTfynr0VOUhCMdqbu5xlvNiszsAJygRzwvpVycdzejlbpY+SWJOn+s75Og7FEA==} - tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.5: - resolution: {integrity: sha512-RfEzKWcq5fHUOFq7J3rl3Oz6ylKGtcHqUznzj4EcXsxLSIjJcvpbXAQtWGeJQ0xKnimR5e0Cn+cn9TssfMzm+g==} - hasBin: true - tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -6277,10 +5709,6 @@ packages: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -6300,20 +5728,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - tsconfig-paths-webpack-plugin@4.2.0: resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} engines: {node: '>=10.13.0'} @@ -6351,10 +5765,6 @@ packages: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} - type-fest@5.7.0: - resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} - engines: {node: '>=20'} - type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -6418,11 +5828,8 @@ packages: unrs-resolver@1.12.2: resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} - until-async@3.0.2: - resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + update-browserslist-db@1.3.1: + resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -6444,9 +5851,6 @@ packages: resolution: {integrity: sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==} hasBin: true - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} @@ -6458,90 +5862,6 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite@8.1.2: - resolution: {integrity: sha512-6YYPbRXTxx6bRXmOn7XdnQAy5DQNHhDgtjhDHI13oe4pY93kkcdGJWxpGwOm++/Wh0QpQhDrpIoVMrmrsI5AGQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.3.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.9.0 <3.0.0' - 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@4.1.9: - resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} - 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.9 - '@vitest/browser-preview': 4.1.9 - '@vitest/browser-webdriverio': 4.1.9 - '@vitest/coverage-istanbul': 4.1.9 - '@vitest/coverage-v8': 4.1.9 - '@vitest/ui': 4.1.9 - 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 - w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -6680,11 +6000,6 @@ packages: engines: {node: '>= 8'} hasBin: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} @@ -6711,8 +6026,8 @@ packages: resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} engines: {node: ^20.17.0 || >=22.9.0} - ws@8.21.0: - resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -6754,10 +6069,6 @@ packages: resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} engines: {node: '>=12'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -6792,7 +6103,7 @@ snapshots: '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 - '@babel/generator': 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) '@babel/helpers': 7.29.7 @@ -6825,7 +6136,7 @@ snapshots: gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 - obug: 2.1.3 + obug: 2.1.4 semver: 7.8.5 '@babel/eslint-parser@7.29.7(@babel/core@7.29.7)(eslint@9.39.5(jiti@2.7.0))': @@ -6836,14 +6147,6 @@ snapshots: eslint-visitor-keys: 2.1.0 semver: 6.3.1 - '@babel/generator@7.29.7': - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - '@babel/generator@7.29.8': dependencies: '@babel/parser': 7.29.8 @@ -6869,7 +6172,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.4 + browserslist: 4.28.8 lru-cache: 5.1.1 semver: 6.3.1 @@ -6877,8 +6180,8 @@ snapshots: dependencies: '@babel/compat-data': 8.0.0 '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.4 - lru-cache: 11.5.1 + browserslist: 4.28.8 + lru-cache: 11.5.2 semver: 7.8.5 '@babel/helper-create-class-features-plugin@8.0.1(@babel/core@8.0.1)': @@ -7000,10 +6303,6 @@ snapshots: '@babel/template': 8.0.0 '@babel/types': 8.0.4 - '@babel/parser@7.29.7': - dependencies: - '@babel/types': 7.29.7 - '@babel/parser@7.29.8': dependencies: '@babel/types': 7.29.8 @@ -7540,7 +6839,7 @@ snapshots: '@babel/plugin-transform-unicode-sets-regex': 8.0.1(@babel/core@8.0.1) '@babel/preset-modules': 0.2.0(@babel/core@8.0.1) babel-plugin-polyfill-corejs3: 1.0.0(@babel/core@8.0.1) - core-js-compat: 3.49.0 + core-js-compat: 3.50.0 semver: 7.8.5 '@babel/preset-modules@0.2.0(@babel/core@8.0.1)': @@ -7604,12 +6903,7 @@ snapshots: '@babel/parser': 8.0.4 '@babel/template': 8.0.0 '@babel/types': 8.0.4 - obug: 2.1.3 - - '@babel/types@7.29.7': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 + obug: 2.1.4 '@babel/types@7.29.8': dependencies: @@ -7623,9 +6917,6 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@bcoe/v8-coverage@1.0.2': - optional: true - '@cacheable/memory@2.2.0': dependencies: '@cacheable/utils': 2.5.0 @@ -7638,12 +6929,7 @@ snapshots: hashery: 1.5.1 keyv: 5.6.0 - '@colordx/core@5.5.0': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - optional: true + '@colordx/core@5.6.0': {} '@csstools/color-helpers@5.1.0': {} @@ -7652,7 +6938,7 @@ snapshots: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -7672,7 +6958,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.6(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.8(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -7759,17 +7045,17 @@ snapshots: dependencies: postcss: 8.5.26 - '@csstools/selector-resolve-nested@4.0.1(postcss-selector-parser@7.1.4)': + '@csstools/selector-resolve-nested@4.0.1(postcss-selector-parser@7.1.5)': dependencies: - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 '@csstools/selector-specificity@2.2.0(postcss-selector-parser@6.1.4)': dependencies: postcss-selector-parser: 6.1.4 - '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.4)': + '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.5)': dependencies: - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 '@discoveryjs/json-ext@0.6.3': {} @@ -7781,35 +7067,19 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/core@1.11.1': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.11.1': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - '@epic-web/invariant@1.0.0': {} - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.5(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0))': dependencies: eslint: 9.39.5(jiti@2.7.0) eslint-visitor-keys: 3.4.3 @@ -7882,38 +7152,6 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@2.0.7': - optional: true - - '@inquirer/confirm@6.1.1(@types/node@26.2.0)': - dependencies: - '@inquirer/core': 11.2.1(@types/node@26.2.0) - '@inquirer/type': 4.0.7(@types/node@26.2.0) - optionalDependencies: - '@types/node': 26.2.0 - optional: true - - '@inquirer/core@11.2.1(@types/node@26.2.0)': - dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@26.2.0) - cli-width: 4.1.0 - fast-wrap-ansi: 0.2.2 - mute-stream: 3.0.0 - signal-exit: 4.1.0 - optionalDependencies: - '@types/node': 26.2.0 - optional: true - - '@inquirer/figures@2.0.7': - optional: true - - '@inquirer/type@4.0.7(@types/node@26.2.0)': - optionalDependencies: - '@types/node': 26.2.0 - optional: true - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -7942,7 +7180,7 @@ snapshots: jest-util: 30.4.1 slash: 3.0.0 - '@jest/core@30.4.2(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3))': + '@jest/core@30.4.2': dependencies: '@jest/console': 30.4.1 '@jest/pattern': 30.4.0 @@ -7958,7 +7196,7 @@ snapshots: fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 jest-changed-files: 30.4.1 - jest-config: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + jest-config: 30.4.2(@types/node@26.2.0) jest-haste-map: 30.4.1 jest-message-util: 30.4.1 jest-regex-util: 30.4.0 @@ -8060,7 +7298,7 @@ snapshots: '@jest/schemas@30.4.1': dependencies: - '@sinclair/typebox': 0.34.49 + '@sinclair/typebox': 0.34.52 '@jest/snapshot-utils@30.4.1': dependencies: @@ -8140,12 +7378,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - optional: true - '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 @@ -8170,58 +7402,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.68.1(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-node@4.57.8(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-core': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.68.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.68.1(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -8234,7 +7467,7 @@ snapshots: '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.6.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -8246,7 +7479,7 @@ snapshots: '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.6.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -8287,30 +7520,13 @@ snapshots: '@mdn/browser-compat-data@6.1.5': {} - '@mswjs/interceptors@0.41.9': - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 - optional: true - - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.2.3(@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 - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -8329,96 +7545,78 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@open-draft/deferred-promise@2.2.0': - optional: true - - '@open-draft/deferred-promise@3.0.0': - optional: true - - '@open-draft/logger@0.3.0': + '@peculiar/asn1-cms@2.9.4': dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - optional: true - - '@open-draft/until@2.1.0': - optional: true - - '@oxc-project/types@0.137.0': - optional: true - - '@peculiar/asn1-cms@2.8.0': - dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 - '@peculiar/asn1-x509-attr': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-x509-attr': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-csr@2.8.0': + '@peculiar/asn1-csr@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.8.0': + '@peculiar/asn1-ecc@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.8.0': + '@peculiar/asn1-pfx@2.9.4': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-pkcs8': 2.8.0 - '@peculiar/asn1-rsa': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-pkcs8': 2.9.4 + '@peculiar/asn1-rsa': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.8.0': + '@peculiar/asn1-pkcs8@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.8.0': + '@peculiar/asn1-pkcs9@2.9.4': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-pfx': 2.8.0 - '@peculiar/asn1-pkcs8': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 - '@peculiar/asn1-x509-attr': 2.8.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-pfx': 2.9.4 + '@peculiar/asn1-pkcs8': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-x509-attr': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.8.0': + '@peculiar/asn1-rsa@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-schema@2.8.0': + '@peculiar/asn1-schema@2.9.4': dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.8.0': + '@peculiar/asn1-x509-attr@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509@2.8.0': + '@peculiar/asn1-x509@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 @@ -8429,13 +7627,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-csr': 2.8.0 - '@peculiar/asn1-ecc': 2.8.0 - '@peculiar/asn1-pkcs9': 2.8.0 - '@peculiar/asn1-rsa': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-csr': 2.9.4 + '@peculiar/asn1-ecc': 2.9.4 + '@peculiar/asn1-pkcs9': 2.9.4 + '@peculiar/asn1-rsa': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -8448,61 +7646,9 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@rolldown/binding-android-arm64@1.1.3': - optional: true - - '@rolldown/binding-darwin-arm64@1.1.3': - optional: true - - '@rolldown/binding-darwin-x64@1.1.3': - optional: true - - '@rolldown/binding-freebsd-x64@1.1.3': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.1.3': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.1.3': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-x64-musl@1.1.3': - optional: true - - '@rolldown/binding-openharmony-arm64@1.1.3': - optional: true - - '@rolldown/binding-wasm32-wasi@1.1.3': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.1.3': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.1.3': - optional: true - - '@rolldown/pluginutils@1.0.1': - optional: true - '@rtsao/scc@1.1.0': {} - '@sinclair/typebox@0.34.49': {} + '@sinclair/typebox@0.34.52': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -8518,72 +7664,6 @@ snapshots: dependencies: size-limit: 13.0.3 - '@standard-schema/spec@1.1.0': - optional: true - - '@swc/core-darwin-arm64@1.16.1': - optional: true - - '@swc/core-darwin-x64@1.16.1': - optional: true - - '@swc/core-linux-arm-gnueabihf@1.16.1': - optional: true - - '@swc/core-linux-arm64-gnu@1.16.1': - optional: true - - '@swc/core-linux-arm64-musl@1.16.1': - optional: true - - '@swc/core-linux-ppc64-gnu@1.16.1': - optional: true - - '@swc/core-linux-s390x-gnu@1.16.1': - optional: true - - '@swc/core-linux-x64-gnu@1.16.1': - optional: true - - '@swc/core-linux-x64-musl@1.16.1': - optional: true - - '@swc/core-win32-arm64-msvc@1.16.1': - optional: true - - '@swc/core-win32-ia32-msvc@1.16.1': - optional: true - - '@swc/core-win32-x64-msvc@1.16.1': - optional: true - - '@swc/core@1.16.1': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.28 - optionalDependencies: - '@swc/core-darwin-arm64': 1.16.1 - '@swc/core-darwin-x64': 1.16.1 - '@swc/core-linux-arm-gnueabihf': 1.16.1 - '@swc/core-linux-arm64-gnu': 1.16.1 - '@swc/core-linux-arm64-musl': 1.16.1 - '@swc/core-linux-ppc64-gnu': 1.16.1 - '@swc/core-linux-s390x-gnu': 1.16.1 - '@swc/core-linux-x64-gnu': 1.16.1 - '@swc/core-linux-x64-musl': 1.16.1 - '@swc/core-win32-arm64-msvc': 1.16.1 - '@swc/core-win32-ia32-msvc': 1.16.1 - '@swc/core-win32-x64-msvc': 1.16.1 - optional: true - - '@swc/counter@0.1.3': - optional: true - - '@swc/types@0.1.28': - dependencies: - '@swc/counter': 0.1.3 - optional: true - '@testing-library/dom@8.20.1': dependencies: '@babel/code-frame': 7.29.7 @@ -8595,7 +7675,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@7.0.1(@testing-library/dom@8.20.1)(vitest@4.1.9)': + '@testing-library/jest-dom@7.0.1(@testing-library/dom@8.20.1)': dependencies: '@adobe/css-tools': 4.5.0 '@testing-library/dom': 8.20.1 @@ -8604,26 +7684,12 @@ snapshots: dom-accessibility-api: 0.6.3 picocolors: 1.1.1 redent: 3.0.0 - optionalDependencies: - vitest: 4.1.9(@types/node@26.2.0)(@vitest/coverage-v8@4.1.9)(jsdom@26.1.0)(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) '@testing-library/preact@3.2.4(preact@10.29.8)': dependencies: '@testing-library/dom': 8.20.1 preact: 10.29.8 - '@tsconfig/node10@1.0.12': - optional: true - - '@tsconfig/node12@1.0.11': - optional: true - - '@tsconfig/node14@1.0.3': - optional: true - - '@tsconfig/node16@1.0.4': - optional: true - '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 @@ -8633,24 +7699,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/body-parser@1.19.6': dependencies: @@ -8661,30 +7727,15 @@ snapshots: dependencies: '@types/node': 26.2.0 - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - optional: true - '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 5.1.3 + '@types/express-serve-static-core': 4.19.9 '@types/node': 26.2.0 '@types/connect@3.4.38': dependencies: '@types/node': 26.2.0 - '@types/deep-eql@4.0.2': - optional: true - - '@types/eslint@8.56.12': - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - optional: true - '@types/estree@1.0.9': {} '@types/express-serve-static-core@4.19.9': @@ -8694,13 +7745,6 @@ snapshots: '@types/range-parser': 1.2.7 '@types/send': 1.2.1 - '@types/express-serve-static-core@5.1.3': - dependencies: - '@types/node': 26.2.0 - '@types/qs': 6.15.1 - '@types/range-parser': 1.2.7 - '@types/send': 1.2.1 - '@types/express@4.17.25': dependencies: '@types/body-parser': 1.19.6 @@ -8708,12 +7752,6 @@ snapshots: '@types/qs': 6.15.1 '@types/serve-static': 1.15.10 - '@types/express@5.0.6': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.1.3 - '@types/serve-static': 2.2.0 - '@types/gensync@1.0.5': {} '@types/glob@7.2.0': @@ -8758,9 +7796,9 @@ snapshots: '@types/lodash-es@4.17.12': dependencies: - '@types/lodash': 4.17.24 + '@types/lodash': 4.17.25 - '@types/lodash@4.17.24': {} + '@types/lodash@4.17.25': {} '@types/mime@1.3.5': {} @@ -8793,7 +7831,7 @@ snapshots: '@types/serve-index@1.9.4': dependencies: - '@types/express': 5.0.6 + '@types/express': 4.17.25 '@types/serve-static@1.15.10': dependencies: @@ -8801,25 +7839,12 @@ snapshots: '@types/node': 26.2.0 '@types/send': 0.17.6 - '@types/serve-static@2.2.0': - dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 26.2.0 - - '@types/set-cookie-parser@2.4.10': - dependencies: - '@types/node': 26.2.0 - optional: true - '@types/sockjs@0.3.36': dependencies: '@types/node': 26.2.0 '@types/stack-utils@2.0.3': {} - '@types/statuses@2.0.6': - optional: true - '@types/tough-cookie@4.0.5': {} '@types/webpack-env@1.18.8': {} @@ -8843,7 +7868,7 @@ snapshots: '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.67.0 eslint: 9.39.5(jiti@2.7.0) - ignore: 7.0.5 + ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 @@ -8901,7 +7926,7 @@ snapshots: '@typescript-eslint/types': 8.67.0 '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3 - minimatch: 10.2.5 + minimatch: 10.2.6 semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@5.9.3) @@ -8911,7 +7936,7 @@ snapshots: '@typescript-eslint/utils@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) '@typescript-eslint/scope-manager': 8.67.0 '@typescript-eslint/types': 8.67.0 '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) @@ -8927,7 +7952,7 @@ snapshots: '@ungap/custom-elements@1.3.0': {} - '@ungap/structured-clone@1.3.2': {} + '@ungap/structured-clone@1.3.3': {} '@unrs/resolver-binding-android-arm-eabi@1.12.2': optional: true @@ -8987,7 +8012,7 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': @@ -8999,70 +8024,6 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true - '@vitest/coverage-v8@4.1.9(vitest@4.1.9)': - dependencies: - '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.9 - ast-v8-to-istanbul: 1.0.4 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 - magicast: 0.5.3 - obug: 2.1.3 - std-env: 4.1.0 - tinyrainbow: 3.1.0 - vitest: 4.1.9(@types/node@26.2.0)(@vitest/coverage-v8@4.1.9)(jsdom@26.1.0)(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) - optional: true - - '@vitest/expect@4.1.9': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - chai: 6.2.2 - tinyrainbow: 3.1.0 - optional: true - - '@vitest/mocker@4.1.9(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0))': - dependencies: - '@vitest/spy': 4.1.9 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - msw: 2.14.6(@types/node@26.2.0)(typescript@5.9.3) - vite: 8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) - optional: true - - '@vitest/pretty-format@4.1.9': - dependencies: - tinyrainbow: 3.1.0 - optional: true - - '@vitest/runner@4.1.9': - dependencies: - '@vitest/utils': 4.1.9 - pathe: 2.0.3 - optional: true - - '@vitest/snapshot@4.1.9': - dependencies: - '@vitest/pretty-format': 4.1.9 - '@vitest/utils': 4.1.9 - magic-string: 0.30.21 - pathe: 2.0.3 - optional: true - - '@vitest/spy@4.1.9': - optional: true - - '@vitest/utils@4.1.9': - dependencies: - '@vitest/pretty-format': 4.1.9 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 - optional: true - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -9148,15 +8109,15 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-jsx@5.3.2(acorn@8.17.0): + acorn-jsx@5.3.2(acorn@8.18.0): dependencies: - acorn: 8.17.0 + acorn: 8.18.0 acorn-walk@8.3.5: dependencies: - acorn: 8.17.0 + acorn: 8.18.0 - acorn@8.17.0: {} + acorn@8.18.0: {} agent-base@7.1.4: {} @@ -9199,7 +8160,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} + ansi-regex@6.3.0: {} ansi-styles@3.2.1: dependencies: @@ -9218,9 +8179,6 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.2 - arg@4.1.3: - optional: true - argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -9311,33 +8269,23 @@ snapshots: asn1js@3.0.10: dependencies: pvtsutils: 1.3.6 - pvutils: 1.1.5 + pvutils: 1.2.0 tslib: 2.8.1 - assertion-error@2.0.1: - optional: true - ast-metadata-inferer@0.8.1: dependencies: '@mdn/browser-compat-data': 5.7.6 ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@1.0.4: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - estree-walker: 3.0.3 - js-tokens: 10.0.0 - optional: true - astral-regex@2.0.0: {} async-function@1.0.0: {} - autoprefixer@10.5.2(postcss@8.5.26): + autoprefixer@10.5.4(postcss@8.5.26): dependencies: - browserslist: 4.28.4 - caniuse-lite: 1.0.30001800 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.26 @@ -9347,7 +8295,7 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.12.1: {} + axe-core@4.13.0: {} axobject-query@4.1.0: {} @@ -9367,7 +8315,7 @@ snapshots: '@babel/core': 8.0.1 find-up: 5.0.0 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) babel-plugin-istanbul@7.0.1: dependencies: @@ -9385,7 +8333,7 @@ snapshots: dependencies: '@babel/core': 8.0.1 '@babel/helper-define-polyfill-provider': 1.0.0(@babel/core@8.0.1) - core-js-compat: 3.49.0 + core-js-compat: 3.50.0 babel-preset-current-node-syntax@1.2.0(@babel/core@8.0.1): dependencies: @@ -9416,7 +8364,7 @@ snapshots: balanced-match@4.0.4: {} - baseline-browser-mapping@2.10.40: {} + baseline-browser-mapping@2.11.17: {} batch@0.6.1: {} @@ -9441,7 +8389,7 @@ snapshots: transitivePeerDependencies: - supports-color - bonjour-service@1.4.2: + bonjour-service@1.4.4: dependencies: fast-deep-equal: 3.1.3 multicast-dns: 7.2.5 @@ -9465,13 +8413,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.4: + browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.10.40 - caniuse-lite: 1.0.30001800 - electron-to-chromium: 1.5.382 - node-releases: 2.0.50 - update-browserslist-db: 1.2.3(browserslist@4.28.4) + baseline-browser-mapping: 2.11.17 + caniuse-lite: 1.0.30001809 + electron-to-chromium: 1.5.412 + node-releases: 2.0.53 + update-browserslist-db: 1.3.1(browserslist@4.28.8) bser@2.1.1: dependencies: @@ -9527,15 +8475,12 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.28.4 - caniuse-lite: 1.0.30001800 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001800: {} - - chai@6.2.2: - optional: true + caniuse-lite@1.0.30001809: {} chalk@2.4.2: dependencies: @@ -9581,7 +8526,7 @@ snapshots: clean-webpack-plugin@4.0.0(webpack@5.109.2): dependencies: del: 4.1.1 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) cli-cursor@4.0.0: dependencies: @@ -9592,9 +8537,6 @@ snapshots: slice-ansi: 5.0.0 string-width: 5.1.2 - cli-width@4.1.0: - optional: true - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -9625,7 +8567,7 @@ snapshots: color-name@1.1.4: {} - colord@2.9.3: {} + colord@2.10.0: {} colorette@2.0.20: {} @@ -9673,12 +8615,9 @@ snapshots: cookie@0.7.2: {} - cookie@1.1.1: - optional: true - - core-js-compat@3.49.0: + core-js-compat@3.50.0: dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 core-util-is@1.0.3: {} @@ -9700,9 +8639,6 @@ snapshots: optionalDependencies: typescript: 5.9.3 - create-require@1.1.1: - optional: true - cross-env@10.1.0: dependencies: '@epic-web/invariant': 1.0.0 @@ -9714,14 +8650,6 @@ snapshots: transitivePeerDependencies: - encoding - cross-spawn@6.0.6: - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -9755,7 +8683,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.8.5 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) css-minimizer-webpack-plugin@8.0.0(webpack@5.109.2): dependencies: @@ -9765,7 +8693,7 @@ snapshots: postcss: 8.5.26 schema-utils: 4.3.3 serialize-javascript: 7.1.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) css-prefers-color-scheme@6.0.3(postcss@8.5.26): dependencies: @@ -9807,7 +8735,7 @@ snapshots: cssnano-preset-default@7.0.17(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 css-declaration-sorter: 7.4.0(postcss@8.5.26) cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 @@ -9930,7 +8858,7 @@ snapshots: default-browser-id@5.0.1: {} - default-browser@5.5.0: + default-browser@5.5.1: dependencies: bundle-name: 4.1.0 default-browser-id: 5.0.1 @@ -9965,16 +8893,10 @@ snapshots: destroy@1.2.0: {} - detect-libc@2.1.2: - optional: true - detect-newline@3.1.0: {} detect-node@2.1.0: {} - diff@4.0.4: - optional: true - dns-packet@5.6.1: dependencies: '@leichtgewicht/ip-codec': 2.0.5 @@ -10044,7 +8966,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.382: {} + electron-to-chromium@1.5.412: {} emittery@0.13.1: {} @@ -10058,11 +8980,6 @@ snapshots: encodeurl@2.0.0: {} - enhanced-resolve@5.24.1: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - enhanced-resolve@5.24.5: dependencies: graceful-fs: 4.2.11 @@ -10129,7 +9046,7 @@ snapshots: object-inspect: 1.13.4 object-keys: 1.1.1 object.assign: 4.1.7 - own-keys: 1.0.1 + own-keys: 1.0.2 regexp.prototype.flags: 1.5.4 safe-array-concat: 1.1.4 safe-push-apply: 1.0.0 @@ -10162,7 +9079,7 @@ snapshots: isarray: 2.0.5 stop-iteration-iterator: 1.1.0 - es-iterator-helpers@1.3.3: + es-iterator-helpers@1.4.0: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 @@ -10181,7 +9098,7 @@ snapshots: iterator.prototype: 1.1.5 math-intrinsics: 1.1.0 - es-module-lexer@2.2.0: {} + es-module-lexer@2.3.2: {} es-object-atoms@1.1.2: dependencies: @@ -10246,7 +9163,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.13.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: @@ -10260,7 +9177,7 @@ snapshots: dependencies: '@mdn/browser-compat-data': 6.1.5 ast-metadata-inferer: 0.8.1 - browserslist: 4.28.4 + browserslist: 4.28.8 eslint: 9.39.5(jiti@2.7.0) find-up: 5.0.0 globals: 15.15.0 @@ -10278,7 +9195,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.5(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -10302,7 +9219,7 @@ snapshots: array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.12.1 + axe-core: 4.13.0 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -10315,14 +9232,13 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.6(@types/eslint@8.56.12)(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6): + eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6): dependencies: eslint: 9.39.5(jiti@2.7.0) prettier: 3.9.6 prettier-linter-helpers: 1.0.1 synckit: 0.11.13 optionalDependencies: - '@types/eslint': 8.56.12 eslint-config-prettier: 10.1.8(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-react-hooks@5.2.0(eslint@9.39.5(jiti@2.7.0)): @@ -10336,7 +9252,7 @@ snapshots: array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.3.3 + es-iterator-helpers: 1.4.0 eslint: 9.39.5(jiti@2.7.0) estraverse: 5.3.0 hasown: 2.0.4 @@ -10371,7 +9287,7 @@ snapshots: eslint@9.39.5(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 @@ -10412,8 +9328,8 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} @@ -10430,11 +9346,6 @@ snapshots: estraverse@5.3.0: {} - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.9 - optional: true - esutils@2.0.3: {} etag@1.8.1: {} @@ -10471,9 +9382,6 @@ snapshots: exit-x@0.2.2: {} - expect-type@1.4.0: - optional: true - expect@30.4.1: dependencies: '@jest/expect-utils': 30.4.1 @@ -10535,21 +9443,8 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-string-truncated-width@3.0.3: - optional: true - - fast-string-width@3.0.2: - dependencies: - fast-string-truncated-width: 3.0.3 - optional: true - fast-uri@4.1.2: {} - fast-wrap-ansi@0.2.2: - dependencies: - fast-string-width: 3.0.2 - optional: true - fastest-levenshtein@1.0.16: {} fastq@1.20.1: @@ -10564,9 +9459,9 @@ snapshots: dependencies: bser: 2.1.1 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 file-entry-cache@11.1.5: dependencies: @@ -10580,7 +9475,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) fill-range@7.1.1: dependencies: @@ -10610,18 +9505,18 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.4.2 + flatted: 3.4.4 keyv: 4.5.4 flat-cache@6.1.23: dependencies: cacheable: 2.5.0 - flatted: 3.4.2 + flatted: 3.4.4 hookified: 1.15.1 flat@5.0.2: {} - flatted@3.4.2: {} + flatted@3.4.4: {} follow-redirects@1.16.0: {} @@ -10649,7 +9544,7 @@ snapshots: semver: 7.8.5 tapable: 2.3.3 typescript: 5.9.3 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) forwarded@0.2.0: {} @@ -10777,7 +9672,7 @@ snapshots: dependencies: '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 - ignore: 7.0.5 + ignore: 7.0.6 is-path-inside: 4.0.0 micromatch: 4.0.8 slash: 5.1.0 @@ -10797,9 +9692,6 @@ snapshots: graceful-fs@4.2.11: {} - graphql@16.14.2: - optional: true - handle-thing@2.0.1: {} harmony-reflect@1.6.2: {} @@ -10836,12 +9728,6 @@ snapshots: he@1.2.0: {} - headers-polyfill@5.0.1: - dependencies: - '@types/set-cookie-parser': 2.4.10 - set-cookie-parser: 3.1.1 - optional: true - hookified@1.15.1: {} hookified@2.2.0: {} @@ -10871,7 +9757,7 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.48.0 + terser: 5.50.0 html-tags@5.1.0: {} @@ -10883,7 +9769,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.3 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) htmlparser2@6.1.0: dependencies: @@ -10979,7 +9865,7 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.5: {} + ignore@7.0.6: {} import-fresh@3.3.1: dependencies: @@ -11018,7 +9904,7 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.4.0: {} + ipaddr.js@2.5.0: {} is-arguments@1.2.0: dependencies: @@ -11111,9 +9997,6 @@ snapshots: is-network-error@1.3.2: {} - is-node-process@1.2.0: - optional: true - is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -11201,7 +10084,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 8.0.1 - '@babel/parser': 7.29.7 + '@babel/parser': 7.29.8 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 7.8.5 @@ -11271,15 +10154,15 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - jest-cli@30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)): + jest-cli@30.4.2(@types/node@26.2.0): dependencies: - '@jest/core': 30.4.2(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + '@jest/core': 30.4.2 '@jest/test-result': 30.4.1 '@jest/types': 30.4.1 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + jest-config: 30.4.2(@types/node@26.2.0) jest-util: 30.4.1 jest-validate: 30.4.1 yargs: 17.7.3 @@ -11290,7 +10173,7 @@ snapshots: - supports-color - ts-node - jest-config@30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)): + jest-config@30.4.2(@types/node@26.2.0): dependencies: '@babel/core': 8.0.1 '@jest/get-type': 30.1.0 @@ -11317,7 +10200,6 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 26.2.0 - ts-node: 10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros @@ -11376,7 +10258,7 @@ snapshots: jest-regex-util: 30.4.0 jest-util: 30.4.1 jest-worker: 30.4.1 - picomatch: 4.0.4 + picomatch: 4.0.5 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 @@ -11403,7 +10285,7 @@ snapshots: chalk: 4.1.2 graceful-fs: 4.2.11 jest-util: 30.4.1 - picomatch: 4.0.4 + picomatch: 4.0.5 pretty-format: 30.4.1 slash: 3.0.0 stack-utils: 2.0.6 @@ -11489,10 +10371,10 @@ snapshots: jest-snapshot@30.4.1: dependencies: '@babel/core': 8.0.1 - '@babel/generator': 7.29.7 + '@babel/generator': 7.29.8 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@8.0.1) '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@8.0.1) - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@jest/expect-utils': 30.4.1 '@jest/get-type': 30.1.0 '@jest/snapshot-utils': 30.4.1 @@ -11517,7 +10399,7 @@ snapshots: chalk: 4.1.2 ci-info: 4.4.0 graceful-fs: 4.2.11 - picomatch: 4.0.4 + picomatch: 4.0.5 jest-validate@30.4.1: dependencies: @@ -11548,17 +10430,17 @@ snapshots: jest-worker@30.4.1: dependencies: '@types/node': 26.2.0 - '@ungap/structured-clone': 1.3.2 + '@ungap/structured-clone': 1.3.3 jest-util: 30.4.1 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)): + jest@30.4.2(@types/node@26.2.0): dependencies: - '@jest/core': 30.4.2(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + '@jest/core': 30.4.2 '@jest/types': 30.4.1 import-local: 3.2.0 - jest-cli: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + jest-cli: 30.4.2(@types/node@26.2.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11603,7 +10485,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.21.0 + ws: 8.21.3 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -11662,7 +10544,7 @@ snapshots: launch-editor@2.14.1: dependencies: picocolors: 1.1.1 - shell-quote: 1.9.0 + shell-quote: 1.10.0 leven@3.1.0: {} @@ -11671,56 +10553,6 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.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 - optional: true - lilconfig@2.1.0: {} lilconfig@3.1.3: {} @@ -11807,7 +10639,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.5.1: {} + lru-cache@11.5.2: {} lru-cache@5.1.1: dependencies: @@ -11815,25 +10647,10 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - optional: true - - magicast@0.5.3: - dependencies: - '@babel/parser': 7.29.8 - '@babel/types': 7.29.8 - source-map-js: 1.2.1 - optional: true - make-dir@4.0.0: dependencies: semver: 7.8.5 - make-error@1.3.6: - optional: true - makeerror@1.0.12: dependencies: tmpl: 1.0.5 @@ -11852,20 +10669,20 @@ snapshots: dependencies: fs-monkey: 1.1.0 - memfs@4.57.8(tslib@2.8.1): + memfs@4.68.1: dependencies: - '@jsonjoy.com/fs-core': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -11910,11 +10727,11 @@ snapshots: dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) minimalistic-assert@1.0.1: {} - minimatch@10.2.5: + minimatch@10.2.6: dependencies: brace-expansion: 5.0.9 @@ -11928,15 +10745,14 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.6.1(@swc/core@1.16.1)(postcss@8.5.26)(webpack@5.109.2): + minimizer-webpack-plugin@5.6.1(postcss@8.5.26)(webpack@5.109.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.48.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + terser: 5.50.0 + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) optionalDependencies: - '@swc/core': 1.16.1 postcss: 8.5.26 minipass@7.1.3: {} @@ -11949,40 +10765,11 @@ snapshots: ms@2.1.3: {} - msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3): - dependencies: - '@inquirer/confirm': 6.1.1(@types/node@26.2.0) - '@mswjs/interceptors': 0.41.9 - '@open-draft/deferred-promise': 3.0.0 - '@types/statuses': 2.0.6 - cookie: 1.1.1 - graphql: 16.14.2 - headers-polyfill: 5.0.1 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - rettime: 0.11.11 - statuses: 2.0.2 - strict-event-emitter: 0.5.1 - tough-cookie: 6.0.1 - type-fest: 5.7.0 - until-async: 3.0.2 - yargs: 17.7.3 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - '@types/node' - optional: true - multicast-dns@7.2.5: dependencies: dns-packet: 5.6.1 thunky: 1.1.0 - mute-stream@3.0.0: - optional: true - nanoid@3.3.18: {} nanospinner@1.2.2: @@ -11999,8 +10786,6 @@ snapshots: neo-async@2.6.2: {} - nice-try@1.0.5: {} - no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -12025,13 +10810,13 @@ snapshots: node-int64@0.4.0: {} - node-releases@2.0.50: {} + node-releases@2.0.53: {} normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 resolve: 1.22.12 - semver: 5.7.2 + semver: 7.8.5 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} @@ -12040,12 +10825,12 @@ snapshots: dependencies: ansi-styles: 3.2.1 chalk: 2.4.2 - cross-spawn: 6.0.6 + cross-spawn: 7.0.6 memorystream: 0.3.1 minimatch: 3.1.5 pidtree: 0.3.1 read-pkg: 3.0.0 - shell-quote: 1.9.0 + shell-quote: 1.10.0 string.prototype.padend: 3.1.6 npm-run-path@4.0.1: @@ -12111,7 +10896,7 @@ snapshots: obuf@1.1.2: {} - obug@2.1.3: {} + obug@2.1.4: {} on-finished@2.4.1: dependencies: @@ -12133,7 +10918,7 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.5.0 + default-browser: 5.5.1 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 @@ -12149,11 +10934,9 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - outvariant@1.4.3: - optional: true - - own-keys@1.0.1: + own-keys@1.0.2: dependencies: + call-bound: 1.0.4 get-intrinsic: 1.3.0 object-keys: 1.1.1 safe-push-apply: 1.0.0 @@ -12224,8 +11007,6 @@ snapshots: path-is-inside@1.0.2: {} - path-key@2.0.1: {} - path-key@3.1.1: {} path-key@4.0.0: {} @@ -12239,23 +11020,17 @@ snapshots: path-to-regexp@0.1.13: {} - path-to-regexp@6.3.0: - optional: true - path-type@3.0.0: dependencies: pify: 3.0.0 path-type@4.0.0: {} - pathe@2.0.3: - optional: true - picocolors@1.1.1: {} picomatch@2.3.2: {} - picomatch@4.0.4: {} + picomatch@4.0.5: {} pidtree@0.3.1: {} @@ -12285,7 +11060,7 @@ snapshots: asn1js: 3.0.10 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 - pvutils: 1.1.5 + pvutils: 1.2.0 tslib: 2.8.1 possible-typed-array-names@1.1.0: {} @@ -12298,7 +11073,7 @@ snapshots: postcss-calc@10.1.1(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 postcss-clamp@4.1.0(postcss@8.5.26): @@ -12323,15 +11098,15 @@ snapshots: postcss-colormin@7.0.10(postcss@8.5.26): dependencies: - '@colordx/core': 5.5.0 - browserslist: 4.28.4 + '@colordx/core': 5.6.0 + browserslist: 4.28.8 caniuse-api: 3.0.0 postcss: 8.5.26 postcss-value-parser: 4.2.0 postcss-convert-values@7.0.12(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 postcss: 8.5.26 postcss-value-parser: 4.2.0 @@ -12358,7 +11133,7 @@ snapshots: postcss-discard-comments@7.0.8(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-discard-duplicates@7.0.4(postcss@8.5.26): dependencies: @@ -12430,7 +11205,7 @@ snapshots: postcss: 8.5.26 semver: 7.8.5 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) transitivePeerDependencies: - typescript @@ -12450,11 +11225,11 @@ snapshots: postcss-merge-rules@7.0.11(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 caniuse-api: 3.0.0 cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-minify-font-values@7.0.3(postcss@8.5.26): dependencies: @@ -12463,25 +11238,25 @@ snapshots: postcss-minify-gradients@7.0.5(postcss@8.5.26): dependencies: - '@colordx/core': 5.5.0 + '@colordx/core': 5.6.0 cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 postcss-value-parser: 4.2.0 postcss-minify-params@7.0.9(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 postcss-value-parser: 4.2.0 postcss-minify-selectors@7.1.2(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 caniuse-api: 3.0.0 cssesc: 3.0.0 postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-modules-extract-imports@3.1.0(postcss@8.5.26): dependencies: @@ -12491,13 +11266,13 @@ snapshots: dependencies: icss-utils: 5.1.0(postcss@8.5.26) postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 postcss-modules-scope@3.2.1(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-modules-values@4.0.0(postcss@8.5.26): dependencies: @@ -12541,7 +11316,7 @@ snapshots: postcss-normalize-unicode@7.0.9(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 postcss: 8.5.26 postcss-value-parser: 4.2.0 @@ -12595,8 +11370,8 @@ snapshots: '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.26) '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.26) '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.26) - autoprefixer: 10.5.2(postcss@8.5.26) - browserslist: 4.28.4 + autoprefixer: 10.5.4(postcss@8.5.26) + browserslist: 4.28.8 css-blank-pseudo: 3.0.3(postcss@8.5.26) css-has-pseudo: 3.0.4(postcss@8.5.26) css-prefers-color-scheme: 6.0.3(postcss@8.5.26) @@ -12639,7 +11414,7 @@ snapshots: postcss-reduce-initial@7.0.9(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 caniuse-api: 3.0.0 postcss: 8.5.26 @@ -12670,7 +11445,7 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.4: + postcss-selector-parser@7.1.5: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -12684,7 +11459,7 @@ snapshots: postcss-unique-selectors@7.0.7(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser@4.2.0: {} @@ -12743,7 +11518,7 @@ snapshots: dependencies: tslib: 2.8.1 - pvutils@1.1.5: {} + pvutils@1.2.0: {} qified@0.10.1: dependencies: @@ -12915,9 +11690,6 @@ snapshots: retry@0.13.1: {} - rettime@0.11.11: - optional: true - reusify@1.1.0: {} rfdc@1.4.1: {} @@ -12926,28 +11698,6 @@ snapshots: dependencies: glob: 7.2.3 - rolldown@1.1.3: - dependencies: - '@oxc-project/types': 0.137.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.3 - '@rolldown/binding-darwin-arm64': 1.1.3 - '@rolldown/binding-darwin-x64': 1.1.3 - '@rolldown/binding-freebsd-x64': 1.1.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.3 - '@rolldown/binding-linux-arm64-gnu': 1.1.3 - '@rolldown/binding-linux-arm64-musl': 1.1.3 - '@rolldown/binding-linux-ppc64-gnu': 1.1.3 - '@rolldown/binding-linux-s390x-gnu': 1.1.3 - '@rolldown/binding-linux-x64-gnu': 1.1.3 - '@rolldown/binding-linux-x64-musl': 1.1.3 - '@rolldown/binding-openharmony-arm64': 1.1.3 - '@rolldown/binding-wasm32-wasi': 1.1.3 - '@rolldown/binding-win32-arm64-msvc': 1.1.3 - '@rolldown/binding-win32-x64-msvc': 1.1.3 - optional: true - rrweb-cssom@0.8.0: {} run-applescript@7.1.0: {} @@ -12981,7 +11731,7 @@ snapshots: safer-buffer@2.1.2: {} - sax@1.6.0: {} + sax@1.6.1: {} saxes@6.0.0: dependencies: @@ -13007,8 +11757,6 @@ snapshots: '@peculiar/x509': 1.14.3 pkijs: 3.4.0 - semver@5.7.2: {} - semver@6.3.1: {} semver@7.8.5: {} @@ -13054,9 +11802,6 @@ snapshots: transitivePeerDependencies: - supports-color - set-cookie-parser@3.1.1: - optional: true - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -13085,19 +11830,13 @@ snapshots: dependencies: kind-of: 6.0.3 - shebang-command@1.2.0: - dependencies: - shebang-regex: 1.0.0 - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - shebang-regex@1.0.0: {} - shebang-regex@3.0.0: {} - shell-quote@1.9.0: {} + shell-quote@1.10.0: {} side-channel-list@1.0.1: dependencies: @@ -13127,9 +11866,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - siginfo@2.0.0: - optional: true - signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -13222,24 +11958,15 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - stackback@0.0.2: - optional: true - statuses@1.5.0: {} statuses@2.0.2: {} - std-env@4.1.0: - optional: true - stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 internal-slot: 1.1.0 - strict-event-emitter@0.5.1: - optional: true - string-argv@0.3.2: {} string-length@4.0.2: @@ -13336,7 +12063,7 @@ snapshots: strip-ansi@7.2.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.3.0 strip-bom@3.0.0: {} @@ -13354,13 +12081,13 @@ snapshots: style-loader@4.0.0(webpack@5.109.2): dependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) stylehacks@7.0.11(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 stylelint-config-recommended@18.0.0(stylelint@17.14.1(typescript@5.9.3)): dependencies: @@ -13383,14 +12110,14 @@ snapshots: stylelint@17.14.1(typescript@5.9.3): dependencies: - '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.1.6(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.8(css-tree@3.2.1) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/selector-resolve-nested': 4.0.1(postcss-selector-parser@7.1.4) - '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.4) - colord: 2.9.3 + '@csstools/selector-resolve-nested': 4.0.1(postcss-selector-parser@7.1.5) + '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.5) + colord: 2.10.0 cosmiconfig: 9.0.2(typescript@5.9.3) css-functions-list: 3.3.3 css-tree: 3.2.1 @@ -13402,7 +12129,7 @@ snapshots: globby: 16.2.4 globjoin: 0.1.4 html-tags: 5.1.0 - ignore: 7.0.5 + ignore: 7.0.6 import-meta-resolve: 4.2.0 mathml-tag-names: 4.0.0 meow: 14.1.0 @@ -13411,7 +12138,7 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.26 postcss-safe-parser: 7.0.1(postcss@8.5.26) - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 string-width: 8.2.2 supports-hyperlinks: 4.5.0 @@ -13453,7 +12180,7 @@ snapshots: css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 - sax: 1.6.0 + sax: 1.6.1 symbol-tree@3.2.4: {} @@ -13469,15 +12196,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tagged-tag@1.0.0: - optional: true - tapable@2.3.3: {} - terser@5.48.0: + terser@5.50.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.17.0 + acorn: 8.18.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -13487,40 +12211,23 @@ snapshots: glob: 7.2.3 minimatch: 3.1.5 - thingies@2.6.0(tslib@2.8.1): + thingies@2.6.1(tslib@2.8.1): dependencies: tslib: 2.8.1 thunky@1.1.0: {} - tinybench@2.9.0: - optional: true - - tinyexec@1.2.4: - optional: true - tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - - tinyrainbow@3.1.0: - optional: true + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tldts-core@6.1.86: {} - tldts-core@7.4.5: - optional: true - tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.5: - dependencies: - tldts-core: 7.4.5 - optional: true - tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -13535,11 +12242,6 @@ snapshots: dependencies: tldts: 6.1.86 - tough-cookie@6.0.1: - dependencies: - tldts: 7.4.5 - optional: true - tr46@0.0.3: {} tr46@5.1.1: @@ -13554,31 +12256,10 @@ snapshots: dependencies: typescript: 5.9.3 - ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 26.2.0 - acorn: 8.17.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.4 - make-error: 1.3.6 - typescript: 5.9.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.16.1 - optional: true - tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.24.1 + enhanced-resolve: 5.24.5 tapable: 2.3.3 tsconfig-paths: 4.2.0 @@ -13613,11 +12294,6 @@ snapshots: type-fest@1.4.0: {} - type-fest@5.7.0: - dependencies: - tagged-tag: 1.0.0 - optional: true - type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -13711,12 +12387,9 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 - until-async@3.0.2: - optional: true - - update-browserslist-db@1.2.3(browserslist@4.28.4): + update-browserslist-db@1.3.1(browserslist@4.28.8): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 escalade: 3.2.0 picocolors: 1.1.1 @@ -13732,9 +12405,6 @@ snapshots: uuid@14.0.2: {} - v8-compile-cache-lib@3.0.1: - optional: true - v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -13748,51 +12418,6 @@ snapshots: vary@1.1.2: {} - vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.26 - rolldown: 1.1.3 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 26.2.0 - fsevents: 2.3.3 - jiti: 2.7.0 - terser: 5.48.0 - yaml: 2.9.0 - optional: true - - vitest@4.1.9(@types/node@26.2.0)(@vitest/coverage-v8@4.1.9)(jsdom@26.1.0)(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)): - dependencies: - '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.9 - '@vitest/runner': 4.1.9 - '@vitest/snapshot': 4.1.9 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - es-module-lexer: 2.2.0 - expect-type: 1.4.0 - magic-string: 0.30.21 - obug: 2.1.3 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 26.2.0 - '@vitest/coverage-v8': 4.1.9(vitest@4.1.9) - jsdom: 26.1.0 - transitivePeerDependencies: - - msw - optional: true - w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 @@ -13816,7 +12441,7 @@ snapshots: webpack-bundle-analyzer@5.3.1: dependencies: '@discoveryjs/json-ext': 0.6.3 - acorn: 8.17.0 + acorn: 8.18.0 acorn-walk: 8.3.5 commander: 14.0.3 escape-string-regexp: 5.0.0 @@ -13824,7 +12449,7 @@ snapshots: opener: 1.5.2 picocolors: 1.1.1 sirv: 3.0.2 - ws: 8.21.0 + ws: 8.21.3 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -13838,28 +12463,26 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) webpack-merge: 6.0.1 optionalDependencies: js-yaml: 5.3.0 json5: 2.2.3 webpack-bundle-analyzer: 5.3.1 - webpack-dev-server: 5.2.6(tslib@2.8.1)(webpack-cli@7.2.2)(webpack@5.109.2) + webpack-dev-server: 5.2.6(webpack-cli@7.2.2)(webpack@5.109.2) - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.109.2): + webpack-dev-middleware@7.4.5(webpack@5.109.2): dependencies: colorette: 2.0.20 - memfs: 4.57.8(tslib@2.8.1) + memfs: 4.68.1 mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.3.0 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) - transitivePeerDependencies: - - tslib + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) - webpack-dev-server@5.2.6(tslib@2.8.1)(webpack-cli@7.2.2)(webpack@5.109.2): + webpack-dev-server@5.2.6(webpack-cli@7.2.2)(webpack@5.109.2): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -13870,7 +12493,7 @@ snapshots: '@types/sockjs': 0.3.36 '@types/ws': 8.18.1 ansi-html-community: 0.0.8 - bonjour-service: 1.4.2 + bonjour-service: 1.4.4 chokidar: 3.6.0 colorette: 2.0.20 compression: 1.8.1 @@ -13878,7 +12501,7 @@ snapshots: express: 4.22.2 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.10(@types/express@4.17.25) - ipaddr.js: 2.4.0 + ipaddr.js: 2.5.0 launch-editor: 2.14.1 open: 10.2.0 p-retry: 6.2.1 @@ -13887,16 +12510,15 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.109.2) - ws: 8.21.0 + webpack-dev-middleware: 7.4.5(webpack@5.109.2) + ws: 8.21.3 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) webpack-cli: 7.2.2(js-yaml@5.3.0)(json5@2.2.3)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.2) transitivePeerDependencies: - bufferutil - debug - supports-color - - tslib - utf-8-validate webpack-merge@6.0.1: @@ -13907,23 +12529,23 @@ snapshots: webpack-sources@3.5.1: {} - webpack@5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2): + webpack@5.109.2(postcss@8.5.26)(webpack-cli@7.2.2): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.17.0 - browserslist: 4.28.4 + acorn: 8.18.0 + browserslist: 4.28.8 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.5 - es-module-lexer: 2.2.0 + es-module-lexer: 2.3.2 eslint-scope: 5.1.1 events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(@swc/core@1.16.1)(postcss@8.5.26)(webpack@5.109.2) + minimizer-webpack-plugin: 5.6.1(postcss@8.5.26)(webpack@5.109.2) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 @@ -14018,12 +12640,6 @@ snapshots: dependencies: isexe: 2.0.0 - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - optional: true - wildcard@2.0.1: {} word-wrap@1.2.5: {} @@ -14051,7 +12667,7 @@ snapshots: dependencies: signal-exit: 4.1.0 - ws@8.21.0: {} + ws@8.21.3: {} wsl-utils@0.1.0: dependencies: @@ -14079,7 +12695,4 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yn@3.1.1: - optional: true - yocto-queue@0.1.0: {} diff --git a/frontend/apps/remark42/templates/comments.ejs b/frontend/apps/remark42/templates/comments.ejs index 2de9a26f..1efcdc6a 100644 --- a/frontend/apps/remark42/templates/comments.ejs +++ b/frontend/apps/remark42/templates/comments.ejs @@ -63,7 +63,17 @@ })(); if (query.site_id && query.url) { var titleElement = document.getElementById('title'); - titleElement.innerHTML = 'Comments for ' + query.url + ''; + // built through the DOM rather than innerHTML: query.url is attacker-controlled and this + // page is a top-level document on the instance origin, so an injected script would run + // there rather than inside the sandboxed widget frame + var link = document.createElement('a'); + link.textContent = query.url; + // and only http(s) reaches href, or a javascript: url survives the escaping + if (/^https?:\/\//i.test(query.url)) { + link.href = query.url; + } + titleElement.textContent = 'Comments for '; + titleElement.appendChild(link); var remark_config = { site_id: query.site_id, host: '<%= htmlWebpackPlugin.options.REMARK_URL %>', diff --git a/frontend/apps/remark42/templates/iframe.ejs b/frontend/apps/remark42/templates/iframe.ejs index 17c3e159..abf61bad 100644 --- a/frontend/apps/remark42/templates/iframe.ejs +++ b/frontend/apps/remark42/templates/iframe.ejs @@ -75,6 +75,10 @@