diff --git a/.storybook/main.ts b/.storybook/main.ts index 38b3b201..c4fabf57 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -84,6 +84,43 @@ const datavisLegacySubpathDependencies = [ 'core-js/es/string/replace-all', ] as const; +// CJS-only transitive dependencies (via react-i18next → html-parse-stringify → +// void-elements) that live only in the pnpm virtual store. They must be aliased +// to a resolvable path and force-included so Vite pre-bundles them with proper +// CJS→ESM default-export interop; otherwise `void-elements` is served raw and +// throws "does not provide an export named 'default'". +// +// The shared `pnpmVirtualNodeModulesDir` is computed from `monorepoRoot`, which +// does not match this repo's layout; resolve against the workspace-local pnpm +// store instead. +const workspacePnpmVirtualNodeModulesDir = path.join( + rootNodeModulesDir, + '.pnpm/node_modules', +); + +const pnpmVirtualCjsInteropDependencies = [ + 'react-i18next', + 'html-parse-stringify', + 'void-elements', +] as const; + +const pnpmVirtualCjsInteropAliases = pnpmVirtualCjsInteropDependencies + .filter( + (dependencyName) => + !existsSync(path.join(rootNodeModulesDir, dependencyName)) && + existsSync(path.join(workspacePnpmVirtualNodeModulesDir, dependencyName)), + ) + .map((dependencyName) => ({ + find: new RegExp(`^${escapeRegExp(dependencyName)}(\/.*)?$`), + replacement: `${path.join(workspacePnpmVirtualNodeModulesDir, dependencyName)}$1`, + })); + +const pnpmVirtualCjsInteropIncludes = pnpmVirtualCjsInteropDependencies.filter( + (dependencyName) => + existsSync(path.join(rootNodeModulesDir, dependencyName)) || + existsSync(path.join(workspacePnpmVirtualNodeModulesDir, dependencyName)), +); + function getPackageRootName(dependencyName: string): string { if (dependencyName.startsWith('@')) { return dependencyName.split('/').slice(0, 2).join('/'); @@ -188,6 +225,7 @@ const config: StorybookConfig = { : []), ...localUiAliases, ...buildVirtualStoreAliases(optimizeDepNames), + ...pnpmVirtualCjsInteropAliases, ...esheetSourceAliases, ]; @@ -222,6 +260,12 @@ const config: StorybookConfig = { ...optimizeDepNames, ].filter(isLocalNodeModuleDependency)), ); + config.optimizeDeps.include = Array.from( + new Set([ + ...(config.optimizeDeps.include ?? []), + ...pnpmVirtualCjsInteropIncludes, + ]), + ); config.optimizeDeps.esbuildOptions = { ...config.optimizeDeps.esbuildOptions, jsx: 'automatic', diff --git a/.storybook/manager.ts b/.storybook/manager.ts index 17bc3f81..74b79509 100644 --- a/.storybook/manager.ts +++ b/.storybook/manager.ts @@ -268,6 +268,14 @@ function injectBrandCSS(brandKey: BrandKey, isDark = false) { [role="toolbar"] button[data-active="true"] { color: ${brand.primary} !important; } + + /* Brand-theme switcher reflects the active brand (higher specificity than + the generic muted toolbar-button rule, so it wins in both light/dark). */ + [role="toolbar"] button[aria-label*="brand themes"], + [class*="toolbar"] button[aria-label*="brand themes"], + [class*="bar"] button[aria-label*="brand themes"] { + color: ${brand.primary} !important; + } /* Links */ a[href]:hover { diff --git a/.storybook/preview.css b/.storybook/preview.css index e82d2693..26cb373e 100644 --- a/.storybook/preview.css +++ b/.storybook/preview.css @@ -144,10 +144,33 @@ html, body { [data-theme="dark"] .docblock-argstable code, [data-theme="dark"] .sbdocs code { background-color: var(--mieweb-card, #27272a) !important; - color: var(--mieweb-primary, #3b82f6) !important; + color: var(--mieweb-primary-400, #3b82f6) !important; border-color: var(--mieweb-border, #3f3f46) !important; } +/* ============================================ + PROSE TABLES (Markdown / README) - DARK MODE + ============================================ */ + +/* Markdown-authored tables in docs (e.g. the README rendered on the Overview + page) are plain /
/, NOT .docblock-argstable. Storybook's docs + theme hardcodes a dark cell color (rgb(46,51,56)) that is unreadable on the + dark background, so force the themed foreground + borders here. */ +[data-theme="dark"] .sbdocs-content table th, +[data-theme="dark"] .sbdocs-content table td { + color: var(--mieweb-foreground) !important; + border-color: var(--mieweb-border, #3f3f46) !important; +} + +/* Header row + zebra striping for legibility. */ +[data-theme="dark"] .sbdocs-content table th { + background-color: var(--mieweb-card, #27272a) !important; +} + +[data-theme="dark"] .sbdocs-content table tr:nth-child(even) td { + background-color: var(--mieweb-card, #27272a) !important; +} + /* ============================================ CONTROLS / INPUTS - DARK MODE ============================================ */ @@ -201,7 +224,7 @@ html, body { } [data-theme="dark"] .docblock-argstable button:hover { - background-color: var(--mieweb-accent, #3f3f46) !important; + background-color: var(--mieweb-muted, #3f3f46) !important; } /* ============================================ @@ -233,7 +256,7 @@ html, body { /* Story name labels */ [data-theme="dark"] .sbdocs-a, [data-theme="dark"] .sbdocs a:not(.docs-story a):not(.sb-story a):not(.sb-unstyled a) { - color: var(--mieweb-primary, #3b82f6) !important; + color: var(--mieweb-primary-400, #3b82f6) !important; } /* ============================================ @@ -246,7 +269,7 @@ html, body { } [data-theme="dark"] [class*="IconButton"]:hover { - background-color: var(--mieweb-accent, #3f3f46) !important; + background-color: var(--mieweb-muted, #3f3f46) !important; } /* Show code button */ diff --git a/eslint.config.js b/eslint.config.js index 11f0a092..dea91b12 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -93,6 +93,13 @@ export default [ IntersectionObserver: 'readonly', IntersectionObserverEntry: 'readonly', MutationObserver: 'readonly', + // IndexedDB + indexedDB: 'readonly', + IDBDatabase: 'readonly', + IDBObjectStore: 'readonly', + IDBTransactionMode: 'readonly', + IDBOpenDBRequest: 'readonly', + IDBRequest: 'readonly', // DOM types Element: 'readonly', Document: 'readonly', diff --git a/package.json b/package.json index 24f08d62..3e69566a 100644 --- a/package.json +++ b/package.json @@ -198,10 +198,17 @@ "ag-grid-react": ">=32.0.0", "datavis-ace": "=4.0.0-PRE.2", "js-yaml": ">=4.0.0", - "mermaid": ">=10.0.0", + "katex": ">=0.16.0", + "mermaid": ">=11.0.0", "papaparse": ">=5.0.0", "react": ">=18.0.0", "react-dom": ">=18.0.0", + "react-markdown": ">=9.0.0", + "rehype-highlight": ">=7.0.0", + "rehype-katex": ">=7.0.0", + "rehype-sanitize": ">=6.0.0", + "remark-gfm": ">=4.0.0", + "remark-math": ">=6.0.0", "wavesurfer.js": ">=7.0.0" }, "peerDependenciesMeta": { @@ -235,6 +242,27 @@ "papaparse": { "optional": true }, + "react-markdown": { + "optional": true + }, + "remark-gfm": { + "optional": true + }, + "remark-math": { + "optional": true + }, + "rehype-katex": { + "optional": true + }, + "katex": { + "optional": true + }, + "rehype-sanitize": { + "optional": true + }, + "rehype-highlight": { + "optional": true + }, "react": { "optional": false }, @@ -247,6 +275,7 @@ }, "dependencies": { "@swc/helpers": "^0.5.19", + "@tanstack/react-virtual": "^3.14.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "dompurify": "^3.4.0", @@ -272,6 +301,7 @@ "@kerebron/editor": "0.7.9", "@kerebron/editor-kits": "0.7.9", "@kerebron/wasm": "0.7.9", + "@mieweb/datavis": "=0.0.0-PRE.2", "@monaco-editor/react": "^4.7.0", "@playwright/test": "^1.58.2", "@storybook/addon-a11y": "^10.2.11", @@ -309,21 +339,28 @@ "d3-selection": "^3.0.0", "d3-shape": "^3.2.0", "d3-zoom": "^3.0.0", - "@mieweb/datavis": "=0.0.0-PRE.2", "eslint": "^9.39.3", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-storybook": "^10.2.11", + "fake-indexeddb": "^6.2.5", "js-yaml": "^4.1.1", "jsdom": "^26.1.0", - "mermaid": "^11.12.3", + "katex": "^0.17.0", + "mermaid": "^11.15.0", "papaparse": "^5.5.3", "postcss": "^8.5.10", "prettier": "^3.8.1", "prettier-plugin-tailwindcss": "^0.6.14", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-markdown": "^10.1.0", + "rehype-highlight": "^7.0.2", + "rehype-katex": "^7.0.1", + "rehype-sanitize": "^6.0.0", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0", "sass": "1.100.0", "sortablejs": "^1.15.7", "storybook": "^10.2.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 662dc98a..8c515969 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,9 @@ importers: '@swc/helpers': specifier: ^0.5.19 version: 0.5.19 + '@tanstack/react-virtual': + specifier: ^3.14.2 + version: 3.14.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -169,7 +172,7 @@ importers: version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: ^3.2.6 - version: 3.2.6(vitest@3.2.6(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0)) + version: 3.2.6(vitest@3.2.6(@types/debug@4.1.13)(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0)) ag-grid-community: specifier: ^35.1.0 version: 35.1.0 @@ -227,14 +230,20 @@ importers: eslint-plugin-storybook: specifier: ^10.2.11 version: 10.2.11(eslint@9.39.3(jiti@2.6.1))(storybook@10.2.11(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + fake-indexeddb: + specifier: ^6.2.5 + version: 6.2.5 js-yaml: specifier: ^4.1.1 version: 4.1.1 jsdom: specifier: ^26.1.0 version: 26.1.0 + katex: + specifier: ^0.17.0 + version: 0.17.0 mermaid: - specifier: ^11.12.3 + specifier: ^11.15.0 version: 11.15.0 papaparse: specifier: ^5.5.3 @@ -254,6 +263,24 @@ importers: react-dom: specifier: ^19.2.4 version: 19.2.4(react@19.2.4) + react-markdown: + specifier: ^10.1.0 + version: 10.1.0(@types/react@19.2.14)(react@19.2.4) + rehype-highlight: + specifier: ^7.0.2 + version: 7.0.2 + rehype-katex: + specifier: ^7.0.1 + version: 7.0.1 + rehype-sanitize: + specifier: ^6.0.0 + version: 6.0.0 + remark-gfm: + specifier: ^4.0.1 + version: 4.0.1 + remark-math: + specifier: ^6.0.0 + version: 6.0.0 sass: specifier: 1.100.0 version: 1.100.0 @@ -277,7 +304,7 @@ importers: version: 7.3.5(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.100.0) vitest: specifier: ^3.2.6 - version: 3.2.6(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0) + version: 3.2.6(@types/debug@4.1.13)(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0) wavesurfer.js: specifier: ^7.12.1 version: 7.12.1 @@ -1600,6 +1627,15 @@ packages: '@tailwindcss/postcss@4.2.1': resolution: {integrity: sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==} + '@tanstack/react-virtual@3.14.2': + resolution: {integrity: sha512-IpWnmCLvuymRfeeLNVXIzNEYBFLpd3drVIS91sqV78VTZFyldlChkOocZRCPp1B+Wnk09bcLNme8WaMU/9/9bQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/virtual-core@3.17.0': + resolution: {integrity: sha512-gOxY/hFkPh/XQYhnThBHzkbkX3Ed+z/iushyz+R+JAr213aXxUDgQoTgTdrDpBSRsjFM73P/KfUyWmaF9WHMkQ==} + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -1743,12 +1779,18 @@ packages: '@types/d3@7.4.3': resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/doctrine@0.0.9': resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -1758,6 +1800,9 @@ packages: '@types/google-libphonenumber@7.4.30': resolution: {integrity: sha512-Td1X1ayRxePEm6/jPHUBs2tT6TzW1lrVB6ZX7ViPGellyzO/0xMNi+wx5nH6jEitjznq276VGIqjK5qAju0XVw==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -1773,12 +1818,21 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + '@types/luxon@3.7.1': resolution: {integrity: sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@22.19.11': resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==} @@ -1802,6 +1856,12 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/wait-on@5.3.4': resolution: {integrity: sha512-EBsPjFMrFlMbbUFf9D1Fp+PAB2TwmUn7a3YtHyD9RLuTIk1jDd8SxXVAoez2Ciy+8Jsceo2MYEYZzJ/DvorOKw==} @@ -1872,6 +1932,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} @@ -2221,6 +2282,9 @@ packages: peerDependencies: '@babel/core': ^7.11.0 || ^8.0.0-beta.1 + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2304,6 +2368,9 @@ packages: caniuse-lite@1.0.30001774: resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -2324,6 +2391,18 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + check-error@2.1.3: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} @@ -2388,6 +2467,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -2673,6 +2755,9 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + dedent@1.7.2: resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} peerDependencies: @@ -2738,6 +2823,9 @@ packages: devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diffable-html@4.1.0: resolution: {integrity: sha512-++kyNek+YBLH8cLXS+iTj/Hiy2s5qkRJEJ8kgu/WHbFrVY2vz9xPFUT+fii2zGF0m1CaojDlQJjkfrCt7YWM1g==} @@ -2897,6 +2985,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + eslint-plugin-jsx-a11y@6.10.2: resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} engines: {node: '>=4.0'} @@ -2983,6 +3075,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -3027,6 +3122,13 @@ packages: ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fake-indexeddb@6.2.5: + resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} + engines: {node: '>=18'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -3258,6 +3360,39 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-sanitize@5.0.2: + resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -3276,6 +3411,9 @@ packages: html-parse-stringify@3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + html@1.0.0: resolution: {integrity: sha512-lw/7YsdKiP3kk5PnR1INY17iJuzdAtJewxr14ozKJWbbR97znovZ0mh+WEMZ8rjc3lgTK+ID/htTjuyGKB52Kw==} hasBin: true @@ -3348,6 +3486,9 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -3359,6 +3500,12 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -3394,6 +3541,9 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3423,6 +3573,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -3440,6 +3593,10 @@ packages: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -3775,6 +3932,10 @@ packages: resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} hasBin: true + katex@0.17.0: + resolution: {integrity: sha512-Vdw0ATsQ9V+LuegM/BTwQqV/6cTl5lbGcIrU+BCgLxyf6bo38ybOr372tuSIxir3CN720flu1meYR6XzNMwQnw==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -3928,6 +4089,9 @@ packages: resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} engines: {node: '>= 0.6.0'} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -3935,6 +4099,9 @@ packages: loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lowlight@3.3.0: + resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -3980,6 +4147,9 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked@14.0.0: resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} engines: {node: '>= 18'} @@ -4002,12 +4172,147 @@ packages: mathml2latex@1.1.3: resolution: {integrity: sha512-/ykNcqkOyxl3V2U/avnMMK0BHGASbQZzsLJU6f98BdP96XR6VXcpRarfpRM3Td7hxHomr7JK5XDC4Enzbhy6/g==} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} mermaid@11.15.0: resolution: {integrity: sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -4213,6 +4518,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -4416,6 +4724,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + prosemirror-dev-toolkit@1.1.8: resolution: {integrity: sha512-Qi549XA+DqU5cCkn/xv+M53gy1sQbyOTjiOfiG7Gjq5gm6ZxLilGN04UITWTAYx9kzLBi7Y9RJmvmWB4xiRauA==} @@ -4487,6 +4798,12 @@ packages: react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-markdown@10.1.0: + resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + react@19.2.4: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} @@ -4522,10 +4839,34 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + rehype-highlight@7.0.2: + resolution: {integrity: sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA==} + + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + + rehype-sanitize@6.0.0: + resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==} + release-zalgo@1.0.0: resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} engines: {node: '>=4'} + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -4711,6 +5052,9 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spawn-wrap@2.0.0: resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} engines: {node: '>=8'} @@ -4795,6 +5139,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -4833,6 +5180,12 @@ packages: style-mod@4.1.3: resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + stylis@4.4.0: resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} @@ -4949,6 +5302,12 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} @@ -5047,6 +5406,30 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + unplugin@2.3.11: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} @@ -5079,6 +5462,15 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -5189,6 +5581,9 @@ packages: wavesurfer.js@7.12.1: resolution: {integrity: sha512-NswPjVHxk0Q1F/VMRemCPUzSojjuHHisQrBqQiRXg7MVbe3f5vQ6r0rTTXA/a/neC/4hnOEC4YpXca4LpH0SUg==} + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-tree-sitter@0.26.6: resolution: {integrity: sha512-fSPR7VBW/fZQdUSp/bXTDLT+i/9dwtbnqgEBMzowrM4U3DzeCwDbY3MKo0584uQxID4m/1xpLflrlT/rLIRPew==} @@ -5361,6 +5756,9 @@ packages: use-sync-external-store: optional: true + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@adobe/css-tools@4.4.4': {} @@ -6781,6 +7179,14 @@ snapshots: postcss: 8.5.15 tailwindcss: 4.2.1 + '@tanstack/react-virtual@3.14.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tanstack/virtual-core': 3.17.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@tanstack/virtual-core@3.17.0': {} + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -6965,16 +7371,28 @@ snapshots: '@types/d3-transition': 3.0.9 '@types/d3-zoom': 3.0.8 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} '@types/doctrine@0.0.9': {} + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + '@types/estree@1.0.8': {} '@types/geojson@7946.0.16': {} '@types/google-libphonenumber@7.4.30': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -6989,10 +7407,18 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/katex@0.16.8': {} + '@types/luxon@3.7.1': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} + '@types/ms@2.1.0': {} + '@types/node@22.19.11': dependencies: undici-types: 6.21.0 @@ -7015,6 +7441,10 @@ snapshots: '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + '@types/wait-on@5.3.4': dependencies: '@types/node': 22.19.11 @@ -7182,7 +7612,7 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitest/coverage-v8@3.2.6(vitest@3.2.6(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0))': + '@vitest/coverage-v8@3.2.6(vitest@3.2.6(@types/debug@4.1.13)(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -7197,7 +7627,7 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.2 tinyrainbow: 2.0.0 - vitest: 3.2.6(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0) + vitest: 3.2.6(@types/debug@4.1.13)(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0) transitivePeerDependencies: - supports-color @@ -7501,6 +7931,8 @@ snapshots: babel-plugin-jest-hoist: 30.3.0 babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + bail@2.0.2: {} + balanced-match@1.0.2: {} balanced-match@4.0.4: {} @@ -7579,6 +8011,8 @@ snapshots: caniuse-lite@1.0.30001774: {} + ccount@2.0.1: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -7602,6 +8036,14 @@ snapshots: char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + check-error@2.1.3: {} chokidar@4.0.3: @@ -7666,6 +8108,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} + commander@12.1.0: {} commander@3.0.2: {} @@ -7980,6 +8424,10 @@ snapshots: decimal.js@10.6.0: {} + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + dedent@1.7.2: {} deep-eql@5.0.2: {} @@ -8027,6 +8475,10 @@ snapshots: devalue@5.8.1: {} + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + diffable-html@4.1.0: dependencies: htmlparser2: 3.10.1 @@ -8268,6 +8720,8 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.3(jiti@2.6.1)): dependencies: aria-query: 5.3.2 @@ -8407,6 +8861,8 @@ snapshots: estraverse@5.3.0: {} + estree-util-is-identifier-name@3.0.0: {} + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -8457,6 +8913,10 @@ snapshots: dependencies: type: 2.7.3 + extend@3.0.2: {} + + fake-indexeddb@6.2.5: {} + fast-deep-equal@3.1.3: {} fast-json-stable-stringify@2.1.0: {} @@ -8688,6 +9148,92 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.2.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-sanitize@5.0.2: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.3.0 + unist-util-position: 5.0.0 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + highlight.js@11.11.1: {} homedir-polyfill@1.0.3: @@ -8704,6 +9250,8 @@ snapshots: dependencies: void-elements: 3.1.0 + html-url-attributes@3.0.1: {} + html@1.0.0: dependencies: concat-stream: 1.6.2 @@ -8772,6 +9320,8 @@ snapshots: ini@1.3.8: {} + inline-style-parser@0.2.7: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -8782,6 +9332,13 @@ snapshots: internmap@2.0.3: {} + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -8824,6 +9381,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-decimal@2.0.1: {} + is-docker@3.0.0: {} is-extglob@2.1.1: {} @@ -8848,6 +9407,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -8861,6 +9422,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} is-reference@3.0.3: @@ -9431,6 +9994,10 @@ snapshots: dependencies: commander: 8.3.0 + katex@0.17.0: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -9539,12 +10106,20 @@ snapshots: loglevel@1.9.2: {} + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 loupe@3.2.1: {} + lowlight@3.3.0: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + highlight.js: 11.11.1 + lru-cache@10.4.3: {} lru-cache@11.2.6: {} @@ -9587,6 +10162,8 @@ snapshots: dependencies: tmpl: 1.0.5 + markdown-table@3.0.4: {} + marked@14.0.0: {} marked@16.4.2: {} @@ -9599,6 +10176,171 @@ snapshots: dependencies: domino: 2.1.7 + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + merge-stream@2.0.0: {} mermaid@11.15.0: @@ -9625,6 +10367,207 @@ snapshots: ts-dedent: 2.2.0 uuid: 11.1.1 + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.47 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + mime-db@1.52.0: {} mime-types@2.1.35: @@ -9853,6 +10796,16 @@ snapshots: dependencies: callsites: 3.1.0 + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.29.0 @@ -9977,6 +10930,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + property-information@7.2.0: {} + prosemirror-dev-toolkit@1.1.8(svelte@5.56.3(@typescript-eslint/types@8.56.1)): dependencies: html: 1.0.0 @@ -10063,6 +11018,24 @@ snapshots: react-is@18.3.1: {} + react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.4): + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/react': 19.2.14 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.1 + react: 19.2.4 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + react@19.2.4: {} readable-stream@2.3.8: @@ -10118,10 +11091,76 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + rehype-highlight@7.0.2: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-text: 4.0.2 + lowlight: 3.3.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + rehype-katex@7.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/katex': 0.16.8 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + katex: 0.16.47 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + + rehype-sanitize@6.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-sanitize: 5.0.2 + release-zalgo@1.0.0: dependencies: es6-error: 4.1.1 + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-math@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + require-directory@2.1.1: {} require-main-filename@2.0.0: {} @@ -10336,6 +11375,8 @@ snapshots: source-map@0.7.6: {} + space-separated-tokens@2.0.2: {} + spawn-wrap@2.0.0: dependencies: foreground-child: 2.0.0 @@ -10475,6 +11516,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -10503,6 +11549,14 @@ snapshots: style-mod@4.1.3: {} + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + stylis@4.4.0: {} sucrase@3.35.1: @@ -10623,6 +11677,10 @@ snapshots: tree-kill@1.2.2: {} + trim-lines@3.0.1: {} + + trough@2.2.0: {} + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -10734,6 +11792,49 @@ snapshots: undici-types@6.21.0: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 @@ -10789,6 +11890,21 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + vite-node@3.2.4(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.100.0): dependencies: cac: 6.7.14 @@ -10825,7 +11941,7 @@ snapshots: lightningcss: 1.31.1 sass: 1.100.0 - vitest@3.2.6(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0): + vitest@3.2.6(@types/debug@4.1.13)(@types/node@22.19.11)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(sass@1.100.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.6 @@ -10851,6 +11967,7 @@ snapshots: vite-node: 3.2.4(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.100.0) why-is-node-running: 2.3.0 optionalDependencies: + '@types/debug': 4.1.13 '@types/node': 22.19.11 jsdom: 26.1.0 transitivePeerDependencies: @@ -10908,6 +12025,8 @@ snapshots: wavesurfer.js@7.12.1: {} + web-namespaces@2.0.1: {} + web-tree-sitter@0.26.6: {} webidl-conversions@7.0.0: {} @@ -11084,3 +12203,5 @@ snapshots: '@types/react': 19.2.14 react: 19.2.4 use-sync-external-store: 1.6.0(react@19.2.4) + + zwitch@2.0.4: {} diff --git a/src/components/SuperChat/MAINTAINERS.md b/src/components/SuperChat/MAINTAINERS.md new file mode 100644 index 00000000..6fd07bcb --- /dev/null +++ b/src/components/SuperChat/MAINTAINERS.md @@ -0,0 +1,291 @@ +# SuperChat — Maintainer Notes + +> **Provider notes** — how to *change* the SuperChat module. Consumers should read +> the [README.md](README.md) (getting started + vocabulary) and the Storybook +> autodocs (Product › Feature Modules › SuperChat). The design rationale lives in +> [Mission](#mission), below. General conventions live in +> [CONTRIBUTING.md](../../../CONTRIBUTING.md). This module **composes** the AI +> module — see [../AI/MAINTAINERS.md](../AI/MAINTAINERS.md). + +## What's in here + +| Surface | File | Role | +|---------|------|------| +| `SuperChatInbox` | [SuperChatInbox.tsx](SuperChatInbox.tsx) | Combined surface: composes the list + panel; owns active-conversation selection (drop-in for the original monolithic component) | +| `SuperChat` | [SuperChat.tsx](SuperChat.tsx) | Single-conversation **panel**: header + thread + composer (takes one `conversation`) | +| `SuperChatConversations` | [SuperChatConversations.tsx](SuperChatConversations.tsx) | Conversation **list** (sidebar); controlled/uncontrolled selection | +| shared internals | [parts.tsx](parts.tsx) | Internal-only helpers + presentational pieces (`ParticipantAvatar`, `ReferenceChip`, `MessageRow`, `Composer`, `sidebarItem`) shared by all three components — **not** exported from `index.ts` | +| `createMarkdownRenderer` | [render/createMarkdownRenderer.tsx](render/createMarkdownRenderer.tsx) | Composes render plugins → one `renderTextContent` (Markdown core) | +| render context | [render/renderContext.ts](render/renderContext.ts) | Threads `messageId`/`streaming` into custom nodes (GenUI) | +| code / math / genui / mermaid / image / nitro-table plugins | [plugins/](plugins) | Opt-in rich plugins (subpath entry) | +| types | [types.ts](types.ts) | Participant model + chat-component-compatible data model + plugin/GenUI contracts | + +> **Component split.** The three components share one folder and one import path +> (`@mieweb/ui/components/SuperChat`) and one tsup entry. `SuperChat` owns the +> panel-only state (`renderText` memo, thread scroll effect, `participantById`, +> `orderedThread`); `SuperChatConversations` owns the list-only state (sorting + +> selection); `SuperChatInbox` owns the shared active-conversation coordination +> and renders the other two. Data slots: `superchat-inbox` (inbox root), +> `superchat` (panel root), `superchat-conversations` (list root). + +## Architecture (3 decisions, summarized) + +1. **Native reimplementation** preserving the `chat-component` prop/data-model + shape (`SuperChatConversation` / `SuperChatMessage` with `participantId`, + `channel`, `ref`, `linkBuilder`, callbacks). No bundled React / `tw-` prefix. +2. **Participant model** (`Participant { id, kind, name, color?, … }`) unifies the + AI module's `user`/`assistant` and chat-component's `external`/`internal`/`system`. + The thread is append-only and **ordered by `time`**; concurrent agent replies + interleave and are disambiguated by per-participant `color`/avatar/name. +3. **Pluggable Markdown pipeline** wired through the AI module's + `renderTextContent` seam. **The host owns sanitization** — untrusted output is + run through `rehype-sanitize` with an allow-list extended per plugin. + +## Bundle / entry layout + +- `@mieweb/ui/components/SuperChat` ships the three components (`SuperChatInbox` + / `SuperChat` / `SuperChatConversations`) **+ Markdown core** only + (`react-markdown` + `remark-gfm` + `rehype-sanitize`). +- `@mieweb/ui/components/SuperChat/plugins` ships `code` / `math` / `genui` / + `mermaid` / `image` / `nitro-table`. Each rich dependency (`rehype-highlight`, + `rehype-katex`/`katex`, `mermaid`, `datavis`/`datavis-ace`) is an **optional + peer dependency** — not in the base bundle. tsup entries: + `components/SuperChat/index` and `components/SuperChat/plugins/index`. +- SuperChat is intentionally **not** re-exported from the top-level `src/index.ts` + (same pattern as `datavis` / `ag-grid`) so the main bundle stays light. + +## Render plugin contract (read before adding a plugin) + +A `SuperChatRenderPlugin` contributes `remarkPlugins`, `rehypePlugins`, +`components` (node → React), `widgets` (GenUI), and a `sanitizeSchema` fragment. +The composer: + +- always prepends `remark-gfm`; +- appends `rehype-sanitize` **last** (after highlight/katex) so their classNames + exist to be allow-listed — order matters, don't reshuffle; +- merges each plugin's `sanitizeSchema` (tagNames union, per-tag attribute concat). + +**Gotchas** + +- The base schema broadens `className` on `code`/`pre`/`span`/`div` so `.hljs-*` + syntax tokens survive. If you tighten this you will strip highlight colors. +- The math plugin must allow KaTeX's HTML+MathML tags — see `KATEX_TAGS`. +- Consumers of the math plugin must import `katex/dist/katex.min.css` themselves. + +## GenUI widgets + +- Wire format is a **fenced ```genui JSON block**, not inline. A small rehype + transformer rewrites `
` → ``
+  (payload as a text child) *before* sanitize (the tag is allow-listed), which
+  avoids `pre`/`code` component-override conflicts with the code plugin.
+- Widgets are **host-registered, lazy, schema-validated**. Unknown widget →
+  inert code-block fallback (never arbitrary HTML).
+- Prefetch is split: **component (code)** may load while streaming per policy
+  (`eager`/`visible`/`idle`); **data** validation/prefetch runs only once the
+  payload parses *and* the message has stopped streaming. **Registry policy
+  overrides the wire hint.**
+- Versioning: key the registry by base name; resolve `version` explicitly (do not
+  bake the version into the lookup key).
+
+## Mermaid / image / NITRO-table plugins
+
+- **Mermaid** ([plugins/mermaid.tsx](plugins/mermaid.tsx)) — a rehype transformer
+  rewrites `
` → `` (source as
+  a text child, like GenUI). `mermaid` is **lazy-loaded once** and initialized
+  with `securityLevel: 'strict'`; the rendered SVG is injected via
+  `dangerouslySetInnerHTML`, so it **bypasses `rehype-sanitize`** — strict mode is
+  the trust boundary. Rendering is gated on `streaming` (partial source shows a
+  pending card). Render failure → inert code-block fallback.
+- **Image** ([plugins/image.tsx](plugins/image.tsx)) — overrides the `img` node
+  with a click-to-zoom button that opens Messaging's `LightboxModal`. Because
+  Markdown images live inside a `

