@ox-content/vite-plugin 2.10.0 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -220,6 +220,210 @@ declare function mergeThemes(...themes: ThemeConfig[]): ThemeConfig;
220
220
  */
221
221
  declare function resolveTheme(config?: ThemeConfig): ResolvedThemeConfig;
222
222
  //#endregion
223
+ //#region src/plugins/github.d.ts
224
+ /**
225
+ * GitHub Plugin - Repository and source code embedding
226
+ *
227
+ * Transforms <GitHub> components into static repository and source code cards
228
+ * by fetching data from GitHub API at build time.
229
+ */
230
+ interface GitHubRepoData {
231
+ name: string;
232
+ full_name: string;
233
+ description: string | null;
234
+ html_url: string;
235
+ stargazers_count: number;
236
+ forks_count: number;
237
+ language: string | null;
238
+ owner: {
239
+ login: string;
240
+ avatar_url: string;
241
+ };
242
+ }
243
+ interface GitHubLineRange {
244
+ start: number;
245
+ end: number;
246
+ }
247
+ interface GitHubSourceRef {
248
+ repo: string;
249
+ ref: string;
250
+ path: string;
251
+ permalink: string;
252
+ lines?: GitHubLineRange;
253
+ }
254
+ interface GitHubSourceData {
255
+ repo: string;
256
+ ref: string;
257
+ path: string;
258
+ permalink: string;
259
+ content: string;
260
+ size: number;
261
+ html_url: string;
262
+ language: string | null;
263
+ }
264
+ interface GitHubOptions {
265
+ /** GitHub API token for higher rate limits. */
266
+ token?: string;
267
+ /** Cache fetched data. Default: true */
268
+ cache?: boolean;
269
+ /** Cache TTL in milliseconds. Default: 3600000 (1 hour) */
270
+ cacheTTL?: number;
271
+ /** Maximum source file size to inline in bytes. Default: 200000 */
272
+ maxSourceBytes?: number;
273
+ /** Maximum source lines to inline when no line range is specified. Default: 120 */
274
+ maxSourceLines?: number;
275
+ }
276
+ declare function parseGitHubLineRange(value: string | undefined): GitHubLineRange | undefined;
277
+ declare function parseGitHubPermalink(value: string): GitHubSourceRef | null;
278
+ /**
279
+ * Fetch repository data from GitHub API.
280
+ */
281
+ declare function fetchRepoData(repo: string, options: Required<GitHubOptions>): Promise<GitHubRepoData | null>;
282
+ /**
283
+ * Fetch source file data from GitHub API.
284
+ */
285
+ declare function fetchGitHubSource(source: GitHubSourceRef, options: Required<GitHubOptions>): Promise<GitHubSourceData | null>;
286
+ /**
287
+ * Collect all GitHub repos from HTML for pre-fetching.
288
+ */
289
+ declare function collectGitHubRepos(html: string): Promise<string[]>;
290
+ /**
291
+ * Collect all GitHub source references from HTML for pre-fetching.
292
+ */
293
+ declare function collectGitHubSources(html: string): Promise<GitHubSourceRef[]>;
294
+ /**
295
+ * Pre-fetch all GitHub repos data.
296
+ */
297
+ declare function prefetchGitHubRepos(repos: string[], options?: GitHubOptions): Promise<Map<string, GitHubRepoData | null>>;
298
+ /**
299
+ * Pre-fetch all GitHub source files.
300
+ */
301
+ declare function prefetchGitHubSources(sources: GitHubSourceRef[], options?: GitHubOptions): Promise<Map<string, GitHubSourceData | null>>;
302
+ /**
303
+ * Transform GitHub components in HTML.
304
+ */
305
+ declare function transformGitHub(html: string, repoDataMap?: Map<string, GitHubRepoData | null>, options?: GitHubOptions): Promise<string>;
306
+ //#endregion
307
+ //#region src/plugins/ogp.d.ts
308
+ /**
309
+ * OGP Card Plugin - Link card embedding
310
+ *
311
+ * Transforms <OgCard> components into static link preview cards
312
+ * by fetching OGP metadata at build time.
313
+ */
314
+ interface OgpData {
315
+ url: string;
316
+ title: string;
317
+ description?: string;
318
+ image?: string;
319
+ siteName?: string;
320
+ favicon?: string;
321
+ }
322
+ interface OgpOptions {
323
+ /** Request timeout in milliseconds. Default: 10000 */
324
+ timeout?: number;
325
+ /** Cache fetched data. Default: true */
326
+ cache?: boolean;
327
+ /** Cache TTL in milliseconds. Default: 3600000 (1 hour) */
328
+ cacheTTL?: number;
329
+ /** User agent for requests */
330
+ userAgent?: string;
331
+ }
332
+ /**
333
+ * Fetch OGP data for a URL.
334
+ */
335
+ declare function fetchOgpData(url: string, options: Required<OgpOptions>): Promise<OgpData | null>;
336
+ /**
337
+ * Collect all OGP URLs from HTML for pre-fetching.
338
+ */
339
+ declare function collectOgpUrls(html: string): Promise<string[]>;
340
+ /**
341
+ * Pre-fetch all OGP data.
342
+ */
343
+ declare function prefetchOgpData(urls: string[], options?: OgpOptions): Promise<Map<string, OgpData | null>>;
344
+ /**
345
+ * Transform OgCard components in HTML.
346
+ */
347
+ declare function transformOgp(html: string, ogpDataMap?: Map<string, OgpData | null>, options?: OgpOptions): Promise<string>;
348
+ //#endregion
349
+ //#region src/plugins/tabs.d.ts
350
+ /**
351
+ * Transform Tabs components in HTML.
352
+ */
353
+ declare function transformTabs(html: string): Promise<string>;
354
+ /**
355
+ * Generate dynamic CSS for :has() based tab switching.
356
+ * This is needed because :has() selectors need unique IDs.
357
+ */
358
+ declare function generateTabsCSS(groupCount: number): string;
359
+ //#endregion
360
+ //#region src/plugins/youtube.d.ts
361
+ /**
362
+ * YouTube Plugin - Privacy-enhanced iframe embedding
363
+ *
364
+ * Transforms <YouTube> components into responsive iframe embeds
365
+ * using youtube-nocookie.com for enhanced privacy.
366
+ */
367
+ interface YouTubeOptions {
368
+ /** Use privacy-enhanced mode (youtube-nocookie.com). Default: true */
369
+ privacyEnhanced?: boolean;
370
+ /** Default aspect ratio. Default: "16/9" */
371
+ aspectRatio?: string;
372
+ /** Allow fullscreen. Default: true */
373
+ allowFullscreen?: boolean;
374
+ /** Lazy load iframe. Default: true */
375
+ lazyLoad?: boolean;
376
+ }
377
+ /**
378
+ * Extract YouTube video ID from various URL formats.
379
+ */
380
+ declare function extractVideoId(input: string): string | null;
381
+ /**
382
+ * Transform YouTube components in HTML.
383
+ */
384
+ declare function transformYouTube(html: string, options?: YouTubeOptions): Promise<string>;
385
+ //#endregion
386
+ //#region src/plugins/mermaid.d.ts
387
+ /**
388
+ * Mermaid Plugin - Native Rust renderer via NAPI
389
+ *
390
+ * Renders mermaid code blocks to SVG using the native Rust renderer
391
+ * via NAPI. Delegates to the NAPI `transformMermaid` function which
392
+ * extracts mermaid code blocks from HTML and renders them using mmdc.
393
+ */
394
+ interface MermaidOptions {
395
+ /** Mermaid theme. Default: "neutral" */
396
+ theme?: "default" | "dark" | "forest" | "neutral" | "base";
397
+ }
398
+ /**
399
+ * Transforms mermaid code blocks in HTML to rendered SVG diagrams.
400
+ * Uses the native Rust NAPI transformMermaid function.
401
+ */
402
+ declare function transformMermaidStatic(html: string, _options?: MermaidOptions): Promise<string>;
403
+ /**
404
+ * @deprecated No longer used. Mermaid rendering is now done at build time via NAPI.
405
+ */
406
+ declare const mermaidClientScript = "";
407
+ //#endregion
408
+ //#region src/plugins/index.d.ts
409
+ /**
410
+ * Transform all plugin components in HTML.
411
+ * Call this during SSG build to process all plugins at once.
412
+ */
413
+ interface TransformAllOptions {
414
+ tabs?: boolean;
415
+ youtube?: boolean;
416
+ github?: boolean | GitHubOptions;
417
+ ogp?: boolean | OgpOptions;
418
+ openGraph?: boolean | OgpOptions;
419
+ mermaid?: boolean;
420
+ githubToken?: string;
421
+ }
422
+ /**
423
+ * Transform all enabled plugins in HTML content.
424
+ */
425
+ declare function transformAllPlugins(html: string, options?: TransformAllOptions): Promise<string>;
426
+ //#endregion
223
427
  //#region src/types.d.ts
224
428
  /**
225
429
  * Hero section action button.
@@ -424,6 +628,11 @@ interface OxContentOptions {
424
628
  * @default '/'
425
629
  */
426
630
  base?: string;
631
+ /**
632
+ * Markdown-like file extensions to process.
633
+ * @default ['.md', '.markdown', '.mdx']
634
+ */
635
+ extensions?: string[];
427
636
  /**
428
637
  * SSG (Static Site Generation) options.
429
638
  * Set to false to disable SSG completely.
@@ -534,6 +743,12 @@ interface OxContentOptions {
534
743
  * @default true
535
744
  */
