diff --git a/CHANGELOG.md b/CHANGELOG.md index d855e73..9e3dd3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,41 @@ All notable changes to this project are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions track `packages/framework`'s own `package.json`. +## [Unreleased] + +### Added + +- **`loadCollection(dir, parse?)`** in `@inkform/framework/content` loads any + folder of MDX (`content//*.mdx`, sorted by file name) for collections + beyond blog and changelog: podcast episodes, course notes, case studies. + Files starting with `_` are skipped, so examples and drafts can sit next to + real entries. Pass `parse`, for example a zod schema's `.parse`, to type and + validate the frontmatter. When it throws, the error names the file, so a bad + field fails the build with a pointer to it. +- **`@inkform/framework/prose.css`**: MDX content styles only (`.fw-prose`, + callouts, cards, steps, tabs, subscribe, mermaid) for sites that bring their + own layout and design system. It has no global reset, so it never restyles the + host's `html`, `body` or bare elements. + +### Fixed + +- **Search index on Vercel with Next.js 16.3.8.** Built with a deployment + adapter, Next.js 16.3.8 writes prerendered HTML to `.next/server/route-cache/` + instead of `.next/server/app/`, so `pagefind --site .next/server/app` found + nothing and failed the build. Templates and examples now run + `node scripts/pagefind.mjs`, which reads both layouts and indexes each page + under its real URL (`/docs/intro`, not `/docs/intro.html`). Existing sites: + copy `templates/canopy/scripts/pagefind.mjs` and point `postbuild` at it. + +### Changed + +- Templates and examples pin `next` 16.3.8 (security release), `vitest` is on + 4.x, and the `sharp`, `vite` and `@modelcontextprotocol/sdk` floors are raised + to clear new npm audit advisories. +- The global reset moved out of `styles/tokens.css` into `styles/base.css`. + `styles.css` imports both in the same order as before, so its output is + unchanged. + ## [0.6.1] — 2026-09-27 ### Changed diff --git a/examples/inkform-docs/content/docs/getting-started/deploying.mdx b/examples/inkform-docs/content/docs/getting-started/deploying.mdx index 4597895..6621ecb 100644 --- a/examples/inkform-docs/content/docs/getting-started/deploying.mdx +++ b/examples/inkform-docs/content/docs/getting-started/deploying.mdx @@ -42,7 +42,7 @@ a database, a build service, or any external API to render. ## Search indexing -Every theme runs Pagefind as a `postbuild` step -(`pagefind --site .next/server/app --output-path public/_pagefind`), so +Every theme runs Pagefind as a `postbuild` step (`node scripts/pagefind.mjs`, +which indexes the prerendered HTML into `public/_pagefind`), so Cmd/Ctrl+K search works out of the box on the very first production build — no separate indexing service, no third-party search SaaS. diff --git a/examples/inkform-docs/content/docs/guides/docs.mdx b/examples/inkform-docs/content/docs/guides/docs.mdx index 179f20f..be36674 100644 --- a/examples/inkform-docs/content/docs/guides/docs.mdx +++ b/examples/inkform-docs/content/docs/guides/docs.mdx @@ -77,7 +77,7 @@ by default. Cmd/Ctrl+K search works out of the box via [Pagefind](https://pagefind.app/), indexed at build time -(`postbuild: pagefind --site .next/server/app --output-path public/_pagefind`). +(`postbuild: node scripts/pagefind.mjs`). No third-party search service, no API keys, no separate indexing step to remember. diff --git a/examples/inkform-docs/next.config.ts b/examples/inkform-docs/next.config.ts index 02714a1..6a2b367 100644 --- a/examples/inkform-docs/next.config.ts +++ b/examples/inkform-docs/next.config.ts @@ -3,12 +3,12 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { transpilePackages: ['@inkform/framework'], images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] }, - // Pagefind indexes .next/server/app's built .html files directly, so its - // search results carry a trailing .html this app doesn't actually serve - // (e.g. /essentials/markdown.html) — this app's real routes are - // extensionless. Redirect (not rewrite) so the address bar ends up on the - // real, shareable permalink; query params (?q=... for highlighting) are - // preserved automatically. + // Search indexes built with `pagefind --site .next/server/app` linked to + // each page's .html file (e.g. /essentials/markdown.html), which this app + // doesn't serve — its real routes are extensionless. scripts/pagefind.mjs + // now indexes the real URLs; this redirect keeps old links working. + // Redirect (not rewrite) so the address bar ends up on the real, shareable + // permalink; query params (?q=... for highlighting) are preserved. async redirects() { return [{ source: '/:path*.html', destination: '/:path*', permanent: false }]; }, diff --git a/examples/inkform-docs/package.json b/examples/inkform-docs/package.json index 02c23ba..2406d6f 100644 --- a/examples/inkform-docs/package.json +++ b/examples/inkform-docs/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "next dev", "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "postbuild": "node scripts/pagefind.mjs", "start": "next start", "typecheck": "tsc --noEmit" }, @@ -15,7 +15,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/examples/inkform-docs/scripts/pagefind.mjs b/examples/inkform-docs/scripts/pagefind.mjs new file mode 100644 index 0000000..14b4737 --- /dev/null +++ b/examples/inkform-docs/scripts/pagefind.mjs @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Postbuild: builds the Pagefind search index from this app's prerendered HTML. + * + * A plain `next build` writes static pages to .next/server/app/.html. + * Built with a deployment adapter (Vercel uses one, and from Next.js 16.3.8 it + * changes the layout), the same pages land in + * .next/server/route-cache/APP_PAGE//$/.html instead, and + * `pagefind --site .next/server/app` finds nothing and fails the build. This + * reads both layouts and hands Pagefind each page's real URL (/docs/intro, not + * /docs/intro.html), using Pagefind's Node API. + */ +import { readdir, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import * as pagefind from 'pagefind'; + +const SERVER_DIR = path.join('.next', 'server'); +const OUTPUT_PATH = path.join('public', '_pagefind'); +// Next's own error pages are not search results. +const SKIP = new Set(['/_not-found', '/_global-error']); + +async function htmlFiles(dir) { + let entries; + try { + entries = await readdir(dir, { withFileTypes: true, recursive: true }); + } catch { + return []; + } + return entries + .filter((entry) => entry.isFile() && entry.name.endsWith('.html')) + .map((entry) => path.join(entry.parentPath, entry.name)); +} + +/** "docs/intro.html" → "/docs/intro"; "index.html" → "/". */ +function toUrl(relativeHtmlPath) { + const route = `/${relativeHtmlPath.split(path.sep).join('/').replace(/\.html$/, '')}`; + return route === '/index' ? '/' : route; +} + +const pages = new Map(); + +// Plain build: .next/server/app/.html +const appDir = path.join(SERVER_DIR, 'app'); +for (const file of await htmlFiles(appDir)) { + pages.set(toUrl(path.relative(appDir, file)), file); +} + +// Adapter build: .next/server/route-cache/APP_PAGE//$/.html +const routeCacheDir = path.join(SERVER_DIR, 'route-cache', 'APP_PAGE'); +for (const file of await htmlFiles(routeCacheDir)) { + const [, marker, ...route] = path.relative(routeCacheDir, file).split(path.sep); + if (marker === '$' && route.length) pages.set(toUrl(route.join(path.sep)), file); +} + +for (const url of SKIP) pages.delete(url); + +if (pages.size === 0) { + console.error(`[pagefind] No prerendered HTML found under ${SERVER_DIR}. Run \`next build\` first.`); + process.exit(1); +} + +const fail = (step, errors) => { + console.error(`[pagefind] ${step} failed:\n${errors.join('\n')}`); + process.exit(1); +}; + +const { index, errors: createErrors } = await pagefind.createIndex(); +if (!index) fail('createIndex', createErrors); + +for (const [url, file] of pages) { + const { errors } = await index.addHTMLFile({ url, content: await readFile(file, 'utf8') }); + if (errors.length) fail(`Indexing ${url}`, errors); +} + +const { errors: writeErrors } = await index.writeFiles({ outputPath: OUTPUT_PATH }); +if (writeErrors.length) fail('writeFiles', writeErrors); +await pagefind.close(); + +console.log(`[pagefind] Indexed ${pages.size} pages into ${OUTPUT_PATH}`); diff --git a/examples/markdown-docs/next.config.ts b/examples/markdown-docs/next.config.ts index 02714a1..6a2b367 100644 --- a/examples/markdown-docs/next.config.ts +++ b/examples/markdown-docs/next.config.ts @@ -3,12 +3,12 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { transpilePackages: ['@inkform/framework'], images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] }, - // Pagefind indexes .next/server/app's built .html files directly, so its - // search results carry a trailing .html this app doesn't actually serve - // (e.g. /essentials/markdown.html) — this app's real routes are - // extensionless. Redirect (not rewrite) so the address bar ends up on the - // real, shareable permalink; query params (?q=... for highlighting) are - // preserved automatically. + // Search indexes built with `pagefind --site .next/server/app` linked to + // each page's .html file (e.g. /essentials/markdown.html), which this app + // doesn't serve — its real routes are extensionless. scripts/pagefind.mjs + // now indexes the real URLs; this redirect keeps old links working. + // Redirect (not rewrite) so the address bar ends up on the real, shareable + // permalink; query params (?q=... for highlighting) are preserved. async redirects() { return [{ source: '/:path*.html', destination: '/:path*', permanent: false }]; }, diff --git a/examples/markdown-docs/package.json b/examples/markdown-docs/package.json index 8812637..282d2ba 100644 --- a/examples/markdown-docs/package.json +++ b/examples/markdown-docs/package.json @@ -7,14 +7,14 @@ "scripts": { "dev": "next dev", "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "postbuild": "node scripts/pagefind.mjs", "start": "next start", "typecheck": "tsc --noEmit" }, "dependencies": { "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/examples/markdown-docs/scripts/pagefind.mjs b/examples/markdown-docs/scripts/pagefind.mjs new file mode 100644 index 0000000..14b4737 --- /dev/null +++ b/examples/markdown-docs/scripts/pagefind.mjs @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Postbuild: builds the Pagefind search index from this app's prerendered HTML. + * + * A plain `next build` writes static pages to .next/server/app/.html. + * Built with a deployment adapter (Vercel uses one, and from Next.js 16.3.8 it + * changes the layout), the same pages land in + * .next/server/route-cache/APP_PAGE//$/.html instead, and + * `pagefind --site .next/server/app` finds nothing and fails the build. This + * reads both layouts and hands Pagefind each page's real URL (/docs/intro, not + * /docs/intro.html), using Pagefind's Node API. + */ +import { readdir, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import * as pagefind from 'pagefind'; + +const SERVER_DIR = path.join('.next', 'server'); +const OUTPUT_PATH = path.join('public', '_pagefind'); +// Next's own error pages are not search results. +const SKIP = new Set(['/_not-found', '/_global-error']); + +async function htmlFiles(dir) { + let entries; + try { + entries = await readdir(dir, { withFileTypes: true, recursive: true }); + } catch { + return []; + } + return entries + .filter((entry) => entry.isFile() && entry.name.endsWith('.html')) + .map((entry) => path.join(entry.parentPath, entry.name)); +} + +/** "docs/intro.html" → "/docs/intro"; "index.html" → "/". */ +function toUrl(relativeHtmlPath) { + const route = `/${relativeHtmlPath.split(path.sep).join('/').replace(/\.html$/, '')}`; + return route === '/index' ? '/' : route; +} + +const pages = new Map(); + +// Plain build: .next/server/app/.html +const appDir = path.join(SERVER_DIR, 'app'); +for (const file of await htmlFiles(appDir)) { + pages.set(toUrl(path.relative(appDir, file)), file); +} + +// Adapter build: .next/server/route-cache/APP_PAGE//$/.html +const routeCacheDir = path.join(SERVER_DIR, 'route-cache', 'APP_PAGE'); +for (const file of await htmlFiles(routeCacheDir)) { + const [, marker, ...route] = path.relative(routeCacheDir, file).split(path.sep); + if (marker === '$' && route.length) pages.set(toUrl(route.join(path.sep)), file); +} + +for (const url of SKIP) pages.delete(url); + +if (pages.size === 0) { + console.error(`[pagefind] No prerendered HTML found under ${SERVER_DIR}. Run \`next build\` first.`); + process.exit(1); +} + +const fail = (step, errors) => { + console.error(`[pagefind] ${step} failed:\n${errors.join('\n')}`); + process.exit(1); +}; + +const { index, errors: createErrors } = await pagefind.createIndex(); +if (!index) fail('createIndex', createErrors); + +for (const [url, file] of pages) { + const { errors } = await index.addHTMLFile({ url, content: await readFile(file, 'utf8') }); + if (errors.length) fail(`Indexing ${url}`, errors); +} + +const { errors: writeErrors } = await index.writeFiles({ outputPath: OUTPUT_PATH }); +if (writeErrors.length) fail('writeFiles', writeErrors); +await pagefind.close(); + +console.log(`[pagefind] Indexed ${pages.size} pages into ${OUTPUT_PATH}`); diff --git a/examples/pokeapi-docs/next.config.ts b/examples/pokeapi-docs/next.config.ts index 02714a1..6a2b367 100644 --- a/examples/pokeapi-docs/next.config.ts +++ b/examples/pokeapi-docs/next.config.ts @@ -3,12 +3,12 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { transpilePackages: ['@inkform/framework'], images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] }, - // Pagefind indexes .next/server/app's built .html files directly, so its - // search results carry a trailing .html this app doesn't actually serve - // (e.g. /essentials/markdown.html) — this app's real routes are - // extensionless. Redirect (not rewrite) so the address bar ends up on the - // real, shareable permalink; query params (?q=... for highlighting) are - // preserved automatically. + // Search indexes built with `pagefind --site .next/server/app` linked to + // each page's .html file (e.g. /essentials/markdown.html), which this app + // doesn't serve — its real routes are extensionless. scripts/pagefind.mjs + // now indexes the real URLs; this redirect keeps old links working. + // Redirect (not rewrite) so the address bar ends up on the real, shareable + // permalink; query params (?q=... for highlighting) are preserved. async redirects() { return [{ source: '/:path*.html', destination: '/:path*', permanent: false }]; }, diff --git a/examples/pokeapi-docs/package.json b/examples/pokeapi-docs/package.json index b7387be..8b234e0 100644 --- a/examples/pokeapi-docs/package.json +++ b/examples/pokeapi-docs/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "next dev", "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "postbuild": "node scripts/pagefind.mjs", "start": "next start", "typecheck": "tsc --noEmit", "test:e2e": "playwright test" @@ -15,7 +15,7 @@ "dependencies": { "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/examples/pokeapi-docs/scripts/pagefind.mjs b/examples/pokeapi-docs/scripts/pagefind.mjs new file mode 100644 index 0000000..14b4737 --- /dev/null +++ b/examples/pokeapi-docs/scripts/pagefind.mjs @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Postbuild: builds the Pagefind search index from this app's prerendered HTML. + * + * A plain `next build` writes static pages to .next/server/app/.html. + * Built with a deployment adapter (Vercel uses one, and from Next.js 16.3.8 it + * changes the layout), the same pages land in + * .next/server/route-cache/APP_PAGE//$/.html instead, and + * `pagefind --site .next/server/app` finds nothing and fails the build. This + * reads both layouts and hands Pagefind each page's real URL (/docs/intro, not + * /docs/intro.html), using Pagefind's Node API. + */ +import { readdir, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import * as pagefind from 'pagefind'; + +const SERVER_DIR = path.join('.next', 'server'); +const OUTPUT_PATH = path.join('public', '_pagefind'); +// Next's own error pages are not search results. +const SKIP = new Set(['/_not-found', '/_global-error']); + +async function htmlFiles(dir) { + let entries; + try { + entries = await readdir(dir, { withFileTypes: true, recursive: true }); + } catch { + return []; + } + return entries + .filter((entry) => entry.isFile() && entry.name.endsWith('.html')) + .map((entry) => path.join(entry.parentPath, entry.name)); +} + +/** "docs/intro.html" → "/docs/intro"; "index.html" → "/". */ +function toUrl(relativeHtmlPath) { + const route = `/${relativeHtmlPath.split(path.sep).join('/').replace(/\.html$/, '')}`; + return route === '/index' ? '/' : route; +} + +const pages = new Map(); + +// Plain build: .next/server/app/.html +const appDir = path.join(SERVER_DIR, 'app'); +for (const file of await htmlFiles(appDir)) { + pages.set(toUrl(path.relative(appDir, file)), file); +} + +// Adapter build: .next/server/route-cache/APP_PAGE//$/.html +const routeCacheDir = path.join(SERVER_DIR, 'route-cache', 'APP_PAGE'); +for (const file of await htmlFiles(routeCacheDir)) { + const [, marker, ...route] = path.relative(routeCacheDir, file).split(path.sep); + if (marker === '$' && route.length) pages.set(toUrl(route.join(path.sep)), file); +} + +for (const url of SKIP) pages.delete(url); + +if (pages.size === 0) { + console.error(`[pagefind] No prerendered HTML found under ${SERVER_DIR}. Run \`next build\` first.`); + process.exit(1); +} + +const fail = (step, errors) => { + console.error(`[pagefind] ${step} failed:\n${errors.join('\n')}`); + process.exit(1); +}; + +const { index, errors: createErrors } = await pagefind.createIndex(); +if (!index) fail('createIndex', createErrors); + +for (const [url, file] of pages) { + const { errors } = await index.addHTMLFile({ url, content: await readFile(file, 'utf8') }); + if (errors.length) fail(`Indexing ${url}`, errors); +} + +const { errors: writeErrors } = await index.writeFiles({ outputPath: OUTPUT_PATH }); +if (writeErrors.length) fail('writeFiles', writeErrors); +await pagefind.close(); + +console.log(`[pagefind] Indexed ${pages.size} pages into ${OUTPUT_PATH}`); diff --git a/package-lock.json b/package-lock.json index 6bf6434..7bebee8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, @@ -48,7 +48,7 @@ "dependencies": { "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, @@ -67,7 +67,7 @@ "dependencies": { "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, @@ -189,15 +189,6 @@ "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@antfu/install-pkg/node_modules/tinyexec": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", - "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -228,42 +219,40 @@ "license": "MIT" }, "node_modules/@chevrotain/cst-dts-gen": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz", - "integrity": "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-13.2.0.tgz", + "integrity": "sha512-bA9dvWlhAUcHkNwU+8w9yiUxJPlj/Lm3VqS7MD+NbIR/7LmpNLuK/AWNFdCo/T3SK5ND0/UHf3IJvl/Jn/i6yg==", "license": "Apache-2.0", "dependencies": { - "@chevrotain/gast": "11.1.2", - "@chevrotain/types": "11.1.2", - "lodash-es": "4.17.23" + "@chevrotain/gast": "13.2.0", + "@chevrotain/types": "13.2.0" } }, "node_modules/@chevrotain/gast": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.2.tgz", - "integrity": "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-13.2.0.tgz", + "integrity": "sha512-bCARdAsG+eEbOveSXcOAC7pVxA04I1ionzeMOwIYf5NX7SaS7zgn4Dgug2BSqoL+iyKeMNSorQjsFSHJHsCNwg==", "license": "Apache-2.0", "dependencies": { - "@chevrotain/types": "11.1.2", - "lodash-es": "4.17.23" + "@chevrotain/types": "13.2.0" } }, "node_modules/@chevrotain/regexp-to-ast": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz", - "integrity": "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-13.2.0.tgz", + "integrity": "sha512-kxpUkLtiaK09ph+dib+Yvm+3sWSnuwlo25gqfKRgTPNmF6H7uW4gVkMjaRdtnN783S9sM6vUNWh9CsxYX4QwKw==", "license": "Apache-2.0" }, "node_modules/@chevrotain/types": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", - "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-13.2.0.tgz", + "integrity": "sha512-7qrYHRlKfWf2AvBfJi5eVOrKAkbxvMFsy/iIHTGIiApNcEecCaVIdR+mIQhyCBsTDJxBz4JWXHMo6krbhR9hVg==", "license": "Apache-2.0" }, "node_modules/@chevrotain/utils": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.2.tgz", - "integrity": "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-13.2.0.tgz", + "integrity": "sha512-SzKYY68rseOrb9KILVzPsl6SjkQtdWw01SRGB5aCVI5kFcHltQsOYV3JB0Ffst72DgkvHCyDQ0NLwxtmCCf97Q==", "license": "Apache-2.0" }, "node_modules/@clack/core": { @@ -779,9 +768,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", - "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz", + "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==", "cpu": [ "arm64" ], @@ -797,13 +786,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.3" + "@img/sharp-libvips-darwin-arm64": "1.3.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", - "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz", + "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==", "cpu": [ "x64" ], @@ -819,20 +808,20 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.3" + "@img/sharp-libvips-darwin-x64": "1.3.4" } }, "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", - "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz", + "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==", "license": "Apache-2.0", "optional": true, "os": [ "freebsd" ], "dependencies": { - "@img/sharp-wasm32": "0.35.4" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -842,9 +831,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", - "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz", + "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==", "cpu": [ "arm64" ], @@ -858,9 +847,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", - "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz", + "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==", "cpu": [ "x64" ], @@ -874,9 +863,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", - "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz", + "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==", "cpu": [ "arm" ], @@ -893,9 +882,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", - "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz", + "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==", "cpu": [ "arm64" ], @@ -912,9 +901,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", - "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz", + "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==", "cpu": [ "ppc64" ], @@ -931,9 +920,9 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", - "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz", + "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==", "cpu": [ "riscv64" ], @@ -950,9 +939,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", - "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz", + "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==", "cpu": [ "s390x" ], @@ -969,9 +958,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", - "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz", + "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==", "cpu": [ "x64" ], @@ -988,9 +977,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", - "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz", + "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==", "cpu": [ "arm64" ], @@ -1007,9 +996,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", - "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz", + "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==", "cpu": [ "x64" ], @@ -1026,9 +1015,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", - "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz", + "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==", "cpu": [ "arm" ], @@ -1047,13 +1036,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.3" + "@img/sharp-libvips-linux-arm": "1.3.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", - "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz", + "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==", "cpu": [ "arm64" ], @@ -1072,13 +1061,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.3" + "@img/sharp-libvips-linux-arm64": "1.3.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", - "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz", + "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==", "cpu": [ "ppc64" ], @@ -1097,13 +1086,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.3" + "@img/sharp-libvips-linux-ppc64": "1.3.4" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", - "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz", + "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==", "cpu": [ "riscv64" ], @@ -1122,13 +1111,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.3" + "@img/sharp-libvips-linux-riscv64": "1.3.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", - "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz", + "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==", "cpu": [ "s390x" ], @@ -1147,13 +1136,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.3" + "@img/sharp-libvips-linux-s390x": "1.3.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", - "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz", + "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==", "cpu": [ "x64" ], @@ -1172,13 +1161,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.3" + "@img/sharp-libvips-linux-x64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", - "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz", + "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==", "cpu": [ "arm64" ], @@ -1197,13 +1186,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", - "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz", + "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==", "cpu": [ "x64" ], @@ -1222,13 +1211,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.3" + "@img/sharp-libvips-linuxmusl-x64": "1.3.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", - "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz", + "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==", "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -1242,16 +1231,16 @@ } }, "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", - "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz", + "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==", "cpu": [ "wasm32" ], "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/sharp-wasm32": "0.35.4" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -1261,9 +1250,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", - "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz", + "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==", "cpu": [ "arm64" ], @@ -1280,9 +1269,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", - "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz", + "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==", "cpu": [ "ia32" ], @@ -1299,9 +1288,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", - "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz", + "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==", "cpu": [ "x64" ], @@ -1411,21 +1400,21 @@ } }, "node_modules/@mermaid-js/parser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-2.0.0.tgz", - "integrity": "sha512-K8BeapFUfrfxbRAUQAG5oBOCwo1+bNWzaVnPxTCutkfrTBn6T/j91FIhqxWJ32SUeQ9T3iy1zcmPZ5ROZEvDrg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-2.0.1.tgz", + "integrity": "sha512-j37dj/h6p6pots1L7pLPPNuABEEu9WP4OYg9pW1g+nYG331j0+3canE9OagtYdytYvdSAMG+2fKU5cxep6LgjA==", "license": "MIT", "dependencies": { - "@chevrotain/types": "~11.1.2" + "@chevrotain/types": "~13.2.0" }, "engines": { "node": ">=22.12.0" } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.1.tgz", - "integrity": "sha512-H2HxLvC3HDNybePJaLdSrU1hhUK5iQw+WvV1b01myFyI7sdVGe1u/IPTE5D9fGCiJDVtgMV/lmFkQXLmQyIFYA==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.1.tgz", + "integrity": "sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==", "license": "MIT", "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", @@ -1483,15 +1472,15 @@ } }, "node_modules/@next/env": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.6.tgz", - "integrity": "sha512-x9Vblze1EbtltQYnNH38xCPWU3TVfBd1eXqA3+w9+BTpedkkdNpAaltXlGQ/nsc1+E0mVTNrtcbX3GoO09zeLQ==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.8.tgz", + "integrity": "sha512-Al9zqHVV7TJv0eFuOU4U7Lvv74PTih4Ch63sk2xCIpSTkE3udFnaOcnzP2lQVymiL7yS9Cj2iClUXlR3EQ5sEw==", "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.6.tgz", - "integrity": "sha512-E/7GEqaUkt8mk/T8v9lAnrhzR06kdq1ZBkC12F8tAMkdIadwNp3H1KqHynDHrpcTlGCUdq/qu6vUL2aYVyYBdw==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.8.tgz", + "integrity": "sha512-2JPRMh2nmQG5CiL7cXGL9AGwnPWJQ//cTtAUCT+w511QHk79SYz3LGv/pc5X643B/WEO0rvu3Yww0hqwt3kgeA==", "cpu": [ "arm64" ], @@ -1505,9 +1494,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.6.tgz", - "integrity": "sha512-yBE893/nDWTlaiBD1p+qgt7NUen4U5R6FXyH0s67Npq1S3E0cVSef1WIXC2xBRgQvwAvJq6DnS6Y6PrY0cy4Ew==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.8.tgz", + "integrity": "sha512-GZtCCOBKJ4leVIT/Th0llWKhD1ca92lzbQiS5R5ON9QkoiFnilFsebDae1JU2a3HWoKMEmEZWGs1AGLavVM72Q==", "cpu": [ "x64" ], @@ -1521,9 +1510,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.6.tgz", - "integrity": "sha512-KJDpjBqBPYlvkivmyrp+Qys6k/7ksbqGQvRVc6ZEGfR+cjQxx+nUkJaWmNZJsmoOrqYNbaXByF8wa0lBwDhB3Q==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.8.tgz", + "integrity": "sha512-O659ygeQYqneJ1fBKMpFxIFqYkYswu8IAS1OCKK/4f3ZgJJm1dRz4fVJZRi/kLLWjnBKnebOePA4WNv+sV1pVA==", "cpu": [ "arm64" ], @@ -1540,9 +1529,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.6.tgz", - "integrity": "sha512-mqNg2K+hvWskSRb/QM+Ix412DvBsuSF0XV+frTSw5vmoucNnIlynFwKYew8D01bfATErMOM7Bujrf0BA5DRKFA==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.8.tgz", + "integrity": "sha512-dSjKSyWpzxoO1d3DIZZcP4XJcNaKeLmxQMFOiYl5vuBRMmweIqnAhty8tAmRsvTss779cK1FtYnDMj40e4TQlg==", "cpu": [ "arm64" ], @@ -1559,9 +1548,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.6.tgz", - "integrity": "sha512-nFncBNGAYouRHjRVaITs9beZRfhX4ssVwpnvPIAbkZVH6LtGoAVlH4bJ8Cnf9SOo9bsXgPFer/GdHtEE3JNOkw==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.8.tgz", + "integrity": "sha512-lbqOuz3RPRcv+o9msNsJw5x4+Y1ZwPTs6vmL6DCf7i0fZfvng/F59wyeDwqHIvV0mK//RBy/jJkZ+nCKsSMXjQ==", "cpu": [ "x64" ], @@ -1578,9 +1567,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.6.tgz", - "integrity": "sha512-5Mf3cHDGR/Iz0ng2Bj3zUR3p5QS9YK3Hn2QiAfavFmyF48zwThAjpFoiTKNIcOHLYS4zEk+gzyJ/9deQ2ZB8yQ==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.8.tgz", + "integrity": "sha512-+316WswI8ScVgZeUd+1KGaXkHhaYQzCjvH/05TZSpJ8zBizb1a4G7DtO7F12jcBIqMOtsz9ji1t48fmKtzqsGA==", "cpu": [ "x64" ], @@ -1597,9 +1586,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.6.tgz", - "integrity": "sha512-0jkJy0C2kbrJWTk4YLa3xk80pVBpx8FCHJym7CnUfDAXe/FWv5qT7SQJbR0KuemyxaEDlEx5WT4VQJoTW+/9Qw==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.8.tgz", + "integrity": "sha512-ji0gd4kMYUxO+1fJBIbiBVRCjzG/lloiyCccnlebvb1ZJ5qXCPZqYg4Jl1DrrixnWNMKylzgpmMWx0yNDYXlzw==", "cpu": [ "arm64" ], @@ -1613,9 +1602,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.6.tgz", - "integrity": "sha512-/YXjI1e5OXcZ7YpxRwgP/1jAV/SBKTzeVKqN2mk7mLpcICsyn3Gl5+dIfDTJp70M0ccMhyMMRso4v6mPDCGepg==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.8.tgz", + "integrity": "sha512-WcTlaKt/TWkh5kUjdJcUmB1XgZ+1c6fz4Y9fDHL73YNSdGaUWjceeWrrlwF0nv19iABYWC4iAq1oX1w4Bn0vfg==", "cpu": [ "x64" ], @@ -1749,9 +1738,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.5.tgz", - "integrity": "sha512-J25QJU+B78T4FhhBsNpLJyVWOi31mwtpcMwywHmOKH65Q9IWGA81gPj+dnwlhU8wktVriYE+tFAaQgrnJRzAZg==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.64.12.tgz", + "integrity": "sha512-Z8lz+5UOiCJLonjeqwJlhUtHA/Sr6R1AidkccQxdWF0nigNzP81aLoU+udgOaGfL5s1uzFXzcux/pCwGAMu0lw==", "cpu": [ "arm" ], @@ -1763,9 +1752,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.5.tgz", - "integrity": "sha512-LDopB3zuZM5Ux9TT2luNEBJW/tYbGU2g1d+VpKk6I+gSKDb+/7sYE6M225gRQt4RbMX6MSwMsVR/phdjVUgRLg==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.64.12.tgz", + "integrity": "sha512-+tKxNa2psFmiTb0KfXlXs4Yj7vkEhzAvZ0DrQ5+0gWHQJM10jSleQ3l1FIVm5uvD53YM8lHfM4mgCLDDN9f1Gg==", "cpu": [ "arm64" ], @@ -1777,9 +1766,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.5.tgz", - "integrity": "sha512-wlJEERGfeuHeBavCL2qVnNacOK43NDoZM4sjkeRPymd04OAE9T1zBqDJgmZ+CIsPTYKwdzpUC8vmOw84dwY4Tg==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.64.12.tgz", + "integrity": "sha512-iiripdfvyRBugV55/Dk7GplNXQtN/PG85OcKeveU1z2UkTg0MofbBF1qk//qgPWiqJbVvQcXAVCfE56oDGO4EQ==", "cpu": [ "arm64" ], @@ -1791,9 +1780,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.5.tgz", - "integrity": "sha512-4nJJGg5jbo2wwPP4JP+LfEBA3bvP8rU9CLuhp7jWvq9sxEyhjQFTFdrqi+/dHEin/pd8jpT0vcehIpnZtmEdcQ==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.64.12.tgz", + "integrity": "sha512-BmATib8swSMAagWNIfDZMnb+k34RXR4bbGOUfZgK8lLlniuMyVoSDDXCOGkdhtUmBXL4aygDh7bhjQ+TmhTvIw==", "cpu": [ "x64" ], @@ -1805,9 +1794,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.5.tgz", - "integrity": "sha512-DrZbyCDF1hneuO6jRbvZ2D7+PIBM6yIwYnJpg2vIk58T+wuFpiaGZrfUr59lDWw45bg+IrpTGLPiNi/Fk4w3Cg==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.64.12.tgz", + "integrity": "sha512-GzrO0CiUq8vcAI/hYJuIcp6wNm3T3YhOpumYtf9Z3Fz+cfN1VESCVfy7EPcM3/m2K8l+Gn2U+4XtNZjwhUXctQ==", "cpu": [ "arm64" ], @@ -1819,9 +1808,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.5.tgz", - "integrity": "sha512-gqfUVMJMB3mehqywxp6hTBFfgtMQykZY19+cfiaYP0toIJLb/1DZRJHVkQQGP13W4TAwfZDWeg1qBcheTRioXQ==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.64.12.tgz", + "integrity": "sha512-Dpta6gigm4o6SYioXtTkZBlGLA/Sl6OpzgLqY+51uafJE2blPejAtR1w82CVLPN+F9cvo1+/em92x/zcOgY0uQ==", "cpu": [ "x64" ], @@ -1833,9 +1822,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.5.tgz", - "integrity": "sha512-CFmhpvAwzSaWMlN3VN7UtmoTihlZNzoP0juQib5TQRnYUyDV8dXeWOp29sobWAT6gXl/hQgAClLlEiYozQG3OQ==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.64.12.tgz", + "integrity": "sha512-YpeDwQ5uFaogRvytNC8RK0keDO65kI5wNEhGSs+4GiJc3KHhxj4j5cnQh2nCu9ybJj6RP0/ycB6bkN0yFJ9I+w==", "cpu": [ "arm" ], @@ -1850,9 +1839,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.5.tgz", - "integrity": "sha512-Uc9H8eXCOayV6JLTH5bXKMId6qbhNHa818/BgYjm4jrlq3vZquC9cqyvHBw17xy5Mnj5f+I3gFK5JcEf3hSqrw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.64.12.tgz", + "integrity": "sha512-LQrB3/sImIr1ycrlEyaApOLH1rAy8JV4/dH4eoK817aWATdcs4fESXz53/w72NwDnwPM5zEUpoL7socH4ZDnwA==", "cpu": [ "arm" ], @@ -1867,9 +1856,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.5.tgz", - "integrity": "sha512-VcPr/szv/1BFw112Kt//fxulXt/JPqzzidU84iW68L2DdjnOO8QFUv2zTSYBEPHD6movBD4z+bbr5y60GYM7Jw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.64.12.tgz", + "integrity": "sha512-iAF2iYu9S4SBfNsb4k0ewNBjO83WxHEltIuKQBGMzEKFgrYfmJn+gatBDXR2t/0zJN0UW0kzR4rfvQ1UHzkZ1A==", "cpu": [ "arm64" ], @@ -1884,9 +1873,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.5.tgz", - "integrity": "sha512-BnxtJ5/91BrIHYIkGrmjz/lbMhqEHt1dPFqIxIFR+jPn0xVc/oUSCtIT089zfp5ufwGDlYz2UC+Fe1SRBpYFbQ==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.64.12.tgz", + "integrity": "sha512-0MQdRtdbirJCXPIVeW/hd/LXLR8Qz96pc+2EBptuuV5q/zSGOzND7SZt8gBTE58NC9cUG/8UxcUXQiKRZ2WzzA==", "cpu": [ "arm64" ], @@ -1901,9 +1890,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.5.tgz", - "integrity": "sha512-LrYcHZwF+fAMNKHYTOQ5osWM4AZF7YF6D+XtsjDyEvljtt11twc+zHVXBLNEjxVSUnKYsOhvVz4Z213eW02COQ==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.64.12.tgz", + "integrity": "sha512-yGDEwn0AGnrY/KCz2oY8R9KKNiQnTcwNuCWXeSXF0VLxXzlqoCgaS5QHsf1lbQvKWwPuN2Czkjk1wXRCBONTOQ==", "cpu": [ "loong64" ], @@ -1918,9 +1907,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.5.tgz", - "integrity": "sha512-nj7QKQePAAUpCpJHtg0pR0W/b92A9NO17JS3BAQmHDn/yhmkir2p8llrKY9TOhleKIaSzy1JhxS3T9FVld6coA==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.64.12.tgz", + "integrity": "sha512-AjlbD0efZEhHaJ3bsNjxSFDoguNq6VZvC+FKGJGBCA+ZN7BrZq2TuuSWFa6AI8IpOeuvhp2LoYcP7jiZwmtU0Q==", "cpu": [ "loong64" ], @@ -1935,9 +1924,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.5.tgz", - "integrity": "sha512-5ylkX6dWMeBKge9nTU+Rxfb+ZfaCIJ9lRqIFaK0eAMcWp7OJbYnLveLgXmm0VrvuLKb8qIK+mHyH0qu88RM+iA==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.64.12.tgz", + "integrity": "sha512-sDW0CiPoUCEEUV25uBG5sJ2gKe75DJqLpj91m1eK1vKffywyY7v4i6q1450ZuR6QW4NArXg7JpbMGgKU8di3HQ==", "cpu": [ "ppc64" ], @@ -1952,9 +1941,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.5.tgz", - "integrity": "sha512-oHK4ZHYFDKjZviK34I+NwgfbGxgI7ztrNxj2hPTSSNFgeq1a/lEd7dHV2fdGAuTH4Iym3RHJg+vAbWaWG4B7Zg==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.64.12.tgz", + "integrity": "sha512-VTQYUhMjl8kv999VuYqScgv7P9cR9KuxI/6bkUsEa3bsswqG0+otFjuLZmJ1U+ffEP4IAz0jxOeV0DX6NRBhjg==", "cpu": [ "ppc64" ], @@ -1969,9 +1958,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.5.tgz", - "integrity": "sha512-UcetmHZ6XOXuUByiKZyQmb55ZPr0LABr3Ec/HB9wKZn6CEAFWZkE+hsJErJ9hbPBC7nI0dKuELx7CoV6IM7TMg==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.64.12.tgz", + "integrity": "sha512-ppsKwpSjNrzJ8hge3Z3uiCcoRgAAQk2tU7auy3MFF348ffWRldFPnWIT/a/enK7huijlTfnwn4DYpDoapEb45A==", "cpu": [ "riscv64" ], @@ -1986,9 +1975,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.5.tgz", - "integrity": "sha512-C5CmDPQBtvjVo8cgQsBs+w6WB0JLkiixhgi6hVLV11hERWdn/p0XcPU2OUcZzac9BPOFq7SbaHFa8r3SWEysCQ==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.64.12.tgz", + "integrity": "sha512-Gc3cVRC1trFH+GFWWTsJz6YuD4u75fzr/q99jqQGimonN/zvN6Wecck5WGzllOHj+XYXHcq0Ibor0tanGjfI6A==", "cpu": [ "riscv64" ], @@ -2003,9 +1992,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.5.tgz", - "integrity": "sha512-lHVQHJFKsuuxLMi3MQO9XVL8Tje3JR82CzB+QDKC5NWBcsIWuwsn9uIM5e3lBhI+fF1/s63qnyYqsg65+8rV/w==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.64.12.tgz", + "integrity": "sha512-pjmDTFStvwFE3shTeUDvSDiSp8/qAf5bQXejcEUDDavWz4jEhTIpCdpS06G0PEwSCSNK0Lngjz2v9l4hk3Z74A==", "cpu": [ "s390x" ], @@ -2020,9 +2009,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.5.tgz", - "integrity": "sha512-3W9bTFcQNJn71cSJVM9RKIiZOy8DO/XLDii8Uv/Pm6WKqDRj7JV3ZfuXIEfyuy5LXpIzAbB/1M4Ukp9GKNa7nA==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.64.12.tgz", + "integrity": "sha512-mkbjxPqpR91u1JD7xY4aLZhr/Mqka4/RqGcG4WNGgN/lC1o7TzyCyqJoSJXp9qVVxMwpJGFlEF1VlERb+Ghw1Q==", "cpu": [ "x64" ], @@ -2037,9 +2026,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.5.tgz", - "integrity": "sha512-VDC7rRJlee/scpki96GZ27Omf6yU87s1YXwVTpjE5841faVlDYYT565rgfmoR1U0sqL7z5ivQSDjcsF6VRXyBA==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.64.12.tgz", + "integrity": "sha512-vIeut2LkuVc3gcsawLJPahNAzvzBcFRhu2O+yVb//BuQKz7PIItMF0piXRbN/lIDO3d68TSDd368Vg6YwgTybw==", "cpu": [ "x64" ], @@ -2054,9 +2043,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.5.tgz", - "integrity": "sha512-z86Ok2p4pTdv5xqCKZsTooO7yBEiaJR/HzU3Wx8RmWsPoLppnMKROhJusQob8B3IE1ghC343kUW9rC2r+Wf3ig==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.64.12.tgz", + "integrity": "sha512-3Sx+D3r9oPkTdNUcPrIRM2Am+vzEV6VGWoImHG4ZVK2jJeOW+eDjLeTm6nvu/z/m0fiX2YmGLXIypblc336MXg==", "cpu": [ "x64" ], @@ -2068,9 +2057,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.5.tgz", - "integrity": "sha512-IzQmj+xXwQFGhMAMKMQVXkMwMZN3TqkJgAE0nSsqvVwWWciP4AIPMmWRqOQ2GfX7TUDZr+xqGFcBS36CRPGw0g==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.64.12.tgz", + "integrity": "sha512-Nn2xh0teFnl71EiiUrKvECWcdGXtWF8q0uGclYwXGVw6QClGAcME0/bJSGdK+xIvd6MLEKYmjkTUvCBV+7m5Kw==", "cpu": [ "arm64" ], @@ -2082,9 +2071,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.5.tgz", - "integrity": "sha512-F6qpTaPc9bwBH85kjy0/BLmLSW1uv7AoOXCoRIkg2arlgCYlWYcAbiMkvZuAcaWk9TpCRG//okznLAqLGshkMw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.64.12.tgz", + "integrity": "sha512-n1/0H9TS+kBa4xp6n9aV7yiynBNfmerjkj2nAMIfY0ZHv1zShWRXnsAuAPAH0sfEK4ZSMK+z24q2RjAPFLCN1w==", "cpu": [ "arm64" ], @@ -2096,9 +2085,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.5.tgz", - "integrity": "sha512-igoDsTFhhwECBeGbUuLeIk7t8Y1apa+cs6mDWpx2EZ0ch7oEQgzHbFUXN9euoHekCAQzXdXApAGkV6jznS7tWw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.64.12.tgz", + "integrity": "sha512-AdlDbQpsLfGlsHr1NfLZFtdnvxCKNp9TwlYVYExs8JJLWjLafUQEKJk0r9zUbmU57mw9nglMEvzqPHuLWYmaKw==", "cpu": [ "ia32" ], @@ -2110,9 +2099,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.5.tgz", - "integrity": "sha512-U3teMeMbXFmaM5D+OTJpsOXd+wV/qftIeYF9kBKL4v73641qyJmoXFtA28DQLsnmlyayEsTe72xpLHrArq6vHw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.64.12.tgz", + "integrity": "sha512-u5SSUJBHod51UamjkigSr+JPre6xMy5vaWTTV2K0SnFG4RuKyYpf66dTSLFKX2cwaldpwyBurXPUCxq8riQMEg==", "cpu": [ "x64" ], @@ -2124,9 +2113,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.5.tgz", - "integrity": "sha512-ypfC34F3RKXvCXBglGqGMsUSMKlgwd1HX9AOAlx9RoZZ6GaI42YHVeKpzg3JG+wpBUJYTG+NNZhqbDWL8tBZkw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.64.12.tgz", + "integrity": "sha512-j5rXD4R/4DM5+V991AA9xOnG2Rwu2g3p5TPgu1Eu7apju0NUrLl+Bn/KpWc6wYJtlXqzwz1r+LNV1JeBU4VGvw==", "cpu": [ "x64" ], @@ -2773,39 +2762,40 @@ } }, "node_modules/@vitest/expect": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", - "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.12.tgz", + "integrity": "sha512-vFlTt+YEu9WBpNjdGayNmlMVzrWPi1+sv853/7t2FU7hpO5gAFBKHzQmkCq5Xjpr+evegF2994LQT3hF3mRlqQ==", "dev": true, "license": "MIT", "dependencies": { + "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", - "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.12.tgz", + "integrity": "sha512-fKShNpKZzupWZuY0z7egydvL0sqW4INEZBEExMBMAa6izlENEVHwoXgdaTCaBZ5fwlr4xf2o1wXC83n9RpO+NA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.7", + "@vitest/spy": "4.1.12", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -2817,42 +2807,42 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", - "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.12.tgz", + "integrity": "sha512-XW9O8+Mxx4VpCtkYdMJLZQQwsVryP9wk7cPKDxtXFfwSak6yRh5+2fep/Y0XF/ElBvJHq8bcYdi6aeuai0opZA==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^2.0.0" + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", - "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.12.tgz", + "integrity": "sha512-NKlVKCr5QnCe8jijdMnmkpHHU+WTqiLFR6G0pHji9uRjXK9xJl1k1nTw6F3pOOj2PDcsDt2GKQMI7wIsaT491w==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.7", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" + "@vitest/utils": "4.1.12", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", - "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.12.tgz", + "integrity": "sha512-ko1y1Qgb/slzQ9mr+b89Cuqud8WG1TKtsPD8r7ZUBdvVOGt85Af2HwCqHujrhwJq95hs/9RM7fcAPg57o1vlzw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.7", - "magic-string": "^0.30.17", + "@vitest/pretty-format": "4.1.12", + "@vitest/utils": "4.1.12", + "magic-string": "^0.30.21", "pathe": "^2.0.3" }, "funding": { @@ -2860,28 +2850,25 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", - "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.12.tgz", + "integrity": "sha512-RGq9x4JNGNTZHEJxvN0oSiJjeSCExm0n2gZKKJZHY9cX5AVA6M7VJILBT3ZJ/tJ/0J9uWT7fETV9/btoi//vSg==", "dev": true, "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", - "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.12.tgz", + "integrity": "sha512-Q3awXrwOfEV+qc3WmO5ONyE0yO7Q1gQ9/oyHxGLZ/pl7N3NO/ZztqQwKLuwMkV+CA1JYSIeO3gkHnRDIo4AVaA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.7", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" + "@vitest/pretty-format": "4.1.12", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -3087,16 +3074,6 @@ "node": ">= 0.8" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -3157,18 +3134,11 @@ } }, "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } @@ -3213,28 +3183,20 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chevrotain": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz", - "integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-13.2.0.tgz", + "integrity": "sha512-GTouk5YzgBxlTPCaDn5q0q2EJKkrYmnPF+HmF8v0Qo4r3iyPG7HJivkN1wthCXZcm3sIcZFpGTRovLPNdJNRCA==", "license": "Apache-2.0", "dependencies": { - "@chevrotain/cst-dts-gen": "11.1.2", - "@chevrotain/gast": "11.1.2", - "@chevrotain/regexp-to-ast": "11.1.2", - "@chevrotain/types": "11.1.2", - "@chevrotain/utils": "11.1.2", - "lodash-es": "4.17.23" + "@chevrotain/cst-dts-gen": "13.2.0", + "@chevrotain/gast": "13.2.0", + "@chevrotain/regexp-to-ast": "13.2.0", + "@chevrotain/types": "13.2.0", + "@chevrotain/utils": "13.2.0" + }, + "engines": { + "node": ">=22.0.0" } }, "node_modules/client-only": { @@ -3294,6 +3256,13 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -3905,16 +3874,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/delaunator": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", @@ -4046,9 +4005,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "dev": true, "license": "MIT" }, @@ -4803,9 +4762,9 @@ } }, "node_modules/hono": { - "version": "4.13.9", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.9.tgz", - "integrity": "sha512-7dMkQmZoC4E6F7AtaQSPhlWAdnBti+j7rreMZl8QB4jFiEhP9TWbGWUMi8WYzBCgmgulxuvLQupKqo+Co6Omyg==", + "version": "4.13.13", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.13.tgz", + "integrity": "sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -5045,28 +5004,28 @@ } }, "node_modules/katex": { - "version": "0.16.47", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", - "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.18.10.tgz", + "integrity": "sha512-/B6p9eY9DX7aHBfpkHdpirDTZ5QH9xTwL9y837PWuzuv41O5jFdqNQwVQEQsimY0/iVNkwBY4+4hMfhQ7d4Dbw==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" ], "license": "MIT", "dependencies": { - "commander": "^8.3.0" + "commander": "^15.0.0" }, "bin": { "katex": "cli.js" } }, "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", "license": "MIT", "engines": { - "node": ">= 12" + "node": ">=22.12.0" } }, "node_modules/khroma": { @@ -5117,13 +5076,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lucide-react": { "version": "0.483.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.483.0.tgz", @@ -5520,17 +5472,17 @@ } }, "node_modules/mermaid": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-12.0.0.tgz", - "integrity": "sha512-/wQXC9iBxoGV8p3erbvaXs9h77VyLDBH6GdayVjj3hEcSQhFU4N1WUhUppotCEqlIxI2pRMwjwBSwTB1MfZBgQ==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-12.2.0.tgz", + "integrity": "sha512-w7nr/SFrLO7BaVTs3dQTvYSV6nYSBj0Yy9DjBhsIJtAcHqRzXSq4Pg32ujHZ/AdWsAMNEvvhbm5dt9E2tOiHzw==", "license": "MIT", "dependencies": { "@braintree/sanitize-url": "^7.1.2", "@iconify/utils": "^3.0.2", - "@mermaid-js/parser": "^2.0.0", + "@mermaid-js/parser": "^2.0.1", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", - "chevrotain": "~11.1.2", + "chevrotain": "~13.2.0", "cytoscape": "^3.34.0", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", @@ -5541,7 +5493,7 @@ "dompurify": "^3.4.12", "elkjs": "^0.9.3", "es-toolkit": "^1.45.1", - "katex": "^0.16.47", + "katex": "^0.18.0", "khroma": "^2.1.0", "marked": "^16.3.0", "roughjs": "^4.6.6", @@ -6368,12 +6320,12 @@ } }, "node_modules/next": { - "version": "16.3.6", - "resolved": "https://registry.npmjs.org/next/-/next-16.3.6.tgz", - "integrity": "sha512-L+otWM/aQbYTx98aZhgEoMb4bZAXx1YVW4UMA/vuCyCoWG5HJyZUili8QAkqzrcC+5///tsz3s0M+SlyB5bLMw==", + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/next/-/next-16.3.8.tgz", + "integrity": "sha512-U7QEZaTini6wKrb8A8hqLLqYQyCetegKjCpJOyxk642vWoMoU1x5PyZCJFvgYgiptA8xc5j/9xYlZFO7w9Sjmw==", "license": "MIT", "dependencies": { - "@next/env": "16.3.6", + "@next/env": "16.3.8", "@swc/helpers": "0.5.23", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", @@ -6387,14 +6339,14 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.3.6", - "@next/swc-darwin-x64": "16.3.6", - "@next/swc-linux-arm64-gnu": "16.3.6", - "@next/swc-linux-arm64-musl": "16.3.6", - "@next/swc-linux-x64-gnu": "16.3.6", - "@next/swc-linux-x64-musl": "16.3.6", - "@next/swc-win32-arm64-msvc": "16.3.6", - "@next/swc-win32-x64-msvc": "16.3.6", + "@next/swc-darwin-arm64": "16.3.8", + "@next/swc-darwin-x64": "16.3.8", + "@next/swc-linux-arm64-gnu": "16.3.8", + "@next/swc-linux-arm64-musl": "16.3.8", + "@next/swc-linux-x64-gnu": "16.3.8", + "@next/swc-linux-x64-musl": "16.3.8", + "@next/swc-win32-arm64-msvc": "16.3.8", + "@next/swc-win32-x64-msvc": "16.3.8", "sharp": "^0.35.4" }, "peerDependencies": { @@ -6463,6 +6415,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -6603,16 +6569,6 @@ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -7111,9 +7067,9 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "4.63.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.5.tgz", - "integrity": "sha512-KRWwmNLlPw5M7HcdYfm15oBv9n9LPtjzpzCIxS/phwqvPyxHSoKX6Y2YU3pxSPfy0CLquVgsx/j/hBi6OvH1Nw==", + "version": "4.64.12", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.64.12.tgz", + "integrity": "sha512-GhAu8ZglZ61VWSX/ZW3K/qkazgURBIQL0/Yy51QsS8DPyebR5Cf/Z2PANJFpTU0aVZ9byJcyqR6xvBbkXhdGYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7128,31 +7084,31 @@ }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@rollup/rollup-android-arm-eabi": "4.63.5", - "@rollup/rollup-android-arm64": "4.63.5", - "@rollup/rollup-darwin-arm64": "4.63.5", - "@rollup/rollup-darwin-x64": "4.63.5", - "@rollup/rollup-freebsd-arm64": "4.63.5", - "@rollup/rollup-freebsd-x64": "4.63.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.63.5", - "@rollup/rollup-linux-arm-musleabihf": "4.63.5", - "@rollup/rollup-linux-arm64-gnu": "4.63.5", - "@rollup/rollup-linux-arm64-musl": "4.63.5", - "@rollup/rollup-linux-loong64-gnu": "4.63.5", - "@rollup/rollup-linux-loong64-musl": "4.63.5", - "@rollup/rollup-linux-ppc64-gnu": "4.63.5", - "@rollup/rollup-linux-ppc64-musl": "4.63.5", - "@rollup/rollup-linux-riscv64-gnu": "4.63.5", - "@rollup/rollup-linux-riscv64-musl": "4.63.5", - "@rollup/rollup-linux-s390x-gnu": "4.63.5", - "@rollup/rollup-linux-x64-gnu": "4.63.5", - "@rollup/rollup-linux-x64-musl": "4.63.5", - "@rollup/rollup-openbsd-x64": "4.63.5", - "@rollup/rollup-openharmony-arm64": "4.63.5", - "@rollup/rollup-win32-arm64-msvc": "4.63.5", - "@rollup/rollup-win32-ia32-msvc": "4.63.5", - "@rollup/rollup-win32-x64-gnu": "4.63.5", - "@rollup/rollup-win32-x64-msvc": "4.63.5", + "@rollup/rollup-android-arm-eabi": "4.64.12", + "@rollup/rollup-android-arm64": "4.64.12", + "@rollup/rollup-darwin-arm64": "4.64.12", + "@rollup/rollup-darwin-x64": "4.64.12", + "@rollup/rollup-freebsd-arm64": "4.64.12", + "@rollup/rollup-freebsd-x64": "4.64.12", + "@rollup/rollup-linux-arm-gnueabihf": "4.64.12", + "@rollup/rollup-linux-arm-musleabihf": "4.64.12", + "@rollup/rollup-linux-arm64-gnu": "4.64.12", + "@rollup/rollup-linux-arm64-musl": "4.64.12", + "@rollup/rollup-linux-loong64-gnu": "4.64.12", + "@rollup/rollup-linux-loong64-musl": "4.64.12", + "@rollup/rollup-linux-ppc64-gnu": "4.64.12", + "@rollup/rollup-linux-ppc64-musl": "4.64.12", + "@rollup/rollup-linux-riscv64-gnu": "4.64.12", + "@rollup/rollup-linux-riscv64-musl": "4.64.12", + "@rollup/rollup-linux-s390x-gnu": "4.64.12", + "@rollup/rollup-linux-x64-gnu": "4.64.12", + "@rollup/rollup-linux-x64-musl": "4.64.12", + "@rollup/rollup-openbsd-x64": "4.64.12", + "@rollup/rollup-openharmony-arm64": "4.64.12", + "@rollup/rollup-win32-arm64-msvc": "4.64.12", + "@rollup/rollup-win32-ia32-msvc": "4.64.12", + "@rollup/rollup-win32-x64-gnu": "4.64.12", + "@rollup/rollup-win32-x64-msvc": "4.64.12", "fsevents": "~2.3.2" } }, @@ -7280,9 +7236,9 @@ "license": "ISC" }, "node_modules/sharp": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", - "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz", + "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -7297,31 +7253,31 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.4", - "@img/sharp-darwin-x64": "0.35.4", - "@img/sharp-freebsd-wasm32": "0.35.4", - "@img/sharp-libvips-darwin-arm64": "1.3.3", - "@img/sharp-libvips-darwin-x64": "1.3.3", - "@img/sharp-libvips-linux-arm": "1.3.3", - "@img/sharp-libvips-linux-arm64": "1.3.3", - "@img/sharp-libvips-linux-ppc64": "1.3.3", - "@img/sharp-libvips-linux-riscv64": "1.3.3", - "@img/sharp-libvips-linux-s390x": "1.3.3", - "@img/sharp-libvips-linux-x64": "1.3.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", - "@img/sharp-libvips-linuxmusl-x64": "1.3.3", - "@img/sharp-linux-arm": "0.35.4", - "@img/sharp-linux-arm64": "0.35.4", - "@img/sharp-linux-ppc64": "0.35.4", - "@img/sharp-linux-riscv64": "0.35.4", - "@img/sharp-linux-s390x": "0.35.4", - "@img/sharp-linux-x64": "0.35.4", - "@img/sharp-linuxmusl-arm64": "0.35.4", - "@img/sharp-linuxmusl-x64": "0.35.4", - "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" + "@img/sharp-darwin-arm64": "0.35.5", + "@img/sharp-darwin-x64": "0.35.5", + "@img/sharp-freebsd-wasm32": "0.35.5", + "@img/sharp-libvips-darwin-arm64": "1.3.4", + "@img/sharp-libvips-darwin-x64": "1.3.4", + "@img/sharp-libvips-linux-arm": "1.3.4", + "@img/sharp-libvips-linux-arm64": "1.3.4", + "@img/sharp-libvips-linux-ppc64": "1.3.4", + "@img/sharp-libvips-linux-riscv64": "1.3.4", + "@img/sharp-libvips-linux-s390x": "1.3.4", + "@img/sharp-libvips-linux-x64": "1.3.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", + "@img/sharp-libvips-linuxmusl-x64": "1.3.4", + "@img/sharp-linux-arm": "0.35.5", + "@img/sharp-linux-arm64": "0.35.5", + "@img/sharp-linux-ppc64": "0.35.5", + "@img/sharp-linux-riscv64": "0.35.5", + "@img/sharp-linux-s390x": "0.35.5", + "@img/sharp-linux-x64": "0.35.5", + "@img/sharp-linuxmusl-arm64": "0.35.5", + "@img/sharp-linuxmusl-x64": "0.35.5", + "@img/sharp-webcontainers-wasm32": "0.35.5", + "@img/sharp-win32-arm64": "0.35.5", + "@img/sharp-win32-ia32": "0.35.5", + "@img/sharp-win32-x64": "0.35.5" }, "peerDependenciesMeta": { "@types/node": { @@ -7461,9 +7417,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -7502,9 +7458,9 @@ } }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "dev": true, "license": "MIT" }, @@ -7531,26 +7487,6 @@ "node": ">=0.10.0" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/style-to-js": { "version": "1.1.21", "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", @@ -7618,11 +7554,13 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.17", @@ -7641,30 +7579,10 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.6.tgz", - "integrity": "sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.2.0.tgz", + "integrity": "sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==", "dev": true, "license": "MIT", "engines": { @@ -8013,9 +7931,9 @@ } }, "node_modules/vite": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", - "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.7.tgz", + "integrity": "sha512-AHEzTORMbi7/7aXp7w7KZ5+DCUdSeLsJz0grY8xHpc9DHdYb0vQu6DqJfm2tOw3gDExNgPgnJTXxM6syYFHaCA==", "dev": true, "license": "MIT", "dependencies": { @@ -8087,89 +8005,80 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vitest": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", - "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.12.tgz", + "integrity": "sha512-5eWdz2yb3ajxWF3C8C4TjkXl7FGm3n2E/VlazALrQHzK7nYMSGFnCZto0bbPNl77AwkOZVLk0YnBAejUu0NiWA==", "dev": true, "license": "MIT", "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.7", - "@vitest/mocker": "3.2.7", - "@vitest/pretty-format": "^3.2.7", - "@vitest/runner": "3.2.7", - "@vitest/snapshot": "3.2.7", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", + "@vitest/expect": "4.1.12", + "@vitest/mocker": "4.1.12", + "@vitest/pretty-format": "4.1.12", + "@vitest/runner": "4.1.12", + "@vitest/snapshot": "4.1.12", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.7", - "@vitest/ui": "3.2.7", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.12", + "@vitest/browser-preview": "4.1.12", + "@vitest/browser-webdriverio": "^4.1.11", + "@vitest/coverage-istanbul": "4.1.12", + "@vitest/coverage-v8": "4.1.12", + "@vitest/ui": "4.1.12", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@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": { @@ -8180,6 +8089,9 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, @@ -8298,7 +8210,7 @@ "@ai-sdk/anthropic": "^4.0.16", "@ai-sdk/google": "^4.0.18", "@ai-sdk/openai": "^4.0.16", - "@modelcontextprotocol/sdk": "^1.29.0", + "@modelcontextprotocol/sdk": "^1.32.1", "@panzoom/panzoom": "^4.6.2", "@scalar/json-magic": "^0.12.19", "@scalar/openapi-parser": "^0.28.10", @@ -8322,7 +8234,7 @@ "mermaid": "^12.0.0", "tsx": "^4.23.1", "typescript": "^5", - "vitest": "^3.2.4" + "vitest": "^4.1.12" }, "engines": { "node": ">=22" @@ -8347,7 +8259,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, @@ -8367,7 +8279,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, @@ -8387,7 +8299,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/package.json b/package.json index 1523b8a..5863b3a 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,11 @@ "js-yaml": "^3.15.1", "next": { "postcss": "8.5.23", - "sharp": "0.35.4" + "sharp": "0.35.5" }, "postcss": "8.5.23", - "sharp": "0.35.4", + "sharp": "0.35.5", + "vite": "^7.3.7", "@modelcontextprotocol/sdk": { "@hono/node-server": "2.0.12" }, diff --git a/packages/framework/ARCHITECTURE.md b/packages/framework/ARCHITECTURE.md index c79ab80..ec1b5b1 100644 --- a/packages/framework/ARCHITECTURE.md +++ b/packages/framework/ARCHITECTURE.md @@ -90,7 +90,9 @@ parsed spec is needed inside the Next.js build itself, e.g. `ApiLink` and the native renderer), `resolveOpenApiSource(openapi, dir?)` (resolves to whichever shape Scalar's own client-side config expects: `{ url }` or `{ content }`), `loadBlogPosts`, `loadBlogPost`, `loadSeries`, `loadChangelogEntries`, -`loadSlugHistory`, `readingTimeMinutes`, `extractHeadings(content)` → +`loadCollection(dir, parse?)` (any `content//*.mdx`, `_` files skipped, +frontmatter typed and validated by an optional `parse` such as a zod schema's +`.parse`; errors name the file), `loadSlugHistory`, `readingTimeMinutes`, `extractHeadings(content)` → `Heading[] = { depth, text, slug }`, `slugify(text)`. --- @@ -560,6 +562,13 @@ used by SearchDialog), `fw-reactions*`, `fw-comments*`, `fw-subscribe*`. Dark theme: scope overrides under `html.dark` (the ThemeToggle toggles `dark` on ``). +`styles.css` = `styles/tokens.css` (variables only) + `styles/base.css` (global +reset: box model, `html`/`body` background and font, media max-width) + the +structural files. `./prose.css` (file: `src/prose.css`) is the subset for host +sites with their own layout and design system: tokens, `prose.css`, +`components.css` and `mermaid.css`, and no `base.css`, so every rule stays inside +`.fw-*` classes and nothing restyles the host's `html`, `body` or bare elements. + --- ## 12. The theme contract diff --git a/packages/framework/README.md b/packages/framework/README.md index 99d8e28..23bd738 100644 --- a/packages/framework/README.md +++ b/packages/framework/README.md @@ -35,6 +35,8 @@ anywhere Next.js runs (Vercel, AWS Amplify, a Node server, a container). **feature-flagged Ask-AI widget** (`./search-dialog`, `./pagefind-highlight`, `./ask-ai`) — see "Search (Pagefind)" below for the required postbuild step. - **Standalone CSS** (`./styles.css`) — no Tailwind required in the host app. + Sites with their own design import `./prose.css` instead: MDX content styles + only, with no global reset. ## Install @@ -76,7 +78,7 @@ Content lives under `content/{docs,blog,changelog}` (override the root with | Export | What | | --- | --- | | `.` | nav model, slug redirects, OpenAPI types/helpers, `FRAMEWORK_VERSION` | -| `./content` | filesystem loaders: `loadDocsConfig`, `loadDocPage`, `loadBlogPosts`, `loadOpenApiSpec`, `extractHeadings` | +| `./content` | filesystem loaders: `loadDocsConfig`, `loadDocPage`, `loadBlogPosts`, `loadCollection`, `loadOpenApiSpec`, `extractHeadings` | | `./nav` | `DocsConfig`, `docTabs`, `listDocPages`, `docNeighbours` | | `./openapi` | `parseOpenApi`, `normalizeOperations`, `operationNavGroups`, `curlExample`, `sampleFromSchema` | | `./mdx` | ``, `remarkMermaid` | @@ -89,6 +91,7 @@ Content lives under `content/{docs,blog,changelog}` (override the root with | `./ask-ai` | `` (feature-flagged AI assistant) | | `./theme-toggle` | `` | | `./styles.css` | base structural CSS + design-token defaults | +| `./prose.css` | MDX content styles only (`.fw-prose` + the component kit), no global reset, for hosts with their own layout | ## Search (Pagefind) @@ -101,7 +104,7 @@ every consuming app needs a postbuild step: { "scripts": { "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind" + "postbuild": "node scripts/pagefind.mjs" }, "devDependencies": { "pagefind": "^1.5.0" @@ -109,10 +112,17 @@ every consuming app needs a postbuild step: } ``` -`.next/server/app` is where Next.js writes fully-rendered static HTML for every -statically-generated route (this works even though these apps are NOT using -`output: 'export'` — they can't, because of the `/api/ask` route handler — as -long as every doc/blog/changelog route is covered by `generateStaticParams`). +`scripts/pagefind.mjs` ships with every template (copy it from +`templates/canopy/scripts/`). It reads the fully-rendered static HTML Next.js +writes for every statically-generated route and indexes each page under its +real, extensionless URL through Pagefind's Node API. That HTML lives in +`.next/server/app/.html` after a plain `next build`, and in +`.next/server/route-cache/APP_PAGE//$/.html` when a deployment +adapter is active (Vercel's, from Next.js 16.3.8), where +`pagefind --site .next/server/app` finds nothing. The script handles both. +This works even though these apps are NOT using `output: 'export'` (they +can't, because of the `/api/ask` route handler), as long as every +doc/blog/changelog route is covered by `generateStaticParams`. Add `public/_pagefind/` to `.gitignore`; the index is a build artifact, not source. `` marks its content region with `data-pagefind-body` so only real article content is indexed, not nav/sidebar/header chrome. diff --git a/packages/framework/package.json b/packages/framework/package.json index 02a550a..02e7021 100644 --- a/packages/framework/package.json +++ b/packages/framework/package.json @@ -34,6 +34,7 @@ "exports": { ".": "./src/index.ts", "./styles.css": "./src/styles.css", + "./prose.css": "./src/prose.css", "./content": "./src/content.ts", "./nav": "./src/nav.ts", "./openapi": "./src/openapi.ts", @@ -90,7 +91,7 @@ "@ai-sdk/anthropic": "^4.0.16", "@ai-sdk/google": "^4.0.18", "@ai-sdk/openai": "^4.0.16", - "@modelcontextprotocol/sdk": "^1.29.0", + "@modelcontextprotocol/sdk": "^1.32.1", "@panzoom/panzoom": "^4.6.2", "@scalar/json-magic": "^0.12.19", "@scalar/openapi-parser": "^0.28.10", @@ -114,6 +115,6 @@ "mermaid": "^12.0.0", "tsx": "^4.23.1", "typescript": "^5", - "vitest": "^3.2.4" + "vitest": "^4.1.12" } } diff --git a/packages/framework/src/content.test.ts b/packages/framework/src/content.test.ts index b8f7d6a..609a89f 100644 --- a/packages/framework/src/content.test.ts +++ b/packages/framework/src/content.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { loadBlogPosts, loadChangelogEntries } from './content'; +import { loadBlogPosts, loadChangelogEntries, loadCollection } from './content'; let tmpRoot: string; let prevContentRoot: string | undefined; @@ -55,3 +55,44 @@ describe('loadChangelogEntries date parsing', () => { expect(entries[0].date).toBe('2026-02-10'); }); }); + +describe('loadCollection', () => { + it('loads a folder of MDX sorted by file name, skipping _ files', () => { + const dir = path.join(tmpRoot, 'podcast', 'episodes'); + writeMdx(dir, 'ep-02-second.mdx', 'title: Second\nnumber: 2'); + writeMdx(dir, 'ep-01-first.mdx', 'title: First\nnumber: 1\ndate: 2026-03-04', 'Show notes.'); + writeMdx(dir, '_example.mdx', 'title: Example\nnumber: 0'); + const entries = loadCollection('podcast/episodes'); + expect(entries.map((e) => e.slug)).toEqual(['ep-01-first', 'ep-02-second']); + expect(entries[0].file).toBe('podcast/episodes/ep-01-first.mdx'); + expect(entries[0].content.trim()).toBe('Show notes.'); + expect(entries[0].readingTime).toBe(1); + // gray-matter hands an unquoted YAML date through as a Date + expect(entries[0].data.date).toBeInstanceOf(Date); + }); + + it('types and validates frontmatter through parse', () => { + const dir = path.join(tmpRoot, 'notes'); + writeMdx(dir, 'a.mdx', 'title: A\ncredits: 3'); + const entries = loadCollection('notes', (data) => { + if (typeof data.credits !== 'number') throw new Error('credits: expected a number'); + return { title: String(data.title), credits: data.credits }; + }); + expect(entries[0].data).toEqual({ title: 'A', credits: 3 }); + }); + + it('names the file when parse throws', () => { + const dir = path.join(tmpRoot, 'notes'); + writeMdx(dir, 'bad.mdx', 'title: Bad\ncredits: three'); + expect(() => + loadCollection('notes', (data) => { + if (typeof data.credits !== 'number') throw new Error('credits: expected a number'); + return data; + }), + ).toThrow('Invalid frontmatter in content/notes/bad.mdx:\ncredits: expected a number'); + }); + + it('returns an empty list for a missing folder', () => { + expect(loadCollection('nope')).toEqual([]); + }); +}); diff --git a/packages/framework/src/content.ts b/packages/framework/src/content.ts index 7a2dbb4..a730a07 100644 --- a/packages/framework/src/content.ts +++ b/packages/framework/src/content.ts @@ -197,6 +197,63 @@ export function loadChangelogEntries(dir = 'changelog', includeDrafts = false): .sort((a, b) => (a.date < b.date ? 1 : -1)); } +// ── collections ───────────────────────────────────────────────────────── + +export type CollectionEntry = { + /** File name without `.mdx`: `episodes/ep-01-intro.mdx` → `ep-01-intro`. */ + slug: string; + /** Path relative to the content root, for error messages: `podcast/episodes/ep-01-intro.mdx`. */ + file: string; + /** Frontmatter, as returned by `parse` (raw gray-matter data when no parser is given). */ + data: T; + content: string; + excerpt: string; + readingTime: number; +}; + +/** + * Load any folder of MDX files: `content//*.mdx`, sorted by file name. + * Files starting with `_` are skipped, so drafts and examples can live next to + * real entries. Pass `parse` to validate and type the frontmatter — for + * example a zod schema's `.parse`. When it throws, the error names the file, + * so a bad field fails the build with a pointer to where it is. + * + * Frontmatter arrives as gray-matter parses it: an unquoted YAML date is a + * `Date` (at UTC midnight), not a string. Schemas such as `z.coerce.date()` + * accept both; note that they turn YAML `null` into 1970, so treat empty + * values as missing first. + */ +export function loadCollection>( + dir: string, + parse?: (data: Record, file: string) => T, +): CollectionEntry[] { + const base = path.join(contentRoot(), dir); + return listMdx(base) + .filter((f) => !f.startsWith('_')) + .flatMap((f) => { + const parsed = readMdx(path.join(base, f)); + if (!parsed) return []; + const file = path.posix.join(dir, f); + let data: T; + try { + data = parse ? parse(parsed.data, file) : (parsed.data as T); + } catch (err) { + const reason = err instanceof Error ? err.message : String(err); + throw new Error(`Invalid frontmatter in content/${file}:\n${reason}`, { cause: err }); + } + return [ + { + slug: f.replace(/\.mdx$/, ''), + file, + data, + content: parsed.content, + excerpt: plainExcerpt(parsed.content), + readingTime: readingTimeMinutes(parsed.content), + }, + ]; + }); +} + // ── docs ────────────────────────────────────────────────────────────────── export function loadDocsConfig(dir = 'docs'): DocsConfig | null { diff --git a/packages/framework/src/prose.css b/packages/framework/src/prose.css new file mode 100644 index 0000000..b4000f2 --- /dev/null +++ b/packages/framework/src/prose.css @@ -0,0 +1,11 @@ +/* @inkform/framework/prose.css — MDX content styles only, for sites that bring + their own layout and design system. Same .fw-prose typography and component + kit (callouts, cards, steps, tabs, subscribe, mermaid) as styles.css, but no + global reset: nothing here touches html, body or bare elements outside + .fw-* classes. Every rule is keyed off the --fw-* tokens, so a host maps its + own palette onto them. */ + +@import './styles/tokens.css'; +@import './styles/prose.css'; +@import './styles/components.css'; +@import './styles/mermaid.css'; diff --git a/packages/framework/src/styles.css b/packages/framework/src/styles.css index ed764db..60cfd97 100644 --- a/packages/framework/src/styles.css +++ b/packages/framework/src/styles.css @@ -6,6 +6,7 @@ `themeInitScript` sets it before paint based on localStorage / system pref). */ @import './styles/tokens.css'; +@import './styles/base.css'; @import './styles/prose.css'; @import './styles/components.css'; @import './styles/layout.css'; diff --git a/packages/framework/src/styles/base.css b/packages/framework/src/styles/base.css new file mode 100644 index 0000000..c893944 --- /dev/null +++ b/packages/framework/src/styles/base.css @@ -0,0 +1,47 @@ +/* base.css — global reset and document styles. Part of styles.css (the full + framework shell); left out of prose.css so a host site keeps its own. */ + +/* ── Global reset + base document styling ────────────────────────────────── + A docs framework owns the page chrome, so it sets the box model and base + document styles. Without `body { margin: 0 }` the browser's default 8px + margin shows as a white border around the shell — `body` resets that + below. But `body`'s own background isn't enough on its own: `html` paints + behind it, and on overscroll/rubber-band bounce (trackpad momentum + scroll, mobile pull-past-the-top) the browser reveals whatever is behind + the document — white, since `html` had no background of its own. That's + the same "white border" bug, just triggered by scroll physics instead of + a stray margin. Both halves of the fix live here. */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + -webkit-text-size-adjust: 100%; + text-size-adjust: 100%; + background: var(--fw-bg); + color-scheme: light dark; +} + +body { + margin: 0; + padding: 0; + min-height: 100dvh; + background: var(--fw-bg); + color: var(--fw-fg); + font-family: var(--fw-font); + font-size: 16px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +/* Media never overflows its container (a common source of horizontal scroll). */ +img, +svg, +video, +canvas { + max-width: 100%; +} diff --git a/packages/framework/src/styles/tokens.css b/packages/framework/src/styles/tokens.css index 75918bb..80c984f 100644 --- a/packages/framework/src/styles/tokens.css +++ b/packages/framework/src/styles/tokens.css @@ -131,48 +131,3 @@ html.dark { --fw-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); --fw-shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.5); } - -/* ── Global reset + base document styling ────────────────────────────────── - A docs framework owns the page chrome, so it sets the box model and base - document styles. Without `body { margin: 0 }` the browser's default 8px - margin shows as a white border around the shell — `body` resets that - below. But `body`'s own background isn't enough on its own: `html` paints - behind it, and on overscroll/rubber-band bounce (trackpad momentum - scroll, mobile pull-past-the-top) the browser reveals whatever is behind - the document — white, since `html` had no background of its own. That's - the same "white border" bug, just triggered by scroll physics instead of - a stray margin. Both halves of the fix live here. */ -*, -*::before, -*::after { - box-sizing: border-box; -} - -html { - -webkit-text-size-adjust: 100%; - text-size-adjust: 100%; - background: var(--fw-bg); - color-scheme: light dark; -} - -body { - margin: 0; - padding: 0; - min-height: 100dvh; - background: var(--fw-bg); - color: var(--fw-fg); - font-family: var(--fw-font); - font-size: 16px; - line-height: 1.5; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-rendering: optimizeLegibility; -} - -/* Media never overflows its container (a common source of horizontal scroll). */ -img, -svg, -video, -canvas { - max-width: 100%; -} diff --git a/templates/canopy/next.config.ts b/templates/canopy/next.config.ts index 02714a1..6a2b367 100644 --- a/templates/canopy/next.config.ts +++ b/templates/canopy/next.config.ts @@ -3,12 +3,12 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { transpilePackages: ['@inkform/framework'], images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] }, - // Pagefind indexes .next/server/app's built .html files directly, so its - // search results carry a trailing .html this app doesn't actually serve - // (e.g. /essentials/markdown.html) — this app's real routes are - // extensionless. Redirect (not rewrite) so the address bar ends up on the - // real, shareable permalink; query params (?q=... for highlighting) are - // preserved automatically. + // Search indexes built with `pagefind --site .next/server/app` linked to + // each page's .html file (e.g. /essentials/markdown.html), which this app + // doesn't serve — its real routes are extensionless. scripts/pagefind.mjs + // now indexes the real URLs; this redirect keeps old links working. + // Redirect (not rewrite) so the address bar ends up on the real, shareable + // permalink; query params (?q=... for highlighting) are preserved. async redirects() { return [{ source: '/:path*.html', destination: '/:path*', permanent: false }]; }, diff --git a/templates/canopy/package.json b/templates/canopy/package.json index 9ba1ad9..d3c56e0 100644 --- a/templates/canopy/package.json +++ b/templates/canopy/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "next dev", "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "postbuild": "node scripts/pagefind.mjs", "start": "next start", "typecheck": "tsc --noEmit" }, @@ -15,7 +15,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/templates/canopy/scripts/pagefind.mjs b/templates/canopy/scripts/pagefind.mjs new file mode 100644 index 0000000..14b4737 --- /dev/null +++ b/templates/canopy/scripts/pagefind.mjs @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Postbuild: builds the Pagefind search index from this app's prerendered HTML. + * + * A plain `next build` writes static pages to .next/server/app/.html. + * Built with a deployment adapter (Vercel uses one, and from Next.js 16.3.8 it + * changes the layout), the same pages land in + * .next/server/route-cache/APP_PAGE//$/.html instead, and + * `pagefind --site .next/server/app` finds nothing and fails the build. This + * reads both layouts and hands Pagefind each page's real URL (/docs/intro, not + * /docs/intro.html), using Pagefind's Node API. + */ +import { readdir, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import * as pagefind from 'pagefind'; + +const SERVER_DIR = path.join('.next', 'server'); +const OUTPUT_PATH = path.join('public', '_pagefind'); +// Next's own error pages are not search results. +const SKIP = new Set(['/_not-found', '/_global-error']); + +async function htmlFiles(dir) { + let entries; + try { + entries = await readdir(dir, { withFileTypes: true, recursive: true }); + } catch { + return []; + } + return entries + .filter((entry) => entry.isFile() && entry.name.endsWith('.html')) + .map((entry) => path.join(entry.parentPath, entry.name)); +} + +/** "docs/intro.html" → "/docs/intro"; "index.html" → "/". */ +function toUrl(relativeHtmlPath) { + const route = `/${relativeHtmlPath.split(path.sep).join('/').replace(/\.html$/, '')}`; + return route === '/index' ? '/' : route; +} + +const pages = new Map(); + +// Plain build: .next/server/app/.html +const appDir = path.join(SERVER_DIR, 'app'); +for (const file of await htmlFiles(appDir)) { + pages.set(toUrl(path.relative(appDir, file)), file); +} + +// Adapter build: .next/server/route-cache/APP_PAGE//$/.html +const routeCacheDir = path.join(SERVER_DIR, 'route-cache', 'APP_PAGE'); +for (const file of await htmlFiles(routeCacheDir)) { + const [, marker, ...route] = path.relative(routeCacheDir, file).split(path.sep); + if (marker === '$' && route.length) pages.set(toUrl(route.join(path.sep)), file); +} + +for (const url of SKIP) pages.delete(url); + +if (pages.size === 0) { + console.error(`[pagefind] No prerendered HTML found under ${SERVER_DIR}. Run \`next build\` first.`); + process.exit(1); +} + +const fail = (step, errors) => { + console.error(`[pagefind] ${step} failed:\n${errors.join('\n')}`); + process.exit(1); +}; + +const { index, errors: createErrors } = await pagefind.createIndex(); +if (!index) fail('createIndex', createErrors); + +for (const [url, file] of pages) { + const { errors } = await index.addHTMLFile({ url, content: await readFile(file, 'utf8') }); + if (errors.length) fail(`Indexing ${url}`, errors); +} + +const { errors: writeErrors } = await index.writeFiles({ outputPath: OUTPUT_PATH }); +if (writeErrors.length) fail('writeFiles', writeErrors); +await pagefind.close(); + +console.log(`[pagefind] Indexed ${pages.size} pages into ${OUTPUT_PATH}`); diff --git a/templates/galley/next.config.ts b/templates/galley/next.config.ts index 02714a1..6a2b367 100644 --- a/templates/galley/next.config.ts +++ b/templates/galley/next.config.ts @@ -3,12 +3,12 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { transpilePackages: ['@inkform/framework'], images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] }, - // Pagefind indexes .next/server/app's built .html files directly, so its - // search results carry a trailing .html this app doesn't actually serve - // (e.g. /essentials/markdown.html) — this app's real routes are - // extensionless. Redirect (not rewrite) so the address bar ends up on the - // real, shareable permalink; query params (?q=... for highlighting) are - // preserved automatically. + // Search indexes built with `pagefind --site .next/server/app` linked to + // each page's .html file (e.g. /essentials/markdown.html), which this app + // doesn't serve — its real routes are extensionless. scripts/pagefind.mjs + // now indexes the real URLs; this redirect keeps old links working. + // Redirect (not rewrite) so the address bar ends up on the real, shareable + // permalink; query params (?q=... for highlighting) are preserved. async redirects() { return [{ source: '/:path*.html', destination: '/:path*', permanent: false }]; }, diff --git a/templates/galley/package.json b/templates/galley/package.json index 35f3a08..22842d1 100644 --- a/templates/galley/package.json +++ b/templates/galley/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "next dev", "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "postbuild": "node scripts/pagefind.mjs", "start": "next start", "typecheck": "tsc --noEmit" }, @@ -15,7 +15,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/templates/galley/scripts/pagefind.mjs b/templates/galley/scripts/pagefind.mjs new file mode 100644 index 0000000..14b4737 --- /dev/null +++ b/templates/galley/scripts/pagefind.mjs @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Postbuild: builds the Pagefind search index from this app's prerendered HTML. + * + * A plain `next build` writes static pages to .next/server/app/.html. + * Built with a deployment adapter (Vercel uses one, and from Next.js 16.3.8 it + * changes the layout), the same pages land in + * .next/server/route-cache/APP_PAGE//$/.html instead, and + * `pagefind --site .next/server/app` finds nothing and fails the build. This + * reads both layouts and hands Pagefind each page's real URL (/docs/intro, not + * /docs/intro.html), using Pagefind's Node API. + */ +import { readdir, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import * as pagefind from 'pagefind'; + +const SERVER_DIR = path.join('.next', 'server'); +const OUTPUT_PATH = path.join('public', '_pagefind'); +// Next's own error pages are not search results. +const SKIP = new Set(['/_not-found', '/_global-error']); + +async function htmlFiles(dir) { + let entries; + try { + entries = await readdir(dir, { withFileTypes: true, recursive: true }); + } catch { + return []; + } + return entries + .filter((entry) => entry.isFile() && entry.name.endsWith('.html')) + .map((entry) => path.join(entry.parentPath, entry.name)); +} + +/** "docs/intro.html" → "/docs/intro"; "index.html" → "/". */ +function toUrl(relativeHtmlPath) { + const route = `/${relativeHtmlPath.split(path.sep).join('/').replace(/\.html$/, '')}`; + return route === '/index' ? '/' : route; +} + +const pages = new Map(); + +// Plain build: .next/server/app/.html +const appDir = path.join(SERVER_DIR, 'app'); +for (const file of await htmlFiles(appDir)) { + pages.set(toUrl(path.relative(appDir, file)), file); +} + +// Adapter build: .next/server/route-cache/APP_PAGE//$/.html +const routeCacheDir = path.join(SERVER_DIR, 'route-cache', 'APP_PAGE'); +for (const file of await htmlFiles(routeCacheDir)) { + const [, marker, ...route] = path.relative(routeCacheDir, file).split(path.sep); + if (marker === '$' && route.length) pages.set(toUrl(route.join(path.sep)), file); +} + +for (const url of SKIP) pages.delete(url); + +if (pages.size === 0) { + console.error(`[pagefind] No prerendered HTML found under ${SERVER_DIR}. Run \`next build\` first.`); + process.exit(1); +} + +const fail = (step, errors) => { + console.error(`[pagefind] ${step} failed:\n${errors.join('\n')}`); + process.exit(1); +}; + +const { index, errors: createErrors } = await pagefind.createIndex(); +if (!index) fail('createIndex', createErrors); + +for (const [url, file] of pages) { + const { errors } = await index.addHTMLFile({ url, content: await readFile(file, 'utf8') }); + if (errors.length) fail(`Indexing ${url}`, errors); +} + +const { errors: writeErrors } = await index.writeFiles({ outputPath: OUTPUT_PATH }); +if (writeErrors.length) fail('writeFiles', writeErrors); +await pagefind.close(); + +console.log(`[pagefind] Indexed ${pages.size} pages into ${OUTPUT_PATH}`); diff --git a/templates/shadcn/next.config.ts b/templates/shadcn/next.config.ts index 02714a1..6a2b367 100644 --- a/templates/shadcn/next.config.ts +++ b/templates/shadcn/next.config.ts @@ -3,12 +3,12 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { transpilePackages: ['@inkform/framework'], images: { remotePatterns: [{ protocol: 'https', hostname: '**' }] }, - // Pagefind indexes .next/server/app's built .html files directly, so its - // search results carry a trailing .html this app doesn't actually serve - // (e.g. /essentials/markdown.html) — this app's real routes are - // extensionless. Redirect (not rewrite) so the address bar ends up on the - // real, shareable permalink; query params (?q=... for highlighting) are - // preserved automatically. + // Search indexes built with `pagefind --site .next/server/app` linked to + // each page's .html file (e.g. /essentials/markdown.html), which this app + // doesn't serve — its real routes are extensionless. scripts/pagefind.mjs + // now indexes the real URLs; this redirect keeps old links working. + // Redirect (not rewrite) so the address bar ends up on the real, shareable + // permalink; query params (?q=... for highlighting) are preserved. async redirects() { return [{ source: '/:path*.html', destination: '/:path*', permanent: false }]; }, diff --git a/templates/shadcn/package.json b/templates/shadcn/package.json index 8da023a..a60f4d6 100644 --- a/templates/shadcn/package.json +++ b/templates/shadcn/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "next dev", "build": "next build", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "postbuild": "node scripts/pagefind.mjs", "start": "next start", "typecheck": "tsc --noEmit" }, @@ -15,7 +15,7 @@ "@inkform/framework": "^0.6.0", "lucide-react": "^0.483.0", "mermaid": "^12.0.0", - "next": "16.3.6", + "next": "16.3.8", "react": "19.2.1", "react-dom": "19.2.1" }, diff --git a/templates/shadcn/scripts/pagefind.mjs b/templates/shadcn/scripts/pagefind.mjs new file mode 100644 index 0000000..14b4737 --- /dev/null +++ b/templates/shadcn/scripts/pagefind.mjs @@ -0,0 +1,79 @@ +#!/usr/bin/env node +/** + * Postbuild: builds the Pagefind search index from this app's prerendered HTML. + * + * A plain `next build` writes static pages to .next/server/app/.html. + * Built with a deployment adapter (Vercel uses one, and from Next.js 16.3.8 it + * changes the layout), the same pages land in + * .next/server/route-cache/APP_PAGE//$/.html instead, and + * `pagefind --site .next/server/app` finds nothing and fails the build. This + * reads both layouts and hands Pagefind each page's real URL (/docs/intro, not + * /docs/intro.html), using Pagefind's Node API. + */ +import { readdir, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import * as pagefind from 'pagefind'; + +const SERVER_DIR = path.join('.next', 'server'); +const OUTPUT_PATH = path.join('public', '_pagefind'); +// Next's own error pages are not search results. +const SKIP = new Set(['/_not-found', '/_global-error']); + +async function htmlFiles(dir) { + let entries; + try { + entries = await readdir(dir, { withFileTypes: true, recursive: true }); + } catch { + return []; + } + return entries + .filter((entry) => entry.isFile() && entry.name.endsWith('.html')) + .map((entry) => path.join(entry.parentPath, entry.name)); +} + +/** "docs/intro.html" → "/docs/intro"; "index.html" → "/". */ +function toUrl(relativeHtmlPath) { + const route = `/${relativeHtmlPath.split(path.sep).join('/').replace(/\.html$/, '')}`; + return route === '/index' ? '/' : route; +} + +const pages = new Map(); + +// Plain build: .next/server/app/.html +const appDir = path.join(SERVER_DIR, 'app'); +for (const file of await htmlFiles(appDir)) { + pages.set(toUrl(path.relative(appDir, file)), file); +} + +// Adapter build: .next/server/route-cache/APP_PAGE//$/.html +const routeCacheDir = path.join(SERVER_DIR, 'route-cache', 'APP_PAGE'); +for (const file of await htmlFiles(routeCacheDir)) { + const [, marker, ...route] = path.relative(routeCacheDir, file).split(path.sep); + if (marker === '$' && route.length) pages.set(toUrl(route.join(path.sep)), file); +} + +for (const url of SKIP) pages.delete(url); + +if (pages.size === 0) { + console.error(`[pagefind] No prerendered HTML found under ${SERVER_DIR}. Run \`next build\` first.`); + process.exit(1); +} + +const fail = (step, errors) => { + console.error(`[pagefind] ${step} failed:\n${errors.join('\n')}`); + process.exit(1); +}; + +const { index, errors: createErrors } = await pagefind.createIndex(); +if (!index) fail('createIndex', createErrors); + +for (const [url, file] of pages) { + const { errors } = await index.addHTMLFile({ url, content: await readFile(file, 'utf8') }); + if (errors.length) fail(`Indexing ${url}`, errors); +} + +const { errors: writeErrors } = await index.writeFiles({ outputPath: OUTPUT_PATH }); +if (writeErrors.length) fail('writeFiles', writeErrors); +await pagefind.close(); + +console.log(`[pagefind] Indexed ${pages.size} pages into ${OUTPUT_PATH}`);