`, the lightbox is **portaled to + `document.body`** (don't nest the fixed overlay in the paragraph). `src`/`alt` + are already protocol-restricted by `rehype-sanitize`. +- **NITRO table** ([plugins/nitroTable.tsx](plugins/nitroTable.tsx)) — overrides + the `table` node, parses the GFM table out of the hast `node` into + `{ headers, rows }`, and `React.lazy`-loads the actual grid + ([plugins/nitroTableGrid.tsx](plugins/nitroTableGrid.tsx)) so `datavis` stays + out of the base/test path. Data is handed to `DataVisNitroSource type="http"` + via a short-lived **object-URL** carrying the `{ typeInfo, data }` shape the + engine expects. A `GridErrorBoundary` + `Suspense` **degrades to the themed HTML + table** if the grid can't load. **Note:** the `datavis` submodule must be + checked out (`git submodule update --init`) to render the real grid — without it + the fallback HTML table is shown (the case in CI/dev when the submodule is + absent). + +## Not yet implemented (tracked against the mission) + +- `shiki` upgrade path for the code plugin (currently `rehype-highlight`). + +## Testing + +- Stories: [SuperChat.stories.tsx](SuperChat.stories.tsx) drives the autodocs page + (Markdown core / rich plugins / read-only). +- When adding a plugin, add a story exercising it and confirm sanitized output + still renders. + +--- + +## Mission + +> The design rationale behind SuperChat — the *why* behind the architecture above. +> The module is **implemented**; this section is retained as the entry point for +> maintainers and the record of decisions (including rejected alternatives). + +### Goal + +Bring a first-class **chat UI** into `@mieweb/ui` that: + +1. Supports **multiple participants** — any mix of **multiple AI agents** and + **multiple humans** in one conversation (not just 1 user ↔ 1 assistant). +2. Renders **rich Markdown** message content through a **plugin system**, with + plugins for **math**, **interactive (`genui`) widgets**, **syntax-highlighted + code**, and **tables rendered via NITRO DataVis**. + +It reuses the AI module's extension seam (`renderTextContent` in +[../AI](../AI)) rather than forking the renderer, and aligns with the API contract +shape of the standalone +[`mieweb/chat-component`](https://github.com/mieweb/chat-component) repo. + +### Background: what already existed + +**`@mieweb/ui` AI module ([../AI](../AI)).** `AIChat`, `AIMessageDisplay`, +`AIChatModal`/`FloatingAIChat`, `MCPToolCallDisplay`. Roles: `user` / `assistant`; +content blocks `text` / `tool_use` / `tool_result` / `thinking` / `code`. The +**`renderTextContent` render-prop** is the rich-rendering seam (host owns +sanitization; plain text by default). TypeScript, React 19 peer, Tailwind 4 theme +tokens (`--mieweb-*`), CVA, tree-shakeable. + +**Standalone `mieweb/chat-component` +([repo](https://github.com/mieweb/chat-component)).** JavaScript (not TS), React 19 +**bundled into a self-contained UMD**, **Zustand** store, Tailwind with a `tw-` +prefix + preflight disabled + styles scoped to `.chat-component-root` (drops into +Bootstrap pages without conflicts). Multi-conversation sidebar + thread + compose; +read-only mode; export/import state; `linkBuilder`; callbacks. Data model: +`conversation { id, title, reference_id?, open, unread, lastActivity, thread[] }`; +thread items `type: 'message' | 'ref' | …` with `role: 'external' | 'internal' | +'system'`, `senderId`, `channel` (`portal|sms|voicemail|auto`), `time`, `text`; +`ref` items carry `refType` (`doc|rx|appt`) + `refId` + `title`. **Messages are +plain text today** — that gap is exactly what SuperChat fills. Its `role`/`channel` +model is **healthcare-messaging** oriented while the AI module's is **assistant** +oriented; SuperChat needs a participant model generalizing both. + +### Decision 1 — Native reimplementation + +**Build a native `@mieweb/ui` component that preserves the `chat-component` API +contract shape** — not a git submodule of `mieweb/chat-component`. Reimplement in +`src/components/SuperChat/` (TS, CVA, theme tokens, controlled props, +tree-shakeable), preserving the prop/data-model shape +(conversation/thread/role/channel/`linkBuilder`/callbacks) so existing consumers +migrate with minimal churn. Reuse `AIMessageDisplay` + `renderTextContent` for +message rendering. + +**Why native:** native theme tokens / dark mode / brand switching / a11y / CVA / +shared TS types; one React + one Tailwind (no bundled-React / `tw-`-prefix +duplication); controlled-props model consistent with the rest of `@mieweb/ui` +(host owns state, works with any store); unifies the two role models under one +participant model (Decision 2). The cost is reimplementation — porting the +sidebar, read-only mode, export/import, search — but the standalone repo's +defining traits (self-contained UMD, bundled React, `tw-` prefix, disabled +preflight) exist to be **framework-agnostic embeddable**, the *opposite* of a +tree-shakeable, theme-token-driven library component. + +> **Rejected — submodule (`@mieweb/ui/chat` over `mieweb/chat-component`).** +> Fastest to stand up and a single source of truth, but bundles its own React 19 + +> `tw-` prefix / disabled preflight / `.chat-component-root` scoping (two React + +> two Tailwind configs in one app), can't pick up `--mieweb-*` tokens / dark mode / +> brands without rework, is JavaScript + Zustand-coupled (no shared types, store +> instead of controlled props), and adds submodule friction for a central +> component. + +There is **no requirement** to share a single implementation across the standalone +UMD and `@mieweb/ui`. The rich features (Markdown, math, code, GenUI, NITRO +tables) do **not** need to ship to Bootstrap/non-React embeds — the standalone UMD +stays as-is for that use case, so no shared/headless-core split is needed. + +### Decision 2 — Participant model (multi-agent / multi-human) + +Generalize both role systems into a **participant** concept: +`Participant { id, kind: 'human' | 'agent' | 'system', name, avatar?, color?, +role?, status? }`. Messages reference `participantId` (replacing/augmenting the +binary `user`/`assistant` and `external`/`internal`/`system`). Map existing +models: `assistant`→agent, `user`/`external`→human, `internal`→human (staff), +`system`→system. Backwards compatible: a single-agent chat is just a +2-participant conversation; `AIChat`'s current API keeps working. + +**Turn-taking / routing.** Participants address an agent with an `@`-mention; an +agent's response targets whoever last mentioned it (or a named participant). If +multiple agents respond at once, their messages **interleave in the thread by +timestamp** — no global lock, the thread is append-only and ordered by `time`. +Disambiguate concurrent/interleaved replies with per-participant `color`, avatar, +and name label. Presence/typing, agent-to-agent hand-off, and tool-call +visualization reuse the `MCPToolCall` card chrome. + +### Decision 3 — Markdown + plugin rendering pipeline + +Render message text via a **pluggable Markdown pipeline** wired through +`renderTextContent` (so `AIChat`/`AIMessageDisplay` stay the host, and **the host +owns sanitization** of untrusted model output). Core: `react-markdown` + +`remark-gfm`, with `rehype-sanitize` on untrusted content. Rendering is exposed as +a **plugin registry** so consumers opt into weight: + +| Plugin | Handles | Impl | Notes | +|--------|---------|------|-------| +| **Markdown core** | headings, lists, emphasis, links, blockquote, task lists | `react-markdown` + `remark-gfm` | always on | +| **Math** | `$…$`, `$$…$$`, bracketed `[ a^2 + b^2 = c^2 ]` | `remark-math` + `rehype-katex` (KaTeX) | lazy-load KaTeX | +| **GenUI widgets** | fenced ` ```genui ` JSON blocks | `code` node interceptor → **widget registry** | host-registered, lazy + schema-validated; degrades to a code block | +| **Code** | fenced code blocks | lazy `rehype-highlight` (default); `shiki` upgrade path | `.hljs-*` classes mapped to `--mieweb-*` tokens + copy button | +| **Tables** | GFM tables | **NITRO DataVis** ([../DataVisNITRO/MAINTAINERS.md](../DataVisNITRO/MAINTAINERS.md)) | GFM table → NITRO grid; prefer NITRO over AGGrid | +| **Mermaid** | ` ```mermaid ` fences | lazy `mermaid` | | +| **Images** | inline images | Messaging attachment lightbox | reuse existing lightbox | + +The detailed plugin contract, GenUI wire format/registry, prefetch semantics, and +security model are documented in the implementation sections above +([Render plugin contract](#render-plugin-contract-read-before-adding-a-plugin), +[GenUI widgets](#genui-widgets), +[Mermaid / image / NITRO-table plugins](#mermaid--image--nitro-table-plugins)). +`SuperChat`/`AIChat` accept `renderPlugins?: SuperChatRenderPlugin[]` and compose +them into a single `renderTextContent`. The default export ships only Markdown +core; math/code/genui/NITRO/mermaid are **opt-in** subpath imports to keep the +base bundle light. + +**Security.** Untrusted model/agent output **must** be sanitized +(`rehype-sanitize` allow-list). When composing with `rehype-highlight`, order +matters: allow the highlighter's `className` on `code`/`span` (or highlight after +sanitizing) so token colors survive. GenUI widgets render only **host-registered** +components keyed by name — unknown names fall back to the inert `genui` code block, +never arbitrary HTML/script. Per-widget `schema` validates the payload before it +reaches the component. The host owns the trust boundary, same contract as +`renderTextContent` today. + +### New dependencies (all lazy / opt-in) + +`react-markdown`, `remark-gfm`, `remark-math`, `rehype-katex` (+ `katex`), +`rehype-sanitize`, `rehype-highlight` (default highlighter; `shiki` reserved as an +upgrade path), `mermaid`. NITRO tables reuse the existing `@mieweb/ui/datavis` +entry. None enter the base bundle; each rich plugin is a subpath/lazy import. + +### Resolved decisions + +- **Shared implementation across UMD and `@mieweb/ui`?** No — no Bootstrap/non-React + support for the rich features; the standalone UMD stays as-is, SuperChat is built + natively with a compatible API shape. No headless-core split. *(Decision 1)* +- **Turn-taking for concurrent agents?** `@`-mention addressing; responses target + the last mention; concurrent replies interleave by timestamp with per-participant + visual cues. *(Decision 2)* +- **Highlighter?** `rehype-highlight` by default (lighter, `.hljs-*` classes map to + theme tokens); `shiki` reserved as an upgrade path. *(Decision 3)* +- **GenUI format + prefetch?** Fenced ` ```genui ` JSON blocks; host-registered, + lazy, schema-validated registry; prefetch split into component vs. data with + `eager`/`visible`/`idle` policies (registry overrides wire hint). *(Decision 3)* +- **Fold into the `AI` module, or a new module?** A **new `SuperChat` module** that + composes `AI`. The `AI` module stays a lightweight building-block layer; the chat + UI is heavier and opinionated, so consumers opt in without pulling in chat + dependencies they don't need. + +### Related + +- AI module: [../AI](../AI) · notes: [../AI/MAINTAINERS.md](../AI/MAINTAINERS.md) +- NITRO tables: [../DataVisNITRO/MAINTAINERS.md](../DataVisNITRO/MAINTAINERS.md) +- Provider conventions: [CONTRIBUTING.md](../../../CONTRIBUTING.md) +- Standalone repo: diff --git a/src/components/SuperChat/README.md b/src/components/SuperChat/README.md new file mode 100644 index 00000000..05237198 --- /dev/null +++ b/src/components/SuperChat/README.md @@ -0,0 +1,682 @@ +# SuperChat + +> **Consumer guide** — how to _use_ the SuperChat components in your own +> application. For internals, how to _change_ the module, and the design +> rationale, see [MAINTAINERS.md](MAINTAINERS.md). + +SuperChat is a native, multi-participant chat surface for `@mieweb/ui`: any mix +of **multiple AI agents** and **multiple humans** in a single conversation. +Message text renders through a pluggable Markdown pipeline (code, math, GenUI +widgets, Mermaid, images, NITRO tables). All components are **controlled** — +your application owns conversation state. + +The module ships **three composable components** from one import path: + +| Component | What it is | Use it when | +| ---------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- | +| **`SuperChatInbox`** | The combined surface: conversation list **+** active conversation panel. | You want the full inbox out of the box (drop-in for the original monolithic component). | +| **`SuperChat`** | A single-conversation **panel**: header, message thread, composer. | You manage conversation selection yourself, or only ever show one conversation. | +| **`SuperChatConversations`** | The conversation **list** (sidebar). | You want the switcher on its own, or a custom layout pairing it with `SuperChat`. | + +`SuperChatInbox` is simply `SuperChatConversations` + `SuperChat` composed +together, so anything the inbox does you can rebuild from the two parts. + +- [Install & entry points](#install--entry-points) +- [Quick start](#quick-start) +- [Visual layout & anatomy](#visual-layout--anatomy) +- [Vocabulary](#vocabulary) +- [Props](#props) +- [Rich Markdown plugins](#rich-markdown-plugins) +- [Accessibility](#accessibility) +- [Related chat surfaces](#related-chat-surfaces) — how SuperChat compares to the AI, Messaging, and standalone chat modules + +--- + +## Install & entry points + +SuperChat is **not** re-exported from the top-level package (it keeps the main +bundle light, the same pattern as `datavis` / `ag-grid`). Import the components +from the subpath: + +```ts +// All three components + Markdown core (GFM + sanitization) — base bundle, no rich deps. +import { + SuperChatInbox, + SuperChat, + SuperChatConversations, + createMarkdownRenderer, +} from '@mieweb/ui/components/SuperChat'; + +// Opt-in rich render plugins — each rich dependency is an optional peer dep. +import { + createCodePlugin, + createMathPlugin, + createGenUIPlugin, + createMermaidPlugin, + createImagePlugin, + createNitroTablePlugin, +} from '@mieweb/ui/components/SuperChat/plugins'; +``` + +| Entry | Ships | Notes | +| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `@mieweb/ui/components/SuperChat` | `SuperChatInbox` / `SuperChat` / `SuperChatConversations` + Markdown core (`react-markdown` + `remark-gfm` + `rehype-sanitize`) | Requires the three Markdown-core peers above; no heavy deps. | +| `@mieweb/ui/components/SuperChat/plugins` | `code` / `math` / `genui` / `mermaid` / `image` / `nitro-table` | Each rich dep (`rehype-highlight`, `katex`, `mermaid`, `datavis`) is an **optional peer dependency** — install only what you use. | + +> The **math** plugin renders KaTeX. Consumers must import the stylesheet +> themselves: `import 'katex/dist/katex.min.css';` + +--- + +## Quick start + +### The full inbox (`SuperChatInbox`) + +`SuperChatInbox` is controlled: you pass `conversations` and react to callbacks +by updating your own state. It owns active-conversation selection. + +```tsx +import * as React from 'react'; +import { SuperChatInbox } from '@mieweb/ui/components/SuperChat'; +import type { SuperChatConversation } from '@mieweb/ui/components/SuperChat'; + +const initial: SuperChatConversation[] = [ + { + id: 'c1', + title: 'Patient 4821 — Intake review', + participants: [ + { + id: 'u1', + kind: 'human', + name: 'Dr. Alice Reyes', + role: 'Provider', + color: '#0e7490', + }, + { id: 'a1', kind: 'agent', name: 'Triage Agent', color: '#2563eb' }, + ], + thread: [ + { + id: 'm1', + participantId: 'u1', + text: '@Triage summarize the chief complaint?', + time: '2026-06-07T09:00:00Z', + }, + { + id: 'm2', + participantId: 'a1', + text: '**Chief complaint:** chest tightness on exertion.', + time: '2026-06-07T09:00:30Z', + }, + ], + }, +]; + +export function PatientChat() { + const [conversations, setConversations] = React.useState(initial); + + return ( +