536
745
  ogViewer?: boolean;
746
+ /**
747
+ * Built-in static embeds rendered during Markdown transformation.
748
+ * Set to `false` to disable all built-in embeds.
749
+ * @default { github: true, openGraph: true }
750
+ */
751
+ embeds?: BuiltinEmbedOptions | false;
537
752
  /**
538
753
  * i18n (internationalization) options.
539
754
  * Set to false to disable i18n.
@@ -548,6 +763,7 @@ interface ResolvedOptions {
548
763
  srcDir: string;
549
764
  outDir: string;
550
765
  base: string;
766
+ extensions: string[];
551
767
  ssg: ResolvedSsgOptions;
552
768
  gfm: boolean;
553
769
  footnotes: boolean;
@@ -568,8 +784,33 @@ interface ResolvedOptions {
568
784
  docs: ResolvedDocsOptions | false;
569
785
  search: ResolvedSearchOptions;
570
786
  ogViewer: boolean;
787
+ embeds: ResolvedBuiltinEmbedOptions;
571
788
  i18n: ResolvedI18nOptions | false;
572
789
  }
790
+ /**
791
+ * Built-in embed configuration.
792
+ */
793
+ interface BuiltinEmbedOptions {
794
+ /**
795
+ * Render `<GitHub repo="owner/name" />` repository cards.
796
+ * Pass an options object to configure fetching.
797
+ * @default true
798
+ */
799
+ github?: boolean | GitHubOptions;
800
+ /**
801
+ * Render `<OgCard url="https://example.com" />` Open Graph link cards.
802
+ * Pass an options object to configure fetching.
803
+ * @default true
804
+ */
805
+ openGraph?: boolean | OgpOptions;
806
+ }
807
+ /**
808
+ * Resolved built-in embed configuration.
809
+ */
810
+ interface ResolvedBuiltinEmbedOptions {
811
+ github: GitHubOptions | false;
812
+ openGraph: OgpOptions | false;
813
+ }
573
814
  /**
574
815
  * Supported line annotation kinds for code blocks.
575
816
  */
