diff --git a/.changeset/auto-transform-bible-html.md b/.changeset/auto-transform-bible-html.md new file mode 100644 index 00000000..49ba44e9 --- /dev/null +++ b/.changeset/auto-transform-bible-html.md @@ -0,0 +1,7 @@ +--- +"@youversion/platform-core": minor +"@youversion/platform-react-hooks": minor +"@youversion/platform-react-ui": minor +--- + +Auto-transform Bible HTML in `getPassage` — verse wrapping, footnote extraction, sanitization, and table fixes now happen automatically. Consumers no longer need to call `transformBibleHtml` manually. Uses native DOMParser in browser, dynamic `import('jsdom')` on server. `jsdom` is now declared as an optional peer dependency so install logs surface it for server consumers. Added `data-yv-transformed` idempotency marker so double-transforms are a no-op. Pass `transform: false` to receive raw, untransformed HTML (useful for simple display or when `jsdom` is unavailable); `usePassage` accepts the same `transform` option and forwards it. Bible reader CSS now handles verse label spacing for untransformed HTML automatically. diff --git a/packages/core/AGENTS.md b/packages/core/AGENTS.md index 3772860d..e2cb043b 100644 --- a/packages/core/AGENTS.md +++ b/packages/core/AGENTS.md @@ -7,9 +7,45 @@ Foundation package providing pure TypeScript API clients for YouVersion services - For React hooks wrapping these clients → see `packages/hooks/AGENTS.md` - For pre-built UI components → see `packages/ui/AGENTS.md` -The public API is whatever `src/index.ts`, `src/browser.ts`, and `src/server.ts` -export. Read those rather than a list here. Browser CSS ships from `src/styles/` -and is exported via `./browser/styles/*`. +## STRUCTURE +``` +schemas/ # Zod schemas for all data types (schema-first design) +styles/ # Browser CSS (exported via ./browser/styles/*) + fonts.css # Google Fonts import (Inter, Source Serif 4) + theme.css # --yv-* design tokens on :root, dark mode, scoped preflight + bible-reader.css # USFM/Bible typography for [data-slot='yv-bible-renderer'] + index.css # Barrel: imports fonts + theme + bible-reader +client.ts # ApiClient - main HTTP client +bible.ts # BibleClient - Bible data operations +languages.ts # LanguagesClient - language data +highlights.ts # HighlightsClient - user highlights +YouVersionAPI.ts # Base YouVersion API client +SignInWithYouVersionPKCE.ts # PKCE auth implementation +StorageStrategy.ts # Storage interface (SessionStorage, MemoryStorage) +bible-html-transformer.ts # Runtime-agnostic transformer (also contains browser convenience fn) +bible-html-transformer-server.ts # Server convenience wrapper (uses jsdom) +browser.ts # Browser entry point +server.ts # Server entry point +index.ts # Main entry point (runtime-agnostic) +``` + +## PUBLIC API + +### TypeScript (`@youversion/platform-core`) +- `ApiClient`: Main HTTP client with auth handling +- `BibleClient`: Fetch Bibles, chapters, verses, versions +- `LanguagesClient`: Get available languages +- `HighlightsClient`: Manage user highlights +- `SignInWithYouVersionPKCE()`: PKCE auth flow function +- `SessionStorage`, `MemoryStorage`: Storage strategies +- `transformBibleHtml`: Runtime-agnostic Bible HTML transformer (requires DOM adapters) +- `TransformBibleHtmlOptions`: Options for DOM parsing and serialization + +### Browser CSS (`@youversion/platform-core/browser/styles/*`) +- `index.css`: All-in-one import (fonts + theme + bible-reader) +- `theme.css`: `--yv-*` design tokens on `:root` + dark mode (`[data-yv-theme='dark']`) + scoped preflight +- `bible-reader.css`: USFM typography for `[data-slot='yv-bible-renderer']` or `[data-yv-sdk-bible-reader]` +- `fonts.css`: Google Fonts import (Inter, Source Serif 4) ## DOs / DON'Ts @@ -26,12 +62,35 @@ and is exported via `./browser/styles/*`. Three entry points, deliberately separate: -- `@youversion/platform-core` → runtime-agnostic `transformBibleHtml`, requires DOM adapters -- `@youversion/platform-core/browser` → convenience wrapper using native `DOMParser` -- `@youversion/platform-core/server` → convenience wrapper using `linkedom` +- `@youversion/platform-core` → Runtime-agnostic `transformBibleHtml` (requires DOM adapters) +- `@youversion/platform-core/browser` → Browser convenience wrapper (uses native DOMParser) +- `@youversion/platform-core/server` → Server convenience wrapper (uses jsdom) -The split keeps the main export runtime-agnostic and keeps `linkedom` out of -browser bundles. New DOM-touching code follows the same pattern. +**Examples:** + +```ts +// Runtime-agnostic (works anywhere with custom adapters) +import { transformBibleHtml } from '@youversion/platform-core'; + +const result = transformBibleHtml(html, { + parseHtml: (h) => new DOMParser().parseFromString(h, 'text/html'), + serializeHtml: (doc) => doc.body.innerHTML, +}); + +// Browser convenience (uses native DOMParser) +import { transformBibleHtml } from '@youversion/platform-core/browser'; + +const result = transformBibleHtml(html); + +// Server convenience (uses jsdom, requires: npm install jsdom) +import { transformBibleHtml } from '@youversion/platform-core/server'; + +const result = transformBibleHtml(html); +``` + +**Why separate entry points?** + +This architecture keeps the main export truly runtime-agnostic while providing ergonomic convenience wrappers for common environments. The separate `/browser` and `/server` entry points ensure optimal bundle sizes. `package.json` also maps `"browser": { "jsdom": false }` so Vite/Rollup client builds stub jsdom even when the main entry's dynamic `import('jsdom')` is present (Node-only path; browsers use native `DOMParser`). ## ADDING A NEW ENDPOINT OR CLIENT diff --git a/packages/core/package.json b/packages/core/package.json index e22a6cf2..4051b17d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -16,6 +16,9 @@ "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", + "browser": { + "jsdom": false + }, "exports": { ".": { "types": "./dist/index.d.ts", @@ -48,20 +51,21 @@ "devDependencies": { "@internal/eslint-config": "workspace:*", "@internal/tsconfig": "workspace:*", + "@types/jsdom": "^28.0.1", "@vitest/coverage-v8": "4.0.4", "dotenv-cli": "7.4.2", "eslint": "9.38.0", - "jsdom": "24.0.0", + "jsdom": "28.1.0", "msw": "2.11.6", "tsup": "8.5.0", "typescript": "5.9.3", "vitest": "4.0.4" }, "peerDependencies": { - "linkedom": "^0.18.12" + "jsdom": "^24.0.0 || ^28.0.0" }, "peerDependenciesMeta": { - "linkedom": { + "jsdom": { "optional": true } }, diff --git a/packages/core/src/__tests__/bible.test.ts b/packages/core/src/__tests__/bible.test.ts index 7f3b961f..38834f0f 100644 --- a/packages/core/src/__tests__/bible.test.ts +++ b/packages/core/src/__tests__/bible.test.ts @@ -507,18 +507,16 @@ describe('BibleClient', () => { }); describe('getPassage', () => { - it('should fetch a passage for a verse', async () => { + it('should fetch a passage for a verse and auto-transform HTML', async () => { const passage = await bibleClient.getPassage(111, 'GEN.1.1'); const { success } = BiblePassageSchema.safeParse(passage); expect(success).toBe(true); - expect(passage).toEqual({ - id: 'GEN.1.1', - content: - '
'); - expect(result.html).toContain('Click me'); + // Tag-boundary match so we don't accept a false positive like `
]*)?>Click me<\/p>/);
});
it('should unwrap anchor tags (not in allowlist) preserving text', () => {
@@ -336,7 +336,7 @@ describe('transformBibleHtml - sanitization', () => {
const result = transformBibleHtml(html, createAdapters());
expect(result.html).not.toContain('style');
- expect(result.html).toContain('');
+ expect(result.html).toContain(' {
expect(result.html).toContain('class="p"');
expect(result.html).toContain('class="wj"');
expect(result.html).toContain('colspan="2"');
- expect(result.html).toContain('');
+ expect(result.html).toMatch(/]*)?>/);
});
it('should unwrap unknown custom elements preserving text', () => {
@@ -387,6 +387,68 @@ describe('transformBibleHtml - sanitization', () => {
});
});
+describe('transformBibleHtml - idempotency', () => {
+ it('should add data-yv-transformed marker after transforming', () => {
+ const html =
+ '1Text.';
+ const result = transformBibleHtml(html, createAdapters());
+
+ expect(result.html).toContain('data-yv-transformed');
+ });
+
+ it('should short-circuit when HTML is already transformed', () => {
+ const html =
+ '1Text.';
+ const first = transformBibleHtml(html, createAdapters());
+ const second = transformBibleHtml(first.html, createAdapters());
+
+ expect(second.html).toBe(first.html);
+ });
+
+ it('should produce identical output when transformed twice (idempotent)', () => {
+ const html =
+ '1Verse textA note.';
+ const first = transformBibleHtml(html, createAdapters());
+ const second = transformBibleHtml(first.html, createAdapters());
+
+ expect(second.html).toBe(first.html);
+ });
+
+ it('should not short-circuit on untrusted nested data-yv-transformed', () => {
+ const html =
+ '1TextA note.';
+ const result = transformBibleHtml(html, createAdapters());
+
+ expect(result.html).toContain('data-verse-footnote');
+ expect(result.html).toMatch(/^]*\bdata-yv-transformed\b/);
+ });
+
+ it('should transform raw siblings when only the first top-level element is marked', () => {
+ const raw =
+ '2SecondSibling note.';
+ const transformed = transformBibleHtml(
+ '1First.',
+ createAdapters(),
+ );
+
+ const result = transformBibleHtml(transformed.html + raw, createAdapters());
+
+ expect(result.html).toContain('data-verse-footnote');
+ expect(result.html).toContain('Sibling note');
+ });
+
+ it('should mark every top-level element so a multi-root fragment stays idempotent', () => {
+ const html =
+ '1One.' +
+ '2Two.';
+ const first = transformBibleHtml(html, createAdapters());
+ const second = transformBibleHtml(first.html, createAdapters());
+
+ expect(first.html.match(/data-yv-transformed/g)).toHaveLength(2);
+ expect(second.html).toBe(first.html);
+ });
+});
+
describe('transformBibleHtmlForBrowser - DOMParser fallback', () => {
it('should throw when DOMParser is unavailable', () => {
const original = globalThis.DOMParser;
diff --git a/packages/core/src/bible-html-transformer.ts b/packages/core/src/bible-html-transformer.ts
index 448a26cc..826ee3b9 100644
--- a/packages/core/src/bible-html-transformer.ts
+++ b/packages/core/src/bible-html-transformer.ts
@@ -2,6 +2,8 @@ const NON_BREAKING_SPACE = '\u00A0';
const FOOTNOTE_KEY_ATTR = 'data-footnote-key';
+const TRANSFORMED_ATTR = 'data-yv-transformed';
+
const NEEDS_SPACE_BEFORE = /^[^\s.,;:!?)}\]'"'»›]/;
const ALLOWED_TAGS = new Set([
@@ -47,6 +49,10 @@ const DROP_ENTIRELY_TAGS = new Set([
const ALLOWED_ATTRS = new Set(['class', 'v', 'colspan', 'rowspan', 'dir', 'usfm']);
+function topLevelElements(doc: Document): Element[] {
+ return doc.body ? Array.from(doc.body.children) : [];
+}
+
function sanitizeBibleHtmlDocument(doc: Document): void {
const root = doc.body ?? doc.documentElement;
for (const el of Array.from(root.querySelectorAll('*'))) {
@@ -339,6 +345,16 @@ export function transformBibleHtml(
const doc = options.parseHtml(html);
sanitizeBibleHtmlDocument(doc);
+
+ // Only trust the marker when every top-level element carries it. A nested or
+ // partially-marked fragment (transformed HTML concatenated with raw HTML, or
+ // an untrusted data-yv-transformed preserved by the data-* allowlist) must
+ // still run verse wrapping and footnote extraction.
+ const roots = topLevelElements(doc);
+ if (roots.length > 0 && roots.every((el) => el.hasAttribute(TRANSFORMED_ATTR))) {
+ return { html: options.serializeHtml(doc) };
+ }
+
wrapVerseContent(doc);
assignFootnoteKeys(doc);
@@ -348,6 +364,12 @@ export function transformBibleHtml(
addNbspToVerseLabels(doc);
fixIrregularTables(doc);
+ // Mark every top-level element so a later re-transform can tell the whole
+ // fragment came from here, not just its first sibling.
+ for (const el of topLevelElements(doc)) {
+ el.setAttribute(TRANSFORMED_ATTR, '');
+ }
+
const transformedHtml = options.serializeHtml(doc);
return { html: transformedHtml };
}
diff --git a/packages/core/src/bible.ts b/packages/core/src/bible.ts
index 918fdf3a..6cf1fa16 100644
--- a/packages/core/src/bible.ts
+++ b/packages/core/src/bible.ts
@@ -1,5 +1,6 @@
import { z } from 'zod';
import type { ApiClient } from './client';
+import { transformBibleHtml, type TransformBibleHtmlOptions } from './bible-html-transformer';
import { BibleVersionSchema } from './schemas';
import type {
BibleBook,
@@ -13,6 +14,36 @@ import type {
VOTD,
} from './types';
+async function getHtmlAdapters(): Promise {
+ if (typeof globalThis.DOMParser !== 'undefined') {
+ return {
+ parseHtml: (h) =>
+ new globalThis.DOMParser().parseFromString(h, 'text/html') as unknown as Document,
+ serializeHtml: (doc) => doc.body.innerHTML,
+ };
+ }
+ let jsdom;
+ try {
+ // Literal dynamic import is fine in Node. Client bundlers must not pull
+ // jsdom into browser graphs — see package.json "browser": { "jsdom": false }.
+ jsdom = await import('jsdom');
+ } catch (err) {
+ const detail = err instanceof Error ? err.message : String(err);
+ throw new Error(
+ 'Server-side HTML transformation requires "jsdom". ' +
+ 'Install it as a dependency or pass transform: false to skip transformation. ' +
+ `Original error: ${detail}`,
+ { cause: err },
+ );
+ }
+ return {
+ parseHtml: (h) =>
+ new jsdom.JSDOM(`${h}`).window
+ .document as unknown as Document,
+ serializeHtml: (doc) => doc.body.innerHTML,
+ };
+}
+
/**
* Client for interacting with Bible API endpoints.
*/
@@ -234,18 +265,23 @@ export class BibleClient {
/**
* Fetches a passage (range of verses) from the Bible using the passages endpoint.
- * This is the new API format that returns HTML-formatted content.
*
- * Note: The HTML returned from the API contains inline footnote content that should
- * be transformed before rendering. Use `transformBibleHtml()` or
- * `transformBibleHtmlForBrowser()` to clean up the HTML and extract footnotes.
+ * When format is "html" (the default), the returned content is automatically
+ * sanitized and transformed — verse content is wrapped for CSS targeting,
+ * footnotes are extracted into data attributes, and verse labels get
+ * non-breaking spaces. No manual call to `transformBibleHtml` is needed.
*
* @param versionId The version ID.
* @param usfm The USFM reference (e.g., "JHN.3.1-2", "GEN.1", "JHN.3.16").
* @param format The format to return ("html" or "text", default: "html").
* @param include_headings Whether to include headings in the content.
* @param include_notes Whether to include notes in the content.
- * @returns The requested BiblePassage object with HTML content.
+ * @param transform Whether to auto-transform HTML content (default: `true`).
+ * Set to `false` to receive the original, untransformed HTML from the API.
+ * Raw HTML is sufficient for simple display (e.g., verse-of-the-day) where
+ * verse-level interactivity like highlighting or footnote popovers isn't
+ * needed. Also avoids the `jsdom` dependency on the server.
+ * @returns The requested BiblePassage object.
*
* @example
* ```ts
@@ -258,9 +294,11 @@ export class BibleClient {
* // Get an entire chapter
* const chapter = await bibleClient.getPassage(3034, "GEN.1");
*
- * // Transform HTML before rendering
- * const passage = await bibleClient.getPassage(3034, "JHN.3.16", "html", true, true);
- * const transformed = transformBibleHtmlForBrowser(passage.content);
+ * // Get plain text (no transformation applied)
+ * const text = await bibleClient.getPassage(3034, "JHN.3.16", "text");
+ *
+ * // Get raw, untransformed HTML (no jsdom needed on server)
+ * const raw = await bibleClient.getPassage(3034, "JHN.3.16", "html", undefined, undefined, false);
* ```
*/
async getPassage(
@@ -269,6 +307,7 @@ export class BibleClient {
format: 'html' | 'text' = 'html',
include_headings?: boolean,
include_notes?: boolean,
+ transform?: boolean,
): Promise {
BibleClient.versionIdSchema.parse(versionId);
if (include_headings !== undefined) {
@@ -286,7 +325,18 @@ export class BibleClient {
if (include_notes !== undefined) {
params.include_notes = include_notes;
}
- return this.client.get(`/v1/bibles/${versionId}/passages/${usfm}`, params);
+ const passage = await this.client.get(
+ `/v1/bibles/${versionId}/passages/${usfm}`,
+ params,
+ );
+
+ if (format === 'html' && transform !== false) {
+ const adapters = await getHtmlAdapters();
+ const { html } = transformBibleHtml(passage.content, adapters);
+ return { ...passage, content: html };
+ }
+
+ return passage;
}
/**
diff --git a/packages/core/src/styles/bible-reader.css b/packages/core/src/styles/bible-reader.css
index abeb637d..27d90016 100644
--- a/packages/core/src/styles/bible-reader.css
+++ b/packages/core/src/styles/bible-reader.css
@@ -89,6 +89,12 @@
font-family: var(--yv-font-sans);
}
+ /* When content hasn't been JS-transformed, add spacing after verse labels via CSS.
+ Transformed HTML already has a \u00A0 inserted by addNbspToVerseLabels(). */
+ &:not(:has([data-yv-transformed])) .yv-vlbl::after {
+ content: "\00A0";
+ }
+
/* \f - Footnote container (YouVersion wrapper) */
& .yv-n {
display: none;
diff --git a/packages/core/tsup.config.ts b/packages/core/tsup.config.ts
index 617608e2..a2e8c7da 100644
--- a/packages/core/tsup.config.ts
+++ b/packages/core/tsup.config.ts
@@ -17,6 +17,8 @@ export default defineConfig({
entry: ['src/index.ts', 'src/browser.ts', 'src/server.ts'],
format: ['cjs', 'esm'],
dts: true,
+ // Keep Node-only peer out of published bundles; loaded at runtime on server.
+ external: ['jsdom'],
env: {
YVP_PUBLISH_BUILD: isPublishBuild ? 'true' : '',
},
diff --git a/packages/hooks/src/usePassage.test.tsx b/packages/hooks/src/usePassage.test.tsx
index 88e81290..11b0b074 100644
--- a/packages/hooks/src/usePassage.test.tsx
+++ b/packages/hooks/src/usePassage.test.tsx
@@ -46,7 +46,25 @@ describe('usePassage', () => {
expect(result.current.loading).toBe(false);
});
- expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', false, false);
+ expect
+ .soft(mockGetPassage)
+ .toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', false, false, true);
+ });
+
+ it('should forward transform: false so callers can opt out of HTML transformation', async () => {
+ const wrapper = createYVWrapper();
+ const { result } = renderHook(
+ () => usePassage({ versionId: 3034, usfm: 'JHN.3.16', transform: false }),
+ { wrapper },
+ );
+
+ await waitFor(() => {
+ expect(result.current.loading).toBe(false);
+ });
+
+ expect
+ .soft(mockGetPassage)
+ .toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', false, false, false);
});
});
@@ -76,7 +94,9 @@ describe('usePassage', () => {
expect(result.current.loading).toBe(false);
});
- expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3.16', 'text', false, false);
+ expect
+ .soft(mockGetPassage)
+ .toHaveBeenCalledWith(3034, 'JHN.3.16', 'text', false, false, true);
});
});
@@ -92,7 +112,7 @@ describe('usePassage', () => {
expect(result.current.loading).toBe(false);
});
- expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', true, false);
+ expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', true, false, true);
});
it('should pass include_notes=true', async () => {
@@ -106,7 +126,7 @@ describe('usePassage', () => {
expect(result.current.loading).toBe(false);
});
- expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', false, true);
+ expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3.16', 'html', false, true, true);
});
it('should pass all options combined', async () => {
@@ -127,7 +147,7 @@ describe('usePassage', () => {
expect(result.current.loading).toBe(false);
});
- expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3', 'text', true, true);
+ expect.soft(mockGetPassage).toHaveBeenCalledWith(3034, 'JHN.3', 'text', true, true, true);
});
});
@@ -139,8 +159,8 @@ describe('usePassage', () => {
usePassage({ versionId: val as number, usfm: 'JHN.3.16' }),
initial: { val: 1 },
updated: { val: 3034 },
- expectedInitial: [1, 'JHN.3.16', 'html', false, false],
- expectedUpdated: [3034, 'JHN.3.16', 'html', false, false],
+ expectedInitial: [1, 'JHN.3.16', 'html', false, false, true],
+ expectedUpdated: [3034, 'JHN.3.16', 'html', false, false, true],
},
{
param: 'usfm',
@@ -148,8 +168,8 @@ describe('usePassage', () => {
usePassage({ versionId: 3034, usfm: val as string }),
initial: { val: 'JHN.3.16' },
updated: { val: 'GEN.1.1' },
- expectedInitial: [3034, 'JHN.3.16', 'html', false, false],
- expectedUpdated: [3034, 'GEN.1.1', 'html', false, false],
+ expectedInitial: [3034, 'JHN.3.16', 'html', false, false, true],
+ expectedUpdated: [3034, 'GEN.1.1', 'html', false, false, true],
},
{
param: 'format',
@@ -157,8 +177,8 @@ describe('usePassage', () => {
usePassage({ versionId: 3034, usfm: 'JHN.3.16', format: val as 'html' | 'text' }),
initial: { val: 'html' },
updated: { val: 'text' },
- expectedInitial: [3034, 'JHN.3.16', 'html', false, false],
- expectedUpdated: [3034, 'JHN.3.16', 'text', false, false],
+ expectedInitial: [3034, 'JHN.3.16', 'html', false, false, true],
+ expectedUpdated: [3034, 'JHN.3.16', 'text', false, false, true],
},
])(
'should refetch when $param changes',
diff --git a/packages/hooks/src/usePassage.ts b/packages/hooks/src/usePassage.ts
index 1be29191..bbdaf6e4 100644
--- a/packages/hooks/src/usePassage.ts
+++ b/packages/hooks/src/usePassage.ts
@@ -10,6 +10,12 @@ type usePassageProps = {
format?: 'html' | 'text';
include_headings?: boolean;
include_notes?: boolean;
+ /**
+ * Whether to auto-transform HTML content (default: `true`). Set to `false`
+ * to receive the original, untransformed HTML from the API — useful when
+ * running outside a DOM environment without the optional `jsdom` peer.
+ */
+ transform?: boolean;
options?: UseApiDataOptions;
};
@@ -19,6 +25,7 @@ export function usePassage({
format = 'html',
include_headings = false,
include_notes = false,
+ transform = true,
options,
}: usePassageProps): {
passage: BiblePassage | null;
@@ -32,8 +39,9 @@ export function usePassage({
const isValidUsfm = Boolean(usfm) && usfm !== 'undefined' && usfm !== 'null';
const { data, loading, error, refetch } = useApiData(
- () => bibleClient.getPassage(versionId, usfm, format, include_headings, include_notes),
- [bibleClient, versionId, usfm, format, include_headings, include_notes],
+ () =>
+ bibleClient.getPassage(versionId, usfm, format, include_headings, include_notes, transform),
+ [bibleClient, versionId, usfm, format, include_headings, include_notes, transform],
{ enabled: options?.enabled !== false && isValidUsfm },
);
diff --git a/packages/ui/package.json b/packages/ui/package.json
index b9797d86..3ab2dd8e 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -18,6 +18,9 @@
"module": "./dist/index.js",
"style": "./dist/tailwind.css",
"types": "./dist/index.d.ts",
+ "browser": {
+ "jsdom": false
+ },
"files": [
"dist",
"README.md",
diff --git a/packages/ui/src/components/verse.tsx b/packages/ui/src/components/verse.tsx
index d0f36068..94471036 100644
--- a/packages/ui/src/components/verse.tsx
+++ b/packages/ui/src/components/verse.tsx
@@ -477,9 +477,8 @@ export const Verse = {
}: VerseHtmlProps,
ref,
): ReactNode => {
- // transformBibleHtml uses the browser's native DOMParser, which doesn't
- // exist during SSR. Return raw html on the server; the client-side
- // useLayoutEffect in BibleTextHtml will handle it after hydration.
+ // SSR safety: DOMParser doesn't exist during server render.
+ // Idempotent — already-transformed HTML from getPassage is a no-op.
const transformedHtml = useMemo(
() => (typeof window === 'undefined' ? html : transformBibleHtml(html).html),
[html],
diff --git a/packages/ui/src/i18n/index.ts b/packages/ui/src/i18n/index.ts
index 600470b9..24275595 100644
--- a/packages/ui/src/i18n/index.ts
+++ b/packages/ui/src/i18n/index.ts
@@ -5,7 +5,6 @@ import { resources, supportedLngs } from './resources.generated';
export { resources, supportedLngs };
-
const defaultNS = 'translation';
const BRAND_NAME = 'YouVersion';
/** Used when a key/locale is missing or browser language is unsupported — not the active UI language. */
diff --git a/packages/ui/tsup.config.ts b/packages/ui/tsup.config.ts
index 0880d7ec..21c59b5e 100644
--- a/packages/ui/tsup.config.ts
+++ b/packages/ui/tsup.config.ts
@@ -20,8 +20,9 @@ export default defineConfig({
// building here, and why the env var is scoped to that command alone. See
// packages/core/tsup.config.ts.
noExternal: ['@youversion/platform-core'],
- // Consumers provide these:
- external: ['react', 'react/jsx-runtime', 'react-dom'],
+ // Consumers provide these. jsdom is Node-only (optional peer of platform-core);
+ // never inline it into the UI browser bundle.
+ external: ['react', 'react/jsx-runtime', 'react-dom', 'jsdom'],
dts: false, // types come from `tsc` + API Extractor
// Embed built Tailwind CSS as a global constant for runtime injection
// Users don't need to manually import the CSS file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 52c43ee8..06c9e1bf 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -148,9 +148,6 @@ importers:
packages/core:
dependencies:
- linkedom:
- specifier: ^0.18.12
- version: 0.18.12
zod:
specifier: 4.1.12
version: 4.1.12
@@ -161,6 +158,9 @@ importers:
'@internal/tsconfig':
specifier: workspace:*
version: link:../../tools/tsconfig
+ '@types/jsdom':
+ specifier: ^28.0.1
+ version: 28.0.3
'@vitest/coverage-v8':
specifier: 4.0.4
version: 4.0.4(@vitest/browser@4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))(vitest@4.0.4))(vitest@4.0.4)
@@ -171,8 +171,8 @@ importers:
specifier: 9.38.0
version: 9.38.0(jiti@2.6.1)
jsdom:
- specifier: 24.0.0
- version: 24.0.0
+ specifier: 28.1.0
+ version: 28.1.0(@noble/hashes@1.8.0)
msw:
specifier: 2.11.6
version: 2.11.6(@types/node@24.11.0)(typescript@5.9.3)
@@ -184,7 +184,7 @@ importers:
version: 5.9.3
vitest:
specifier: 4.0.4
- version: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@24.0.0)(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
+ version: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
packages/hooks:
dependencies:
@@ -426,6 +426,9 @@ importers:
packages:
+ '@acemir/cssom@0.9.31':
+ resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==}
+
'@adobe/css-tools@4.4.4':
resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==}
@@ -433,15 +436,23 @@ packages:
resolution: {integrity: sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA==}
hasBin: true
- '@asamuzakjp/css-color@3.2.0':
- resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
-
'@asamuzakjp/css-color@4.0.5':
resolution: {integrity: sha512-lMrXidNhPGsDjytDy11Vwlb6OIGrT3CmLg3VWNFyWkLWtijKl7xjvForlh8vuj0SHGjgl4qZEQzUmYTeQA2JFQ==}
+ '@asamuzakjp/css-color@5.1.11':
+ resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
'@asamuzakjp/dom-selector@6.7.3':
resolution: {integrity: sha512-kiGFeY+Hxf5KbPpjRLf+ffWbkos1aGo8MBfd91oxS3O57RgU3XhZrt/6UzoVF9VMpWbC3v87SRc9jxGrc9qHtQ==}
+ '@asamuzakjp/dom-selector@6.8.1':
+ resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==}
+
+ '@asamuzakjp/generational-cache@1.0.1':
+ resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
'@asamuzakjp/nwsapi@2.3.9':
resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
@@ -678,6 +689,10 @@ packages:
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
+ '@bramus/specificity@2.4.2':
+ resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
+ hasBin: true
+
'@changesets/apply-release-plan@7.0.13':
resolution: {integrity: sha512-BIW7bofD2yAWoE8H4V40FikC+1nNFEKBisMECccS16W1rt6qqhNTBDmIw5HaqmMgtLNz9e7oiALiEUuKrQ4oHg==}
@@ -806,6 +821,10 @@ packages:
resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
engines: {node: '>=18'}
+ '@csstools/color-helpers@6.1.0':
+ resolution: {integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==}
+ engines: {node: '>=20.19.0'}
+
'@csstools/css-calc@2.1.4':
resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==}
engines: {node: '>=18'}
@@ -813,6 +832,13 @@ packages:
'@csstools/css-parser-algorithms': ^3.0.5
'@csstools/css-tokenizer': ^3.0.4
+ '@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
+ '@csstools/css-tokenizer': ^4.0.0
+
'@csstools/css-color-parser@3.1.0':
resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==}
engines: {node: '>=18'}
@@ -820,22 +846,47 @@ packages:
'@csstools/css-parser-algorithms': ^3.0.5
'@csstools/css-tokenizer': ^3.0.4
+ '@csstools/css-color-parser@4.1.10':
+ resolution: {integrity: sha512-UZhQLIUyJaaMepqehrCODwCg2KW25vFvLWBmqYFaPclYvvxzj/sG8LBOhBFCp11i9uE7t1EyS+RAoV9tztPFyw==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^4.0.0
+ '@csstools/css-tokenizer': ^4.0.0
+
'@csstools/css-parser-algorithms@3.0.5':
resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==}
engines: {node: '>=18'}
peerDependencies:
'@csstools/css-tokenizer': ^3.0.4
+ '@csstools/css-parser-algorithms@4.0.0':
+ resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-tokenizer': ^4.0.0
+
'@csstools/css-syntax-patches-for-csstree@1.0.14':
resolution: {integrity: sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==}
engines: {node: '>=18'}
peerDependencies:
postcss: ^8.4
+ '@csstools/css-syntax-patches-for-csstree@1.1.7':
+ resolution: {integrity: sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig==}
+ peerDependencies:
+ css-tree: ^3.2.1
+ peerDependenciesMeta:
+ css-tree:
+ optional: true
+
'@csstools/css-tokenizer@3.0.4':
resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
engines: {node: '>=18'}
+ '@csstools/css-tokenizer@4.0.0':
+ resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
+ engines: {node: '>=20.19.0'}
+
'@dotenvx/dotenvx@1.52.0':
resolution: {integrity: sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w==}
hasBin: true
@@ -1231,6 +1282,15 @@ packages:
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@exodus/bytes@1.15.1':
+ resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ peerDependencies:
+ '@noble/hashes': ^1.8.0 || ^2.0.0
+ peerDependenciesMeta:
+ '@noble/hashes':
+ optional: true
+
'@floating-ui/core@1.7.3':
resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
@@ -2993,6 +3053,9 @@ packages:
'@types/istanbul-lib-coverage@2.0.6':
resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
+ '@types/jsdom@28.0.3':
+ resolution: {integrity: sha512-/HQ2uFoetFTXuye8vzIcHw2z6Fwi7Hi/qcgC+RoS9NCyewiqxhVGqlG+ViGB6lkax481R6dmhf1I7lIGlzJStQ==}
+
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@@ -3025,6 +3088,9 @@ packages:
'@types/statuses@2.0.6':
resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==}
+ '@types/tough-cookie@4.0.5':
+ resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
+
'@types/validate-npm-package-name@4.0.2':
resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==}
@@ -3335,9 +3401,6 @@ packages:
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
engines: {node: '>= 0.4'}
- asynckit@0.4.0:
- resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
-
available-typed-arrays@1.0.7:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
@@ -3371,9 +3434,6 @@ packages:
resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==}
engines: {node: '>=18'}
- boolbase@1.0.0:
- resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
-
brace-expansion@1.1.12:
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
@@ -3516,10 +3576,6 @@ packages:
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
- combined-stream@1.0.8:
- resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
- engines: {node: '>= 0.8'}
-
commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
@@ -3621,17 +3677,10 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
- css-select@5.2.2:
- resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
-
css-tree@3.1.0:
resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
- css-what@6.2.2:
- resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
- engines: {node: '>= 6'}
-
css.escape@1.5.1:
resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
@@ -3640,17 +3689,14 @@ packages:
engines: {node: '>=4'}
hasBin: true
- cssom@0.5.0:
- resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==}
-
- cssstyle@4.6.0:
- resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==}
- engines: {node: '>=18'}
-
cssstyle@5.3.1:
resolution: {integrity: sha512-g5PC9Aiph9eiczFpcgUhd9S4UUO3F+LHGRIi5NUMZ+4xtoIYbHNZwZnWA2JsFGe8OU8nl4WyaEFiZuGuxlutJQ==}
engines: {node: '>=20'}
+ cssstyle@6.2.0:
+ resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==}
+ engines: {node: '>=20'}
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -3662,14 +3708,14 @@ packages:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
- data-urls@5.0.0:
- resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
- engines: {node: '>=18'}
-
data-urls@6.0.0:
resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==}
engines: {node: '>=20'}
+ data-urls@7.0.0:
+ resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
data-view-buffer@1.0.2:
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
engines: {node: '>= 0.4'}
@@ -3742,10 +3788,6 @@ packages:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
- delayed-stream@1.0.0:
- resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
- engines: {node: '>=0.4.0'}
-
depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
@@ -3792,19 +3834,6 @@ packages:
dom-accessibility-api@0.6.3:
resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
- dom-serializer@2.0.0:
- resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
-
- domelementtype@2.3.0:
- resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
-
- domhandler@5.0.3:
- resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
- engines: {node: '>= 4'}
-
- domutils@3.2.2:
- resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
-
dot-prop@5.3.0:
resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
engines: {node: '>=8'}
@@ -3878,18 +3907,10 @@ packages:
resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
engines: {node: '>=8.6'}
- entities@4.5.0:
- resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
- engines: {node: '>=0.12'}
-
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
- entities@7.0.1:
- resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
- engines: {node: '>=0.12'}
-
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
@@ -4191,10 +4212,6 @@ packages:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
- form-data@4.0.4:
- resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
- engines: {node: '>= 6'}
-
formatly@0.3.0:
resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==}
engines: {node: '>=18.3.0'}
@@ -4412,18 +4429,16 @@ packages:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'}
+ html-encoding-sniffer@6.0.0:
+ resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
- html-escaper@3.0.3:
- resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
-
html-parse-stringify@3.0.1:
resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
- htmlparser2@10.1.0:
- resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==}
-
http-errors@2.0.1:
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
engines: {node: '>= 0.8'}
@@ -4778,18 +4793,18 @@ packages:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
- jsdom@24.0.0:
- resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==}
- engines: {node: '>=18'}
+ jsdom@27.0.1:
+ resolution: {integrity: sha512-SNSQteBL1IlV2zqhwwolaG9CwhIhTvVHWg3kTss/cLE7H/X4644mtPQqYvCfsSrGQWt9hSZcgOXX8bOZaMN+kA==}
+ engines: {node: '>=20'}
peerDependencies:
- canvas: ^2.11.2
+ canvas: ^3.0.0
peerDependenciesMeta:
canvas:
optional: true
- jsdom@27.0.1:
- resolution: {integrity: sha512-SNSQteBL1IlV2zqhwwolaG9CwhIhTvVHWg3kTss/cLE7H/X4644mtPQqYvCfsSrGQWt9hSZcgOXX8bOZaMN+kA==}
- engines: {node: '>=20'}
+ jsdom@28.1.0:
+ resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
peerDependencies:
canvas: ^3.0.0
peerDependenciesMeta:
@@ -5016,15 +5031,6 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
- linkedom@0.18.12:
- resolution: {integrity: sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==}
- engines: {node: '>=16'}
- peerDependencies:
- canvas: '>= 2'
- peerDependenciesMeta:
- canvas:
- optional: true
-
lint-staged@16.2.5:
resolution: {integrity: sha512-o36wH3OX0jRWqDw5dOa8a8x6GXTKaLM+LvhRaucZxez0IxA+KNDUCiyjBfNgsMNmchwSX6urLSL7wShcUqAang==}
engines: {node: '>=20.17'}
@@ -5113,6 +5119,10 @@ packages:
resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==}
engines: {node: 20 || >=22}
+ lru-cache@11.5.2:
+ resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==}
+ engines: {node: 20 || >=22}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -5193,18 +5203,10 @@ packages:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
- mime-db@1.52.0:
- resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
- engines: {node: '>= 0.6'}
-
mime-db@1.54.0:
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
engines: {node: '>= 0.6'}
- mime-types@2.1.35:
- resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
- engines: {node: '>= 0.6'}
-
mime-types@3.0.2:
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
engines: {node: '>=18'}
@@ -5339,12 +5341,6 @@ packages:
resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
engines: {node: '>=18'}
- nth-check@2.1.1:
- resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
-
- nwsapi@2.2.22:
- resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==}
-
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@@ -5478,9 +5474,6 @@ packages:
resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
engines: {node: '>=18'}
- parse5@7.3.0:
- resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
-
parse5@8.0.0:
resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
@@ -5659,9 +5652,6 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
- psl@1.15.0:
- resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
-
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
@@ -5673,9 +5663,6 @@ packages:
quansync@0.2.11:
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
- querystringify@2.2.0:
- resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
-
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@@ -5814,9 +5801,6 @@ packages:
resolution: {integrity: sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==}
engines: {node: '>=0.10.5'}
- requires-port@1.0.0:
- resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
-
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -5870,9 +5854,6 @@ packages:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
- rrweb-cssom@0.6.0:
- resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
-
rrweb-cssom@0.8.0:
resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
@@ -6268,10 +6249,6 @@ packages:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
- tough-cookie@4.1.4:
- resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
- engines: {node: '>=6'}
-
tough-cookie@6.0.0:
resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==}
engines: {node: '>=16'}
@@ -6283,10 +6260,6 @@ packages:
tr46@1.0.1:
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
- tr46@5.1.1:
- resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
- engines: {node: '>=18'}
-
tr46@6.0.0:
resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
engines: {node: '>=20'}
@@ -6426,9 +6399,6 @@ packages:
ufo@1.6.1:
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
- uhyphen@0.2.0:
- resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==}
-
unbox-primitive@1.1.0:
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
engines: {node: '>= 0.4'}
@@ -6436,6 +6406,13 @@ packages:
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
+ undici-types@7.29.0:
+ resolution: {integrity: sha512-vamA8dGlzMwhpyYpQp9d8vka3o4D/yn5I7ez7Or+msDA4bZ8Uh+Zy91WvWf3I73gDAkFha9JcYRqm2li0Npfgg==}
+
+ undici@7.29.0:
+ resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==}
+ engines: {node: '>=20.18.1'}
+
unicorn-magic@0.1.0:
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
engines: {node: '>=18'}
@@ -6448,10 +6425,6 @@ packages:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}
- universalify@0.2.0:
- resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
- engines: {node: '>= 4.0.0'}
-
universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
@@ -6482,9 +6455,6 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
- url-parse@1.5.10:
- resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
-
use-callback-ref@1.3.3:
resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
engines: {node: '>=10'}
@@ -6642,14 +6612,14 @@ packages:
webidl-conversions@4.0.2:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
- webidl-conversions@7.0.0:
- resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
- engines: {node: '>=12'}
-
webidl-conversions@8.0.0:
resolution: {integrity: sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==}
engines: {node: '>=20'}
+ webidl-conversions@8.0.1:
+ resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
+ engines: {node: '>=20'}
+
webpack-virtual-modules@0.6.2:
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
@@ -6662,14 +6632,18 @@ packages:
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
engines: {node: '>=18'}
- whatwg-url@14.2.0:
- resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
- engines: {node: '>=18'}
+ whatwg-mimetype@5.0.0:
+ resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
+ engines: {node: '>=20'}
whatwg-url@15.1.0:
resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==}
engines: {node: '>=20'}
+ whatwg-url@16.0.1:
+ resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
whatwg-url@7.1.0:
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
@@ -6815,6 +6789,8 @@ packages:
snapshots:
+ '@acemir/cssom@0.9.31': {}
+
'@adobe/css-tools@4.4.4': {}
'@antfu/ni@25.0.0':
@@ -6824,14 +6800,6 @@ snapshots:
package-manager-detector: 1.6.0
tinyexec: 1.0.2
- '@asamuzakjp/css-color@3.2.0':
- dependencies:
- '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
- '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
- '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
- '@csstools/css-tokenizer': 3.0.4
- lru-cache: 10.4.3
-
'@asamuzakjp/css-color@4.0.5':
dependencies:
'@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
@@ -6840,6 +6808,14 @@ snapshots:
'@csstools/css-tokenizer': 3.0.4
lru-cache: 11.2.1
+ '@asamuzakjp/css-color@5.1.11':
+ dependencies:
+ '@asamuzakjp/generational-cache': 1.0.1
+ '@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-color-parser': 4.1.10(@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-tokenizer': 4.0.0
+
'@asamuzakjp/dom-selector@6.7.3':
dependencies:
'@asamuzakjp/nwsapi': 2.3.9
@@ -6848,6 +6824,16 @@ snapshots:
is-potential-custom-element-name: 1.0.1
lru-cache: 11.2.2
+ '@asamuzakjp/dom-selector@6.8.1':
+ dependencies:
+ '@asamuzakjp/nwsapi': 2.3.9
+ bidi-js: 1.0.3
+ css-tree: 3.1.0
+ is-potential-custom-element-name: 1.0.1
+ lru-cache: 11.5.2
+
+ '@asamuzakjp/generational-cache@1.0.1': {}
+
'@asamuzakjp/nwsapi@2.3.9': {}
'@babel/code-frame@7.27.1':
@@ -7216,6 +7202,10 @@ snapshots:
'@bcoe/v8-coverage@1.0.2': {}
+ '@bramus/specificity@2.4.2':
+ dependencies:
+ css-tree: 3.1.0
+
'@changesets/apply-release-plan@7.0.13':
dependencies:
'@changesets/config': 3.1.1
@@ -7472,11 +7462,18 @@ snapshots:
'@csstools/color-helpers@5.1.0': {}
+ '@csstools/color-helpers@6.1.0': {}
+
'@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
dependencies:
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
+ '@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
+
'@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
dependencies:
'@csstools/color-helpers': 5.1.0
@@ -7484,16 +7481,33 @@ snapshots:
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
+ '@csstools/css-color-parser@4.1.10(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/color-helpers': 6.1.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-tokenizer': 4.0.0
+
'@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)':
dependencies:
'@csstools/css-tokenizer': 3.0.4
+ '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-tokenizer': 4.0.0
+
'@csstools/css-syntax-patches-for-csstree@1.0.14(postcss@8.5.6)':
dependencies:
postcss: 8.5.6
+ '@csstools/css-syntax-patches-for-csstree@1.1.7(css-tree@3.1.0)':
+ optionalDependencies:
+ css-tree: 3.1.0
+
'@csstools/css-tokenizer@3.0.4': {}
+ '@csstools/css-tokenizer@4.0.0': {}
+
'@dotenvx/dotenvx@1.52.0':
dependencies:
commander: 11.1.0
@@ -7760,6 +7774,10 @@ snapshots:
'@eslint/core': 0.17.0
levn: 0.4.1
+ '@exodus/bytes@1.15.1(@noble/hashes@1.8.0)':
+ optionalDependencies:
+ '@noble/hashes': 1.8.0
+
'@floating-ui/core@1.7.3':
dependencies:
'@floating-ui/utils': 0.2.10
@@ -9535,6 +9553,13 @@ snapshots:
'@types/istanbul-lib-coverage@2.0.6': {}
+ '@types/jsdom@28.0.3':
+ dependencies:
+ '@types/node': 24.11.0
+ '@types/tough-cookie': 4.0.5
+ parse5: 8.0.0
+ undici-types: 7.29.0
+
'@types/json-schema@7.0.15': {}
'@types/mdx@2.0.13': {}
@@ -9565,6 +9590,8 @@ snapshots:
'@types/statuses@2.0.6': {}
+ '@types/tough-cookie@4.0.5': {}
+
'@types/validate-npm-package-name@4.0.2': {}
'@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)':
@@ -9751,7 +9778,7 @@ snapshots:
'@vitest/mocker': 4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))
playwright: 1.56.1
tinyrainbow: 3.0.3
- vitest: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@24.0.0)(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
+ vitest: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
transitivePeerDependencies:
- bufferutil
- msw
@@ -9781,7 +9808,7 @@ snapshots:
pngjs: 7.0.0
sirv: 3.0.2
tinyrainbow: 3.0.3
- vitest: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@24.0.0)(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
+ vitest: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
ws: 8.18.3
transitivePeerDependencies:
- bufferutil
@@ -9820,7 +9847,7 @@ snapshots:
magicast: 0.3.5
std-env: 3.9.0
tinyrainbow: 3.0.3
- vitest: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@24.0.0)(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
+ vitest: 4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1)
optionalDependencies:
'@vitest/browser': 4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))(vitest@4.0.4)
transitivePeerDependencies:
@@ -10103,8 +10130,6 @@ snapshots:
async-function@1.0.0: {}
- asynckit@0.4.0: {}
-
available-typed-arrays@1.0.7:
dependencies:
possible-typed-array-names: 1.1.0
@@ -10141,8 +10166,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- boolbase@1.0.0: {}
-
brace-expansion@1.1.12:
dependencies:
balanced-match: 1.0.2
@@ -10278,10 +10301,6 @@ snapshots:
colorette@2.0.20: {}
- combined-stream@1.0.8:
- dependencies:
- delayed-stream: 1.0.0
-
commander@11.1.0: {}
commander@14.0.1: {}
@@ -10369,32 +10388,15 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
- css-select@5.2.2:
- dependencies:
- boolbase: 1.0.0
- css-what: 6.2.2
- domhandler: 5.0.3
- domutils: 3.2.2
- nth-check: 2.1.1
-
css-tree@3.1.0:
dependencies:
mdn-data: 2.12.2
source-map-js: 1.2.1
- css-what@6.2.2: {}
-
css.escape@1.5.1: {}
cssesc@3.0.0: {}
- cssom@0.5.0: {}
-
- cssstyle@4.6.0:
- dependencies:
- '@asamuzakjp/css-color': 3.2.0
- rrweb-cssom: 0.8.0
-
cssstyle@5.3.1(postcss@8.5.6):
dependencies:
'@asamuzakjp/css-color': 4.0.5
@@ -10403,22 +10405,31 @@ snapshots:
transitivePeerDependencies:
- postcss
+ cssstyle@6.2.0:
+ dependencies:
+ '@asamuzakjp/css-color': 5.1.11
+ '@csstools/css-syntax-patches-for-csstree': 1.1.7(css-tree@3.1.0)
+ css-tree: 3.1.0
+ lru-cache: 11.5.2
+
csstype@3.1.3: {}
dargs@8.1.0: {}
data-uri-to-buffer@4.0.1: {}
- data-urls@5.0.0:
- dependencies:
- whatwg-mimetype: 4.0.0
- whatwg-url: 14.2.0
-
data-urls@6.0.0:
dependencies:
whatwg-mimetype: 4.0.0
whatwg-url: 15.1.0
+ data-urls@7.0.0(@noble/hashes@1.8.0):
+ dependencies:
+ whatwg-mimetype: 5.0.0
+ whatwg-url: 16.0.1(@noble/hashes@1.8.0)
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
data-view-buffer@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -10476,8 +10487,6 @@ snapshots:
has-property-descriptors: 1.0.2
object-keys: 1.1.1
- delayed-stream@1.0.0: {}
-
depd@2.0.0: {}
dequal@2.0.3: {}
@@ -10508,24 +10517,6 @@ snapshots:
dom-accessibility-api@0.6.3: {}
- dom-serializer@2.0.0:
- dependencies:
- domelementtype: 2.3.0
- domhandler: 5.0.3
- entities: 4.5.0
-
- domelementtype@2.3.0: {}
-
- domhandler@5.0.3:
- dependencies:
- domelementtype: 2.3.0
-
- domutils@3.2.2:
- dependencies:
- dom-serializer: 2.0.0
- domelementtype: 2.3.0
- domhandler: 5.0.3
-
dot-prop@5.3.0:
dependencies:
is-obj: 2.0.0
@@ -10591,12 +10582,8 @@ snapshots:
ansi-colors: 4.1.3
strip-ansi: 6.0.1
- entities@4.5.0: {}
-
entities@6.0.1: {}
- entities@7.0.1: {}
-
env-paths@2.2.1: {}
environment@1.1.0: {}
@@ -11145,14 +11132,6 @@ snapshots:
cross-spawn: 7.0.6
signal-exit: 4.1.0
- form-data@4.0.4:
- dependencies:
- asynckit: 0.4.0
- combined-stream: 1.0.8
- es-set-tostringtag: 2.1.0
- hasown: 2.0.2
- mime-types: 2.1.35
-
formatly@0.3.0:
dependencies:
fd-package-json: 2.0.0
@@ -11369,21 +11348,18 @@ snapshots:
dependencies:
whatwg-encoding: 3.1.1
- html-escaper@2.0.2: {}
+ html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0):
+ dependencies:
+ '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0)
+ transitivePeerDependencies:
+ - '@noble/hashes'
- html-escaper@3.0.3: {}
+ html-escaper@2.0.2: {}
html-parse-stringify@3.0.1:
dependencies:
void-elements: 3.1.0
- htmlparser2@10.1.0:
- dependencies:
- domelementtype: 2.3.0
- domhandler: 5.0.3
- domutils: 3.2.2
- entities: 7.0.1
-
http-errors@2.0.1:
dependencies:
depd: 2.0.0
@@ -11395,7 +11371,7 @@ snapshots:
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
- debug: 4.4.1
+ debug: 4.4.3
transitivePeerDependencies:
- supports-color
@@ -11711,61 +11687,60 @@ snapshots:
dependencies:
argparse: 2.0.1
- jsdom@24.0.0:
+ jsdom@27.0.1(postcss@8.5.6):
dependencies:
- cssstyle: 4.6.0
- data-urls: 5.0.0
+ '@asamuzakjp/dom-selector': 6.7.3
+ cssstyle: 5.3.1(postcss@8.5.6)
+ data-urls: 6.0.0
decimal.js: 10.6.0
- form-data: 4.0.4
html-encoding-sniffer: 4.0.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
is-potential-custom-element-name: 1.0.1
- nwsapi: 2.2.22
- parse5: 7.3.0
- rrweb-cssom: 0.6.0
+ parse5: 8.0.0
+ rrweb-cssom: 0.8.0
saxes: 6.0.0
symbol-tree: 3.2.4
- tough-cookie: 4.1.4
+ tough-cookie: 6.0.0
w3c-xmlserializer: 5.0.0
- webidl-conversions: 7.0.0
+ webidl-conversions: 8.0.0
whatwg-encoding: 3.1.1
whatwg-mimetype: 4.0.0
- whatwg-url: 14.2.0
+ whatwg-url: 15.1.0
ws: 8.18.3
xml-name-validator: 5.0.0
transitivePeerDependencies:
- bufferutil
+ - postcss
- supports-color
- utf-8-validate
- jsdom@27.0.1(postcss@8.5.6):
+ jsdom@28.1.0(@noble/hashes@1.8.0):
dependencies:
- '@asamuzakjp/dom-selector': 6.7.3
- cssstyle: 5.3.1(postcss@8.5.6)
- data-urls: 6.0.0
+ '@acemir/cssom': 0.9.31
+ '@asamuzakjp/dom-selector': 6.8.1
+ '@bramus/specificity': 2.4.2
+ '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0)
+ cssstyle: 6.2.0
+ data-urls: 7.0.0(@noble/hashes@1.8.0)
decimal.js: 10.6.0
- html-encoding-sniffer: 4.0.0
+ html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0)
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
is-potential-custom-element-name: 1.0.1
parse5: 8.0.0
- rrweb-cssom: 0.8.0
saxes: 6.0.0
symbol-tree: 3.2.4
- tough-cookie: 6.0.0
+ tough-cookie: 6.0.1
+ undici: 7.29.0
w3c-xmlserializer: 5.0.0
- webidl-conversions: 8.0.0
- whatwg-encoding: 3.1.1
- whatwg-mimetype: 4.0.0
- whatwg-url: 15.1.0
- ws: 8.18.3
+ webidl-conversions: 8.0.1
+ whatwg-mimetype: 5.0.0
+ whatwg-url: 16.0.1(@noble/hashes@1.8.0)
xml-name-validator: 5.0.0
transitivePeerDependencies:
- - bufferutil
- - postcss
+ - '@noble/hashes'
- supports-color
- - utf-8-validate
jsesc@3.1.0: {}
@@ -11934,14 +11909,6 @@ snapshots:
lines-and-columns@1.2.4: {}
- linkedom@0.18.12:
- dependencies:
- css-select: 5.2.2
- cssom: 0.5.0
- html-escaper: 3.0.3
- htmlparser2: 10.1.0
- uhyphen: 0.2.0
-
lint-staged@16.2.5:
dependencies:
commander: 14.0.1
@@ -12028,6 +11995,8 @@ snapshots:
lru-cache@11.2.2: {}
+ lru-cache@11.5.2: {}
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -12087,14 +12056,8 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.1
- mime-db@1.52.0: {}
-
mime-db@1.54.0: {}
- mime-types@2.1.35:
- dependencies:
- mime-db: 1.52.0
-
mime-types@3.0.2:
dependencies:
mime-db: 1.54.0
@@ -12236,12 +12199,6 @@ snapshots:
path-key: 4.0.0
unicorn-magic: 0.3.0
- nth-check@2.1.1:
- dependencies:
- boolbase: 1.0.0
-
- nwsapi@2.2.22: {}
-
object-assign@4.1.1: {}
object-inspect@1.13.4: {}
@@ -12418,10 +12375,6 @@ snapshots:
parse-ms@4.0.0: {}
- parse5@7.3.0:
- dependencies:
- entities: 6.0.1
-
parse5@8.0.0:
dependencies:
entities: 6.0.1
@@ -12449,7 +12402,7 @@ snapshots:
path-scurry@2.0.0:
dependencies:
- lru-cache: 11.2.1
+ lru-cache: 11.2.2
minipass: 7.1.2
path-scurry@2.0.2:
@@ -12556,10 +12509,6 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
- psl@1.15.0:
- dependencies:
- punycode: 2.3.1
-
punycode@2.3.1: {}
qs@6.15.0:
@@ -12568,8 +12517,6 @@ snapshots:
quansync@0.2.11: {}
- querystringify@2.2.0: {}
-
queue-microtask@1.2.3: {}
radix-ui@1.4.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.2(react@19.1.2))(react@19.1.2):
@@ -12764,8 +12711,6 @@ snapshots:
requireindex@1.1.0: {}
- requires-port@1.0.0: {}
-
resolve-from@4.0.0: {}
resolve-from@5.0.0: {}
@@ -12843,8 +12788,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- rrweb-cssom@0.6.0: {}
-
rrweb-cssom@0.8.0: {}
run-applescript@7.1.0: {}
@@ -13310,13 +13253,6 @@ snapshots:
totalist@3.0.1: {}
- tough-cookie@4.1.4:
- dependencies:
- psl: 1.15.0
- punycode: 2.3.1
- universalify: 0.2.0
- url-parse: 1.5.10
-
tough-cookie@6.0.0:
dependencies:
tldts: 7.0.17
@@ -13329,10 +13265,6 @@ snapshots:
dependencies:
punycode: 2.3.1
- tr46@5.1.1:
- dependencies:
- punycode: 2.3.1
-
tr46@6.0.0:
dependencies:
punycode: 2.3.1
@@ -13526,8 +13458,6 @@ snapshots:
ufo@1.6.1: {}
- uhyphen@0.2.0: {}
-
unbox-primitive@1.1.0:
dependencies:
call-bound: 1.0.4
@@ -13537,14 +13467,16 @@ snapshots:
undici-types@7.16.0: {}
+ undici-types@7.29.0: {}
+
+ undici@7.29.0: {}
+
unicorn-magic@0.1.0: {}
unicorn-magic@0.3.0: {}
universalify@0.1.2: {}
- universalify@0.2.0: {}
-
universalify@2.0.1: {}
unpipe@1.0.0: {}
@@ -13574,11 +13506,6 @@ snapshots:
dependencies:
punycode: 2.3.1
- url-parse@1.5.10:
- dependencies:
- querystringify: 2.2.0
- requires-port: 1.0.0
-
use-callback-ref@1.3.3(@types/react@19.1.2)(react@19.1.2):
dependencies:
react: 19.1.2
@@ -13647,10 +13574,10 @@ snapshots:
'@types/react': 19.1.2
'@types/react-dom': 19.1.2(@types/react@19.1.2)
- vitest@4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@24.0.0)(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1):
+ vitest@4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@27.0.1(postcss@8.5.6))(lightningcss@1.31.1)(msw@2.13.4(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.4
- '@vitest/mocker': 4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))
+ '@vitest/mocker': 4.0.4(msw@2.13.4(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))
'@vitest/pretty-format': 4.0.4
'@vitest/runner': 4.0.4
'@vitest/snapshot': 4.0.4
@@ -13671,8 +13598,8 @@ snapshots:
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 24.11.0
- '@vitest/browser-playwright': 4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(playwright@1.56.1)(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))(vitest@4.0.4)
- jsdom: 24.0.0
+ '@vitest/browser-playwright': 4.0.4(msw@2.13.4(@types/node@24.11.0)(typescript@5.9.3))(playwright@1.56.1)(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))(vitest@4.0.4)
+ jsdom: 27.0.1(postcss@8.5.6)
transitivePeerDependencies:
- jiti
- less
@@ -13687,10 +13614,10 @@ snapshots:
- tsx
- yaml
- vitest@4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@27.0.1(postcss@8.5.6))(lightningcss@1.31.1)(msw@2.13.4(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1):
+ vitest@4.0.4(@types/node@24.11.0)(@vitest/browser-playwright@4.0.4)(jiti@2.6.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(terser@5.44.0)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.4
- '@vitest/mocker': 4.0.4(msw@2.13.4(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))
+ '@vitest/mocker': 4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))
'@vitest/pretty-format': 4.0.4
'@vitest/runner': 4.0.4
'@vitest/snapshot': 4.0.4
@@ -13711,8 +13638,8 @@ snapshots:
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 24.11.0
- '@vitest/browser-playwright': 4.0.4(msw@2.13.4(@types/node@24.11.0)(typescript@5.9.3))(playwright@1.56.1)(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))(vitest@4.0.4)
- jsdom: 27.0.1(postcss@8.5.6)
+ '@vitest/browser-playwright': 4.0.4(msw@2.11.6(@types/node@24.11.0)(typescript@5.9.3))(playwright@1.56.1)(vite@7.3.3(@types/node@24.11.0)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(yaml@2.8.1))(vitest@4.0.4)
+ jsdom: 28.1.0(@noble/hashes@1.8.0)
transitivePeerDependencies:
- jiti
- less
@@ -13739,10 +13666,10 @@ snapshots:
webidl-conversions@4.0.2: {}
- webidl-conversions@7.0.0: {}
-
webidl-conversions@8.0.0: {}
+ webidl-conversions@8.0.1: {}
+
webpack-virtual-modules@0.6.2: {}
whatwg-encoding@3.1.1:
@@ -13751,16 +13678,21 @@ snapshots:
whatwg-mimetype@4.0.0: {}
- whatwg-url@14.2.0:
- dependencies:
- tr46: 5.1.1
- webidl-conversions: 7.0.0
+ whatwg-mimetype@5.0.0: {}
whatwg-url@15.1.0:
dependencies:
tr46: 6.0.0
webidl-conversions: 8.0.0
+ whatwg-url@16.0.1(@noble/hashes@1.8.0):
+ dependencies:
+ '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0)
+ tr46: 6.0.0
+ webidl-conversions: 8.0.1
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
whatwg-url@7.1.0:
dependencies:
lodash.sortby: 4.7.0