+ { + // The host owns state: append the sent message to the thread. + setConversations((prev) => + prev.map((c) => + c.id === conversation.id + ? { + ...c, + thread: [ + ...c.thread, + { + id: `m-${Date.now()}`, + participantId: 'u1', + text, + time: new Date().toISOString(), + }, + ], + } + : c + ) + ); + // `mentions` holds the ids of any @-addressed participants — route to your agents here. + }} + /> +
+ ); +} +``` + +Give the wrapper an explicit height — the inbox fills its container (`h-full`). + +### A single conversation panel (`SuperChat`) + +When you already know which conversation to show (or manage selection +yourself), render the panel directly. It takes **one** `conversation`: + +```tsx +import { SuperChat } from '@mieweb/ui/components/SuperChat'; + +
+ { + /* … */ + }} + /> +
; +``` + +### A custom layout (`SuperChatConversations` + `SuperChat`) + +Compose the two parts yourself for a bespoke layout — this is exactly what +`SuperChatInbox` does internally: + +```tsx +import * as React from 'react'; +import { + SuperChatConversations, + SuperChat, +} from '@mieweb/ui/components/SuperChat'; + +export function MyInbox({ conversations, currentParticipantId }) { + const [activeId, setActiveId] = React.useState(conversations[0]?.id); + const active = + conversations.find((c) => c.id === activeId) ?? conversations[0]; + + return ( +
+ setActiveId(c.id)} + /> + {active && ( + + )} +
+ ); +} +``` + +--- + +## Visual layout & anatomy + +Every structural region carries a stable `data-slot` attribute (for styling / +test selectors) **and** an ARIA role + accessible name (for assistive tech and +keyboard navigation). The slot names below are the canonical vocabulary — +they map one-to-one to the regions you see on screen. + +`SuperChatInbox` (root `superchat-inbox`) composes the conversations list +(`superchat-conversations`) and the panel (`superchat`): + +```text +┌─ data-slot="superchat-inbox" ─────────────────────────────────────────────────┐ +│ role=group · "Chat: {title}" │ +│ │ +│ ┌─ superchat-conversations ┐ ┌─ data-slot="superchat" ──────────────────────┐ │ +│ │