@@ -1226,6 +1467,9 @@ declare function generateMarkdown(docs: ExtractedDocs[], options: ResolvedDocsOp
1226
1467
  * Writes generated documentation to the output directory.
1227
1468
  */
1228
1469
  declare function writeDocs(docs: Record<string, string>, outDir: string, extractedDocs?: ExtractedDocs[], options?: ResolvedDocsOptions): Promise<void>;
1470
+ /**
1471
+ * Resolves docs options with defaults.
1472
+ */
1229
1473
  declare function resolveDocsOptions(options: DocsOptions | false | undefined): ResolvedDocsOptions | false;
1230
1474
  //#endregion
1231
1475
  //#region src/lint.d.ts
@@ -1442,7 +1686,7 @@ interface MarkdownLintFileOptions extends MarkdownLintOptions {
1442
1686
  cwd?: string;
1443
1687
  /**
1444
1688
  * Glob patterns for files to lint.
1445
- * @default ['**\/*.md', '**\/*.markdown']
1689
+ * @default ['**\/*.md', '**\/*.markdown', '**\/*.mdx']
1446
1690
  */
1447
1691
  include?: string[];
1448
1692
  /**
@@ -1499,9 +1743,12 @@ declare function lintMarkdownFiles(options?: MarkdownLintFileOptions): Promise<M
1499
1743
  //#endregion
1500
1744
  //#region src/ssg.d.ts
1501
1745
  /**
1502
- * Default HTML template for SSG pages with navigation.
1746
+ * Deprecated compatibility export for consumers that imported the former
1747
+ * TypeScript SSG template. HTML generation is Rust-backed now.
1748
+ *
1749
+ * @deprecated Use `generateHtmlPage`/`buildSsg` instead.
1503
1750
  */
1504
- declare const DEFAULT_HTML_TEMPLATE = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>{{title}}{{#siteName}} - {{siteName}}{{/siteName}}</title>\n {{#description}}<meta name=\"description\" content=\"{{description}}\">{{/description}}\n <!-- Open Graph -->\n <meta property=\"og:type\" content=\"website\">\n <meta property=\"og:title\" content=\"{{title}}{{#siteName}} - {{siteName}}{{/siteName}}\">\n {{#description}}<meta property=\"og:description\" content=\"{{description}}\">{{/description}}\n {{#ogImage}}<meta property=\"og:image\" content=\"{{ogImage}}\">{{/ogImage}}\n <!-- Twitter Card -->\n {{#ogImage}}<meta name=\"twitter:card\" content=\"summary_large_image\">{{/ogImage}}\n {{^ogImage}}<meta name=\"twitter:card\" content=\"summary\">{{/ogImage}}\n <meta name=\"twitter:title\" content=\"{{title}}{{#siteName}} - {{siteName}}{{/siteName}}\">\n {{#description}}<meta name=\"twitter:description\" content=\"{{description}}\">{{/description}}\n {{#ogImage}}<meta name=\"twitter:image\" content=\"{{ogImage}}\">{{/ogImage}}\n <style>\n :root {\n --sidebar-width: 260px;\n --header-height: 60px;\n --max-content-width: 960px;\n --font-sans: 'IBM Plex Sans', 'Avenir Next', 'Segoe UI Variable', 'Segoe UI', sans-serif;\n --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;\n --color-bg: #ffffff;\n --color-bg-alt: #f5f7fb;\n --color-text: #131a30;\n --color-text-muted: #4f607b;\n --color-border: #d2dbea;\n --color-primary: #4f6fae;\n --color-primary-hover: #425f96;\n --color-code-bg: #101a31;\n --color-code-bg-top: #18264a;\n --color-code-text: #edf3ff;\n --color-code-line-highlight: rgba(56, 189, 248, 0.16);\n --color-code-line-warning: rgba(245, 158, 11, 0.18);\n --color-code-line-warning-border: #f59e0b;\n --color-code-line-error: rgba(239, 68, 68, 0.18);\n --color-code-line-error-border: #ef4444;\n --color-code-frame-border: rgba(147, 166, 200, 0.46);\n --surface-noise-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 180 180'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23noise)' opacity='0.062'/%3E%3C/svg%3E\");\n --surface-noise-size: 164px 164px;\n }\n [data-theme=\"dark\"] {\n --color-bg: #060816;\n --color-bg-alt: #0d1528;\n --color-text: #ebf2ff;\n --color-text-muted: #8ea0bf;\n --color-border: #223252;\n --color-primary: #86a4da;\n --color-primary-hover: #a3bbe8;\n --color-code-bg: #0a1020;\n --color-code-bg-top: #0a1020;\n --color-code-text: #e7f0ff;\n --color-code-line-highlight: rgba(14, 165, 233, 0.2);\n --color-code-line-warning: rgba(245, 158, 11, 0.2);\n --color-code-line-warning-border: #f59e0b;\n --color-code-line-error: rgba(239, 68, 68, 0.22);\n --color-code-line-error-border: #f87171;\n --color-code-frame-border: rgba(34, 50, 82, 0.92);\n --surface-noise-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 180 180'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.25' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23noise)' opacity='0.098'/%3E%3C/svg%3E\");\n }\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n --color-bg: #060816;\n --color-bg-alt: #0d1528;\n --color-text: #ebf2ff;\n --color-text-muted: #8ea0bf;\n --color-border: #223252;\n --color-primary: #86a4da;\n --color-primary-hover: #a3bbe8;\n --color-code-bg: #0a1020;\n --color-code-bg-top: #0a1020;\n --color-code-text: #e7f0ff;\n --color-code-line-highlight: rgba(14, 165, 233, 0.2);\n --color-code-line-warning: rgba(245, 158, 11, 0.2);\n --color-code-line-warning-border: #f59e0b;\n --color-code-line-error: rgba(239, 68, 68, 0.22);\n --color-code-line-error-border: #f87171;\n --color-code-frame-border: rgba(34, 50, 82, 0.92);\n --surface-noise-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 180 180'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.25' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23noise)' opacity='0.098'/%3E%3C/svg%3E\");\n }\n }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n html { scroll-behavior: smooth; }\n body {\n font-family: var(--font-sans);\n line-height: 1.7;\n color: var(--color-text);\n background: var(--color-bg);\n background-image: var(--surface-noise-image);\n background-size: var(--surface-noise-size);\n background-repeat: repeat;\n background-blend-mode: soft-light;\n }\n a { color: var(--color-primary); text-decoration: none; }\n a:hover { color: var(--color-primary-hover); text-decoration: underline; }\n\n /* Header */\n .header {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: var(--header-height);\n background: var(--color-bg);\n border-bottom: 1px solid var(--color-border);\n display: flex;\n align-items: center;\n padding: 0 1.5rem;\n z-index: 100;\n }\n .header,\n .sidebar,\n .search-modal,\n .mobile-footer,\n .content .ox-api-entry,\n .content .ox-api-module,\n .content blockquote.ox-callout {\n background-image: var(--surface-noise-image);\n background-size: var(--surface-noise-size);\n background-repeat: repeat;\n background-blend-mode: soft-light;\n }\n .header-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--color-text);\n }\n .header-title:hover { text-decoration: none; }\n .menu-toggle {\n display: none;\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n margin-right: 0.75rem;\n }\n .menu-toggle svg { display: block; }\n .menu-toggle path { stroke: var(--color-text); }\n .header-actions { margin-left: auto; display: flex; align-items: center; gap: 0.5rem; }\n .search-button {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n background: var(--color-bg-alt);\n border: 1px solid var(--color-border);\n border-radius: 4px;\n color: var(--color-text-muted);\n cursor: pointer;\n font-size: 0.875rem;\n transition: border-color 0.15s, color 0.15s;\n }\n .search-button:hover { border-color: var(--color-primary); color: var(--color-text); }\n .search-button svg { width: 16px; height: 16px; }\n .search-button kbd {\n padding: 0.125rem 0.375rem;\n background: var(--color-bg);\n border: 1px solid var(--color-border);\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: 0.75rem;\n }\n @media (max-width: 640px) {\n .search-button span, .search-button kbd { display: none; }\n .search-button { padding: 0.5rem; }\n }\n .search-modal-overlay {\n display: none;\n position: fixed;\n inset: 0;\n z-index: 200;\n background: rgba(0,0,0,0.6);\n justify-content: center;\n padding-top: 10vh;\n }\n .search-modal-overlay.open { display: flex; }\n .search-modal {\n width: 100%;\n max-width: 560px;\n margin: 0 1rem;\n background: var(--color-bg);\n border: 1px solid var(--color-border);\n border-radius: 4px;\n overflow: hidden;\n max-height: 70vh;\n display: flex;\n flex-direction: column;\n }\n .search-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n border-bottom: 1px solid var(--color-border);\n }\n .search-header svg { flex-shrink: 0; color: var(--color-text-muted); }\n .search-input {\n flex: 1;\n background: none;\n border: none;\n outline: none;\n font-size: 1rem;\n color: var(--color-text);\n }\n .search-input::placeholder { color: var(--color-text-muted); }\n .search-close {\n padding: 0.25rem 0.5rem;\n background: var(--color-bg-alt);\n border: 1px solid var(--color-border);\n border-radius: 4px;\n color: var(--color-text-muted);\n font-family: var(--font-mono);\n font-size: 0.75rem;\n cursor: pointer;\n }\n .search-results {\n flex: 1;\n overflow-y: auto;\n padding: 0.5rem;\n }\n .search-result {\n display: block;\n padding: 0.75rem 1rem;\n border-radius: 4px;\n color: var(--color-text);\n text-decoration: none;\n }\n .search-result:hover, .search-result.selected { background: var(--color-bg-alt); text-decoration: none; }\n .search-result-title { font-weight: 600; font-size: 0.875rem; margin-bottom: 0.25rem; }\n .search-result-snippet { font-size: 0.8125rem; color: var(--color-text-muted); }\n .search-empty { padding: 2rem 1rem; text-align: center; color: var(--color-text-muted); }\n .search-footer {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 1rem;\n padding: 0.75rem 1rem;\n border-top: 1px solid var(--color-border);\n background: var(--color-bg-alt);\n font-size: 0.75rem;\n color: var(--color-text-muted);\n }\n .search-footer kbd {\n padding: 0.125rem 0.375rem;\n background: var(--color-bg);\n border: 1px solid var(--color-border);\n border-radius: 4px;\n font-family: var(--font-mono);\n }\n .theme-toggle {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 4px;\n color: var(--color-text-muted);\n transition: background 0.15s, color 0.15s;\n }\n .theme-toggle:hover { background: var(--color-bg-alt); color: var(--color-text); }\n .theme-toggle svg { display: block; width: 20px; height: 20px; }\n .theme-toggle .icon-sun { display: none; }\n .theme-toggle .icon-moon { display: block; }\n [data-theme=\"dark\"] .theme-toggle .icon-sun { display: block; }\n [data-theme=\"dark\"] .theme-toggle .icon-moon { display: none; }\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) .theme-toggle .icon-sun { display: block; }\n :root:not([data-theme=\"light\"]) .theme-toggle .icon-moon { display: none; }\n }\n\n /* Layout */\n .layout {\n display: flex;\n padding-top: var(--header-height);\n min-height: 100vh;\n }\n\n /* Sidebar */\n .sidebar {\n position: fixed;\n top: var(--header-height);\n left: 0;\n bottom: 0;\n width: var(--sidebar-width);\n background: color-mix(in srgb, var(--color-bg-alt) 16%, var(--color-bg));\n border-right: 1px solid color-mix(in srgb, var(--color-border) 48%, transparent);\n overflow-y: auto;\n padding: 1rem 0.875rem 1.5rem;\n }\n .sidebar--entry { display: none; }\n .sidebar nav {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n .nav-section { margin-bottom: 0; }\n .nav-title {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--color-text-muted);\n margin-bottom: 0.4rem;\n padding: 0 0.625rem;\n }\n .nav-list {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n }\n .nav-item { margin: 0; }\n .nav-link {\n display: block;\n padding: 0.45rem 0.625rem;\n border-radius: 0;\n color: color-mix(in srgb, var(--color-text) 92%, var(--color-text-muted));\n font-size: 0.875rem;\n }\n .nav-link:hover {\n background: color-mix(in srgb, var(--color-bg-alt) 58%, transparent);\n color: var(--color-text);\n text-decoration: none;\n }\n .nav-link.active {\n background: color-mix(in srgb, var(--color-bg-alt) 72%, transparent);\n color: var(--color-text);\n font-weight: 600;\n }\n\n /* Main content */\n .main {\n flex: 1;\n margin-left: var(--sidebar-width);\n padding: 2rem;\n min-width: 0;\n overflow-x: hidden;\n }\n .content {\n max-width: var(--max-content-width);\n margin: 0 auto;\n overflow-wrap: break-word;\n word-wrap: break-word;\n word-break: break-word;\n }\n\n /* TOC (right sidebar) */\n .toc {\n position: fixed;\n top: calc(var(--header-height) + 2rem);\n right: 2rem;\n width: 200px;\n font-size: 0.8125rem;\n }\n .toc-title {\n font-weight: 600;\n margin-bottom: 0.75rem;\n color: var(--color-text-muted);\n }\n .toc-list { list-style: none; }\n .toc-item { margin: 0.375rem 0; }\n .toc-link {\n color: var(--color-text-muted);\n display: block;\n padding-left: calc((var(--depth, 1) - 1) * 0.75rem);\n }\n .toc-link:hover { color: var(--color-primary); }\n @media (max-width: 1200px) { .toc { display: none; } }\n\n /* Typography */\n .content h1 { font-size: 2.25rem; margin-bottom: 1rem; line-height: 1.2; }\n .content h2 { font-size: 1.5rem; margin-top: 2.5rem; margin-bottom: 1rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--color-border); }\n .content h3 { font-size: 1.25rem; margin-top: 2rem; margin-bottom: 0.75rem; }\n .content h4 { font-size: 1rem; margin-top: 1.5rem; margin-bottom: 0.5rem; }\n .content p { margin-bottom: 1rem; }\n .content ul, .content ol { margin: 1rem 0; padding-left: 1.5rem; }\n .content li { margin: 0.375rem 0; }\n .content blockquote {\n border-left: 4px solid var(--color-primary);\n padding: 0.5rem 1rem;\n margin: 1rem 0;\n background: var(--color-bg-alt);\n border-radius: 0 4px 4px 0;\n }\n .content blockquote.ox-callout {\n --callout-accent: var(--color-primary);\n border-left-width: 3px;\n border-left-color: var(--callout-accent);\n padding: 0.9rem 1rem;\n border-radius: 4px;\n background: color-mix(in srgb, var(--color-bg-alt) 92%, var(--callout-accent) 8%);\n }\n .content blockquote.ox-callout.ox-callout--note,\n .content blockquote.ox-callout.ox-callout--important { --callout-accent: var(--color-primary); }\n .content blockquote.ox-callout.ox-callout--tip { --callout-accent: #0891b2; }\n .content blockquote.ox-callout.ox-callout--warning { --callout-accent: #d97706; }\n .content blockquote.ox-callout.ox-callout--caution { --callout-accent: #dc2626; }\n .content .ox-callout-title {\n margin: 0 0 0.5rem;\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--callout-accent, var(--color-primary));\n }\n .content blockquote.ox-callout > :last-child { margin-bottom: 0; }\n .content blockquote.ox-callout > :not(.ox-callout-title):first-of-type { margin-top: 0; }\n .content code {\n font-family: var(--font-mono);\n font-size: 0.875em;\n background: var(--color-bg-alt);\n padding: 0.2em 0.4em;\n border-radius: 4px;\n word-break: break-all;\n }\n .content pre {\n background: linear-gradient(\n 180deg,\n var(--color-code-bg-top) 0,\n var(--color-code-bg) 3.5rem\n ) !important;\n color: var(--color-code-text);\n padding: 1rem 1.25rem;\n border-radius: 4px;\n border: 1px solid var(--color-code-frame-border);\n overflow-x: auto;\n margin: 1.5rem 0;\n line-height: 1.5;\n }\n .content pre code {\n background: transparent;\n border: 0;\n padding: 0;\n border-radius: 0;\n font-size: 0.8125rem;\n word-break: normal;\n }\n .content pre.ox-code-block code {\n display: block;\n }\n .content pre.ox-code-block .line {\n display: block;\n margin: 0 -1.25rem;\n padding: 0 1.25rem;\n }\n .content pre.ox-code-block .ox-code-line--highlight {\n background: var(--color-code-line-highlight);\n }\n .content pre.ox-code-block .ox-code-line--warning {\n background: var(--color-code-line-warning);\n border-left: 3px solid var(--color-code-line-warning-border);\n }\n .content pre.ox-code-block .ox-code-line--error {\n background: var(--color-code-line-error);\n border-left: 3px solid var(--color-code-line-error-border);\n }\n .content table {\n width: 100%;\n border-collapse: collapse;\n margin: 1.5rem 0;\n font-size: 0.875rem;\n }\n .content th, .content td {\n border: 1px solid var(--color-border);\n padding: 0.75rem 1rem;\n text-align: left;\n }\n .content th { background: var(--color-bg-alt); font-weight: 600; }\n .content img { max-width: 100%; height: auto; border-radius: 4px; display: block; }\n .content img[alt*=\"Logo\"] { max-width: 200px; display: block; margin: 1rem 0; }\n .content img[alt*=\"Architecture\"] { max-width: 600px; }\n .content img[alt*=\"Benchmark\"] { max-width: 680px; }\n .content hr { border: none; border-top: 1px solid var(--color-border); margin: 2rem 0; }\n .content .ox-api-controls {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 0.5rem;\n margin: 0 0 1rem;\n }\n .content .ox-api-controls__button {\n appearance: none;\n border: 1px solid color-mix(in srgb, var(--color-border) 82%, transparent);\n background: color-mix(in srgb, var(--color-bg-alt) 82%, var(--color-bg));\n padding: 0.4rem 0.7rem;\n border-radius: 4px;\n color: color-mix(in srgb, var(--color-text) 82%, var(--color-text-muted));\n font-family: var(--font-mono);\n font-size: 0.78rem;\n font-weight: 600;\n line-height: 1.4;\n cursor: pointer;\n }\n .content .ox-api-controls__button:hover {\n color: var(--color-primary);\n border-color: color-mix(in srgb, var(--color-primary) 38%, var(--color-border));\n background: color-mix(in srgb, var(--color-bg-alt) 68%, var(--color-primary) 6%);\n }\n .content .ox-api-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));\n gap: 0.55rem;\n margin: 1rem 0 1.35rem;\n }\n .content .ox-api-stat {\n min-width: 0;\n padding: 0.7rem 0.75rem;\n border: 1px solid color-mix(in srgb, var(--color-border) 76%, transparent);\n border-radius: 4px;\n background: color-mix(in srgb, var(--color-bg-alt) 72%, transparent);\n }\n .content .ox-api-stat strong {\n display: block;\n font-family: var(--font-mono);\n font-size: 1rem;\n line-height: 1.2;\n color: var(--color-text);\n }\n .content .ox-api-stat span {\n display: block;\n margin-top: 0.25rem;\n font-family: var(--font-mono);\n font-size: 0.7rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--color-text-muted);\n }\n .content .ox-api-stat--warning {\n border-color: color-mix(in srgb, #f59e0b 42%, var(--color-border));\n background: color-mix(in srgb, var(--color-bg-alt) 78%, #f59e0b 8%);\n }\n .content .ox-api-entry,\n .content .ox-api-module {\n margin: 0;\n border: 0;\n border-top: 1px solid color-mix(in srgb, var(--color-border) 74%, transparent);\n border-radius: 0;\n background: transparent;\n overflow: visible;\n }\n .content .ox-api-entry:last-child,\n .content .ox-api-module:last-child {\n border-bottom: 1px solid color-mix(in srgb, var(--color-border) 74%, transparent);\n }\n .content .ox-api-entry summary,\n .content .ox-api-module summary {\n list-style: none;\n cursor: pointer;\n padding: 1rem 0;\n position: relative;\n }\n .content .ox-api-entry summary::-webkit-details-marker,\n .content .ox-api-module summary::-webkit-details-marker { display: none; }\n .content .ox-api-entry summary {\n display: grid;\n grid-template-columns: var(--octc-api-kind-width, 6.5rem) minmax(0, 1fr) auto;\n align-items: start;\n gap: 0.95rem;\n }\n .content .ox-api-entry summary::after,\n .content .ox-api-module summary::after {\n content: \"+\";\n align-self: center;\n color: var(--color-text-muted);\n font-family: var(--font-mono);\n font-size: 0.95rem;\n font-weight: 600;\n line-height: 1;\n }\n .content .ox-api-entry[open] summary::after,\n .content .ox-api-module[open] summary::after {\n content: \"\u2212\";\n color: var(--color-primary);\n }\n .content .ox-api-entry[open] summary,\n .content .ox-api-module[open] summary {\n border-bottom: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);\n }\n .content .ox-api-entry__kind,\n .content .ox-api-module__kind {\n display: block;\n width: var(--octc-api-kind-width, 6.5rem);\n padding: 0.3rem 0 0;\n background: transparent;\n border: 0;\n font-family: var(--font-mono);\n font-size: 0.76rem;\n font-weight: 600;\n letter-spacing: 0.01em;\n text-align: left;\n white-space: nowrap;\n color: var(--color-text-muted);\n }\n .content .ox-api-module__count {\n display: inline-flex;\n align-items: center;\n padding: 0.2rem 0.48rem;\n border-radius: 4px;\n background: color-mix(in srgb, var(--color-bg-alt) 84%, var(--color-primary) 8%);\n border: 1px solid color-mix(in srgb, var(--color-border) 82%, transparent);\n color: var(--color-text-muted);\n font-family: var(--font-mono);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.03em;\n white-space: nowrap;\n }\n .content .ox-api-entry__name {\n display: block;\n font-family: var(--font-mono);\n font-size: 0.95rem;\n font-weight: 600;\n line-height: 1.55;\n }\n .content .ox-api-entry__signature,\n .content .ox-api-module__signature {\n display: block;\n width: 100%;\n min-width: 0;\n font-family: var(--font-mono);\n font-size: 0.95rem;\n line-height: 1.55;\n white-space: nowrap;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n }\n .content .ox-api-entry__description {\n display: block;\n color: color-mix(in srgb, var(--color-text) 78%, var(--color-text-muted));\n font-size: 0.9rem;\n line-height: 1.6;\n max-width: 72ch;\n }\n .content .ox-api-entry__summary-main {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 0.55rem;\n }\n .content .ox-api-entry__meta,\n .content .ox-api-module__meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n }\n .content .ox-api-badge {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n padding: 0.18rem 0.42rem;\n border: 1px solid color-mix(in srgb, var(--color-border) 78%, transparent);\n border-radius: 4px;\n background: color-mix(in srgb, var(--color-bg-alt) 78%, var(--color-primary) 6%);\n color: color-mix(in srgb, var(--color-text) 74%, var(--color-text-muted));\n font-family: var(--font-mono);\n font-size: 0.68rem;\n font-weight: 600;\n line-height: 1.35;\n }\n .content .ox-api-badge--warning {\n border-color: color-mix(in srgb, #f59e0b 46%, var(--color-border));\n background: color-mix(in srgb, var(--color-bg-alt) 78%, #f59e0b 9%);\n color: color-mix(in srgb, var(--color-text) 86%, #f59e0b);\n }\n .content .ox-api-entry__name,\n .content .ox-api-entry__signature,\n .content .ox-api-module__name,\n .content .ox-api-module__signature {\n background: transparent;\n padding: 0;\n border-radius: 0;\n word-break: normal;\n }\n .content code.shiki-inline.ox-api-entry__signature--highlighted,\n .content code.shiki-inline.ox-api-module__signature--highlighted {\n display: block;\n width: 100%;\n max-width: 100%;\n background: linear-gradient(\n 180deg,\n var(--color-code-bg-top) 0,\n var(--color-code-bg) 2.75rem\n ) !important;\n border: 1px solid var(--color-code-frame-border) !important;\n padding: 0.55rem 0.7rem !important;\n border-radius: 4px !important;\n white-space: nowrap;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n }\n .content code.shiki-inline.ox-api-entry__signature--highlighted .line,\n .content code.shiki-inline.ox-api-module__signature--highlighted .line {\n display: block;\n width: max-content;\n min-width: 100%;\n }\n .content .ox-api-entry__body,\n .content .ox-api-module__body { padding: 0.7rem 0 1.9rem; }\n .content .ox-api-entry__body {\n margin-left: calc(var(--octc-api-kind-width, 6.5rem) + 0.95rem);\n margin-top: 0.7rem;\n padding: 1.45rem 1rem 2.1rem 1.1rem;\n border: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);\n border-radius: 4px;\n background: color-mix(in srgb, var(--color-bg-alt) 68%, transparent);\n }\n .content .ox-api-entry__body > :first-child { margin-top: 0; }\n .content .ox-api-entry__body > :last-child { margin-bottom: 0; }\n .content .ox-api-entry[open] summary {\n padding-bottom: 0.35rem;\n }\n .content .ox-api-entry__section {\n display: grid;\n grid-template-columns: 6.5rem minmax(0, 1fr);\n gap: 0.2rem 1.25rem;\n align-items: start;\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);\n }\n .content .ox-api-entry__section h4 {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 0.25rem;\n font-family: var(--font-mono);\n font-size: 0.78rem;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--color-text-muted);\n }\n .content .ox-api-entry__section > :not(h4) { min-width: 0; }\n .content .ox-api-entry__source {\n margin: 0 0 0.15rem;\n font-family: var(--font-mono);\n font-size: 0.78rem;\n color: var(--color-text-muted);\n }\n .content .ox-api-entry__source a {\n color: inherit;\n text-decoration-color: color-mix(in srgb, var(--color-text-muted) 38%, transparent);\n }\n .content .ox-api-entry__tags,\n .content .ox-api-module__list {\n list-style: none;\n padding-left: 0;\n margin: 0;\n }\n .content .ox-api-entry__tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.6rem;\n }\n .content .ox-api-entry__tags li {\n display: inline-flex;\n align-items: center;\n gap: 0.45rem;\n padding: 0.4rem 0.55rem;\n border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);\n border-radius: 4px;\n background: color-mix(in srgb, var(--color-bg-alt) 72%, transparent);\n }\n .content .ox-api-module__list li {\n display: grid;\n grid-template-columns: var(--octc-api-kind-width, 6.5rem) minmax(0, 1fr);\n align-items: start;\n gap: 1rem;\n padding: 0.85rem 0;\n border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);\n }\n .content .ox-api-module__list li:first-child { border-top: none; }\n .content .ox-api-entry__tag-name,\n .content .ox-api-module__title { font-weight: 700; }\n .content .ox-api-entry__tag-name {\n color: var(--color-primary);\n font-family: var(--font-mono);\n font-size: 0.74rem;\n }\n .content .ox-api-entry__tag-value {\n color: var(--color-text);\n font-size: 0.84rem;\n line-height: 1.45;\n }\n .content .ox-api-module summary {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 0.9rem;\n }\n .content .ox-api-module__body { padding-top: 0.15rem; }\n .content .ox-api-module__item { min-width: 0; }\n .content .ox-api-module__link {\n display: block;\n text-decoration: none;\n }\n .content .ox-api-module__link:hover { text-decoration: none; }\n .content .ox-api-module__name,\n .content .ox-api-module__signature {\n display: block;\n font-family: var(--font-mono);\n font-size: 0.91rem;\n line-height: 1.55;\n color: var(--color-text);\n }\n .content .ox-api-module__summary {\n display: block;\n margin-top: 0.45rem;\n color: color-mix(in srgb, var(--color-text) 76%, var(--color-text-muted));\n font-size: 0.88rem;\n line-height: 1.55;\n }\n .content .ox-api-entry__section--signature pre {\n margin: 0;\n border: 1px solid var(--color-code-frame-border);\n border-radius: 4px;\n }\n .content .ox-api-entry__example + .ox-api-entry__example {\n margin-top: 0.85rem;\n }\n .content .ox-api-entry__example-heading {\n margin-bottom: 0.45rem;\n font-family: var(--font-mono);\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--color-text-muted);\n }\n .content .ox-api-entry__section--examples pre {\n margin: 0;\n border: 1px solid var(--color-code-frame-border);\n border-radius: 4px;\n }\n .content .ox-api-entry__params {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n .content .ox-api-entry__param {\n padding: 0.8rem 0;\n border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);\n }\n .content .ox-api-entry__param:first-child {\n padding-top: 0;\n border-top: 0;\n }\n .content .ox-api-entry__param-heading {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n }\n .content .ox-api-entry__param-name,\n .content .ox-api-entry__return-type {\n font-family: var(--font-mono);\n font-size: 0.84rem;\n font-weight: 600;\n color: var(--color-text);\n background: color-mix(in srgb, var(--color-bg-alt) 84%, transparent);\n border: 1px solid color-mix(in srgb, var(--color-border) 82%, transparent);\n padding: 0.28rem 0.42rem;\n border-radius: 4px;\n }\n .content .ox-api-entry__param-type {\n font-family: var(--font-mono);\n font-size: 0.78rem;\n color: var(--color-code-text);\n background: color-mix(in srgb, var(--color-code-bg) 96%, #243556);\n border: 1px solid color-mix(in srgb, var(--color-code-bg) 82%, var(--color-border));\n padding: 0.26rem 0.42rem;\n border-radius: 4px;\n }\n .content .ox-api-entry__param-description,\n .content .ox-api-entry__return-description {\n margin: 0.55rem 0 0;\n font-size: 0.88rem;\n line-height: 1.6;\n color: color-mix(in srgb, var(--color-text) 78%, var(--color-text-muted));\n }\n .content .ox-api-entry__return { margin: 0; }\n\n /* Responsive */\n @media (max-width: 768px) {\n .menu-toggle { display: block; }\n .sidebar {\n transform: translateX(-100%);\n z-index: 99;\n width: 280px;\n }\n .sidebar--entry { display: block; }\n .sidebar.open { transform: translateX(0); }\n .main { margin-left: 0; padding: 1rem 0.75rem; }\n .content { padding: 0 0.25rem; }\n .content h1 { font-size: 1.5rem; line-height: 1.3; margin-bottom: 0.75rem; }\n .content h2 { font-size: 1.2rem; margin-top: 2rem; }\n .content h3 { font-size: 1.1rem; }\n .content p { font-size: 0.9375rem; margin-bottom: 0.875rem; }\n .content ul, .content ol { padding-left: 1.25rem; font-size: 0.9375rem; }\n .content pre {\n padding: 0.75rem;\n font-size: 0.75rem;\n margin: 1rem -0.75rem;\n border-radius: 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .content .ox-api-controls {\n justify-content: flex-start;\n gap: 0.75rem;\n }\n .content .ox-api-entry__body {\n margin-left: 0;\n margin-top: 0.55rem;\n padding: 1.2rem 0 1.7rem;\n border-left: 0;\n border-right: 0;\n border-bottom: 0;\n border-radius: 0;\n background: transparent;\n }\n .content .ox-api-entry__section {\n grid-template-columns: 1fr;\n gap: 0.5rem;\n }\n .content .ox-api-entry__tags li,\n .content .ox-api-module__list li,\n .content .ox-api-module summary {\n grid-template-columns: 1fr;\n }\n .content .ox-api-entry__signature { width: 100%; }\n .content pre.ox-code-block .line {\n margin: 0 -0.75rem;\n padding: 0 0.75rem;\n }\n .content code { font-size: 0.8125em; }\n .content table {\n display: block;\n width: max-content;\n min-width: 100%;\n max-width: calc(100vw - 1.5rem);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n font-size: 0.8125rem;\n margin: 1rem 0;\n border-collapse: separate;\n border-spacing: 0;\n }\n .content th, .content td { padding: 0.5rem 0.75rem; white-space: nowrap; vertical-align: top; }\n .content img { margin: 1rem 0; }\n .content img[alt*=\"Logo\"] { max-width: 150px; }\n .content img[alt*=\"Architecture\"] { max-width: 100%; }\n .content img[alt*=\"Benchmark\"] { max-width: 100%; }\n .content blockquote { padding: 0.5rem 0.75rem; margin: 1rem 0; font-size: 0.9375rem; }\n .header { padding: 0 1rem; }\n .header-title { font-size: 1rem; }\n .header-title:not(.header-title--logo-only) img { width: 24px; height: 24px; }\n .header-title--logo-only .header-logo { width: 152px; height: auto; }\n .overlay {\n display: none;\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 98;\n }\n .overlay.open { display: block; }\n }\n\n /* Extra small devices */\n @media (max-width: 480px) {\n .main { padding: 0.75rem 0.5rem; }\n .content h1 { font-size: 1.35rem; }\n .content pre { font-size: 0.6875rem; padding: 0.625rem; }\n .content table { max-width: calc(100vw - 1rem); font-size: 0.75rem; }\n .content th, .content td { padding: 0.375rem 0.5rem; }\n }\n </style>\n</head>\n<body>\n <header class=\"header\">\n <button class=\"menu-toggle\" aria-label=\"Toggle menu\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\">\n <path d=\"M3 12h18M3 6h18M3 18h18\"/>\n </svg>\n </button>\n <a href=\"{{base}}index.html\" class=\"header-title\">\n <img src=\"{{base}}logo.svg\" alt=\"\" width=\"28\" height=\"28\" style=\"margin-right: 8px; vertical-align: middle;\" />\n {{siteName}}\n </a>\n <div class=\"header-actions\">\n <button class=\"search-button\" aria-label=\"Search\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/>\n </svg>\n <span>Search</span>\n <kbd>/</kbd>\n </button>\n <button class=\"theme-toggle\" aria-label=\"Toggle theme\">\n <svg class=\"icon-sun\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"5\"/><path d=\"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42\"/>\n </svg>\n <svg class=\"icon-moon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/>\n </svg>\n </button>\n </div>\n </header>\n <div class=\"search-modal-overlay\">\n <div class=\"search-modal\">\n <div class=\"search-header\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/>\n </svg>\n <input type=\"text\" class=\"search-input\" placeholder=\"Search documentation...\" />\n <button class=\"search-close\">Esc</button>\n </div>\n <div class=\"search-results\"></div>\n <div class=\"search-footer\">\n <span><kbd>\u2191</kbd><kbd>\u2193</kbd> to navigate</span>\n <span><kbd>Enter</kbd> to select</span>\n <span><kbd>Esc</kbd> to close</span>\n </div>\n </div>\n </div>\n <div class=\"overlay\"></div>\n <div class=\"layout\">\n <aside class=\"sidebar{{#entryPage}} sidebar--entry{{/entryPage}}\">\n <nav>\n{{navigation}}\n </nav>\n </aside>\n <main class=\"main\">\n <article class=\"content\">\n{{content}}\n </article>\n </main>\n{{#hasToc}}\n <aside class=\"toc\">\n <div class=\"toc-title\">On this page</div>\n <ul class=\"toc-list\">\n{{toc}}\n </ul>\n </aside>\n{{/hasToc}}\n </div>\n <script>\n // Menu toggle\n const toggle = document.querySelector('.menu-toggle');\n const sidebar = document.querySelector('.sidebar');\n const overlay = document.querySelector('.overlay');\n if (toggle && sidebar && overlay) {\n const close = () => { sidebar.classList.remove('open'); overlay.classList.remove('open'); };\n toggle.addEventListener('click', () => {\n sidebar.classList.toggle('open');\n overlay.classList.toggle('open');\n });\n overlay.addEventListener('click', close);\n sidebar.querySelectorAll('a').forEach(a => a.addEventListener('click', close));\n }\n\n // Theme toggle\n const themeToggle = document.querySelector('.theme-toggle');\n const getPreferredTheme = () => {\n const stored = localStorage.getItem('theme');\n if (stored) return stored;\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n };\n const setTheme = (theme) => {\n document.documentElement.setAttribute('data-theme', theme);\n localStorage.setItem('theme', theme);\n };\n // Initialize theme\n setTheme(getPreferredTheme());\n if (themeToggle) {\n themeToggle.addEventListener('click', () => {\n const current = document.documentElement.getAttribute('data-theme') || getPreferredTheme();\n setTheme(current === 'dark' ? 'light' : 'dark');\n });\n }\n\n document.querySelectorAll('.ox-api-controls').forEach((controls) => {\n const targetSelector = controls.getAttribute('data-ox-api-target');\n if (!targetSelector) return;\n\n controls.querySelectorAll('[data-ox-api-toggle]').forEach((button) => {\n button.addEventListener('click', () => {\n const shouldOpen = button.getAttribute('data-ox-api-toggle') === 'expand';\n document.querySelectorAll(targetSelector).forEach((entry) => {\n if (entry instanceof HTMLDetailsElement) {\n entry.open = shouldOpen;\n }\n });\n });\n });\n });\n\n // Search functionality\n const searchButton = document.querySelector('.search-button');\n const searchOverlay = document.querySelector('.search-modal-overlay');\n const searchInput = document.querySelector('.search-input');\n const searchResults = document.querySelector('.search-results');\n const searchClose = document.querySelector('.search-close');\n let searchIndex = null;\n let selectedIndex = 0;\n let results = [];\n\n const openSearch = () => {\n searchOverlay.classList.add('open');\n searchInput.focus();\n };\n const closeSearch = () => {\n searchOverlay.classList.remove('open');\n searchInput.value = '';\n searchResults.innerHTML = '';\n selectedIndex = 0;\n results = [];\n };\n\n // Load search index\n const loadSearchIndex = async () => {\n if (searchIndex) return;\n try {\n const res = await fetch('{{base}}search-index.json');\n searchIndex = await res.json();\n } catch (e) {\n console.warn('Failed to load search index:', e);\n }\n };\n\n const parseScopedQuery = (query) => {\n const scopes = [];\n const terms = [];\n for (const part of query.trim().split(/\\s+/).filter(Boolean)) {\n if (part.startsWith('@') && part.length > 1) {\n scopes.push(part.slice(1).toLowerCase());\n } else {\n terms.push(part);\n }\n }\n return { text: terms.join(' ').trim(), scopes: [...new Set(scopes)] };\n };\n\n const getScopesForDoc = (doc) => {\n const source = (doc.id || doc.url || '').replace(/^\\/+/, '').toLowerCase();\n const segments = source.split('/').filter(Boolean);\n if (segments.length <= 1) return [];\n\n const scopes = [];\n let current = '';\n for (const segment of segments.slice(0, -1)) {\n current = current ? current + '/' + segment : segment;\n scopes.push(current);\n }\n return scopes;\n };\n\n const matchesScopes = (doc, scopes) => {\n if (!scopes.length) return true;\n const docScopes = new Set(getScopesForDoc(doc));\n return scopes.some((scope) => docScopes.has(scope));\n };\n\n // Tokenize query\n const tokenize = (text) => {\n const tokens = [];\n let current = '';\n for (const char of text) {\n const isCjk = /[\\u4E00-\\u9FFF\\u3400-\\u4DBF\\u3040-\\u309F\\u30A0-\\u30FF\\uAC00-\\uD7AF]/.test(char);\n if (isCjk) {\n if (current) { tokens.push(current.toLowerCase()); current = ''; }\n tokens.push(char);\n } else if (/[a-zA-Z0-9_]/.test(char)) {\n current += char;\n } else if (current) {\n tokens.push(current.toLowerCase());\n current = '';\n }\n }\n if (current) tokens.push(current.toLowerCase());\n return tokens;\n };\n\n // Perform search\n const performSearch = async (query) => {\n await loadSearchIndex();\n if (!searchIndex) {\n searchResults.innerHTML = '<div class=\"search-empty\">Search index not available</div>';\n return;\n }\n\n const parsedQuery = parseScopedQuery(query);\n if (!parsedQuery.text && parsedQuery.scopes.length === 0) {\n searchResults.innerHTML = '';\n results = [];\n return;\n }\n\n const tokens = tokenize(parsedQuery.text);\n const k1 = 1.2, b = 0.75;\n const docScores = new Map();\n\n if (!tokens.length) {\n searchIndex.documents.forEach((doc, docIdx) => {\n if (matchesScopes(doc, parsedQuery.scopes)) {\n docScores.set(docIdx, { score: 0, matches: new Set() });\n }\n });\n }\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n const isLast = i === tokens.length - 1;\n let matchingTerms = [];\n if (isLast && token.length >= 2) {\n matchingTerms = Object.keys(searchIndex.index).filter(t => t.startsWith(token));\n } else if (searchIndex.index[token]) {\n matchingTerms = [token];\n }\n\n for (const term of matchingTerms) {\n const postings = searchIndex.index[term] || [];\n const df = searchIndex.df[term] || 1;\n const idf = Math.log((searchIndex.doc_count - df + 0.5) / (df + 0.5) + 1.0);\n\n for (const posting of postings) {\n const doc = searchIndex.documents[posting.doc_idx];\n if (!doc) continue;\n if (!matchesScopes(doc, parsedQuery.scopes)) continue;\n const boost = posting.field === 'Title' ? 10 : posting.field === 'Heading' ? 5 : 1;\n const tf = posting.tf;\n const docLen = doc.body.length;\n const score = idf * ((tf * (k1 + 1)) / (tf + k1 * (1 - b + b * docLen / searchIndex.avg_dl))) * boost;\n\n if (!docScores.has(posting.doc_idx)) {\n docScores.set(posting.doc_idx, { score: 0, matches: new Set() });\n }\n const entry = docScores.get(posting.doc_idx);\n entry.score += score;\n entry.matches.add(term);\n }\n }\n }\n\n results = Array.from(docScores.entries())\n .map(([docIdx, data]) => {\n const doc = searchIndex.documents[docIdx];\n const scopes = getScopesForDoc(doc);\n let snippet = '';\n if (doc.body) {\n const bodyLower = doc.body.toLowerCase();\n let firstPos = -1;\n for (const match of data.matches) {\n const pos = bodyLower.indexOf(match);\n if (pos !== -1 && (firstPos === -1 || pos < firstPos)) firstPos = pos;\n }\n const start = firstPos === -1 ? 0 : Math.max(0, firstPos - 50);\n const end = Math.min(doc.body.length, start + 150);\n snippet = doc.body.slice(start, end);\n if (start > 0) snippet = '...' + snippet;\n if (end < doc.body.length) snippet += '...';\n }\n return { ...doc, score: data.score, scopes, snippet };\n })\n .sort((a, b) => b.score - a.score || a.title.localeCompare(b.title))\n .slice(0, 10);\n\n selectedIndex = 0;\n renderResults();\n };\n\n const renderResults = () => {\n if (!results.length) {\n searchResults.innerHTML = '<div class=\"search-empty\">No results found</div>';\n return;\n }\n searchResults.innerHTML = results.map((r, i) =>\n '<a href=\"' + r.url + '\" class=\"search-result' + (i === selectedIndex ? ' selected' : '') + '\">' +\n '<div class=\"search-result-title\">' + r.title + (r.scopes?.length ? '<span class=\"search-result-scope\">@' + r.scopes[0] + '</span>' : '') + '</div>' +\n (r.snippet ? '<div class=\"search-result-snippet\">' + r.snippet + '</div>' : '') +\n '</a>'\n ).join('');\n };\n\n // Event listeners\n if (searchButton) searchButton.addEventListener('click', openSearch);\n if (searchClose) searchClose.addEventListener('click', closeSearch);\n if (searchOverlay) searchOverlay.addEventListener('click', (e) => { if (e.target === searchOverlay) closeSearch(); });\n\n let searchTimeout = null;\n if (searchInput) {\n searchInput.addEventListener('input', () => {\n if (searchTimeout) clearTimeout(searchTimeout);\n searchTimeout = setTimeout(() => performSearch(searchInput.value), 150);\n });\n searchInput.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') closeSearch();\n else if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (selectedIndex < results.length - 1) { selectedIndex++; renderResults(); }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (selectedIndex > 0) { selectedIndex--; renderResults(); }\n } else if (e.key === 'Enter' && results[selectedIndex]) {\n e.preventDefault();\n window.location.href = results[selectedIndex].url;\n }\n });\n }\n\n // Global keyboard shortcut (/ or Cmd+K)\n document.addEventListener('keydown', (e) => {\n if ((e.key === '/' && !(e.target instanceof HTMLInputElement)) ||\n ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k')) {\n e.preventDefault();\n openSearch();\n }\n });\n </script>\n</body>\n</html>";
1751
+ declare const DEFAULT_HTML_TEMPLATE = "<!-- ox-content default HTML template is Rust-backed -->";
1505
1752
  /**
1506
1753
  * Resolves SSG options with defaults.
1507
1754
  */
@@ -1522,12 +1769,18 @@ declare function resolveSearchOptions(options: SearchOptions | boolean | undefin
1522
1769
  /**
1523
1770
  * Builds the search index from Markdown files.
1524
1771
  */
1525
- declare function buildSearchIndex(srcDir: string, base: string): Promise<string>;
1772
+ declare function buildSearchIndex(srcDir: string, base: string, extensions?: readonly string[]): Promise<string>;
1526
1773
  /**
1527
1774
  * Writes the search index to a file.
1528
1775
  */
1529
1776
  declare function writeSearchIndex(indexJson: string, outDir: string): Promise<void>;
1530
1777
  //#endregion
1778
+ //#region src/markdown.d.ts
1779
+ declare const DEFAULT_MARKDOWN_EXTENSIONS: readonly [".md", ".markdown", ".mdx"];
1780
+ declare function normalizeMarkdownExtensions(extensions?: readonly string[]): string[];
1781
+ declare function isMarkdownFilePath(filePath: string, extensions?: readonly string[]): boolean;
1782
+ declare function stripMarkdownExtension(filePath: string, extensions?: readonly string[]): string;
1783
+ //#endregion
1531
1784
  //#region src/vitepress.d.ts
1532
1785
  interface VitePressLogo {
1533
1786
  light?: string;
@@ -1994,170 +2247,6 @@ declare function createTheme(config: {
1994
2247
  defaultLayout?: string;
1995
2248
  }): ThemeComponent;
1996
2249
  //#endregion
1997
- //#region src/plugins/tabs.d.ts
1998
- /**
1999
- * Transform Tabs components in HTML.
2000
- */
2001
- declare function transformTabs(html: string): Promise<string>;
2002
- /**
2003
- * Generate dynamic CSS for :has() based tab switching.
2004
- * This is needed because :has() selectors need unique IDs.
2005
- */
2006
- declare function generateTabsCSS(groupCount: number): string;
2007
- //#endregion
2008
- //#region src/plugins/youtube.d.ts
2009
- /**
2010
- * YouTube Plugin - Privacy-enhanced iframe embedding
2011
- *
2012
- * Transforms <YouTube> components into responsive iframe embeds
2013
- * using youtube-nocookie.com for enhanced privacy.
2014
- */
2015
- interface YouTubeOptions {
2016
- /** Use privacy-enhanced mode (youtube-nocookie.com). Default: true */
2017
- privacyEnhanced?: boolean;
2018
- /** Default aspect ratio. Default: "16/9" */
2019
- aspectRatio?: string;
2020
- /** Allow fullscreen. Default: true */
2021
- allowFullscreen?: boolean;
2022
- /** Lazy load iframe. Default: true */
2023
- lazyLoad?: boolean;
2024
- }
2025
- /**
2026
- * Extract YouTube video ID from various URL formats.
2027
- */
2028
- declare function extractVideoId(input: string): string | null;
2029
- /**
2030
- * Transform YouTube components in HTML.
2031
- */
2032
- declare function transformYouTube(html: string, options?: YouTubeOptions): Promise<string>;
2033
- //#endregion
2034
- //#region src/plugins/github.d.ts
2035
- /**
2036
- * GitHub Plugin - Repository card embedding
2037
- *
2038
- * Transforms <GitHub> components into static repository cards
2039
- * by fetching data from GitHub API at build time.
2040
- */
2041
- interface GitHubRepoData {
2042
- name: string;
2043
- full_name: string;
2044
- description: string | null;
2045
- html_url: string;
2046
- stargazers_count: number;
2047
- forks_count: number;
2048
- language: string | null;
2049
- owner: {
2050
- login: string;
2051
- avatar_url: string;
2052
- };
2053
- }
2054
- interface GitHubOptions {
2055
- /** GitHub API token for higher rate limits. */
2056
- token?: string;
2057
- /** Cache fetched data. Default: true */
2058
- cache?: boolean;
2059
- /** Cache TTL in milliseconds. Default: 3600000 (1 hour) */
2060
- cacheTTL?: number;
2061
- }
2062
- /**
2063
- * Fetch repository data from GitHub API.
2064
- */
2065
- declare function fetchRepoData(repo: string, options: Required<GitHubOptions>): Promise<GitHubRepoData | null>;
2066
- /**
2067
- * Collect all GitHub repos from HTML for pre-fetching.
2068
- */
2069
- declare function collectGitHubRepos(html: string): Promise<string[]>;
2070
- /**
2071
- * Pre-fetch all GitHub repos data.
2072
- */
2073
- declare function prefetchGitHubRepos(repos: string[], options?: GitHubOptions): Promise<Map<string, GitHubRepoData | null>>;
2074
- /**
2075
- * Transform GitHub components in HTML.
2076
- */
2077
- declare function transformGitHub(html: string, repoDataMap?: Map<string, GitHubRepoData | null>, options?: GitHubOptions): Promise<string>;
2078
- //#endregion
2079
- //#region src/plugins/ogp.d.ts
2080
- /**
2081
- * OGP Card Plugin - Link card embedding
2082
- *
2083
- * Transforms <OgCard> components into static link preview cards
2084
- * by fetching OGP metadata at build time.
2085
- */
2086
- interface OgpData {
2087
- url: string;
2088
- title: string;
2089
- description?: string;
2090
- image?: string;
2091
- siteName?: string;
2092
- favicon?: string;
2093
- }
2094
- interface OgpOptions {
2095
- /** Request timeout in milliseconds. Default: 10000 */
2096
- timeout?: number;
2097
- /** Cache fetched data. Default: true */
2098
- cache?: boolean;
2099
- /** Cache TTL in milliseconds. Default: 3600000 (1 hour) */
2100
- cacheTTL?: number;
2101
- /** User agent for requests */
2102
- userAgent?: string;
2103
- }
2104
- /**
2105
- * Fetch OGP data for a URL.
2106
- */
2107
- declare function fetchOgpData(url: string, options: Required<OgpOptions>): Promise<OgpData | null>;
2108
- /**
2109
- * Collect all OGP URLs from HTML for pre-fetching.
2110
- */
2111
- declare function collectOgpUrls(html: string): Promise<string[]>;
2112
- /**
2113
- * Pre-fetch all OGP data.
2114
- */
2115
- declare function prefetchOgpData(urls: string[], options?: OgpOptions): Promise<Map<string, OgpData | null>>;
2116
- /**
2117
- * Transform OgCard components in HTML.
2118
- */
2119
- declare function transformOgp(html: string, ogpDataMap?: Map<string, OgpData | null>, options?: OgpOptions): Promise<string>;
2120
- //#endregion
2121
- //#region src/plugins/mermaid.d.ts
2122
- /**
2123
- * Mermaid Plugin - Native Rust renderer via NAPI
2124
- *
2125
- * Renders mermaid code blocks to SVG using the native Rust renderer
2126
- * via NAPI. Delegates to the NAPI `transformMermaid` function which
2127
- * extracts mermaid code blocks from HTML and renders them using mmdc.
2128
- */
2129
- interface MermaidOptions {
2130
- /** Mermaid theme. Default: "neutral" */
2131
- theme?: "default" | "dark" | "forest" | "neutral" | "base";
2132
- }
2133
- /**
2134
- * Transforms mermaid code blocks in HTML to rendered SVG diagrams.
2135
- * Uses the native Rust NAPI transformMermaid function.
2136
- */
2137
- declare function transformMermaidStatic(html: string, _options?: MermaidOptions): Promise<string>;
2138
- /**
2139
- * @deprecated No longer used. Mermaid rendering is now done at build time via NAPI.
2140
- */
2141
- declare const mermaidClientScript = "";
2142
- //#endregion
2143
- //#region src/plugins/index.d.ts
2144
- /**
2145
- * Transform all plugin components in HTML.
2146
- * Call this during SSG build to process all plugins at once.
2147
- */
2148
- interface TransformAllOptions {
2149
- tabs?: boolean;
2150
- youtube?: boolean;
2151
- github?: boolean;
2152
- ogp?: boolean;
2153
- mermaid?: boolean;
2154
- githubToken?: string;
2155
- }
2156
- /**
2157
- * Transform all enabled plugins in HTML content.
2158
- */
2159
- declare function transformAllPlugins(html: string, options?: TransformAllOptions): Promise<string>;
2160
- //#endregion
2161
2250
  //#region src/island/parse.d.ts
2162
2251
  /**
2163
2252
  * Island Parser
@@ -2372,10 +2461,11 @@ declare function createI18nPlugin(resolvedOptions: ResolvedOptions): Plugin;
2372
2461
  * ```
2373
2462
  */
2374
2463
  declare function oxContent(options?: OxContentOptions): Plugin[];
2464
+ declare function resolveBuiltinEmbedOptions(options: OxContentOptions["embeds"]): ResolvedOptions["embeds"];
2375
2465
  /**
2376
2466
  * Generates virtual module content.
2377
2467
  */
2378
2468
  declare function generateVirtualModule(path: string, options: ResolvedOptions): string;
2379
2469
  //#endregion
2380
- export { type BasePageProps, CodeAnnotationKind, type CodeAnnotationSyntax, type CodeAnnotationsOptions, DEFAULT_HTML_TEMPLATE, DefaultTheme, type DocEntry, type DocsOptions, DocsSummary, type EntryPageConfig, type ExtractedDocs, type FeatureConfig, Fragment, type FrontmatterSchema, type GenerateVitePressMigrationConfigOptions, GeneratedDocsData, type GitHubOptions, type GitHubRepoData, type HeroAction, type HeroConfig, type HeroImage, HeroNotice, type I18nOptions, type IslandInfo, type JSXChild, type JSXElementType, type JSXNode, type JSXProps, type LanguageRegistration, type LoadStrategy, type LocaleConfig, type MarkdownLintFileDiagnostic as MarkdownLintBatchDiagnostic, type MarkdownLintFileDiagnostic, type MarkdownLintDiagnostic, type MarkdownLintDictionaryOptions, type MarkdownLintFileOptions, type MarkdownLintFileOptions as MarkdownLintProjectOptions, type MarkdownLintFileResult, type MarkdownLintFilesResult, type MarkdownLintLanguage, type MarkdownLintOptions, type MarkdownLintResult, type MarkdownLintRuleOptions, type MarkdownLintSeverity, type MarkdownLintStandardDictionaryOptions, MarkdownNode, MarkdownTransformer, type MermaidOptions, type NavGroup, type NavItem, type OgBrowserSession, type OgImageOptions, type OgImagePageEntry, type OgImageOptions$1 as OgImagePluginOptions, type OgImageResult, type OgImageTemplateFn, type OgImageTemplateProps, type OgpData, type OgpOptions, type OxContentOptions, type PageData, type PageProps, type ParamDoc, type ParseIslandsResult, type RenderContext, type ResolvedCodeAnnotationsOptions, type ResolvedDocsOptions, type ResolvedI18nOptions, type ResolvedOgImageOptions, ResolvedOptions, type ResolvedSearchOptions, type ResolvedSsgOptions, type ResolvedThemeConfig, type ReturnDoc, ScopedSearchQuery, type SearchDocument, type SearchOptions, type SearchResult, type SiteConfig, type SocialLinks, type SsgNavigationGroup, type SsgNavigationItem, type SsgOptions, type ThemeColors, type ThemeComponent, type ThemeConfig, type ThemeEmbed, type ThemeEntryPage, type ThemeFonts, type ThemeFooter, type ThemeHeader, type ThemeLayout, type ThemeProps, type ThemeRegistration, type ThemeRenderOptions, TocEntry, type TransformAllOptions, TransformContext, TransformResult, type VitePressConfig, type VitePressFooter, type VitePressLogo, type VitePressNavItem, type VitePressSidebar, type VitePressSidebarItem, type VitePressSocialLink, type VitePressThemeConfig, type YouTubeOptions, buildSearchIndex, buildSsg, clearRenderContext, collectGitHubRepos, collectOgpUrls, convertVitePressNav, convertVitePressSidebar, createI18nPlugin, createMarkdownEnvironment, createTheme, defaultTheme, defineTheme, each, extractDocs, extractIslandInfo, extractVideoId, fetchOgpData, fetchRepoData, fromVitePressConfig, generateFrontmatterTypes, generateHydrationScript, generateMarkdown, generateOgImages, generateTabsCSS, generateTypes, generateVirtualModule, generateVitePressMigrationConfig, hasIslands, inferType, jsx, jsxs, lintMarkdown, lintMarkdownAsync, lintMarkdownFile, lintMarkdownFiles, mergeThemes, mermaidClientScript, normalizeVitePressFrontmatter, oxContent, prefetchGitHubRepos, prefetchOgpData, raw, renderAllPages, renderPage, renderToString, resolveDocsOptions, resolveI18nOptions, resolveOgImageOptions, resolveSearchOptions, resolveSsgOptions, resolveTheme, setRenderContext, shouldLintMarkdownFile, transformAllPlugins, transformGitHub, transformIslands, transformMarkdown, transformMermaidStatic, transformOgp, transformTabs, transformYouTube, useIsActive, useNav, usePageProps, useRenderContext, useSiteConfig, when, writeDocs, writeSearchIndex };
2470
+ export { type BasePageProps, type BuiltinEmbedOptions, CodeAnnotationKind, type CodeAnnotationSyntax, type CodeAnnotationsOptions, DEFAULT_HTML_TEMPLATE, DEFAULT_MARKDOWN_EXTENSIONS, DefaultTheme, type DocEntry, type DocsOptions, DocsSummary, type EntryPageConfig, type ExtractedDocs, type FeatureConfig, Fragment, type FrontmatterSchema, type GenerateVitePressMigrationConfigOptions, GeneratedDocsData, type GitHubLineRange, type GitHubOptions, type GitHubRepoData, type GitHubSourceData, type GitHubSourceRef, type HeroAction, type HeroConfig, type HeroImage, HeroNotice, type I18nOptions, type IslandInfo, type JSXChild, type JSXElementType, type JSXNode, type JSXProps, type LanguageRegistration, type LoadStrategy, type LocaleConfig, type MarkdownLintFileDiagnostic as MarkdownLintBatchDiagnostic, type MarkdownLintFileDiagnostic, type MarkdownLintDiagnostic, type MarkdownLintDictionaryOptions, type MarkdownLintFileOptions, type MarkdownLintFileOptions as MarkdownLintProjectOptions, type MarkdownLintFileResult, type MarkdownLintFilesResult, type MarkdownLintLanguage, type MarkdownLintOptions, type MarkdownLintResult, type MarkdownLintRuleOptions, type MarkdownLintSeverity, type MarkdownLintStandardDictionaryOptions, MarkdownNode, MarkdownTransformer, type MermaidOptions, type NavGroup, type NavItem, type OgBrowserSession, type OgImageOptions, type OgImagePageEntry, type OgImageOptions$1 as OgImagePluginOptions, type OgImageResult, type OgImageTemplateFn, type OgImageTemplateProps, type OgpData, type OgpOptions, type OxContentOptions, type PageData, type PageProps, type ParamDoc, type ParseIslandsResult, type RenderContext, type ResolvedBuiltinEmbedOptions, type ResolvedCodeAnnotationsOptions, type ResolvedDocsOptions, type ResolvedI18nOptions, type ResolvedOgImageOptions, ResolvedOptions, type ResolvedSearchOptions, type ResolvedSsgOptions, type ResolvedThemeConfig, type ReturnDoc, ScopedSearchQuery, type SearchDocument, type SearchOptions, type SearchResult, type SiteConfig, type SocialLinks, type SsgNavigationGroup, type SsgNavigationItem, type SsgOptions, type ThemeColors, type ThemeComponent, type ThemeConfig, type ThemeEmbed, type ThemeEntryPage, type ThemeFonts, type ThemeFooter, type ThemeHeader, type ThemeLayout, type ThemeProps, type ThemeRegistration, type ThemeRenderOptions, TocEntry, type TransformAllOptions, TransformContext, TransformResult, type VitePressConfig, type VitePressFooter, type VitePressLogo, type VitePressNavItem, type VitePressSidebar, type VitePressSidebarItem, type VitePressSocialLink, type VitePressThemeConfig, type YouTubeOptions, buildSearchIndex, buildSsg, clearRenderContext, collectGitHubRepos, collectGitHubSources, collectOgpUrls, convertVitePressNav, convertVitePressSidebar, createI18nPlugin, createMarkdownEnvironment, createTheme, defaultTheme, defineTheme, each, extractDocs, extractIslandInfo, extractVideoId, fetchGitHubSource, fetchOgpData, fetchRepoData, fromVitePressConfig, generateFrontmatterTypes, generateHydrationScript, generateMarkdown, generateOgImages, generateTabsCSS, generateTypes, generateVirtualModule, generateVitePressMigrationConfig, hasIslands, inferType, isMarkdownFilePath, jsx, jsxs, lintMarkdown, lintMarkdownAsync, lintMarkdownFile, lintMarkdownFiles, mergeThemes, mermaidClientScript, normalizeMarkdownExtensions, normalizeVitePressFrontmatter, oxContent, parseGitHubLineRange, parseGitHubPermalink, prefetchGitHubRepos, prefetchGitHubSources, prefetchOgpData, raw, renderAllPages, renderPage, renderToString, resolveBuiltinEmbedOptions, resolveDocsOptions, resolveI18nOptions, resolveOgImageOptions, resolveSearchOptions, resolveSsgOptions, resolveTheme, setRenderContext, shouldLintMarkdownFile, stripMarkdownExtension, transformAllPlugins, transformGitHub, transformIslands, transformMarkdown, transformMermaidStatic, transformOgp, transformTabs, transformYouTube, useIsActive, useNav, usePageProps, useRenderContext, useSiteConfig, when, writeDocs, writeSearchIndex };
2381
2471
  //# sourceMappingURL=index.d.cts.map