@coderminer/vue-markdown 1.0.0 → 1.0.1
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/CHANGELOG.md +116 -0
- package/README.md +7 -2
- package/README.zh-CN.md +6 -3
- package/dist/chunks/MarkdownBlockquote-DVXziX2t.js +0 -2
- package/dist/chunks/MarkdownBreak-BwCi2Itt.js +0 -2
- package/dist/chunks/MarkdownCode-B1k9tmW5.js +0 -2
- package/dist/chunks/MarkdownConfigProvider-5N3ylrIu.js +0 -2
- package/dist/chunks/MarkdownContent-BAK6dqo7.js +0 -2
- package/dist/chunks/MarkdownCustomTag-lZJHsD6f.js +46 -0
- package/dist/chunks/MarkdownEmphasis-CppivOEu.js +0 -2
- package/dist/chunks/MarkdownEmpty-Av5k6bqa.js +0 -2
- package/dist/chunks/MarkdownError-C0sPs5W0.js +0 -2
- package/dist/chunks/MarkdownFootnoteReference-Dy3Khwyj.js +0 -2
- package/dist/chunks/MarkdownFootnotes-BRPzkbXv.js +0 -2
- package/dist/chunks/MarkdownHeading-DaNcP0_6.js +0 -2
- package/dist/chunks/MarkdownHorizontalRule-QNe_cuUI.js +0 -2
- package/dist/chunks/MarkdownHtml-66lYkvwM.js +0 -2
- package/dist/chunks/MarkdownImage-BRy76svs.js +0 -2
- package/dist/chunks/MarkdownInlineCode-MXZYFwex.js +0 -2
- package/dist/chunks/MarkdownLink-Dbx3NwgV.js +0 -2
- package/dist/chunks/MarkdownList-BJ-_C71k.js +0 -2
- package/dist/chunks/MarkdownListItem-Z1EHIY26.js +0 -2
- package/dist/chunks/MarkdownLoading-D-RYtXxf.js +0 -2
- package/dist/chunks/MarkdownParagraph-BxLSmSaG.js +0 -2
- package/dist/chunks/MarkdownRenderer-OlkdsvI3.js +482 -0
- package/dist/chunks/MarkdownRoot-DEE6iVfh.js +0 -2
- package/dist/chunks/MarkdownStrikethrough-CblvbqDk.js +0 -2
- package/dist/chunks/MarkdownStrong-uU5MzAoJ.js +0 -2
- package/dist/chunks/MarkdownTable-DmBTg_CR.js +0 -2
- package/dist/chunks/MarkdownTableCell-eiCJe847.js +0 -2
- package/dist/chunks/MarkdownTableRow-DuJaPntg.js +0 -2
- package/dist/chunks/MarkdownTableSection-PFHz-R33.js +0 -2
- package/dist/chunks/MarkdownTaskItem-BcmKo1lk.js +0 -2
- package/dist/chunks/{MarkdownToc-BdOHF-Yo.js → MarkdownToc-DHWWoH6t.js} +1 -3
- package/dist/chunks/MarkdownTocItem-DT9mR3vL.js +0 -2
- package/dist/chunks/{MermaidLiveEditor-W-qf3G-5.js → MermaidLiveEditor-1TKkI5bp.js} +1 -3
- package/dist/chunks/{VueSyntaxHighlighter-DyLsYMwy.js → VueSyntaxHighlighter-BWpCO-cX.js} +1 -3
- package/dist/chunks/adapters-CMwX_NEI.js +0 -2
- package/dist/chunks/{blank-line-Cb-JBP_5.js → blank-line-CKKsFeKR.js} +1 -3
- package/dist/chunks/codemirror-DyphMAEg.js +0 -2
- package/dist/chunks/config-aRYo2R8_.js +0 -2
- package/dist/chunks/context-8NfW6fxI.js +0 -2
- package/dist/chunks/convert-hast-C4Rg2ZuF.js +6 -0
- package/dist/chunks/default-ZQ5aHh-N.js +3 -0
- package/dist/chunks/diagnostics-CtHoJyiX.js +0 -2
- package/dist/chunks/{export-DZQ3cUry.js → export-BrgMLgUp.js} +13 -14
- package/dist/chunks/hast-to-nodes-DuZsi4XT.js +29 -0
- package/dist/chunks/{lib-BQiWGWpu.js → hast-util-from-html-D3e_iQ89.js} +495 -494
- package/dist/chunks/highlightjs-BxJFpKS1.js +196 -0
- package/dist/chunks/{identity-jZEhX2d5.js → identity-Bi27FKyx.js} +7 -8
- package/dist/chunks/labels-BtHiUTQI.js +0 -2
- package/dist/chunks/lib-CCnkLL6S.js +252 -0
- package/dist/chunks/longest-streak-DZE_EqsU.js +0 -2
- package/dist/chunks/{micromark-factory-space-Db040TnW.js → micromark-factory-space-CpXAnYUY.js} +2 -4
- package/dist/chunks/{normalize-CRYv3Wqt.js → normalize-VKfQXZiK.js} +57 -51
- package/dist/chunks/{plugin-DqkFHyny.js → plugin-YWo5uqTh.js} +1 -2
- package/dist/chunks/preset-BjaOuJUL.js +0 -2
- package/dist/chunks/{registry-DLjr93-V.js → registry-B7BfEkuy.js} +1051 -1045
- package/dist/chunks/{render-Cs8iKrgz.js → render-DAqK0w5J.js} +524 -494
- package/dist/chunks/{default-DWVS-I_8.js → rolldown-runtime-QGRDbDUS.js} +1 -5
- package/dist/chunks/{runtime-DJMnzjah.js → runtime-D95F41zG.js} +145 -117
- package/dist/chunks/security-y4EwUyAs.js +0 -2
- package/dist/chunks/{shared-DNAvZ-UY.js → shared-NjFDPmkb.js} +18 -27
- package/dist/chunks/{space-separated-tokens-CmBjEPdR.js → space-separated-tokens-1ebNqf35.js} +1 -3
- package/dist/chunks/url-D2BoivaE.js +0 -2
- package/dist/chunks/{useActiveHeading-BaGVMJnB.js → useActiveHeading-CnyGTG1u.js} +165 -122
- package/dist/components/CodeBlock.js +1 -1
- package/dist/components/MarkdownCustomTag.js +1 -1
- package/dist/components/MarkdownMath.js +1 -1
- package/dist/components/MarkdownMermaid.d.ts +3 -3
- package/dist/components/MarkdownMermaid.js +1 -1
- package/dist/components/MarkdownRenderer.d.ts +16 -19
- package/dist/components/MarkdownRenderer.js +1 -1
- package/dist/components/MarkdownToc.js +1 -1
- package/dist/components/MermaidBlock.js +1 -1
- package/dist/components/MermaidLiveEditor.js +1 -1
- package/dist/components/VueSyntaxHighlighter.js +1 -1
- package/dist/components/context.d.ts +2 -2
- package/dist/components/index.js +6 -6
- package/dist/components/types.d.ts +34 -2
- package/dist/composables/useMarkdownDocument.d.ts +2 -0
- package/dist/core/hast-nodes.d.ts +0 -3
- package/dist/core/hast-to-nodes.d.ts +9 -0
- package/dist/core/normalize.d.ts +10 -0
- package/dist/core/parts.d.ts +1 -0
- package/dist/core/slugger.d.ts +7 -0
- package/dist/core/types.d.ts +3 -1
- package/dist/headless.js +8 -8
- package/dist/highlight/convert-hast.d.ts +8 -0
- package/dist/highlight/index.d.ts +2 -1
- package/dist/highlight/index.js +4 -3
- package/dist/highlight/shared.d.ts +0 -5
- package/dist/highlight/shiki.js +2 -3
- package/dist/html/index.js +0 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +47 -49
- package/dist/math/index.js +18 -16
- package/dist/mermaid/index.d.ts +2 -1
- package/dist/mermaid/index.js +8 -3
- package/dist/mermaid/plugin.d.ts +3 -0
- package/dist/mermaid/runtime.d.ts +3 -1
- package/dist/mermaid/sanitize-svg-lazy.d.ts +10 -0
- package/dist/mermaid/sanitize-svg.d.ts +3 -0
- package/dist/mermaid/sanitize.d.ts +6 -2
- package/dist/node-components.js +6 -6
- package/dist/pipeline.js +1 -1
- package/dist/plugins.js +1 -1
- package/dist/styles/components.css +25 -0
- package/package.json +6 -3
- package/dist/chunks/MarkdownBlockquote-DVXziX2t.js.map +0 -1
- package/dist/chunks/MarkdownBreak-BwCi2Itt.js.map +0 -1
- package/dist/chunks/MarkdownCode-B1k9tmW5.js.map +0 -1
- package/dist/chunks/MarkdownConfigProvider-5N3ylrIu.js.map +0 -1
- package/dist/chunks/MarkdownContent-BAK6dqo7.js.map +0 -1
- package/dist/chunks/MarkdownCustomTag-BBdn3-WO.js +0 -42
- package/dist/chunks/MarkdownCustomTag-BBdn3-WO.js.map +0 -1
- package/dist/chunks/MarkdownEmphasis-CppivOEu.js.map +0 -1
- package/dist/chunks/MarkdownEmpty-Av5k6bqa.js.map +0 -1
- package/dist/chunks/MarkdownError-C0sPs5W0.js.map +0 -1
- package/dist/chunks/MarkdownFootnoteReference-Dy3Khwyj.js.map +0 -1
- package/dist/chunks/MarkdownFootnotes-BRPzkbXv.js.map +0 -1
- package/dist/chunks/MarkdownHeading-DaNcP0_6.js.map +0 -1
- package/dist/chunks/MarkdownHorizontalRule-QNe_cuUI.js.map +0 -1
- package/dist/chunks/MarkdownHtml-66lYkvwM.js.map +0 -1
- package/dist/chunks/MarkdownImage-BRy76svs.js.map +0 -1
- package/dist/chunks/MarkdownInlineCode-MXZYFwex.js.map +0 -1
- package/dist/chunks/MarkdownLink-Dbx3NwgV.js.map +0 -1
- package/dist/chunks/MarkdownList-BJ-_C71k.js.map +0 -1
- package/dist/chunks/MarkdownListItem-Z1EHIY26.js.map +0 -1
- package/dist/chunks/MarkdownLoading-D-RYtXxf.js.map +0 -1
- package/dist/chunks/MarkdownParagraph-BxLSmSaG.js.map +0 -1
- package/dist/chunks/MarkdownRenderer-DLRRfsdI.js +0 -416
- package/dist/chunks/MarkdownRenderer-DLRRfsdI.js.map +0 -1
- package/dist/chunks/MarkdownRoot-DEE6iVfh.js.map +0 -1
- package/dist/chunks/MarkdownStrikethrough-CblvbqDk.js.map +0 -1
- package/dist/chunks/MarkdownStrong-uU5MzAoJ.js.map +0 -1
- package/dist/chunks/MarkdownTable-DmBTg_CR.js.map +0 -1
- package/dist/chunks/MarkdownTableCell-eiCJe847.js.map +0 -1
- package/dist/chunks/MarkdownTableRow-DuJaPntg.js.map +0 -1
- package/dist/chunks/MarkdownTableSection-PFHz-R33.js.map +0 -1
- package/dist/chunks/MarkdownTaskItem-BcmKo1lk.js.map +0 -1
- package/dist/chunks/MarkdownToc-BdOHF-Yo.js.map +0 -1
- package/dist/chunks/MarkdownTocItem-DT9mR3vL.js.map +0 -1
- package/dist/chunks/MermaidLiveEditor-W-qf3G-5.js.map +0 -1
- package/dist/chunks/VueSyntaxHighlighter-DyLsYMwy.js.map +0 -1
- package/dist/chunks/adapters-CMwX_NEI.js.map +0 -1
- package/dist/chunks/blank-line-Cb-JBP_5.js.map +0 -1
- package/dist/chunks/codemirror-DyphMAEg.js.map +0 -1
- package/dist/chunks/config-aRYo2R8_.js.map +0 -1
- package/dist/chunks/context-8NfW6fxI.js.map +0 -1
- package/dist/chunks/default-DWVS-I_8.js.map +0 -1
- package/dist/chunks/diagnostics-CtHoJyiX.js.map +0 -1
- package/dist/chunks/export-DZQ3cUry.js.map +0 -1
- package/dist/chunks/hast-nodes-C0bX3M5Z.js +0 -35
- package/dist/chunks/hast-nodes-C0bX3M5Z.js.map +0 -1
- package/dist/chunks/highlightjs-BEh-YwEG.js +0 -6041
- package/dist/chunks/highlightjs-BEh-YwEG.js.map +0 -1
- package/dist/chunks/identity-jZEhX2d5.js.map +0 -1
- package/dist/chunks/labels-BtHiUTQI.js.map +0 -1
- package/dist/chunks/lib-BQiWGWpu.js.map +0 -1
- package/dist/chunks/lib-LwqA_W3J.js +0 -127
- package/dist/chunks/lib-LwqA_W3J.js.map +0 -1
- package/dist/chunks/longest-streak-DZE_EqsU.js.map +0 -1
- package/dist/chunks/micromark-factory-space-Db040TnW.js.map +0 -1
- package/dist/chunks/normalize-CRYv3Wqt.js.map +0 -1
- package/dist/chunks/plugin-DqkFHyny.js.map +0 -1
- package/dist/chunks/preset-BjaOuJUL.js.map +0 -1
- package/dist/chunks/registry-DLjr93-V.js.map +0 -1
- package/dist/chunks/render-Cs8iKrgz.js.map +0 -1
- package/dist/chunks/runtime-DJMnzjah.js.map +0 -1
- package/dist/chunks/security-y4EwUyAs.js.map +0 -1
- package/dist/chunks/shared-DNAvZ-UY.js.map +0 -1
- package/dist/chunks/space-separated-tokens-CmBjEPdR.js.map +0 -1
- package/dist/chunks/url-D2BoivaE.js.map +0 -1
- package/dist/chunks/useActiveHeading-BaGVMJnB.js.map +0 -1
- package/dist/highlight/shiki.js.map +0 -1
- package/dist/html/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/math/index.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"render-Cs8iKrgz.js","names":["_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_unref","_openBlock","_createBlock","_resolveDynamicComponent","_withCtx","_renderSlot","_createElementBlock","_createElementVNode","_createVNode","_normalizeStyle","_normalizeClass","_sfc_main","_hoisted_1","_hoisted_2","_openBlock","_createElementBlock","_createVNode","_unref","_createBlock","_sfc_main","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_unref","_createCommentVNode","_toDisplayString","_sfc_main","$slots","_openBlock","_createBlock","_resolveDynamicComponent","_createSlots","_withCtx","_renderSlot","_normalizeProps","_guardReactiveProps","MermaidBlock","_sfc_main","MarkdownParagraph","MarkdownHeading","MarkdownEmphasis","MarkdownStrong","MarkdownStrikethrough","MarkdownLink","MarkdownImage","MarkdownList","MarkdownListItem","MarkdownBlockquote","MarkdownHorizontalRule","MarkdownTable","MarkdownTableSection","MarkdownTableRow","MarkdownTableCell","MarkdownInlineCode","MarkdownBreak","MarkdownCode","MarkdownCustomTag","MarkdownMath","MarkdownMermaid","renderer","CodeBlock","MarkdownTaskItem","MarkdownFootnotes","MarkdownFootnoteReference","resolveLabel","errorMessage","createDiagnostic","_objectSpread2","_asyncToGenerator","useMarkdownConfig","isEmptySlotContent","useRenderContext","runHighlighter","plaintextHighlight","splitHighlightLines","useCodeBlockRegion","MarkdownCode_default","MarkdownBlockquote_default","MarkdownBreak_default","MarkdownCustomTag_default","MarkdownEmphasis_default","MarkdownHeading_default","MarkdownHorizontalRule_default","MarkdownImage_default","MarkdownInlineCode_default","MarkdownLink_default","MarkdownList_default","sanitizeMermaidNodes","renderMermaid","sanitizeSvg","createMermaidRenderId","MarkdownListItem_default","MarkdownFootnoteReference_default","MarkdownFootnotes_default","MarkdownParagraph_default","MarkdownStrikethrough_default","MarkdownTaskItem_default","MarkdownStrong_default","MarkdownTable_default","MarkdownTableCell_default","MarkdownTableRow_default","MarkdownTableSection_default","defaultHighlighterPromise","loadDefaultHighlighter","n","module","error","useCodeHighlighter","resolvedTheme","computed","_ref","_toValue","toValue","options","result","shallowRef","active","reportedDiagnostics","reportDiagnostic","_options$onDiagnostic","signature","diagnostic","colorScheme","generation","timer","run","_run","_toValue2","current","instance","_instance$load","_instance$loadLanguag","language","source","refresh","_toValue3","delay","resolve","watch","_toValue4","onMounted","onScopeDispose","getHighlighted","resolveHighlightedLines","lines","value","values","match","start","end","line","useLineWindow","highlightedLines","lineCount","expanded","ref","scrollTop","viewportHeight","scrollRef","clientReady","highlightedLineSet","maxLines","truncatable","limited","totalLines","virtual","virtualThreshold","lineHeight","virtualActive","startLine","endLine","visibleLines","output","index","_highlightedLines$val","onScroll","target","event","measure","toggle","isHighlightedLine","ICON_PATHS","Icon","h","props","_hoisted_1$2","_hoisted_2$2","_hoisted_3$1","_hoisted_4$1","_hoisted_5$1","CodeBlock_default","defineComponent","__expose","__emit","__props","emit","context","config","ownSlots","useSlots","region","_props$node$code","_props$node","_props$node$language","_props$node2","label","_context$onRenderErro","_props$highlighter","_context$theme","blockMode","lineMode","copyState","copyFeedback","copiedTimer","downloadUrl","copy","_copy","area","succeeded","download","_download","blob","url","anchor","actionHandlers","codeSlotContext","actionSlotContext","headerSlotContext","renderLines","children","highlighted","renderNodes","Content","slot","ActionsContent","toolbar","copyLabel","downloadLabel","action","_ref2","HeaderContent","_unref2","unref","openBlock","createBlock","resolveDynamicComponent","withCtx","renderSlot","_ctx","createElementBlock","createElementVNode","createVNode","normalizeStyle","_cache","args","normalizeClass","_hoisted_1$1","_hoisted_2$1","MarkdownMath_default","_props$tex","display","_props$displayMode","rendered","_props$rendered","_props$node3","engine","_props$mathEngine","engineResult","unavailable","nodes","_engineResult$value$n","_engineResult$value","renderedNodes","katexError","node","_node$attrs$class","nested","renderedError","_props$error","_engineResult$value2","reported","reportError","_context$onMathError","_context$onMathError2","_context$onRenderErro2","MathContent","ErrorContent","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","INVALID_RENDERER_OUTPUT","MermaidBlock_default","_props$source","_props$theme","status","lastGood","view","scale","fullscreen","root","copied","mounted","renderer","isValidMermaidRenderer","rendererId","renderToken","prepareResult","_raw$error","raw","svg","sanitized","render","_render","token","id","next","exception","onUnmounted","onKeydown","message","name","exportPng","_exportPng","_lastGood$value","_canvas$getContext","image","reject","canvas","_unused","downloadSvg","_lastGood$value2","toggleFullscreen","_toggleFullscreen","element","_element$focus","_element$requestFulls","_unused2","_unused3","zoom","delta","resetZoom","showPreview","showSource","runAction","_runAction","_context$onRenderErro3","headerContext","tabsContext","actionsSlotContext","PreviewContent","_lastGood$value3","_lastGood$value4","TabsContent","iconButton","icon","actionLabel","createCommentVNode","toDisplayString","MarkdownMermaid_default","block","_props$code","_context$regions","_block$value","_block$value2","_block$value3","_block$value4","_block$value5","$event","createSlots","normalizeProps","guardReactiveProps","slotProps","BUILTINS","TAG_TO_KIND","semanticBuiltin","kind","isComponentValue","isNodeRenderer","kindOf","_TAG_TO_KIND$node$tag","classList","directTaskInput","child","specialNodeKey","hasNodeId","footnoteTarget","_child$attrs$href","rendererKeys","resolveNodeRenderer","key","_ctx$nodeComponents","ctx","resolveNodeComponent","_ctx$nodeComponents2","inline","tag","special","_ctx$nodeComponents3","specialValue","_ctx$nodeComponents4","_ctx$nodeComponents5","nodeValue","tagValue","kindValue","renderText","matchComponent","segment","resolveKindComponent","_ctx$nodeComponents7","rendererShape","childrenRenderer","childrenPropCache","declaresChildrenProp","cached","component","declared","renderComponent","attrs","extraProps","renderCodeElement","_ctx$nodeComponents8","semantic","className","skipRenderer","renderCode","_ctx$nodeComponents9","_ctx$nodeComponents10","tagComponent","renderTaskItem","input","checked","renderFootnotes","renderFootnoteReference","missing","renderSpecialElement","renderCustom","_resolveKindComponent","renderNodeDefault","resolved","_ref3","_resolveNodeComponent","_ref4","_resolveNodeComponent2","_ref5","_resolveNodeComponent3","renderNode","call","childSource"],"sources":["../../src/composables/useCodeHighlighter.ts","../../src/core/highlight-lines.ts","../../src/composables/useLineWindow.ts","../../src/components/Icon.ts","../../src/components/CodeBlock.vue","../../src/components/CodeBlock.vue","../../src/components/MarkdownMath.vue","../../src/components/MarkdownMath.vue","../../src/components/MermaidBlock.vue","../../src/components/MermaidBlock.vue","../../src/components/MarkdownMermaid.vue","../../src/components/MarkdownMermaid.vue","../../src/components/render.ts"],"sourcesContent":["import {\n computed,\n onMounted,\n onScopeDispose,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from 'vue'\nimport type {\n HighlightResult,\n MarkdownDiagnostic,\n MarkdownHighlighter,\n MarkdownTheme,\n} from '../core/types'\nimport { createDiagnostic, errorMessage } from '../core/diagnostics'\nimport { plaintextHighlight, runHighlighter } from '../highlight/shared'\n\nlet defaultHighlighterPromise: Promise<MarkdownHighlighter> | undefined\n\nfunction loadDefaultHighlighter(): Promise<MarkdownHighlighter> {\n if (!defaultHighlighterPromise) {\n defaultHighlighterPromise = import('../highlight/highlightjs')\n .then((module) => module.highlightjs)\n .catch((error) => {\n // Allow a later block to retry after a transient chunk-load failure.\n defaultHighlighterPromise = undefined\n throw error\n })\n }\n return defaultHighlighterPromise\n}\n\nexport interface UseCodeHighlighterOptions {\n source: MaybeRefOrGetter<string>\n language: MaybeRefOrGetter<string>\n highlighter?: MaybeRefOrGetter<MarkdownHighlighter | undefined>\n theme?: MaybeRefOrGetter<MarkdownTheme | undefined>\n /** Nearest provider or render-context theme, below the local `theme` prop. */\n contextTheme?: MaybeRefOrGetter<MarkdownTheme | undefined>\n /** When false the highlighter is neither loaded nor run (for example, a region replacement). */\n enabled?: MaybeRefOrGetter<boolean>\n /** Optional debounce in milliseconds. */\n delay?: MaybeRefOrGetter<number>\n onDiagnostic?: (diagnostic: MarkdownDiagnostic) => void\n}\n\nexport interface UseCodeHighlighterReturn {\n result: ShallowRef<HighlightResult>\n active: ShallowRef<MarkdownHighlighter | undefined>\n resolvedTheme: ComputedRef<MarkdownTheme>\n refresh: () => Promise<void>\n getHighlighted: () => HighlightResult\n}\n\n/**\n * Shared highlighter state for `CodeBlock` and `VueSyntaxHighlighter`.\n *\n * Keeping the lazy default adapter, theme mapping, readiness loading, and\n * diagnostics in one place prevents the two public components from drifting\n * apart as adapters are added.\n */\nexport function useCodeHighlighter(\n options: UseCodeHighlighterOptions,\n): UseCodeHighlighterReturn {\n const resolvedTheme = computed<MarkdownTheme>(\n () => toValue(options.theme) ?? toValue(options.contextTheme) ?? 'light',\n )\n const result = shallowRef<HighlightResult>(\n plaintextHighlight(toValue(options.source), toValue(options.language)),\n )\n const active = shallowRef<MarkdownHighlighter | undefined>(\n toValue(options.highlighter),\n )\n\n const reportedDiagnostics = new Set<string>()\n function reportDiagnostic(diagnostic: MarkdownDiagnostic): void {\n const signature = `${diagnostic.code}\\u001f${diagnostic.message}`\n if (reportedDiagnostics.has(signature)) return\n reportedDiagnostics.add(signature)\n options.onDiagnostic?.(diagnostic)\n }\n\n function colorScheme(): 'light' | 'dark' {\n if (resolvedTheme.value === 'dark') return 'dark'\n if (resolvedTheme.value === 'auto' && typeof window !== 'undefined') {\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n }\n return 'light'\n }\n\n let generation = 0\n let timer: ReturnType<typeof setTimeout> | undefined\n\n async function run(): Promise<void> {\n const current = ++generation\n if (!(toValue(options.enabled) ?? true)) return\n\n let instance = toValue(options.highlighter)\n if (instance && typeof instance.highlight !== 'function') {\n reportDiagnostic(\n createDiagnostic(\n 'highlighter-invalid',\n 'The supplied highlighter does not implement `highlight()`. Falling back to plain text.',\n { severity: 'warning', phase: 'render' },\n ),\n )\n instance = undefined\n }\n\n if (!instance) {\n try {\n instance = await loadDefaultHighlighter()\n } catch (error) {\n reportDiagnostic(\n createDiagnostic(\n 'highlighter-unavailable',\n 'The default highlight.js adapter could not be loaded. Install the optional `highlight.js` peer dependency to enable syntax highlighting.',\n { severity: 'warning', phase: 'render' },\n ),\n )\n if (import.meta.env.DEV) {\n console.error('highlight.js failed to load', error)\n }\n instance = undefined\n }\n }\n\n if (current !== generation) return\n\n if (!instance || typeof instance.highlight !== 'function') {\n active.value = undefined\n result.value = plaintextHighlight(\n toValue(options.source),\n toValue(options.language),\n )\n return\n }\n\n active.value = instance\n try {\n await instance.load?.()\n const language = toValue(options.language)\n if (language) await instance.loadLanguage?.(language)\n } catch (error) {\n // Adapter readiness failures fall back to plain text, but the host should\n // be able to tell a missing peer or language grammar from a parse error.\n reportDiagnostic(\n createDiagnostic(\n 'highlighter-load',\n `The highlighter could not prepare this language: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n }\n\n if (current !== generation) return\n\n const source = toValue(options.source)\n const language = toValue(options.language)\n result.value = runHighlighter(instance, source, language, {\n theme: resolvedTheme.value,\n colorScheme: colorScheme(),\n })\n }\n\n function refresh(): Promise<void> {\n if (timer) {\n clearTimeout(timer)\n timer = undefined\n }\n const delay = toValue(options.delay) ?? 0\n if (delay > 0) {\n return new Promise((resolve) => {\n timer = setTimeout(() => {\n timer = undefined\n void run().then(resolve)\n }, delay)\n })\n }\n return run()\n }\n\n // Show escaped source immediately for a new snippet while an asynchronous\n // adapter prepares its grammar. Theme and adapter changes keep the previous\n // result until the new one is ready.\n watch(\n () => [toValue(options.source), toValue(options.language)] as const,\n ([source, language]) => {\n result.value = plaintextHighlight(source, language)\n },\n )\n\n watch(\n () =>\n [\n toValue(options.source),\n toValue(options.language),\n toValue(options.highlighter),\n resolvedTheme.value,\n toValue(options.enabled) ?? true,\n ] as const,\n () => {\n void refresh()\n },\n )\n\n onMounted(() => {\n void refresh()\n })\n\n onScopeDispose(() => {\n generation += 1\n if (timer) {\n clearTimeout(timer)\n timer = undefined\n }\n })\n\n function getHighlighted(): HighlightResult {\n return result.value\n }\n\n return {\n result,\n active,\n resolvedTheme,\n refresh,\n getHighlighted,\n }\n}\n","import type { HighlightLine } from './types'\n\n/**\n * Expand numeric lines and `start-end` ranges into a lookup set.\n *\n * Invalid, zero, negative, and reversed entries are ignored. Plain numeric\n * strings are treated as a single line.\n */\nexport function resolveHighlightedLines(\n values: readonly HighlightLine[] | undefined,\n): Set<number> {\n const lines = new Set<number>()\n for (const value of values ?? []) {\n if (typeof value === 'number') {\n if (Number.isInteger(value) && value > 0) lines.add(value)\n continue\n }\n if (typeof value !== 'string') continue\n const match = /^\\s*(\\d+)\\s*(?:-\\s*(\\d+))?\\s*$/.exec(value)\n if (!match) continue\n const start = Number(match[1])\n const end = match[2] ? Number(match[2]) : start\n if (start <= 0 || end < start) continue\n for (let line = start; line <= end; line += 1) lines.add(line)\n }\n return lines\n}\n","import {\n computed,\n onMounted,\n ref,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\nimport type { HighlightLine, MarkdownNode } from '../core/types'\nimport { splitHighlightLines } from '../highlight/shared'\nimport { resolveHighlightedLines } from '../core/highlight-lines'\n\nexport interface VisibleLine {\n index: number\n nodes: MarkdownNode[]\n}\n\nexport interface UseLineWindowOptions {\n nodes: MaybeRefOrGetter<readonly MarkdownNode[]>\n source: MaybeRefOrGetter<string>\n maxLines?: MaybeRefOrGetter<number>\n virtual?: MaybeRefOrGetter<boolean>\n virtualThreshold?: MaybeRefOrGetter<number>\n lineHeight?: MaybeRefOrGetter<number>\n highlightLines?: MaybeRefOrGetter<readonly HighlightLine[] | undefined>\n}\n\nexport interface UseLineWindowReturn {\n highlightedLines: ComputedRef<MarkdownNode[][]>\n expanded: Ref<boolean>\n truncatable: ComputedRef<boolean>\n totalLines: ComputedRef<number>\n virtualActive: ComputedRef<boolean>\n startLine: ComputedRef<number>\n endLine: ComputedRef<number>\n visibleLines: ComputedRef<VisibleLine[]>\n lineHeight: ComputedRef<number>\n scrollRef: Ref<HTMLElement | undefined>\n onScroll: (event: Event) => void\n measure: () => void\n toggle: () => void\n isHighlightedLine: (index: number) => boolean\n}\n\n/**\n * Shared line windowing used by `CodeBlock` and `VueSyntaxHighlighter`.\n *\n * The composable owns only presentation state: split lines, truncation, and\n * the visible window. Highlighting itself stays in `useCodeHighlighter`.\n */\nexport function useLineWindow(\n options: UseLineWindowOptions,\n): UseLineWindowReturn {\n const highlightedLines = computed<MarkdownNode[][]>(() =>\n splitHighlightLines(toValue(options.nodes)),\n )\n const lineCount = computed(() => highlightedLines.value.length)\n const expanded = ref(false)\n const scrollTop = ref(0)\n const viewportHeight = ref(0)\n const scrollRef = ref<HTMLElement>()\n const clientReady = ref(false)\n const highlightedLineSet = computed(() =>\n resolveHighlightedLines(toValue(options.highlightLines)),\n )\n const overscan = 4\n\n const maxLines = computed(() => Math.max(0, toValue(options.maxLines) ?? 0))\n const truncatable = computed(\n () => maxLines.value > 0 && lineCount.value > maxLines.value,\n )\n const limited = computed(() => truncatable.value && !expanded.value)\n const totalLines = computed(() =>\n limited.value\n ? Math.min(lineCount.value, maxLines.value)\n : lineCount.value,\n )\n\n const virtual = computed(() => toValue(options.virtual) ?? false)\n const virtualThreshold = computed(\n () => toValue(options.virtualThreshold) ?? 200,\n )\n const lineHeight = computed(() => toValue(options.lineHeight) ?? 20)\n const virtualActive = computed(\n () =>\n clientReady.value &&\n virtual.value &&\n totalLines.value >= virtualThreshold.value,\n )\n const startLine = computed(() =>\n virtualActive.value\n ? Math.max(\n 0,\n Math.floor(scrollTop.value / lineHeight.value) - overscan,\n )\n : 0,\n )\n const endLine = computed(() =>\n virtualActive.value\n ? Math.min(\n totalLines.value,\n Math.ceil(\n (scrollTop.value + viewportHeight.value) / lineHeight.value,\n ) + overscan,\n )\n : totalLines.value,\n )\n\n const visibleLines = computed<VisibleLine[]>(() => {\n const output: VisibleLine[] = []\n for (let index = startLine.value; index < endLine.value; index += 1) {\n output.push({\n index,\n nodes: highlightedLines.value[index] ?? [],\n })\n }\n return output\n })\n\n function onScroll(event: Event): void {\n const target = event.target as HTMLElement\n scrollTop.value = target.scrollTop\n viewportHeight.value = target.clientHeight\n }\n\n function measure(): void {\n if (scrollRef.value) viewportHeight.value = scrollRef.value.clientHeight\n }\n\n function toggle(): void {\n expanded.value = !expanded.value\n }\n\n function isHighlightedLine(index: number): boolean {\n return highlightedLineSet.value.has(index + 1)\n }\n\n onMounted(() => {\n measure()\n clientReady.value = true\n })\n watch(\n () => toValue(options.source),\n () => {\n expanded.value = false\n },\n )\n\n return {\n highlightedLines,\n expanded,\n truncatable,\n totalLines,\n virtualActive,\n startLine,\n endLine,\n visibleLines,\n lineHeight,\n scrollRef,\n onScroll,\n measure,\n toggle,\n isHighlightedLine,\n }\n}\n","import { h, type FunctionalComponent, type VNode } from 'vue'\n\nexport type IconName =\n | 'copy'\n | 'check'\n | 'download'\n | 'preview'\n | 'source'\n | 'zoom-in'\n | 'zoom-out'\n | 'reset'\n | 'image'\n | 'fullscreen'\n | 'exit-fullscreen'\n | 'retry'\n | 'diagram'\n\nconst ICON_PATHS: Record<IconName, string[]> = {\n copy: ['M8 8h12v12H8z', 'M4 16V4h12'],\n check: ['M4 12l5 5L20 6'],\n download: ['M12 3v12', 'M7 10l5 5 5-5', 'M4 20h16'],\n preview: [\n 'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z',\n 'M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z',\n ],\n source: ['M8 6l-5 6 5 6', 'M16 6l5 6-5 6', 'M14 4l-4 16'],\n 'zoom-in': [\n 'M10 4a6 6 0 1 0 0 12 6 6 0 0 0 0-12z',\n 'M10 7v6',\n 'M7 10h6',\n 'M15.5 15.5L21 21',\n ],\n 'zoom-out': [\n 'M10 4a6 6 0 1 0 0 12 6 6 0 0 0 0-12z',\n 'M7 10h6',\n 'M15.5 15.5L21 21',\n ],\n reset: [\n 'M8 8h8v8H8z',\n 'M4 12h4',\n 'M16 12h4',\n 'M12 4v4',\n 'M12 16v4',\n ],\n image: [\n 'M4 5h16v14H4z',\n 'M4 16l4-4 4 4 3-3 5 5',\n 'M9 9a1 1 0 1 0 0 2 1 1 0 0 0 0-2z',\n ],\n fullscreen: [\n 'M8 3H3v5',\n 'M16 3h5v5',\n 'M21 16v5h-5',\n 'M3 16v5h5',\n ],\n 'exit-fullscreen': [\n 'M3 8h5V3',\n 'M21 8h-5V3',\n 'M16 21v-5h5',\n 'M8 21v-5H3',\n ],\n retry: [\n 'M20 12a8 8 0 1 1-2.34-5.66',\n 'M20 4v6h-6',\n ],\n diagram: [\n 'M4 5h6v4H4z',\n 'M14 15h6v4h-6z',\n 'M7 9v3h10v3',\n ],\n}\n\nexport const Icon: FunctionalComponent<{ name: IconName }> = (props): VNode =>\n h(\n 'svg',\n {\n class: 'vmd-icon',\n viewBox: '0 0 24 24',\n 'aria-hidden': 'true',\n focusable: 'false',\n fill: 'none',\n stroke: 'currentColor',\n 'stroke-width': 1.8,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n },\n ICON_PATHS[props.name].map((d) => h('path', { d })),\n )\n\nexport default Icon\n","<script setup lang=\"ts\">\nimport {\n computed,\n defineComponent,\n h,\n onUnmounted,\n ref,\n useSlots,\n watch,\n type VNodeChild,\n} from 'vue'\nimport type {\n CodeBlockAction,\n HighlightLine,\n MarkdownCodeNode,\n MarkdownDiagnostic,\n MarkdownHighlighter,\n MarkdownTheme,\n} from '../core/types'\nimport { createDiagnostic, errorMessage } from '../core/diagnostics'\nimport { resolveLabel } from '../core/labels'\nimport { useCodeHighlighter } from '../composables/useCodeHighlighter'\nimport { useLineWindow } from '../composables/useLineWindow'\nimport { renderNodes } from './render'\nimport { isEmptySlotContent, useRenderContext } from './context'\nimport { useMarkdownConfig } from './config'\nimport { useCodeBlockRegion } from './codeRegion'\nimport Icon from './Icon'\n\nconst props = withDefaults(\n defineProps<{\n node?: MarkdownCodeNode\n code?: string\n language?: string\n highlighter?: MarkdownHighlighter\n theme?: MarkdownTheme\n actions?: CodeBlockAction[]\n showActions?: boolean\n showDownload?: boolean\n title?: string\n fileName?: string\n lineNumbers?: boolean\n highlightLines?: HighlightLine[]\n maxLines?: number\n virtual?: boolean\n virtualThreshold?: number\n lineHeight?: number\n delay?: number\n /** Render this instance without resolving `regions.codeBlock`. */\n standalone?: boolean\n /** Alias for `standalone`; useful when wrapping a region replacement. */\n ignoreRegion?: boolean\n }>(),\n {\n code: undefined,\n language: undefined,\n highlighter: undefined,\n theme: undefined,\n actions: () => [],\n showActions: true,\n showDownload: false,\n title: undefined,\n fileName: undefined,\n lineNumbers: false,\n highlightLines: () => [],\n maxLines: 0,\n virtual: false,\n virtualThreshold: 200,\n lineHeight: 20,\n delay: 0,\n standalone: false,\n ignoreRegion: false,\n },\n)\n\nconst emit = defineEmits<{\n copy: [source: string]\n download: [source: string]\n action: [key: string]\n error: [diagnostic: MarkdownDiagnostic]\n}>()\n\nconst context = useRenderContext()\nconst config = useMarkdownConfig()\nconst ownSlots = useSlots()\nconst region = useCodeBlockRegion({\n standalone: () => props.standalone,\n ignoreRegion: () => props.ignoreRegion,\n})\nconst source = computed(() => {\n if (props.code !== undefined) return props.code\n return props.node?.code ?? ''\n})\nconst language = computed(() => {\n if (props.language !== undefined) return props.language\n return props.node?.language ?? ''\n})\nconst label = computed(() => language.value || 'text')\n\nfunction reportDiagnostic(diagnostic: MarkdownDiagnostic): void {\n context.onRenderError?.(diagnostic)\n emit('error', diagnostic)\n}\n\nconst { result, active, resolvedTheme, getHighlighted } = useCodeHighlighter({\n source,\n language,\n highlighter: () =>\n props.highlighter ?? context.highlighter ?? config.value.highlighter,\n theme: () => props.theme,\n contextTheme: () => context.theme ?? config.value.theme,\n enabled: () => !region.value,\n onDiagnostic: reportDiagnostic,\n})\n\nconst {\n highlightedLines,\n expanded,\n truncatable,\n virtualActive,\n startLine,\n endLine,\n totalLines,\n visibleLines,\n lineHeight,\n scrollRef,\n onScroll,\n toggle,\n isHighlightedLine,\n} = useLineWindow({\n nodes: () => result.value.nodes,\n source,\n maxLines: () => props.maxLines,\n virtual: () => props.virtual,\n virtualThreshold: () => props.virtualThreshold,\n lineHeight: () => props.lineHeight,\n highlightLines: () => props.highlightLines,\n})\n\nconst blockMode = computed(() => result.value.mode === 'block')\n\nconst lineMode = computed(\n () =>\n props.lineNumbers ||\n props.highlightLines.length > 0 ||\n props.maxLines > 0 ||\n props.virtual,\n)\n\nconst copyState = ref<'idle' | 'copied' | 'failed'>('idle')\nconst copyFeedback = computed(() => {\n if (copyState.value === 'copied') return resolveLabel(context.labels.copied)\n if (copyState.value === 'failed') return resolveLabel(context.labels.copyFailed)\n return ''\n})\n\nlet copiedTimer: ReturnType<typeof setTimeout> | undefined\nlet downloadUrl: string | undefined\nonUnmounted(() => {\n if (copiedTimer) clearTimeout(copiedTimer)\n if (downloadUrl) URL.revokeObjectURL(downloadUrl)\n})\n\nasync function copy(): Promise<void> {\n const value = source.value\n try {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n await navigator.clipboard.writeText(value)\n } else if (typeof document !== 'undefined') {\n const area = document.createElement('textarea')\n area.value = value\n document.body.appendChild(area)\n area.select()\n const succeeded = document.execCommand('copy')\n area.remove()\n if (succeeded === false) throw new Error('The copy command was rejected.')\n } else {\n throw new Error('Clipboard access is not available.')\n }\n emit('copy', value)\n copyState.value = 'copied'\n if (copiedTimer) clearTimeout(copiedTimer)\n copiedTimer = setTimeout(() => {\n copyState.value = 'idle'\n }, 1500)\n } catch (error) {\n copyState.value = 'failed'\n reportDiagnostic(\n createDiagnostic(\n 'copy-error',\n `The source could not be copied to the clipboard: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n if (copiedTimer) clearTimeout(copiedTimer)\n copiedTimer = setTimeout(() => {\n copyState.value = 'idle'\n }, 1500)\n }\n}\n\nasync function download(): Promise<void> {\n const value = source.value\n if (typeof document === 'undefined' || typeof URL === 'undefined') return\n try {\n const blob = new Blob([value], { type: 'text/plain;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n downloadUrl = url\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = props.fileName || `code.${language.value || 'txt'}`\n anchor.click()\n // Revoking synchronously can cancel the download in some browsers.\n setTimeout(() => {\n URL.revokeObjectURL(url)\n if (downloadUrl === url) downloadUrl = undefined\n }, 1000)\n emit('download', value)\n } catch (error) {\n reportDiagnostic(\n createDiagnostic(\n 'download-error',\n `The source could not be downloaded: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n }\n}\n\nconst actionHandlers = computed(() => ({\n copy,\n download,\n}))\n\nconst codeSlotContext = computed(() => ({\n node: props.node,\n source: source.value,\n language: language.value,\n highlighted: result.value,\n nodes: result.value.nodes,\n lines: highlightedLines.value,\n visibleLines: visibleLines.value,\n actions: actionHandlers.value,\n}))\n\nconst actionSlotContext = computed(() => ({\n source: source.value,\n language: language.value,\n fileName: props.fileName,\n title: props.title,\n highlighted: result.value,\n nodes: result.value.nodes,\n actions: actionHandlers.value,\n}))\n\nconst headerSlotContext = computed(() => ({\n ...actionSlotContext.value,\n label: label.value,\n}))\n\nfunction renderLines(): VNodeChild[] {\n const children: VNodeChild[] = []\n if (virtualActive.value && startLine.value > 0) {\n children.push(\n h('div', {\n key: 'spacer-top',\n 'aria-hidden': 'true',\n style: { height: `${startLine.value * lineHeight.value}px` },\n }),\n )\n }\n for (const line of visibleLines.value) {\n const highlighted = isHighlightedLine(line.index)\n children.push(\n h(\n 'div',\n {\n class: 'vmd-highlighter-line',\n 'data-vmd-part': 'highlighter-line',\n 'data-line': String(line.index + 1),\n 'data-highlighted': highlighted ? 'true' : undefined,\n key: `line-${line.index}`,\n },\n [\n props.lineNumbers\n ? h(\n 'span',\n {\n class: 'vmd-highlighter-gutter',\n 'data-vmd-part': 'highlighter-gutter',\n 'aria-hidden': 'true',\n },\n String(line.index + 1),\n )\n : null,\n h(\n 'code',\n {\n class: [\n 'vmd-highlighter-code',\n language.value ? `language-${language.value}` : undefined,\n ],\n },\n renderNodes(line.nodes, context),\n ),\n ],\n ),\n )\n }\n if (virtualActive.value && endLine.value < totalLines.value) {\n children.push(\n h('div', {\n key: 'spacer-bottom',\n 'aria-hidden': 'true',\n style: {\n height: `${(totalLines.value - endLine.value) * lineHeight.value}px`,\n },\n }),\n )\n }\n if (truncatable.value) {\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-highlighter-toggle',\n 'data-vmd-part': 'highlighter-toggle',\n 'aria-expanded': expanded.value ? 'true' : 'false',\n onClick: toggle,\n },\n expanded.value\n ? resolveLabel(context.labels.showLess)\n : resolveLabel(context.labels.showAll),\n ),\n )\n }\n return children\n}\n\nconst Content = defineComponent({\n setup() {\n return () =>\n context.renderHostSlot('code', codeSlotContext.value, () => {\n const slot = ownSlots.code\n if (slot) {\n const output = slot(codeSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n if (blockMode.value) return renderNodes(result.value.nodes, context)\n if (lineMode.value) return renderLines()\n return renderNodes(result.value.nodes, context) as VNodeChild\n })\n },\n})\n\nconst ActionsContent = defineComponent({\n setup() {\n return () =>\n context.renderHostSlot('toolbar', actionSlotContext.value, () => {\n const toolbar = ownSlots.toolbar\n if (toolbar) {\n const output = toolbar(actionSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n return context.renderHostSlot(\n 'code-actions',\n actionSlotContext.value,\n () => {\n const slot = ownSlots['code-actions']\n if (slot) {\n const output = slot(actionSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n if (!props.showActions && props.actions.length === 0) return null\n const children: VNodeChild[] = []\n if (props.showActions) {\n const copyLabel =\n copyState.value === 'copied'\n ? resolveLabel(context.labels.copied)\n : copyState.value === 'failed'\n ? resolveLabel(context.labels.copyFailed)\n : resolveLabel(context.labels.copy)\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-code-action',\n 'data-vmd-part': 'code-action',\n 'data-action': 'copy',\n 'data-icon': 'true',\n 'data-state': copyState.value,\n 'aria-label': copyLabel,\n title: copyLabel,\n onClick: copy,\n },\n [\n h(Icon, {\n name: copyState.value === 'copied' ? 'check' : 'copy',\n }),\n h(\n 'span',\n { class: 'vmd-visually-hidden' },\n copyLabel,\n ),\n ],\n ),\n )\n if (props.showDownload) {\n const downloadLabel = resolveLabel(context.labels.download)\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-code-action',\n 'data-vmd-part': 'code-action',\n 'data-action': 'download',\n 'data-icon': 'true',\n 'aria-label': downloadLabel,\n title: downloadLabel,\n onClick: download,\n },\n [\n h(Icon, { name: 'download' }),\n h(\n 'span',\n { class: 'vmd-visually-hidden' },\n downloadLabel,\n ),\n ],\n ),\n )\n }\n }\n for (const action of props.actions) {\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-code-action',\n 'data-vmd-part': 'code-action',\n 'data-action': action.key,\n onClick: async () => {\n try {\n await action.run({\n code: source.value,\n language: language.value,\n copy,\n download,\n })\n emit('action', action.key)\n } catch (error) {\n reportDiagnostic(\n createDiagnostic(\n 'action-error',\n `The \"${action.key}\" action failed: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n }\n },\n },\n resolveLabel(action.label),\n ),\n )\n }\n children.push(\n h(\n 'span',\n {\n class: 'vmd-code-feedback',\n 'data-vmd-part': 'code-feedback',\n 'data-state': copyState.value,\n role: 'status',\n 'aria-live': 'polite',\n },\n copyFeedback.value,\n ),\n )\n return children\n },\n )\n })\n },\n})\n\nconst HeaderContent = defineComponent({\n setup() {\n return () =>\n context.renderHostSlot('header', headerSlotContext.value, () => {\n const slot = ownSlots.header\n if (slot) {\n const output = slot(headerSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n return [\n h(\n 'span',\n { class: 'vmd-code-heading', 'data-vmd-part': 'code-heading' },\n [\n h(Icon, { name: 'source' }),\n props.title\n ? h(\n 'span',\n { class: 'vmd-code-title', 'data-vmd-part': 'code-title' },\n props.title,\n )\n : null,\n props.fileName\n ? h(\n 'span',\n {\n class: 'vmd-code-file-name',\n 'data-vmd-part': 'code-file-name',\n },\n props.fileName,\n )\n : null,\n h(\n 'span',\n { class: 'vmd-code-lang', 'data-vmd-part': 'code-lang' },\n label.value,\n ),\n ],\n ),\n h(\n 'span',\n { class: 'vmd-code-toolbar', 'data-vmd-part': 'code-toolbar' },\n [h(ActionsContent)],\n ),\n ]\n })\n },\n})\n\nwatch(\n () => [source.value, language.value] as const,\n () => {\n copyState.value = 'idle'\n },\n)\n\ndefineExpose({ copy, download, getHighlighted, highlighted: result })\n</script>\n\n<template>\n <component\n :is=\"region\"\n v-if=\"region\"\n :node=\"node\"\n :code=\"source\"\n :language=\"language\"\n :theme=\"resolvedTheme\"\n :highlighter=\"active\"\n :actions=\"actions\"\n :show-actions=\"showActions\"\n :show-download=\"showDownload\"\n :title=\"title\"\n :file-name=\"fileName\"\n :line-numbers=\"lineNumbers\"\n :highlight-lines=\"highlightLines\"\n :max-lines=\"maxLines\"\n :virtual=\"virtual\"\n :virtual-threshold=\"virtualThreshold\"\n :line-height=\"lineHeight\"\n :delay=\"delay\"\n :highlighted=\"result\"\n :action-handlers=\"actionHandlers\"\n :copy=\"copy\"\n :download=\"download\"\n >\n <slot />\n </component>\n <div\n v-else\n data-vmd-part=\"code\"\n class=\"vmd-code vmd-code-block\"\n :data-vmd-theme=\"resolvedTheme\"\n :data-language=\"label\"\n :data-highlighter=\"active?.id\"\n :data-virtual=\"virtualActive ? 'true' : undefined\"\n >\n <div data-vmd-part=\"code-header\" class=\"vmd-code-header\">\n <HeaderContent />\n </div>\n <div\n v-if=\"blockMode\"\n data-vmd-part=\"code-body\"\n class=\"vmd-code-body vmd-code-block-body\"\n >\n <Content />\n </div>\n <div\n v-else-if=\"lineMode\"\n ref=\"scrollRef\"\n data-vmd-part=\"code-body\"\n class=\"vmd-code-body vmd-code-lines\"\n :data-virtual=\"virtualActive ? 'true' : undefined\"\n :style=\"\n virtualActive\n ? { maxHeight: `${lineHeight * 20}px`, overflow: 'auto' }\n : undefined\n \"\n @scroll=\"onScroll\"\n >\n <Content />\n </div>\n <pre\n v-else\n data-vmd-part=\"code-body\"\n class=\"vmd-code-body\"\n ><code\n class=\"vmd-code-element\"\n :class=\"language ? `language-${language}` : undefined\"\n ><Content /></code></pre>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n computed,\n defineComponent,\n h,\n onUnmounted,\n ref,\n useSlots,\n watch,\n type VNodeChild,\n} from 'vue'\nimport type {\n CodeBlockAction,\n HighlightLine,\n MarkdownCodeNode,\n MarkdownDiagnostic,\n MarkdownHighlighter,\n MarkdownTheme,\n} from '../core/types'\nimport { createDiagnostic, errorMessage } from '../core/diagnostics'\nimport { resolveLabel } from '../core/labels'\nimport { useCodeHighlighter } from '../composables/useCodeHighlighter'\nimport { useLineWindow } from '../composables/useLineWindow'\nimport { renderNodes } from './render'\nimport { isEmptySlotContent, useRenderContext } from './context'\nimport { useMarkdownConfig } from './config'\nimport { useCodeBlockRegion } from './codeRegion'\nimport Icon from './Icon'\n\nconst props = withDefaults(\n defineProps<{\n node?: MarkdownCodeNode\n code?: string\n language?: string\n highlighter?: MarkdownHighlighter\n theme?: MarkdownTheme\n actions?: CodeBlockAction[]\n showActions?: boolean\n showDownload?: boolean\n title?: string\n fileName?: string\n lineNumbers?: boolean\n highlightLines?: HighlightLine[]\n maxLines?: number\n virtual?: boolean\n virtualThreshold?: number\n lineHeight?: number\n delay?: number\n /** Render this instance without resolving `regions.codeBlock`. */\n standalone?: boolean\n /** Alias for `standalone`; useful when wrapping a region replacement. */\n ignoreRegion?: boolean\n }>(),\n {\n code: undefined,\n language: undefined,\n highlighter: undefined,\n theme: undefined,\n actions: () => [],\n showActions: true,\n showDownload: false,\n title: undefined,\n fileName: undefined,\n lineNumbers: false,\n highlightLines: () => [],\n maxLines: 0,\n virtual: false,\n virtualThreshold: 200,\n lineHeight: 20,\n delay: 0,\n standalone: false,\n ignoreRegion: false,\n },\n)\n\nconst emit = defineEmits<{\n copy: [source: string]\n download: [source: string]\n action: [key: string]\n error: [diagnostic: MarkdownDiagnostic]\n}>()\n\nconst context = useRenderContext()\nconst config = useMarkdownConfig()\nconst ownSlots = useSlots()\nconst region = useCodeBlockRegion({\n standalone: () => props.standalone,\n ignoreRegion: () => props.ignoreRegion,\n})\nconst source = computed(() => {\n if (props.code !== undefined) return props.code\n return props.node?.code ?? ''\n})\nconst language = computed(() => {\n if (props.language !== undefined) return props.language\n return props.node?.language ?? ''\n})\nconst label = computed(() => language.value || 'text')\n\nfunction reportDiagnostic(diagnostic: MarkdownDiagnostic): void {\n context.onRenderError?.(diagnostic)\n emit('error', diagnostic)\n}\n\nconst { result, active, resolvedTheme, getHighlighted } = useCodeHighlighter({\n source,\n language,\n highlighter: () =>\n props.highlighter ?? context.highlighter ?? config.value.highlighter,\n theme: () => props.theme,\n contextTheme: () => context.theme ?? config.value.theme,\n enabled: () => !region.value,\n onDiagnostic: reportDiagnostic,\n})\n\nconst {\n highlightedLines,\n expanded,\n truncatable,\n virtualActive,\n startLine,\n endLine,\n totalLines,\n visibleLines,\n lineHeight,\n scrollRef,\n onScroll,\n toggle,\n isHighlightedLine,\n} = useLineWindow({\n nodes: () => result.value.nodes,\n source,\n maxLines: () => props.maxLines,\n virtual: () => props.virtual,\n virtualThreshold: () => props.virtualThreshold,\n lineHeight: () => props.lineHeight,\n highlightLines: () => props.highlightLines,\n})\n\nconst blockMode = computed(() => result.value.mode === 'block')\n\nconst lineMode = computed(\n () =>\n props.lineNumbers ||\n props.highlightLines.length > 0 ||\n props.maxLines > 0 ||\n props.virtual,\n)\n\nconst copyState = ref<'idle' | 'copied' | 'failed'>('idle')\nconst copyFeedback = computed(() => {\n if (copyState.value === 'copied') return resolveLabel(context.labels.copied)\n if (copyState.value === 'failed') return resolveLabel(context.labels.copyFailed)\n return ''\n})\n\nlet copiedTimer: ReturnType<typeof setTimeout> | undefined\nlet downloadUrl: string | undefined\nonUnmounted(() => {\n if (copiedTimer) clearTimeout(copiedTimer)\n if (downloadUrl) URL.revokeObjectURL(downloadUrl)\n})\n\nasync function copy(): Promise<void> {\n const value = source.value\n try {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n await navigator.clipboard.writeText(value)\n } else if (typeof document !== 'undefined') {\n const area = document.createElement('textarea')\n area.value = value\n document.body.appendChild(area)\n area.select()\n const succeeded = document.execCommand('copy')\n area.remove()\n if (succeeded === false) throw new Error('The copy command was rejected.')\n } else {\n throw new Error('Clipboard access is not available.')\n }\n emit('copy', value)\n copyState.value = 'copied'\n if (copiedTimer) clearTimeout(copiedTimer)\n copiedTimer = setTimeout(() => {\n copyState.value = 'idle'\n }, 1500)\n } catch (error) {\n copyState.value = 'failed'\n reportDiagnostic(\n createDiagnostic(\n 'copy-error',\n `The source could not be copied to the clipboard: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n if (copiedTimer) clearTimeout(copiedTimer)\n copiedTimer = setTimeout(() => {\n copyState.value = 'idle'\n }, 1500)\n }\n}\n\nasync function download(): Promise<void> {\n const value = source.value\n if (typeof document === 'undefined' || typeof URL === 'undefined') return\n try {\n const blob = new Blob([value], { type: 'text/plain;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n downloadUrl = url\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = props.fileName || `code.${language.value || 'txt'}`\n anchor.click()\n // Revoking synchronously can cancel the download in some browsers.\n setTimeout(() => {\n URL.revokeObjectURL(url)\n if (downloadUrl === url) downloadUrl = undefined\n }, 1000)\n emit('download', value)\n } catch (error) {\n reportDiagnostic(\n createDiagnostic(\n 'download-error',\n `The source could not be downloaded: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n }\n}\n\nconst actionHandlers = computed(() => ({\n copy,\n download,\n}))\n\nconst codeSlotContext = computed(() => ({\n node: props.node,\n source: source.value,\n language: language.value,\n highlighted: result.value,\n nodes: result.value.nodes,\n lines: highlightedLines.value,\n visibleLines: visibleLines.value,\n actions: actionHandlers.value,\n}))\n\nconst actionSlotContext = computed(() => ({\n source: source.value,\n language: language.value,\n fileName: props.fileName,\n title: props.title,\n highlighted: result.value,\n nodes: result.value.nodes,\n actions: actionHandlers.value,\n}))\n\nconst headerSlotContext = computed(() => ({\n ...actionSlotContext.value,\n label: label.value,\n}))\n\nfunction renderLines(): VNodeChild[] {\n const children: VNodeChild[] = []\n if (virtualActive.value && startLine.value > 0) {\n children.push(\n h('div', {\n key: 'spacer-top',\n 'aria-hidden': 'true',\n style: { height: `${startLine.value * lineHeight.value}px` },\n }),\n )\n }\n for (const line of visibleLines.value) {\n const highlighted = isHighlightedLine(line.index)\n children.push(\n h(\n 'div',\n {\n class: 'vmd-highlighter-line',\n 'data-vmd-part': 'highlighter-line',\n 'data-line': String(line.index + 1),\n 'data-highlighted': highlighted ? 'true' : undefined,\n key: `line-${line.index}`,\n },\n [\n props.lineNumbers\n ? h(\n 'span',\n {\n class: 'vmd-highlighter-gutter',\n 'data-vmd-part': 'highlighter-gutter',\n 'aria-hidden': 'true',\n },\n String(line.index + 1),\n )\n : null,\n h(\n 'code',\n {\n class: [\n 'vmd-highlighter-code',\n language.value ? `language-${language.value}` : undefined,\n ],\n },\n renderNodes(line.nodes, context),\n ),\n ],\n ),\n )\n }\n if (virtualActive.value && endLine.value < totalLines.value) {\n children.push(\n h('div', {\n key: 'spacer-bottom',\n 'aria-hidden': 'true',\n style: {\n height: `${(totalLines.value - endLine.value) * lineHeight.value}px`,\n },\n }),\n )\n }\n if (truncatable.value) {\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-highlighter-toggle',\n 'data-vmd-part': 'highlighter-toggle',\n 'aria-expanded': expanded.value ? 'true' : 'false',\n onClick: toggle,\n },\n expanded.value\n ? resolveLabel(context.labels.showLess)\n : resolveLabel(context.labels.showAll),\n ),\n )\n }\n return children\n}\n\nconst Content = defineComponent({\n setup() {\n return () =>\n context.renderHostSlot('code', codeSlotContext.value, () => {\n const slot = ownSlots.code\n if (slot) {\n const output = slot(codeSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n if (blockMode.value) return renderNodes(result.value.nodes, context)\n if (lineMode.value) return renderLines()\n return renderNodes(result.value.nodes, context) as VNodeChild\n })\n },\n})\n\nconst ActionsContent = defineComponent({\n setup() {\n return () =>\n context.renderHostSlot('toolbar', actionSlotContext.value, () => {\n const toolbar = ownSlots.toolbar\n if (toolbar) {\n const output = toolbar(actionSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n return context.renderHostSlot(\n 'code-actions',\n actionSlotContext.value,\n () => {\n const slot = ownSlots['code-actions']\n if (slot) {\n const output = slot(actionSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n if (!props.showActions && props.actions.length === 0) return null\n const children: VNodeChild[] = []\n if (props.showActions) {\n const copyLabel =\n copyState.value === 'copied'\n ? resolveLabel(context.labels.copied)\n : copyState.value === 'failed'\n ? resolveLabel(context.labels.copyFailed)\n : resolveLabel(context.labels.copy)\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-code-action',\n 'data-vmd-part': 'code-action',\n 'data-action': 'copy',\n 'data-icon': 'true',\n 'data-state': copyState.value,\n 'aria-label': copyLabel,\n title: copyLabel,\n onClick: copy,\n },\n [\n h(Icon, {\n name: copyState.value === 'copied' ? 'check' : 'copy',\n }),\n h(\n 'span',\n { class: 'vmd-visually-hidden' },\n copyLabel,\n ),\n ],\n ),\n )\n if (props.showDownload) {\n const downloadLabel = resolveLabel(context.labels.download)\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-code-action',\n 'data-vmd-part': 'code-action',\n 'data-action': 'download',\n 'data-icon': 'true',\n 'aria-label': downloadLabel,\n title: downloadLabel,\n onClick: download,\n },\n [\n h(Icon, { name: 'download' }),\n h(\n 'span',\n { class: 'vmd-visually-hidden' },\n downloadLabel,\n ),\n ],\n ),\n )\n }\n }\n for (const action of props.actions) {\n children.push(\n h(\n 'button',\n {\n type: 'button',\n class: 'vmd-code-action',\n 'data-vmd-part': 'code-action',\n 'data-action': action.key,\n onClick: async () => {\n try {\n await action.run({\n code: source.value,\n language: language.value,\n copy,\n download,\n })\n emit('action', action.key)\n } catch (error) {\n reportDiagnostic(\n createDiagnostic(\n 'action-error',\n `The \"${action.key}\" action failed: ${errorMessage(error)}`,\n { severity: 'warning', phase: 'render' },\n ),\n )\n }\n },\n },\n resolveLabel(action.label),\n ),\n )\n }\n children.push(\n h(\n 'span',\n {\n class: 'vmd-code-feedback',\n 'data-vmd-part': 'code-feedback',\n 'data-state': copyState.value,\n role: 'status',\n 'aria-live': 'polite',\n },\n copyFeedback.value,\n ),\n )\n return children\n },\n )\n })\n },\n})\n\nconst HeaderContent = defineComponent({\n setup() {\n return () =>\n context.renderHostSlot('header', headerSlotContext.value, () => {\n const slot = ownSlots.header\n if (slot) {\n const output = slot(headerSlotContext.value)\n if (!isEmptySlotContent(output)) return output\n }\n return [\n h(\n 'span',\n { class: 'vmd-code-heading', 'data-vmd-part': 'code-heading' },\n [\n h(Icon, { name: 'source' }),\n props.title\n ? h(\n 'span',\n { class: 'vmd-code-title', 'data-vmd-part': 'code-title' },\n props.title,\n )\n : null,\n props.fileName\n ? h(\n 'span',\n {\n class: 'vmd-code-file-name',\n 'data-vmd-part': 'code-file-name',\n },\n props.fileName,\n )\n : null,\n h(\n 'span',\n { class: 'vmd-code-lang', 'data-vmd-part': 'code-lang' },\n label.value,\n ),\n ],\n ),\n h(\n 'span',\n { class: 'vmd-code-toolbar', 'data-vmd-part': 'code-toolbar' },\n [h(ActionsContent)],\n ),\n ]\n })\n },\n})\n\nwatch(\n () => [source.value, language.value] as const,\n () => {\n copyState.value = 'idle'\n },\n)\n\ndefineExpose({ copy, download, getHighlighted, highlighted: result })\n</script>\n\n<template>\n <component\n :is=\"region\"\n v-if=\"region\"\n :node=\"node\"\n :code=\"source\"\n :language=\"language\"\n :theme=\"resolvedTheme\"\n :highlighter=\"active\"\n :actions=\"actions\"\n :show-actions=\"showActions\"\n :show-download=\"showDownload\"\n :title=\"title\"\n :file-name=\"fileName\"\n :line-numbers=\"lineNumbers\"\n :highlight-lines=\"highlightLines\"\n :max-lines=\"maxLines\"\n :virtual=\"virtual\"\n :virtual-threshold=\"virtualThreshold\"\n :line-height=\"lineHeight\"\n :delay=\"delay\"\n :highlighted=\"result\"\n :action-handlers=\"actionHandlers\"\n :copy=\"copy\"\n :download=\"download\"\n >\n <slot />\n </component>\n <div\n v-else\n data-vmd-part=\"code\"\n class=\"vmd-code vmd-code-block\"\n :data-vmd-theme=\"resolvedTheme\"\n :data-language=\"label\"\n :data-highlighter=\"active?.id\"\n :data-virtual=\"virtualActive ? 'true' : undefined\"\n >\n <div data-vmd-part=\"code-header\" class=\"vmd-code-header\">\n <HeaderContent />\n </div>\n <div\n v-if=\"blockMode\"\n data-vmd-part=\"code-body\"\n class=\"vmd-code-body vmd-code-block-body\"\n >\n <Content />\n </div>\n <div\n v-else-if=\"lineMode\"\n ref=\"scrollRef\"\n data-vmd-part=\"code-body\"\n class=\"vmd-code-body vmd-code-lines\"\n :data-virtual=\"virtualActive ? 'true' : undefined\"\n :style=\"\n virtualActive\n ? { maxHeight: `${lineHeight * 20}px`, overflow: 'auto' }\n : undefined\n \"\n @scroll=\"onScroll\"\n >\n <Content />\n </div>\n <pre\n v-else\n data-vmd-part=\"code-body\"\n class=\"vmd-code-body\"\n ><code\n class=\"vmd-code-element\"\n :class=\"language ? `language-${language}` : undefined\"\n ><Content /></code></pre>\n </div>\n</template>\n","<script setup lang=\"ts\">\r\nimport {\r\n computed,\r\n defineComponent,\r\n h,\r\n onMounted,\r\n watch,\r\n type VNodeChild,\r\n} from 'vue'\r\nimport type { MarkdownNode, MathEngine } from '../core/types'\r\nimport { createDiagnostic } from '../core/diagnostics'\r\nimport { resolveLabel } from '../core/labels'\r\nimport { useRenderContext } from './context'\r\nimport { renderNodes } from './render'\r\n\r\nconst props = defineProps<{\r\n node?: MarkdownNode\r\n tex?: string\r\n displayMode?: boolean\r\n rendered?: MarkdownNode[]\r\n error?: string\r\n mathEngine?: MathEngine\r\n}>()\r\n\r\nconst context = useRenderContext()\r\nconst source = computed(\r\n () => props.tex ?? (props.node?.kind === 'math' ? props.node.tex : ''),\r\n)\r\nconst display = computed(\r\n () =>\r\n props.displayMode ??\r\n (props.node?.kind === 'math' ? props.node.displayMode : false),\r\n)\r\nconst rendered = computed(\r\n () => props.rendered ?? (props.node?.kind === 'math' ? props.node.rendered : []),\r\n)\r\nconst engine = computed(() => props.mathEngine ?? context.mathEngine)\r\nconst engineResult = computed(() => {\r\n if (!engine.value) return undefined\r\n try {\r\n return engine.value.render(source.value, { displayMode: display.value })\r\n } catch (error) {\r\n return {\r\n nodes: [{ kind: 'text' as const, key: 'math-error', value: source.value }],\r\n error: error instanceof Error ? error.message : String(error),\r\n }\r\n }\r\n})\r\nconst unavailable = computed(\r\n () =>\r\n !engine.value &&\r\n (rendered.value === undefined || rendered.value.length === 0) &&\r\n source.value !== '',\r\n)\r\nconst nodes = computed(() => {\r\n const renderedNodes = engineResult.value?.nodes ?? rendered.value ?? []\r\n if (renderedNodes.length > 0) return renderedNodes\r\n return unavailable.value\r\n ? [{ kind: 'text' as const, key: 'math-source', value: source.value }]\r\n : renderedNodes\r\n})\r\n\r\nfunction katexError(\r\n nodes: readonly MarkdownNode[] | undefined,\r\n): string | undefined {\r\n if (!nodes) return undefined\r\n for (const node of nodes) {\r\n if (node.kind !== 'element') continue\r\n const classes = (node.attrs.class ?? '').split(/\\s+/)\r\n if (classes.includes('katex-error')) {\r\n return node.attrs.title || 'Invalid TeX expression.'\r\n }\r\n const nested = katexError(node.children)\r\n if (nested) return nested\r\n }\r\n return undefined\r\n}\r\n\r\n// The default pipeline path renders KaTeX markup inside `rendered` rather than\r\n// reporting an engine error, so surface its `katex-error` marker through the\r\n// same diagnostic path as an injected engine failure. When an engine result\r\n// exists its nodes replace `rendered`, so the pipeline markup no longer\r\n// describes what is displayed.\r\nconst renderedError = computed(() =>\r\n engineResult.value ? undefined : katexError(rendered.value),\r\n)\r\nconst error = computed(\r\n () => props.error ?? engineResult.value?.error ?? renderedError.value,\r\n)\r\nconst label = computed(() => resolveLabel(context.labels.math, { tex: source.value }))\r\n\r\nlet reported = false\r\nfunction reportError(): void {\r\n if (reported) return\r\n if (error.value) {\r\n reported = true\r\n const diagnostic = createDiagnostic('math-error', error.value, {\r\n phase: 'render',\r\n })\r\n context.onMathError?.(diagnostic)\r\n context.onRenderError?.(diagnostic)\r\n return\r\n }\r\n if (unavailable.value) {\r\n reported = true\r\n const diagnostic = createDiagnostic(\r\n 'math-engine-unavailable',\r\n 'No math engine or pre-rendered math output is available. Provide `mathEngine`, `rendered`, or use `mathPlugin()`.',\r\n { severity: 'warning', phase: 'render' },\r\n )\r\n context.onMathError?.(diagnostic)\r\n context.onRenderError?.(diagnostic)\r\n }\r\n}\r\n\r\nonMounted(reportError)\r\nwatch([error, unavailable], reportError)\r\n\r\nconst MathContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'math',\r\n {\r\n tex: source.value,\r\n displayMode: display.value,\r\n rendered: nodes.value,\r\n error: error.value,\r\n },\r\n () => renderNodes(nodes.value, context) as VNodeChild,\r\n )\r\n },\r\n})\r\n\r\nconst ErrorContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'math-error',\r\n {\r\n tex: source.value,\r\n error: error.value,\r\n retry: () => undefined,\r\n },\r\n () => h('span', { class: 'vmd-math-fallback' }, source.value),\r\n )\r\n },\r\n})\r\n</script>\r\n\r\n<template>\r\n <span\r\n data-vmd-part=\"math\"\r\n class=\"vmd-math\"\r\n :data-display=\"display ? 'true' : 'false'\"\r\n :data-error=\"error ? 'true' : undefined\"\r\n :aria-label=\"label\"\r\n >\r\n <span\r\n v-if=\"error\"\r\n data-vmd-part=\"math-error\"\r\n class=\"vmd-math-error\"\r\n role=\"status\"\r\n ><ErrorContent /></span>\r\n <MathContent v-else />\r\n </span>\r\n</template>\r\n","<script setup lang=\"ts\">\r\nimport {\r\n computed,\r\n defineComponent,\r\n h,\r\n onMounted,\r\n watch,\r\n type VNodeChild,\r\n} from 'vue'\r\nimport type { MarkdownNode, MathEngine } from '../core/types'\r\nimport { createDiagnostic } from '../core/diagnostics'\r\nimport { resolveLabel } from '../core/labels'\r\nimport { useRenderContext } from './context'\r\nimport { renderNodes } from './render'\r\n\r\nconst props = defineProps<{\r\n node?: MarkdownNode\r\n tex?: string\r\n displayMode?: boolean\r\n rendered?: MarkdownNode[]\r\n error?: string\r\n mathEngine?: MathEngine\r\n}>()\r\n\r\nconst context = useRenderContext()\r\nconst source = computed(\r\n () => props.tex ?? (props.node?.kind === 'math' ? props.node.tex : ''),\r\n)\r\nconst display = computed(\r\n () =>\r\n props.displayMode ??\r\n (props.node?.kind === 'math' ? props.node.displayMode : false),\r\n)\r\nconst rendered = computed(\r\n () => props.rendered ?? (props.node?.kind === 'math' ? props.node.rendered : []),\r\n)\r\nconst engine = computed(() => props.mathEngine ?? context.mathEngine)\r\nconst engineResult = computed(() => {\r\n if (!engine.value) return undefined\r\n try {\r\n return engine.value.render(source.value, { displayMode: display.value })\r\n } catch (error) {\r\n return {\r\n nodes: [{ kind: 'text' as const, key: 'math-error', value: source.value }],\r\n error: error instanceof Error ? error.message : String(error),\r\n }\r\n }\r\n})\r\nconst unavailable = computed(\r\n () =>\r\n !engine.value &&\r\n (rendered.value === undefined || rendered.value.length === 0) &&\r\n source.value !== '',\r\n)\r\nconst nodes = computed(() => {\r\n const renderedNodes = engineResult.value?.nodes ?? rendered.value ?? []\r\n if (renderedNodes.length > 0) return renderedNodes\r\n return unavailable.value\r\n ? [{ kind: 'text' as const, key: 'math-source', value: source.value }]\r\n : renderedNodes\r\n})\r\n\r\nfunction katexError(\r\n nodes: readonly MarkdownNode[] | undefined,\r\n): string | undefined {\r\n if (!nodes) return undefined\r\n for (const node of nodes) {\r\n if (node.kind !== 'element') continue\r\n const classes = (node.attrs.class ?? '').split(/\\s+/)\r\n if (classes.includes('katex-error')) {\r\n return node.attrs.title || 'Invalid TeX expression.'\r\n }\r\n const nested = katexError(node.children)\r\n if (nested) return nested\r\n }\r\n return undefined\r\n}\r\n\r\n// The default pipeline path renders KaTeX markup inside `rendered` rather than\r\n// reporting an engine error, so surface its `katex-error` marker through the\r\n// same diagnostic path as an injected engine failure. When an engine result\r\n// exists its nodes replace `rendered`, so the pipeline markup no longer\r\n// describes what is displayed.\r\nconst renderedError = computed(() =>\r\n engineResult.value ? undefined : katexError(rendered.value),\r\n)\r\nconst error = computed(\r\n () => props.error ?? engineResult.value?.error ?? renderedError.value,\r\n)\r\nconst label = computed(() => resolveLabel(context.labels.math, { tex: source.value }))\r\n\r\nlet reported = false\r\nfunction reportError(): void {\r\n if (reported) return\r\n if (error.value) {\r\n reported = true\r\n const diagnostic = createDiagnostic('math-error', error.value, {\r\n phase: 'render',\r\n })\r\n context.onMathError?.(diagnostic)\r\n context.onRenderError?.(diagnostic)\r\n return\r\n }\r\n if (unavailable.value) {\r\n reported = true\r\n const diagnostic = createDiagnostic(\r\n 'math-engine-unavailable',\r\n 'No math engine or pre-rendered math output is available. Provide `mathEngine`, `rendered`, or use `mathPlugin()`.',\r\n { severity: 'warning', phase: 'render' },\r\n )\r\n context.onMathError?.(diagnostic)\r\n context.onRenderError?.(diagnostic)\r\n }\r\n}\r\n\r\nonMounted(reportError)\r\nwatch([error, unavailable], reportError)\r\n\r\nconst MathContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'math',\r\n {\r\n tex: source.value,\r\n displayMode: display.value,\r\n rendered: nodes.value,\r\n error: error.value,\r\n },\r\n () => renderNodes(nodes.value, context) as VNodeChild,\r\n )\r\n },\r\n})\r\n\r\nconst ErrorContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'math-error',\r\n {\r\n tex: source.value,\r\n error: error.value,\r\n retry: () => undefined,\r\n },\r\n () => h('span', { class: 'vmd-math-fallback' }, source.value),\r\n )\r\n },\r\n})\r\n</script>\r\n\r\n<template>\r\n <span\r\n data-vmd-part=\"math\"\r\n class=\"vmd-math\"\r\n :data-display=\"display ? 'true' : 'false'\"\r\n :data-error=\"error ? 'true' : undefined\"\r\n :aria-label=\"label\"\r\n >\r\n <span\r\n v-if=\"error\"\r\n data-vmd-part=\"math-error\"\r\n class=\"vmd-math-error\"\r\n role=\"status\"\r\n ><ErrorContent /></span>\r\n <MathContent v-else />\r\n </span>\r\n</template>\r\n","<script setup lang=\"ts\">\r\nimport {\r\n computed,\r\n defineComponent,\r\n h,\r\n onMounted,\r\n onUnmounted,\r\n ref,\r\n shallowRef,\r\n useSlots,\r\n watch,\r\n} from 'vue'\r\nimport type {\r\n MarkdownNode,\r\n MarkdownTheme,\r\n MermaidAction,\r\n MermaidRenderResult,\r\n MermaidRenderer,\r\n} from '../core/types'\r\nimport { createDiagnostic, errorMessage } from '../core/diagnostics'\r\nimport { resolveLabel } from '../core/labels'\r\nimport { isValidMermaidRenderer } from '../core/adapters'\r\nimport { isEmptySlotContent, useRenderContext } from './context'\r\nimport { renderNodes } from './render'\r\nimport { createMermaidRenderId, renderMermaid } from '../mermaid/runtime'\r\nimport Icon, { type IconName } from './Icon'\r\nimport { sanitizeMermaidNodes, sanitizeSvg } from '../mermaid/sanitize'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n node?: MarkdownNode\r\n source?: string\r\n renderer?: MermaidRenderer\r\n theme?: MarkdownTheme\r\n showErrors?: boolean\r\n enableZoom?: boolean\r\n allowFullscreen?: boolean\r\n compact?: boolean\r\n actions?: MermaidAction[]\r\n }>(),\r\n {\r\n node: undefined,\r\n source: undefined,\r\n renderer: undefined,\r\n theme: undefined,\r\n showErrors: false,\r\n enableZoom: true,\r\n allowFullscreen: true,\r\n compact: false,\r\n actions: () => [],\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n rendered: [result: MermaidRenderResult]\r\n error: [message: string]\r\n copy: [source: string]\r\n export: [format: 'png' | 'svg']\r\n fullscreen: [active: boolean]\r\n action: [key: string]\r\n}>()\r\n\r\nconst context = useRenderContext()\r\nconst ownSlots = useSlots()\r\nconst source = computed(\r\n () => props.source ?? (props.node?.kind === 'mermaid' ? props.node.code : ''),\r\n)\r\nconst resolvedTheme = computed<MarkdownTheme>(\r\n () => props.theme ?? context.theme ?? 'light',\r\n)\r\nconst status = ref<'idle' | 'pending' | 'ready' | 'error'>('idle')\r\nconst result = shallowRef<MermaidRenderResult>()\r\nconst lastGood = shallowRef<MermaidRenderResult>()\r\nconst error = ref('')\r\nconst view = ref<'preview' | 'source'>('preview')\r\nconst scale = ref(1)\r\nconst fullscreen = ref(false)\r\nconst root = ref<HTMLElement>()\r\nconst copied = ref(false)\r\nlet mounted = false\r\nlet copiedTimer: ReturnType<typeof setTimeout> | undefined\r\n\r\nconst renderer = computed(() =>\r\n props.renderer && isValidMermaidRenderer(props.renderer)\r\n ? props.renderer\r\n : context.mermaidRenderer,\r\n)\r\nconst rendererId = computed(() =>\r\n renderer.value && isValidMermaidRenderer(renderer.value)\r\n ? renderer.value.id\r\n : 'mermaid',\r\n)\r\nconst label = computed(() => resolveLabel(context.labels.mermaid, { source: source.value }))\r\n\r\nconst INVALID_RENDERER_OUTPUT = 'Renderer returned no usable diagram output.'\r\nlet renderToken = 0\r\n\r\nfunction prepareResult(\r\n raw: MermaidRenderResult | null | undefined,\r\n): MermaidRenderResult {\r\n if (!raw || typeof raw !== 'object') {\r\n return { nodes: [], error: INVALID_RENDERER_OUTPUT }\r\n }\r\n const svg = typeof raw.svg === 'string' && raw.svg ? raw.svg : undefined\r\n const nodes = Array.isArray(raw.nodes) ? sanitizeMermaidNodes(raw.nodes) : []\r\n if (nodes.length > 0) return { ...raw, svg, nodes }\r\n if (svg) {\r\n // A renderer may return SVG markup plus no nodes. Parse and sanitize it\r\n // before it can reach the renderer.\r\n const sanitized = sanitizeSvg(svg)\r\n if (sanitized.length > 0) return { ...raw, svg, nodes: sanitized }\r\n }\r\n return {\r\n ...raw,\r\n svg,\r\n nodes: [],\r\n error: raw.error ?? INVALID_RENDERER_OUTPUT,\r\n }\r\n}\r\n\r\nasync function render(): Promise<void> {\r\n const token = ++renderToken\r\n status.value = 'pending'\r\n error.value = ''\r\n const active = renderer.value\r\n const id = createMermaidRenderId()\r\n let next: MermaidRenderResult\r\n if (active && isValidMermaidRenderer(active)) {\r\n try {\r\n next = prepareResult(\r\n await active.render(source.value, { theme: resolvedTheme.value, id }),\r\n )\r\n } catch (exception) {\r\n next = {\r\n nodes: [],\r\n error: exception instanceof Error ? exception.message : String(exception),\r\n }\r\n }\r\n } else {\r\n // The default runtime already returns sanitized nodes.\r\n const rendered = await renderMermaid(source.value, {\r\n theme: resolvedTheme.value,\r\n id,\r\n })\r\n next =\r\n rendered.error || rendered.nodes.length > 0\r\n ? rendered\r\n : { ...rendered, error: INVALID_RENDERER_OUTPUT }\r\n }\r\n\r\n if (token !== renderToken) return\r\n\r\n result.value = next\r\n if (next.error) {\r\n status.value = 'error'\r\n error.value = next.error\r\n emit('error', next.error)\r\n const unavailable =\r\n next.error.indexOf('Mermaid is not available') !== -1\r\n context.onRenderError?.(\r\n createDiagnostic(\r\n unavailable ? 'mermaid-unavailable' : 'mermaid-error',\r\n next.error,\r\n { phase: 'render' },\r\n ),\r\n )\r\n } else {\r\n status.value = 'ready'\r\n lastGood.value = next\r\n emit('rendered', next)\r\n }\r\n}\r\n\r\nonMounted(() => {\r\n mounted = true\r\n void render()\r\n})\r\nonUnmounted(() => {\r\n mounted = false\r\n if (copiedTimer) clearTimeout(copiedTimer)\r\n if (typeof document !== 'undefined') {\r\n document.removeEventListener('keydown', onKeydown)\r\n }\r\n})\r\nwatch(\r\n () => [source.value, renderer.value, resolvedTheme.value] as const,\r\n () => {\r\n if (mounted) void render()\r\n },\r\n)\r\n\r\nasync function copy(): Promise<void> {\r\n try {\r\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\r\n await navigator.clipboard.writeText(source.value)\r\n }\r\n copied.value = true\r\n emit('copy', source.value)\r\n if (copiedTimer) clearTimeout(copiedTimer)\r\n copiedTimer = setTimeout(() => {\r\n copied.value = false\r\n }, 1500)\r\n } catch (exception) {\r\n copied.value = false\r\n const message = `The source could not be copied to the clipboard: ${errorMessage(exception)}`\r\n emit('error', message)\r\n context.onRenderError?.(\r\n createDiagnostic('copy-error', message, {\r\n severity: 'warning',\r\n phase: 'render',\r\n plugin: 'mermaid',\r\n }),\r\n )\r\n }\r\n}\r\n\r\nfunction download(blob: Blob, name: string): void {\r\n if (typeof document === 'undefined' || typeof URL === 'undefined') return\r\n const url = URL.createObjectURL(blob)\r\n const anchor = document.createElement('a')\r\n anchor.href = url\r\n anchor.download = name\r\n anchor.click()\r\n // Revoking synchronously can cancel the download in some browsers.\r\n setTimeout(() => URL.revokeObjectURL(url), 1000)\r\n}\r\n\r\nasync function exportPng(): Promise<void> {\r\n const svg = lastGood.value?.svg\r\n if (!svg || typeof document === 'undefined' || typeof Image === 'undefined') {\r\n return\r\n }\r\n try {\r\n const url = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }))\r\n const image = new Image()\r\n await new Promise<void>((resolve, reject) => {\r\n image.onload = () => resolve()\r\n image.onerror = () => reject(new Error('Mermaid SVG could not be decoded.'))\r\n image.src = url\r\n })\r\n const canvas = document.createElement('canvas')\r\n canvas.width = image.width || 800\r\n canvas.height = image.height || 600\r\n canvas.getContext('2d')?.drawImage(image, 0, 0)\r\n URL.revokeObjectURL(url)\r\n const blob = await new Promise<Blob | null>((resolve) =>\r\n canvas.toBlob(resolve, 'image/png'),\r\n )\r\n if (blob) {\r\n download(blob, 'diagram.png')\r\n emit('export', 'png')\r\n }\r\n } catch {\r\n // PNG export is best-effort; the source remains available.\r\n }\r\n}\r\n\r\nfunction downloadSvg(): void {\r\n const svg = lastGood.value?.svg\r\n if (!svg) return\r\n download(new Blob([svg], { type: 'image/svg+xml' }), 'diagram.svg')\r\n emit('export', 'svg')\r\n}\r\n\r\nfunction onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Escape' && fullscreen.value) {\r\n void toggleFullscreen(false)\r\n }\r\n}\r\n\r\nasync function toggleFullscreen(next = !fullscreen.value): Promise<void> {\r\n if (!props.allowFullscreen) return\r\n const element = root.value\r\n if (typeof document === 'undefined') return\r\n if (next) {\r\n try {\r\n await element?.requestFullscreen?.()\r\n } catch {\r\n // CSS fallback below.\r\n }\r\n if (!mounted) return\r\n fullscreen.value = true\r\n document.addEventListener('keydown', onKeydown)\r\n element?.focus?.()\r\n } else {\r\n try {\r\n if (document.fullscreenElement) await document.exitFullscreen()\r\n } catch {\r\n // Ignore browsers that already exited.\r\n }\r\n if (!mounted) return\r\n fullscreen.value = false\r\n document.removeEventListener('keydown', onKeydown)\r\n }\r\n emit('fullscreen', fullscreen.value)\r\n}\r\n\r\nfunction zoom(delta: number): void {\r\n scale.value = Math.min(4, Math.max(0.25, Number((scale.value + delta).toFixed(2))))\r\n}\r\n\r\nfunction resetZoom(): void {\r\n scale.value = 1\r\n}\r\n\r\nfunction showPreview(): void {\r\n view.value = 'preview'\r\n}\r\n\r\nfunction showSource(): void {\r\n view.value = 'source'\r\n}\r\n\r\nconst actionHandlers = computed(() => ({\r\n copy,\r\n exportPng,\r\n downloadSvg,\r\n fullscreen: () => toggleFullscreen(),\r\n retry: render,\r\n zoomIn: () => zoom(0.25),\r\n zoomOut: () => zoom(-0.25),\r\n resetZoom,\r\n}))\r\n\r\nasync function runAction(action: MermaidAction): Promise<void> {\r\n try {\r\n await action.run({\r\n source: source.value,\r\n ...actionHandlers.value,\r\n })\r\n emit('action', action.key)\r\n } catch (exception) {\r\n const message = `The \"${action.key}\" action failed: ${errorMessage(exception)}`\r\n emit('error', message)\r\n context.onRenderError?.(\r\n createDiagnostic('action-error', message, {\r\n severity: 'warning',\r\n phase: 'render',\r\n plugin: 'mermaid',\r\n }),\r\n )\r\n }\r\n}\r\n\r\nconst headerContext = computed(() => ({\r\n source: source.value,\r\n label: label.value,\r\n view: view.value,\r\n status: status.value,\r\n copied: copied.value,\r\n fullscreen: fullscreen.value,\r\n compact: props.compact,\r\n actions: actionHandlers.value,\r\n showPreview,\r\n showSource,\r\n}))\r\n\r\nconst tabsContext = computed(() => ({\r\n view: view.value,\r\n status: status.value,\r\n actions: {\r\n preview: showPreview,\r\n source: showSource,\r\n },\r\n}))\r\n\r\nconst actionsSlotContext = computed(() => ({\r\n source: source.value,\r\n status: status.value,\r\n copied: copied.value,\r\n fullscreen: fullscreen.value,\r\n enableZoom: props.enableZoom,\r\n allowFullscreen: props.allowFullscreen,\r\n compact: props.compact,\r\n actions: actionHandlers.value,\r\n}))\r\n\r\nconst PreviewContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'mermaid',\r\n {\r\n source: source.value,\r\n svg: lastGood.value?.svg,\r\n status: status.value,\r\n error: error.value,\r\n actions: {\r\n copy,\r\n exportPng,\r\n fullscreen: () => toggleFullscreen(),\r\n retry: render,\r\n },\r\n },\r\n () => {\r\n const slot = ownSlots.mermaid\r\n if (slot) {\r\n const output = slot({\r\n source: source.value,\r\n svg: lastGood.value?.svg,\r\n status: status.value,\r\n error: error.value,\r\n actions: {\r\n copy,\r\n exportPng,\r\n fullscreen: () => toggleFullscreen(),\r\n retry: render,\r\n },\r\n })\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n if (!lastGood.value) {\r\n if (status.value === 'error') {\r\n if (props.showErrors) {\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-error',\r\n class: 'vmd-mermaid-error',\r\n role: 'status',\r\n },\r\n error.value,\r\n )\r\n }\r\n // A failed first render should not leave an empty block. Keep the\r\n // detailed diagnostic behind `showErrors`, but always expose a\r\n // lightweight failure state and the source tab.\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-fallback',\r\n class: 'vmd-mermaid-fallback',\r\n role: 'status',\r\n },\r\n resolveLabel(context.labels.mermaidFallback),\r\n )\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-pending',\r\n class: 'vmd-mermaid-pending',\r\n role: 'status',\r\n },\r\n 'Rendering diagram…',\r\n )\r\n }\r\n return h(\r\n 'div',\r\n {\r\n class: 'vmd-mermaid-diagram',\r\n style: { transform: `scale(${scale.value})` },\r\n },\r\n renderNodes(lastGood.value.nodes, context),\r\n )\r\n },\r\n )\r\n },\r\n})\r\n\r\nconst ErrorContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'mermaid-error',\r\n {\r\n source: source.value,\r\n error: error.value,\r\n retry: render,\r\n focusSource: showSource,\r\n },\r\n () => {\r\n const slot = ownSlots['mermaid-error']\r\n if (slot) {\r\n const output = slot({\r\n source: source.value,\r\n error: error.value,\r\n retry: render,\r\n focusSource: showSource,\r\n })\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-error',\r\n class: 'vmd-mermaid-error',\r\n role: 'status',\r\n },\r\n error.value,\r\n )\r\n },\r\n )\r\n },\r\n})\r\n\r\nconst TabsContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot('tabs', tabsContext.value, () => {\r\n const slot = ownSlots.tabs\r\n if (slot) {\r\n const output = slot(tabsContext.value)\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-tabs',\r\n class: 'vmd-mermaid-tabs',\r\n role: 'tablist',\r\n },\r\n [\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n role: 'tab',\r\n 'data-action': 'preview',\r\n 'aria-selected': view.value === 'preview' ? 'true' : 'false',\r\n 'data-active': view.value === 'preview' ? 'true' : undefined,\r\n onClick: showPreview,\r\n },\r\n [\r\n h(Icon, { name: 'preview' }),\r\n resolveLabel(context.labels.preview),\r\n ],\r\n ),\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n role: 'tab',\r\n 'data-action': 'source',\r\n 'aria-selected': view.value === 'source' ? 'true' : 'false',\r\n 'data-active': view.value === 'source' ? 'true' : undefined,\r\n onClick: showSource,\r\n },\r\n [\r\n h(Icon, { name: 'source' }),\r\n resolveLabel(context.labels.source),\r\n ],\r\n ),\r\n ],\r\n )\r\n })\r\n },\r\n})\r\n\r\nconst ActionsContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot('actions', actionsSlotContext.value, () => {\r\n const slot = ownSlots.actions\r\n if (slot) {\r\n const output = slot(actionsSlotContext.value)\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n if (props.compact) return null\r\n\r\n const copyLabel = copied.value\r\n ? resolveLabel(context.labels.copied)\r\n : resolveLabel(context.labels.copy)\r\n const iconButton = (\r\n action: string,\r\n label: string,\r\n icon: IconName,\r\n onClick: () => void | Promise<void>,\r\n ) =>\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n class: 'vmd-mermaid-action',\r\n 'data-vmd-part': 'mermaid-action',\r\n 'data-action': action,\r\n 'data-icon': 'true',\r\n 'aria-label': label,\r\n title: label,\r\n onClick,\r\n },\r\n [\r\n h(Icon, { name: icon }),\r\n h('span', { class: 'vmd-visually-hidden' }, label),\r\n ],\r\n )\r\n\r\n const children = []\r\n if (props.enableZoom) {\r\n children.push(\r\n iconButton(\r\n 'zoom-in',\r\n resolveLabel(context.labels.zoomIn),\r\n 'zoom-in',\r\n () => zoom(0.25),\r\n ),\r\n iconButton(\r\n 'zoom-out',\r\n resolveLabel(context.labels.zoomOut),\r\n 'zoom-out',\r\n () => zoom(-0.25),\r\n ),\r\n iconButton(\r\n 'reset-zoom',\r\n resolveLabel(context.labels.reset),\r\n 'reset',\r\n resetZoom,\r\n ),\r\n )\r\n }\r\n children.push(\r\n iconButton('copy', copyLabel, copied.value ? 'check' : 'copy', copy),\r\n iconButton(\r\n 'export-png',\r\n resolveLabel(context.labels.exportPng),\r\n 'image',\r\n exportPng,\r\n ),\r\n iconButton(\r\n 'download-svg',\r\n `${resolveLabel(context.labels.download)} SVG`,\r\n 'download',\r\n downloadSvg,\r\n ),\r\n )\r\n if (props.allowFullscreen) {\r\n children.push(\r\n iconButton(\r\n 'fullscreen',\r\n fullscreen.value\r\n ? resolveLabel(context.labels.exitFullscreen)\r\n : resolveLabel(context.labels.fullscreen),\r\n fullscreen.value ? 'exit-fullscreen' : 'fullscreen',\r\n () => toggleFullscreen(),\r\n ),\r\n )\r\n }\r\n children.push(\r\n iconButton('retry', resolveLabel(context.labels.retry), 'retry', render),\r\n )\r\n\r\n for (const action of props.actions) {\r\n const actionLabel = resolveLabel(action.label)\r\n children.push(\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n class: 'vmd-mermaid-action',\r\n 'data-vmd-part': 'mermaid-action',\r\n 'data-action': action.key,\r\n onClick: () => void runAction(action),\r\n },\r\n actionLabel,\r\n ),\r\n )\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-actions',\r\n class: 'vmd-mermaid-actions',\r\n },\r\n children,\r\n )\r\n })\r\n },\r\n})\r\n\r\nconst HeaderContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot('header', headerContext.value, () => {\r\n const slot = ownSlots.header\r\n if (slot) {\r\n const output = slot(headerContext.value)\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n return [\r\n h('span', { class: 'vmd-mermaid-label' }, [\r\n h(Icon, { name: 'diagram' }),\r\n label.value,\r\n ]),\r\n h(TabsContent),\r\n h(ActionsContent),\r\n ]\r\n })\r\n },\r\n})\r\n\r\ndefineExpose({ render, copy, exportPng, downloadSvg, toggleFullscreen })\r\n</script>\r\n\r\n<template>\r\n <div\r\n ref=\"root\"\r\n data-vmd-part=\"mermaid\"\r\n class=\"vmd-mermaid\"\r\n :data-vmd-theme=\"resolvedTheme\"\r\n :data-status=\"status\"\r\n :data-renderer=\"rendererId\"\r\n :data-fullscreen=\"fullscreen ? 'true' : undefined\"\r\n :data-compact=\"compact ? 'true' : undefined\"\r\n :data-view=\"view\"\r\n role=\"figure\"\r\n :aria-label=\"label\"\r\n tabindex=\"-1\"\r\n >\r\n <div\r\n class=\"vmd-mermaid-surface\"\r\n :data-vmd-part=\"fullscreen ? 'mermaid-fullscreen' : undefined\"\r\n >\r\n <div data-vmd-part=\"mermaid-header\" class=\"vmd-mermaid-header\">\r\n <HeaderContent />\r\n </div>\r\n\r\n <div\r\n v-if=\"view === 'preview'\"\r\n data-vmd-part=\"mermaid-preview\"\r\n class=\"vmd-mermaid-preview\"\r\n >\r\n <div\r\n v-if=\"lastGood && status === 'error' && showErrors\"\r\n class=\"vmd-mermaid-error-banner\"\r\n ><ErrorContent /></div>\r\n <PreviewContent />\r\n </div>\r\n <pre\r\n v-else\r\n data-vmd-part=\"mermaid-source\"\r\n class=\"vmd-mermaid-source\"\r\n ><code>{{ source }}</code></pre>\r\n </div>\r\n </div>\r\n</template>\r\n","<script setup lang=\"ts\">\r\nimport {\r\n computed,\r\n defineComponent,\r\n h,\r\n onMounted,\r\n onUnmounted,\r\n ref,\r\n shallowRef,\r\n useSlots,\r\n watch,\r\n} from 'vue'\r\nimport type {\r\n MarkdownNode,\r\n MarkdownTheme,\r\n MermaidAction,\r\n MermaidRenderResult,\r\n MermaidRenderer,\r\n} from '../core/types'\r\nimport { createDiagnostic, errorMessage } from '../core/diagnostics'\r\nimport { resolveLabel } from '../core/labels'\r\nimport { isValidMermaidRenderer } from '../core/adapters'\r\nimport { isEmptySlotContent, useRenderContext } from './context'\r\nimport { renderNodes } from './render'\r\nimport { createMermaidRenderId, renderMermaid } from '../mermaid/runtime'\r\nimport Icon, { type IconName } from './Icon'\r\nimport { sanitizeMermaidNodes, sanitizeSvg } from '../mermaid/sanitize'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n node?: MarkdownNode\r\n source?: string\r\n renderer?: MermaidRenderer\r\n theme?: MarkdownTheme\r\n showErrors?: boolean\r\n enableZoom?: boolean\r\n allowFullscreen?: boolean\r\n compact?: boolean\r\n actions?: MermaidAction[]\r\n }>(),\r\n {\r\n node: undefined,\r\n source: undefined,\r\n renderer: undefined,\r\n theme: undefined,\r\n showErrors: false,\r\n enableZoom: true,\r\n allowFullscreen: true,\r\n compact: false,\r\n actions: () => [],\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n rendered: [result: MermaidRenderResult]\r\n error: [message: string]\r\n copy: [source: string]\r\n export: [format: 'png' | 'svg']\r\n fullscreen: [active: boolean]\r\n action: [key: string]\r\n}>()\r\n\r\nconst context = useRenderContext()\r\nconst ownSlots = useSlots()\r\nconst source = computed(\r\n () => props.source ?? (props.node?.kind === 'mermaid' ? props.node.code : ''),\r\n)\r\nconst resolvedTheme = computed<MarkdownTheme>(\r\n () => props.theme ?? context.theme ?? 'light',\r\n)\r\nconst status = ref<'idle' | 'pending' | 'ready' | 'error'>('idle')\r\nconst result = shallowRef<MermaidRenderResult>()\r\nconst lastGood = shallowRef<MermaidRenderResult>()\r\nconst error = ref('')\r\nconst view = ref<'preview' | 'source'>('preview')\r\nconst scale = ref(1)\r\nconst fullscreen = ref(false)\r\nconst root = ref<HTMLElement>()\r\nconst copied = ref(false)\r\nlet mounted = false\r\nlet copiedTimer: ReturnType<typeof setTimeout> | undefined\r\n\r\nconst renderer = computed(() =>\r\n props.renderer && isValidMermaidRenderer(props.renderer)\r\n ? props.renderer\r\n : context.mermaidRenderer,\r\n)\r\nconst rendererId = computed(() =>\r\n renderer.value && isValidMermaidRenderer(renderer.value)\r\n ? renderer.value.id\r\n : 'mermaid',\r\n)\r\nconst label = computed(() => resolveLabel(context.labels.mermaid, { source: source.value }))\r\n\r\nconst INVALID_RENDERER_OUTPUT = 'Renderer returned no usable diagram output.'\r\nlet renderToken = 0\r\n\r\nfunction prepareResult(\r\n raw: MermaidRenderResult | null | undefined,\r\n): MermaidRenderResult {\r\n if (!raw || typeof raw !== 'object') {\r\n return { nodes: [], error: INVALID_RENDERER_OUTPUT }\r\n }\r\n const svg = typeof raw.svg === 'string' && raw.svg ? raw.svg : undefined\r\n const nodes = Array.isArray(raw.nodes) ? sanitizeMermaidNodes(raw.nodes) : []\r\n if (nodes.length > 0) return { ...raw, svg, nodes }\r\n if (svg) {\r\n // A renderer may return SVG markup plus no nodes. Parse and sanitize it\r\n // before it can reach the renderer.\r\n const sanitized = sanitizeSvg(svg)\r\n if (sanitized.length > 0) return { ...raw, svg, nodes: sanitized }\r\n }\r\n return {\r\n ...raw,\r\n svg,\r\n nodes: [],\r\n error: raw.error ?? INVALID_RENDERER_OUTPUT,\r\n }\r\n}\r\n\r\nasync function render(): Promise<void> {\r\n const token = ++renderToken\r\n status.value = 'pending'\r\n error.value = ''\r\n const active = renderer.value\r\n const id = createMermaidRenderId()\r\n let next: MermaidRenderResult\r\n if (active && isValidMermaidRenderer(active)) {\r\n try {\r\n next = prepareResult(\r\n await active.render(source.value, { theme: resolvedTheme.value, id }),\r\n )\r\n } catch (exception) {\r\n next = {\r\n nodes: [],\r\n error: exception instanceof Error ? exception.message : String(exception),\r\n }\r\n }\r\n } else {\r\n // The default runtime already returns sanitized nodes.\r\n const rendered = await renderMermaid(source.value, {\r\n theme: resolvedTheme.value,\r\n id,\r\n })\r\n next =\r\n rendered.error || rendered.nodes.length > 0\r\n ? rendered\r\n : { ...rendered, error: INVALID_RENDERER_OUTPUT }\r\n }\r\n\r\n if (token !== renderToken) return\r\n\r\n result.value = next\r\n if (next.error) {\r\n status.value = 'error'\r\n error.value = next.error\r\n emit('error', next.error)\r\n const unavailable =\r\n next.error.indexOf('Mermaid is not available') !== -1\r\n context.onRenderError?.(\r\n createDiagnostic(\r\n unavailable ? 'mermaid-unavailable' : 'mermaid-error',\r\n next.error,\r\n { phase: 'render' },\r\n ),\r\n )\r\n } else {\r\n status.value = 'ready'\r\n lastGood.value = next\r\n emit('rendered', next)\r\n }\r\n}\r\n\r\nonMounted(() => {\r\n mounted = true\r\n void render()\r\n})\r\nonUnmounted(() => {\r\n mounted = false\r\n if (copiedTimer) clearTimeout(copiedTimer)\r\n if (typeof document !== 'undefined') {\r\n document.removeEventListener('keydown', onKeydown)\r\n }\r\n})\r\nwatch(\r\n () => [source.value, renderer.value, resolvedTheme.value] as const,\r\n () => {\r\n if (mounted) void render()\r\n },\r\n)\r\n\r\nasync function copy(): Promise<void> {\r\n try {\r\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\r\n await navigator.clipboard.writeText(source.value)\r\n }\r\n copied.value = true\r\n emit('copy', source.value)\r\n if (copiedTimer) clearTimeout(copiedTimer)\r\n copiedTimer = setTimeout(() => {\r\n copied.value = false\r\n }, 1500)\r\n } catch (exception) {\r\n copied.value = false\r\n const message = `The source could not be copied to the clipboard: ${errorMessage(exception)}`\r\n emit('error', message)\r\n context.onRenderError?.(\r\n createDiagnostic('copy-error', message, {\r\n severity: 'warning',\r\n phase: 'render',\r\n plugin: 'mermaid',\r\n }),\r\n )\r\n }\r\n}\r\n\r\nfunction download(blob: Blob, name: string): void {\r\n if (typeof document === 'undefined' || typeof URL === 'undefined') return\r\n const url = URL.createObjectURL(blob)\r\n const anchor = document.createElement('a')\r\n anchor.href = url\r\n anchor.download = name\r\n anchor.click()\r\n // Revoking synchronously can cancel the download in some browsers.\r\n setTimeout(() => URL.revokeObjectURL(url), 1000)\r\n}\r\n\r\nasync function exportPng(): Promise<void> {\r\n const svg = lastGood.value?.svg\r\n if (!svg || typeof document === 'undefined' || typeof Image === 'undefined') {\r\n return\r\n }\r\n try {\r\n const url = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }))\r\n const image = new Image()\r\n await new Promise<void>((resolve, reject) => {\r\n image.onload = () => resolve()\r\n image.onerror = () => reject(new Error('Mermaid SVG could not be decoded.'))\r\n image.src = url\r\n })\r\n const canvas = document.createElement('canvas')\r\n canvas.width = image.width || 800\r\n canvas.height = image.height || 600\r\n canvas.getContext('2d')?.drawImage(image, 0, 0)\r\n URL.revokeObjectURL(url)\r\n const blob = await new Promise<Blob | null>((resolve) =>\r\n canvas.toBlob(resolve, 'image/png'),\r\n )\r\n if (blob) {\r\n download(blob, 'diagram.png')\r\n emit('export', 'png')\r\n }\r\n } catch {\r\n // PNG export is best-effort; the source remains available.\r\n }\r\n}\r\n\r\nfunction downloadSvg(): void {\r\n const svg = lastGood.value?.svg\r\n if (!svg) return\r\n download(new Blob([svg], { type: 'image/svg+xml' }), 'diagram.svg')\r\n emit('export', 'svg')\r\n}\r\n\r\nfunction onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Escape' && fullscreen.value) {\r\n void toggleFullscreen(false)\r\n }\r\n}\r\n\r\nasync function toggleFullscreen(next = !fullscreen.value): Promise<void> {\r\n if (!props.allowFullscreen) return\r\n const element = root.value\r\n if (typeof document === 'undefined') return\r\n if (next) {\r\n try {\r\n await element?.requestFullscreen?.()\r\n } catch {\r\n // CSS fallback below.\r\n }\r\n if (!mounted) return\r\n fullscreen.value = true\r\n document.addEventListener('keydown', onKeydown)\r\n element?.focus?.()\r\n } else {\r\n try {\r\n if (document.fullscreenElement) await document.exitFullscreen()\r\n } catch {\r\n // Ignore browsers that already exited.\r\n }\r\n if (!mounted) return\r\n fullscreen.value = false\r\n document.removeEventListener('keydown', onKeydown)\r\n }\r\n emit('fullscreen', fullscreen.value)\r\n}\r\n\r\nfunction zoom(delta: number): void {\r\n scale.value = Math.min(4, Math.max(0.25, Number((scale.value + delta).toFixed(2))))\r\n}\r\n\r\nfunction resetZoom(): void {\r\n scale.value = 1\r\n}\r\n\r\nfunction showPreview(): void {\r\n view.value = 'preview'\r\n}\r\n\r\nfunction showSource(): void {\r\n view.value = 'source'\r\n}\r\n\r\nconst actionHandlers = computed(() => ({\r\n copy,\r\n exportPng,\r\n downloadSvg,\r\n fullscreen: () => toggleFullscreen(),\r\n retry: render,\r\n zoomIn: () => zoom(0.25),\r\n zoomOut: () => zoom(-0.25),\r\n resetZoom,\r\n}))\r\n\r\nasync function runAction(action: MermaidAction): Promise<void> {\r\n try {\r\n await action.run({\r\n source: source.value,\r\n ...actionHandlers.value,\r\n })\r\n emit('action', action.key)\r\n } catch (exception) {\r\n const message = `The \"${action.key}\" action failed: ${errorMessage(exception)}`\r\n emit('error', message)\r\n context.onRenderError?.(\r\n createDiagnostic('action-error', message, {\r\n severity: 'warning',\r\n phase: 'render',\r\n plugin: 'mermaid',\r\n }),\r\n )\r\n }\r\n}\r\n\r\nconst headerContext = computed(() => ({\r\n source: source.value,\r\n label: label.value,\r\n view: view.value,\r\n status: status.value,\r\n copied: copied.value,\r\n fullscreen: fullscreen.value,\r\n compact: props.compact,\r\n actions: actionHandlers.value,\r\n showPreview,\r\n showSource,\r\n}))\r\n\r\nconst tabsContext = computed(() => ({\r\n view: view.value,\r\n status: status.value,\r\n actions: {\r\n preview: showPreview,\r\n source: showSource,\r\n },\r\n}))\r\n\r\nconst actionsSlotContext = computed(() => ({\r\n source: source.value,\r\n status: status.value,\r\n copied: copied.value,\r\n fullscreen: fullscreen.value,\r\n enableZoom: props.enableZoom,\r\n allowFullscreen: props.allowFullscreen,\r\n compact: props.compact,\r\n actions: actionHandlers.value,\r\n}))\r\n\r\nconst PreviewContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'mermaid',\r\n {\r\n source: source.value,\r\n svg: lastGood.value?.svg,\r\n status: status.value,\r\n error: error.value,\r\n actions: {\r\n copy,\r\n exportPng,\r\n fullscreen: () => toggleFullscreen(),\r\n retry: render,\r\n },\r\n },\r\n () => {\r\n const slot = ownSlots.mermaid\r\n if (slot) {\r\n const output = slot({\r\n source: source.value,\r\n svg: lastGood.value?.svg,\r\n status: status.value,\r\n error: error.value,\r\n actions: {\r\n copy,\r\n exportPng,\r\n fullscreen: () => toggleFullscreen(),\r\n retry: render,\r\n },\r\n })\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n if (!lastGood.value) {\r\n if (status.value === 'error') {\r\n if (props.showErrors) {\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-error',\r\n class: 'vmd-mermaid-error',\r\n role: 'status',\r\n },\r\n error.value,\r\n )\r\n }\r\n // A failed first render should not leave an empty block. Keep the\r\n // detailed diagnostic behind `showErrors`, but always expose a\r\n // lightweight failure state and the source tab.\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-fallback',\r\n class: 'vmd-mermaid-fallback',\r\n role: 'status',\r\n },\r\n resolveLabel(context.labels.mermaidFallback),\r\n )\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-pending',\r\n class: 'vmd-mermaid-pending',\r\n role: 'status',\r\n },\r\n 'Rendering diagram…',\r\n )\r\n }\r\n return h(\r\n 'div',\r\n {\r\n class: 'vmd-mermaid-diagram',\r\n style: { transform: `scale(${scale.value})` },\r\n },\r\n renderNodes(lastGood.value.nodes, context),\r\n )\r\n },\r\n )\r\n },\r\n})\r\n\r\nconst ErrorContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot(\r\n 'mermaid-error',\r\n {\r\n source: source.value,\r\n error: error.value,\r\n retry: render,\r\n focusSource: showSource,\r\n },\r\n () => {\r\n const slot = ownSlots['mermaid-error']\r\n if (slot) {\r\n const output = slot({\r\n source: source.value,\r\n error: error.value,\r\n retry: render,\r\n focusSource: showSource,\r\n })\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-error',\r\n class: 'vmd-mermaid-error',\r\n role: 'status',\r\n },\r\n error.value,\r\n )\r\n },\r\n )\r\n },\r\n})\r\n\r\nconst TabsContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot('tabs', tabsContext.value, () => {\r\n const slot = ownSlots.tabs\r\n if (slot) {\r\n const output = slot(tabsContext.value)\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-tabs',\r\n class: 'vmd-mermaid-tabs',\r\n role: 'tablist',\r\n },\r\n [\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n role: 'tab',\r\n 'data-action': 'preview',\r\n 'aria-selected': view.value === 'preview' ? 'true' : 'false',\r\n 'data-active': view.value === 'preview' ? 'true' : undefined,\r\n onClick: showPreview,\r\n },\r\n [\r\n h(Icon, { name: 'preview' }),\r\n resolveLabel(context.labels.preview),\r\n ],\r\n ),\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n role: 'tab',\r\n 'data-action': 'source',\r\n 'aria-selected': view.value === 'source' ? 'true' : 'false',\r\n 'data-active': view.value === 'source' ? 'true' : undefined,\r\n onClick: showSource,\r\n },\r\n [\r\n h(Icon, { name: 'source' }),\r\n resolveLabel(context.labels.source),\r\n ],\r\n ),\r\n ],\r\n )\r\n })\r\n },\r\n})\r\n\r\nconst ActionsContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot('actions', actionsSlotContext.value, () => {\r\n const slot = ownSlots.actions\r\n if (slot) {\r\n const output = slot(actionsSlotContext.value)\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n if (props.compact) return null\r\n\r\n const copyLabel = copied.value\r\n ? resolveLabel(context.labels.copied)\r\n : resolveLabel(context.labels.copy)\r\n const iconButton = (\r\n action: string,\r\n label: string,\r\n icon: IconName,\r\n onClick: () => void | Promise<void>,\r\n ) =>\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n class: 'vmd-mermaid-action',\r\n 'data-vmd-part': 'mermaid-action',\r\n 'data-action': action,\r\n 'data-icon': 'true',\r\n 'aria-label': label,\r\n title: label,\r\n onClick,\r\n },\r\n [\r\n h(Icon, { name: icon }),\r\n h('span', { class: 'vmd-visually-hidden' }, label),\r\n ],\r\n )\r\n\r\n const children = []\r\n if (props.enableZoom) {\r\n children.push(\r\n iconButton(\r\n 'zoom-in',\r\n resolveLabel(context.labels.zoomIn),\r\n 'zoom-in',\r\n () => zoom(0.25),\r\n ),\r\n iconButton(\r\n 'zoom-out',\r\n resolveLabel(context.labels.zoomOut),\r\n 'zoom-out',\r\n () => zoom(-0.25),\r\n ),\r\n iconButton(\r\n 'reset-zoom',\r\n resolveLabel(context.labels.reset),\r\n 'reset',\r\n resetZoom,\r\n ),\r\n )\r\n }\r\n children.push(\r\n iconButton('copy', copyLabel, copied.value ? 'check' : 'copy', copy),\r\n iconButton(\r\n 'export-png',\r\n resolveLabel(context.labels.exportPng),\r\n 'image',\r\n exportPng,\r\n ),\r\n iconButton(\r\n 'download-svg',\r\n `${resolveLabel(context.labels.download)} SVG`,\r\n 'download',\r\n downloadSvg,\r\n ),\r\n )\r\n if (props.allowFullscreen) {\r\n children.push(\r\n iconButton(\r\n 'fullscreen',\r\n fullscreen.value\r\n ? resolveLabel(context.labels.exitFullscreen)\r\n : resolveLabel(context.labels.fullscreen),\r\n fullscreen.value ? 'exit-fullscreen' : 'fullscreen',\r\n () => toggleFullscreen(),\r\n ),\r\n )\r\n }\r\n children.push(\r\n iconButton('retry', resolveLabel(context.labels.retry), 'retry', render),\r\n )\r\n\r\n for (const action of props.actions) {\r\n const actionLabel = resolveLabel(action.label)\r\n children.push(\r\n h(\r\n 'button',\r\n {\r\n type: 'button',\r\n class: 'vmd-mermaid-action',\r\n 'data-vmd-part': 'mermaid-action',\r\n 'data-action': action.key,\r\n onClick: () => void runAction(action),\r\n },\r\n actionLabel,\r\n ),\r\n )\r\n }\r\n return h(\r\n 'div',\r\n {\r\n 'data-vmd-part': 'mermaid-actions',\r\n class: 'vmd-mermaid-actions',\r\n },\r\n children,\r\n )\r\n })\r\n },\r\n})\r\n\r\nconst HeaderContent = defineComponent({\r\n setup() {\r\n return () =>\r\n context.renderHostSlot('header', headerContext.value, () => {\r\n const slot = ownSlots.header\r\n if (slot) {\r\n const output = slot(headerContext.value)\r\n if (!isEmptySlotContent(output)) return output\r\n }\r\n return [\r\n h('span', { class: 'vmd-mermaid-label' }, [\r\n h(Icon, { name: 'diagram' }),\r\n label.value,\r\n ]),\r\n h(TabsContent),\r\n h(ActionsContent),\r\n ]\r\n })\r\n },\r\n})\r\n\r\ndefineExpose({ render, copy, exportPng, downloadSvg, toggleFullscreen })\r\n</script>\r\n\r\n<template>\r\n <div\r\n ref=\"root\"\r\n data-vmd-part=\"mermaid\"\r\n class=\"vmd-mermaid\"\r\n :data-vmd-theme=\"resolvedTheme\"\r\n :data-status=\"status\"\r\n :data-renderer=\"rendererId\"\r\n :data-fullscreen=\"fullscreen ? 'true' : undefined\"\r\n :data-compact=\"compact ? 'true' : undefined\"\r\n :data-view=\"view\"\r\n role=\"figure\"\r\n :aria-label=\"label\"\r\n tabindex=\"-1\"\r\n >\r\n <div\r\n class=\"vmd-mermaid-surface\"\r\n :data-vmd-part=\"fullscreen ? 'mermaid-fullscreen' : undefined\"\r\n >\r\n <div data-vmd-part=\"mermaid-header\" class=\"vmd-mermaid-header\">\r\n <HeaderContent />\r\n </div>\r\n\r\n <div\r\n v-if=\"view === 'preview'\"\r\n data-vmd-part=\"mermaid-preview\"\r\n class=\"vmd-mermaid-preview\"\r\n >\r\n <div\r\n v-if=\"lastGood && status === 'error' && showErrors\"\r\n class=\"vmd-mermaid-error-banner\"\r\n ><ErrorContent /></div>\r\n <PreviewContent />\r\n </div>\r\n <pre\r\n v-else\r\n data-vmd-part=\"mermaid-source\"\r\n class=\"vmd-mermaid-source\"\r\n ><code>{{ source }}</code></pre>\r\n </div>\r\n </div>\r\n</template>\r\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type {\n MarkdownNode,\n MarkdownTheme,\n MermaidAction,\n MermaidRenderResult,\n MermaidRenderer,\n} from '../core/types'\nimport { useRenderContext } from './context'\nimport MermaidBlock from './MermaidBlock.vue'\n\nconst props = withDefaults(\n defineProps<{\n node?: MarkdownNode\n code?: string\n renderer?: MermaidRenderer\n theme?: MarkdownTheme\n showErrors?: boolean\n enableZoom?: boolean\n allowFullscreen?: boolean\n compact?: boolean\n actions?: MermaidAction[]\n }>(),\n {\n node: undefined,\n code: undefined,\n renderer: undefined,\n theme: undefined,\n showErrors: false,\n enableZoom: true,\n allowFullscreen: true,\n compact: false,\n actions: () => [],\n },\n)\n\nconst emit = defineEmits<{\n rendered: [result: MermaidRenderResult]\n error: [message: string]\n copy: [source: string]\n export: [format: 'png' | 'svg']\n fullscreen: [active: boolean]\n action: [key: string]\n}>()\n\nconst context = useRenderContext()\nconst block = ref<InstanceType<typeof MermaidBlock>>()\nconst source = computed(() =>\n props.code ?? (props.node?.kind === 'mermaid' ? props.node.code : ''),\n)\nconst region = computed(() => context.regions?.mermaidBlock)\n\nfunction render(): Promise<void> | undefined {\n return block.value?.render()\n}\n\nfunction copy(): Promise<void> | undefined {\n return block.value?.copy()\n}\n\nfunction exportPng(): Promise<void> | undefined {\n return block.value?.exportPng()\n}\n\nfunction downloadSvg(): void {\n block.value?.downloadSvg()\n}\n\nfunction toggleFullscreen(): Promise<void> | undefined {\n return block.value?.toggleFullscreen()\n}\n\ndefineExpose({\n render,\n copy,\n exportPng,\n downloadSvg,\n toggleFullscreen,\n})\n</script>\n\n<template>\n <component\n :is=\"region\"\n v-if=\"region\"\n :node=\"node\"\n :source=\"source\"\n :renderer=\"renderer\"\n :theme=\"theme\"\n :show-errors=\"showErrors\"\n :enable-zoom=\"enableZoom\"\n :allow-fullscreen=\"allowFullscreen\"\n :compact=\"compact\"\n :actions=\"actions\"\n @rendered=\"emit('rendered', $event)\"\n @error=\"emit('error', $event)\"\n @copy=\"emit('copy', $event)\"\n @export=\"emit('export', $event)\"\n @fullscreen=\"emit('fullscreen', $event)\"\n @action=\"emit('action', $event)\"\n >\n <template v-if=\"$slots.header\" #header=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.tabs\" #tabs=\"slotProps\">\n <slot name=\"tabs\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.actions\" #actions=\"slotProps\">\n <slot name=\"actions\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.mermaid\" #mermaid=\"slotProps\">\n <slot name=\"mermaid\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots['mermaid-error']\" #mermaid-error=\"slotProps\">\n <slot name=\"mermaid-error\" v-bind=\"slotProps || {}\" />\n </template>\n </component>\n <MermaidBlock\n v-else\n ref=\"block\"\n :node=\"node\"\n :source=\"source\"\n :renderer=\"renderer\"\n :theme=\"theme\"\n :show-errors=\"showErrors\"\n :enable-zoom=\"enableZoom\"\n :allow-fullscreen=\"allowFullscreen\"\n :compact=\"compact\"\n :actions=\"actions\"\n @rendered=\"emit('rendered', $event)\"\n @error=\"emit('error', $event)\"\n @copy=\"emit('copy', $event)\"\n @export=\"emit('export', $event)\"\n @fullscreen=\"emit('fullscreen', $event)\"\n @action=\"emit('action', $event)\"\n >\n <template v-if=\"$slots.header\" #header=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.tabs\" #tabs=\"slotProps\">\n <slot name=\"tabs\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.actions\" #actions=\"slotProps\">\n <slot name=\"actions\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.mermaid\" #mermaid=\"slotProps\">\n <slot name=\"mermaid\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots['mermaid-error']\" #mermaid-error=\"slotProps\">\n <slot name=\"mermaid-error\" v-bind=\"slotProps || {}\" />\n </template>\n </MermaidBlock>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type {\n MarkdownNode,\n MarkdownTheme,\n MermaidAction,\n MermaidRenderResult,\n MermaidRenderer,\n} from '../core/types'\nimport { useRenderContext } from './context'\nimport MermaidBlock from './MermaidBlock.vue'\n\nconst props = withDefaults(\n defineProps<{\n node?: MarkdownNode\n code?: string\n renderer?: MermaidRenderer\n theme?: MarkdownTheme\n showErrors?: boolean\n enableZoom?: boolean\n allowFullscreen?: boolean\n compact?: boolean\n actions?: MermaidAction[]\n }>(),\n {\n node: undefined,\n code: undefined,\n renderer: undefined,\n theme: undefined,\n showErrors: false,\n enableZoom: true,\n allowFullscreen: true,\n compact: false,\n actions: () => [],\n },\n)\n\nconst emit = defineEmits<{\n rendered: [result: MermaidRenderResult]\n error: [message: string]\n copy: [source: string]\n export: [format: 'png' | 'svg']\n fullscreen: [active: boolean]\n action: [key: string]\n}>()\n\nconst context = useRenderContext()\nconst block = ref<InstanceType<typeof MermaidBlock>>()\nconst source = computed(() =>\n props.code ?? (props.node?.kind === 'mermaid' ? props.node.code : ''),\n)\nconst region = computed(() => context.regions?.mermaidBlock)\n\nfunction render(): Promise<void> | undefined {\n return block.value?.render()\n}\n\nfunction copy(): Promise<void> | undefined {\n return block.value?.copy()\n}\n\nfunction exportPng(): Promise<void> | undefined {\n return block.value?.exportPng()\n}\n\nfunction downloadSvg(): void {\n block.value?.downloadSvg()\n}\n\nfunction toggleFullscreen(): Promise<void> | undefined {\n return block.value?.toggleFullscreen()\n}\n\ndefineExpose({\n render,\n copy,\n exportPng,\n downloadSvg,\n toggleFullscreen,\n})\n</script>\n\n<template>\n <component\n :is=\"region\"\n v-if=\"region\"\n :node=\"node\"\n :source=\"source\"\n :renderer=\"renderer\"\n :theme=\"theme\"\n :show-errors=\"showErrors\"\n :enable-zoom=\"enableZoom\"\n :allow-fullscreen=\"allowFullscreen\"\n :compact=\"compact\"\n :actions=\"actions\"\n @rendered=\"emit('rendered', $event)\"\n @error=\"emit('error', $event)\"\n @copy=\"emit('copy', $event)\"\n @export=\"emit('export', $event)\"\n @fullscreen=\"emit('fullscreen', $event)\"\n @action=\"emit('action', $event)\"\n >\n <template v-if=\"$slots.header\" #header=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.tabs\" #tabs=\"slotProps\">\n <slot name=\"tabs\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.actions\" #actions=\"slotProps\">\n <slot name=\"actions\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.mermaid\" #mermaid=\"slotProps\">\n <slot name=\"mermaid\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots['mermaid-error']\" #mermaid-error=\"slotProps\">\n <slot name=\"mermaid-error\" v-bind=\"slotProps || {}\" />\n </template>\n </component>\n <MermaidBlock\n v-else\n ref=\"block\"\n :node=\"node\"\n :source=\"source\"\n :renderer=\"renderer\"\n :theme=\"theme\"\n :show-errors=\"showErrors\"\n :enable-zoom=\"enableZoom\"\n :allow-fullscreen=\"allowFullscreen\"\n :compact=\"compact\"\n :actions=\"actions\"\n @rendered=\"emit('rendered', $event)\"\n @error=\"emit('error', $event)\"\n @copy=\"emit('copy', $event)\"\n @export=\"emit('export', $event)\"\n @fullscreen=\"emit('fullscreen', $event)\"\n @action=\"emit('action', $event)\"\n >\n <template v-if=\"$slots.header\" #header=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.tabs\" #tabs=\"slotProps\">\n <slot name=\"tabs\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.actions\" #actions=\"slotProps\">\n <slot name=\"actions\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots.mermaid\" #mermaid=\"slotProps\">\n <slot name=\"mermaid\" v-bind=\"slotProps || {}\" />\n </template>\n <template v-if=\"$slots['mermaid-error']\" #mermaid-error=\"slotProps\">\n <slot name=\"mermaid-error\" v-bind=\"slotProps || {}\" />\n </template>\n </MermaidBlock>\n</template>\n","import { h, type Component, type VNodeChild } from 'vue'\r\nimport type {\r\n MarkdownCodeNode,\r\n MarkdownComponentValue,\r\n MarkdownCustomTagNode,\r\n MarkdownElementNode,\r\n MarkdownNode,\r\n MarkdownTextNode,\r\n} from '../core/types'\r\nimport type { RenderContext } from './context'\r\nimport CodeBlock from './CodeBlock.vue'\r\nimport MarkdownBlockquote from './MarkdownBlockquote.vue'\r\nimport MarkdownBreak from './MarkdownBreak.vue'\r\nimport MarkdownCode from './MarkdownCode.vue'\r\nimport MarkdownCustomTag from './MarkdownCustomTag.vue'\r\nimport MarkdownEmphasis from './MarkdownEmphasis.vue'\r\nimport MarkdownHeading from './MarkdownHeading.vue'\r\nimport MarkdownHorizontalRule from './MarkdownHorizontalRule.vue'\r\nimport MarkdownImage from './MarkdownImage.vue'\r\nimport MarkdownInlineCode from './MarkdownInlineCode.vue'\r\nimport MarkdownLink from './MarkdownLink.vue'\r\nimport MarkdownList from './MarkdownList.vue'\r\nimport MarkdownMath from './MarkdownMath.vue'\r\nimport MarkdownMermaid from './MarkdownMermaid.vue'\r\nimport MarkdownListItem from './MarkdownListItem.vue'\r\nimport MarkdownFootnoteReference from './MarkdownFootnoteReference.vue'\r\nimport MarkdownFootnotes from './MarkdownFootnotes.vue'\r\nimport MarkdownParagraph from './MarkdownParagraph.vue'\r\nimport MarkdownStrikethrough from './MarkdownStrikethrough.vue'\r\nimport MarkdownTaskItem from './MarkdownTaskItem.vue'\r\nimport MarkdownStrong from './MarkdownStrong.vue'\r\nimport MarkdownTable from './MarkdownTable.vue'\r\nimport MarkdownTableCell from './MarkdownTableCell.vue'\r\nimport MarkdownTableRow from './MarkdownTableRow.vue'\r\nimport MarkdownTableSection from './MarkdownTableSection.vue'\r\n\r\nconst BUILTINS: Record<string, Component> = {\r\n p: MarkdownParagraph,\r\n h1: MarkdownHeading,\r\n h2: MarkdownHeading,\r\n h3: MarkdownHeading,\r\n h4: MarkdownHeading,\r\n h5: MarkdownHeading,\r\n h6: MarkdownHeading,\r\n em: MarkdownEmphasis,\r\n strong: MarkdownStrong,\r\n del: MarkdownStrikethrough,\r\n a: MarkdownLink,\r\n img: MarkdownImage,\r\n ul: MarkdownList,\r\n ol: MarkdownList,\r\n li: MarkdownListItem,\r\n blockquote: MarkdownBlockquote,\r\n hr: MarkdownHorizontalRule,\r\n table: MarkdownTable,\r\n thead: MarkdownTableSection,\r\n tbody: MarkdownTableSection,\r\n tfoot: MarkdownTableSection,\r\n tr: MarkdownTableRow,\r\n th: MarkdownTableCell,\r\n td: MarkdownTableCell,\r\n code: MarkdownInlineCode,\r\n br: MarkdownBreak,\r\n}\r\n\r\n/** Element tags that map to a semantic node kind. */\r\nexport const TAG_TO_KIND: Record<string, string> = {\r\n p: 'paragraph',\r\n h1: 'heading',\r\n h2: 'heading',\r\n h3: 'heading',\r\n h4: 'heading',\r\n h5: 'heading',\r\n h6: 'heading',\r\n em: 'emphasis',\r\n strong: 'strong',\r\n del: 'strikethrough',\r\n a: 'link',\r\n img: 'image',\r\n ul: 'list',\r\n ol: 'list',\r\n li: 'listItem',\r\n blockquote: 'blockquote',\r\n hr: 'horizontalRule',\r\n table: 'table',\r\n thead: 'tableSection',\r\n tbody: 'tableSection',\r\n tfoot: 'tableSection',\r\n tr: 'tableRow',\r\n th: 'tableCell',\r\n td: 'tableCell',\r\n code: 'inlineCode',\r\n br: 'break',\r\n input: 'taskItem',\r\n}\r\n\r\nfunction semanticBuiltin(kind: string): Component | undefined {\r\n if (kind === 'code') return MarkdownCode\r\n if (kind === 'custom') return MarkdownCustomTag\r\n if (kind === 'math') return MarkdownMath\r\n if (kind === 'mermaid') return MarkdownMermaid\r\n return undefined\r\n}\r\n\r\nfunction isComponentValue(\r\n value: MarkdownComponentValue | undefined,\r\n): value is Component | string {\r\n return typeof value === 'string' || typeof value === 'object'\r\n}\r\n\r\nfunction isNodeRenderer(\r\n value: MarkdownComponentValue | undefined,\r\n): value is (...args: never[]) => unknown {\r\n return typeof value === 'function'\r\n}\r\n\r\nfunction kindOf(node: MarkdownNode): string {\r\n if (node.kind !== 'element') return node.kind\r\n return TAG_TO_KIND[node.tag] ?? node.tag\r\n}\r\n\r\nfunction classList(node: MarkdownElementNode): string[] {\r\n return (node.attrs.class ?? '').split(/\\s+/).filter(Boolean)\r\n}\r\n\r\nfunction directTaskInput(\r\n node: MarkdownElementNode,\r\n): MarkdownElementNode | undefined {\r\n return node.children.find(\r\n (child): child is MarkdownElementNode =>\r\n child.kind === 'element' &&\r\n child.tag === 'input' &&\r\n child.attrs.type === 'checkbox',\r\n )\r\n}\r\n\r\nfunction specialNodeKey(node: MarkdownNode): string | undefined {\r\n if (node.kind !== 'element') return undefined\r\n if (node.tag === 'li' && directTaskInput(node)) return 'taskItem'\r\n if (\r\n node.tag === 'sup' &&\r\n (classList(node).includes('footnote-ref') ||\r\n node.attrs['data-footnote-ref'] !== undefined ||\r\n node.children.some(\r\n (child) =>\r\n child.kind === 'element' &&\r\n child.tag === 'a' &&\r\n (classList(child).includes('footnote-ref') ||\r\n child.attrs['data-footnote-ref'] !== undefined),\r\n ))\r\n ) {\r\n return 'footnoteReference'\r\n }\r\n if (\r\n node.tag === 'section' &&\r\n (classList(node).includes('footnotes') ||\r\n node.attrs['data-footnotes'] !== undefined)\r\n ) {\r\n return 'footnotes'\r\n }\r\n return undefined\r\n}\r\n\r\nfunction hasNodeId(nodes: readonly MarkdownNode[], id: string): boolean {\r\n for (const node of nodes) {\r\n if (node.kind === 'element' && node.attrs.id === id) return true\r\n if ('children' in node && Array.isArray(node.children)) {\r\n if (hasNodeId(node.children, id)) return true\r\n }\r\n }\r\n return false\r\n}\r\n\r\nfunction footnoteTarget(node: MarkdownNode): string | undefined {\r\n if (node.kind !== 'element') return undefined\r\n for (const child of node.children) {\r\n if (child.kind === 'element' && child.tag === 'a' && child.attrs.href?.startsWith('#')) {\r\n return child.attrs.href.slice(1)\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\nfunction rendererKeys(node: MarkdownNode): string[] {\r\n if (node.kind === 'element') {\r\n const kind = kindOf(node)\r\n return kind === node.tag ? [node.tag] : [node.tag, kind]\r\n }\r\n if (node.kind === 'custom') return [node.tag, 'custom']\r\n if (node.kind === 'plugin') return [node.type, 'plugin']\r\n return [node.kind]\r\n}\r\n\r\nfunction resolveNodeRenderer(\r\n node: MarkdownNode,\r\n ctx: RenderContext,\r\n): ((...args: never[]) => unknown) | undefined {\r\n for (const key of rendererKeys(node)) {\r\n const value = ctx.nodeComponents?.[key]\r\n if (isNodeRenderer(value)) return value\r\n }\r\n return undefined\r\n}\r\n\r\nfunction resolveNodeComponent(\r\n node: MarkdownNode,\r\n ctx: RenderContext,\r\n): Component | string | undefined {\r\n // Inline code is an element tag, while fenced code is the semantic `code`\r\n // node. `nodeComponents.code` therefore applies to fenced code only; inline\r\n // code follows `nodeComponents.inlineCode` and `components.code`.\r\n if (node.kind === 'element' && node.tag === 'code') {\r\n const inline = ctx.nodeComponents?.inlineCode\r\n if (isComponentValue(inline)) return inline\r\n const tag = ctx.components.code\r\n if (typeof tag === 'function' || isComponentValue(tag)) {\r\n return tag as Component | string\r\n }\r\n return undefined\r\n }\r\n\r\n const special = specialNodeKey(node)\r\n if (special) {\r\n const specialValue = ctx.nodeComponents?.[special]\r\n if (isComponentValue(specialValue)) return specialValue\r\n }\r\n\r\n const kind = kindOf(node)\r\n for (const key of rendererKeys(node)) {\r\n const nodeValue = ctx.nodeComponents?.[key]\r\n if (isComponentValue(nodeValue)) return nodeValue\r\n const tagValue = ctx.components[key]\r\n if (typeof tagValue === 'function' || isComponentValue(tagValue)) {\r\n return tagValue as Component | string\r\n }\r\n if (key !== kind && ctx.nodeComponents?.[kind]) {\r\n const kindValue = ctx.nodeComponents[kind]\r\n if (isComponentValue(kindValue)) return kindValue\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\nfunction renderText(node: MarkdownTextNode, ctx: RenderContext): VNodeChild {\r\n if (!node.segments || node.segments.length === 0) return node.value\r\n const matchComponent = ctx.components.mark\r\n return node.segments.map((segment, index) => {\r\n if (!segment.match) return segment.value\r\n if (typeof matchComponent === 'string') {\r\n return h(\r\n matchComponent,\r\n {\r\n class: 'vmd-search-match',\r\n 'data-vmd-part': 'search-match',\r\n key: index,\r\n },\r\n segment.value,\r\n )\r\n }\r\n if (typeof matchComponent === 'object' || typeof matchComponent === 'function') {\r\n return h(\r\n matchComponent as Component,\r\n {\r\n class: 'vmd-search-match',\r\n 'data-vmd-part': 'search-match',\r\n key: index,\r\n },\r\n { default: () => segment.value },\r\n )\r\n }\r\n return h(\r\n 'mark',\r\n { class: 'vmd-search-match', 'data-vmd-part': 'search-match', key: index },\r\n segment.value,\r\n )\r\n })\r\n}\r\n\r\nexport function resolveTagComponent(\r\n tag: string,\r\n ctx: RenderContext,\r\n): Component | string | undefined {\r\n const nodeComponent = ctx.nodeComponents?.[tag]\r\n if (isComponentValue(nodeComponent)) return nodeComponent\r\n\r\n const tagComponent = ctx.components[tag]\r\n if (\r\n typeof tagComponent === 'function' ||\r\n isComponentValue(tagComponent)\r\n ) {\r\n return tagComponent as Component | string\r\n }\r\n\r\n return BUILTINS[tag]\r\n}\r\n\r\nexport function resolveKindComponent(\r\n kind: string,\r\n ctx: RenderContext,\r\n): Component | string | undefined {\r\n const value = ctx.nodeComponents?.[kind]\r\n return isComponentValue(value) ? value : undefined\r\n}\r\n\r\ninterface NodeRendererContext {\r\n node: MarkdownNode\r\n kind: MarkdownNode['kind']\r\n tag?: string\r\n attrs: Record<string, string>\r\n key: string\r\n children: () => VNodeChild\r\n defaultRender: () => VNodeChild\r\n context: RenderContext\r\n}\r\n\r\ntype NodeRenderer = (context: NodeRendererContext) => VNodeChild\r\n\r\nfunction rendererShape(node: MarkdownNode): Pick<\r\n NodeRendererContext,\r\n 'kind' | 'tag' | 'attrs'\r\n> {\r\n if (node.kind === 'element' || node.kind === 'custom') {\r\n return { kind: node.kind, tag: node.tag, attrs: node.attrs }\r\n }\r\n return { kind: node.kind, attrs: {} }\r\n}\r\n\r\nfunction childrenRenderer(\r\n node: MarkdownElementNode | MarkdownCustomTagNode,\r\n ctx: RenderContext,\r\n): () => VNodeChild[] {\r\n return () => renderNodes(node.children, ctx)\r\n}\r\n\r\nconst childrenPropCache = new WeakMap<object, boolean>()\r\n\r\n/**\r\n * `children` is a DOM property on elements, so forwarding it to a string tag or\r\n * to a component that does not declare it makes Vue warn or leak the node array\r\n * into an attribute. Only components that opt in with a `children` prop receive\r\n * the raw child nodes; everything else reads the rendered default slot.\r\n */\r\nfunction declaresChildrenProp(component: Component): boolean {\r\n const cached = childrenPropCache.get(component as object)\r\n if (cached !== undefined) return cached\r\n const declared = (component as { props?: unknown }).props\r\n const result = Array.isArray(declared)\r\n ? declared.indexOf('children') !== -1\r\n : declared !== null &&\r\n typeof declared === 'object' &&\r\n Object.prototype.hasOwnProperty.call(declared, 'children')\r\n childrenPropCache.set(component as object, result)\r\n return result\r\n}\r\n\r\nfunction renderComponent(\r\n component: Component | string,\r\n node: MarkdownNode,\r\n ctx: RenderContext,\r\n attrs: Record<string, string>,\r\n extraProps: Record<string, unknown> = {},\r\n children?: () => VNodeChild[],\r\n): VNodeChild {\r\n const props: Record<string, unknown> = {\r\n ...attrs,\r\n ...extraProps,\r\n key: node.key,\r\n }\r\n if (\r\n 'children' in props &&\r\n (typeof component === 'string' || !declaresChildrenProp(component))\r\n ) {\r\n delete props.children\r\n }\r\n const slot = children ?? (() => [])\r\n if (typeof component === 'string') return h(component, props, slot)\r\n return h(\r\n component,\r\n {\r\n ...props,\r\n node,\r\n },\r\n { default: slot },\r\n )\r\n}\r\n\r\nfunction renderCodeElement(\r\n node: MarkdownCodeNode,\r\n ctx: RenderContext,\r\n skipRenderer = false,\r\n): VNodeChild {\r\n // react-markdown parity: `components.code` handles both inline and fenced\r\n // code. Fenced code receives a `className` instead of a separate `inline`\r\n // flag, so the same override works for both shapes. The semantic\r\n // `nodeComponents.code` override additionally receives the source and\r\n // language for richer host renderers.\r\n const semantic = ctx.nodeComponents?.code\r\n const className = node.language ? `language-${node.language}` : undefined\r\n const key = `${node.key}-code`\r\n\r\n if (!skipRenderer && isNodeRenderer(semantic)) {\r\n const renderer = semantic as unknown as NodeRenderer\r\n return renderer({\r\n node,\r\n ...rendererShape(node),\r\n key,\r\n children: () => [node.code],\r\n defaultRender: () => renderCodeElement(node, ctx, true),\r\n context: ctx,\r\n })\r\n }\r\n\r\n const component =\r\n (isComponentValue(semantic) ? semantic : undefined) ??\r\n (isComponentValue(ctx.components.code) ? ctx.components.code : undefined) ??\r\n 'code'\r\n\r\n if (typeof component === 'string') {\r\n return h(\r\n component,\r\n {\r\n class: className ? ['vmd-code-element', className] : 'vmd-code-element',\r\n key,\r\n },\r\n node.code,\r\n )\r\n }\r\n\r\n return h(\r\n component,\r\n {\r\n node,\r\n className,\r\n key,\r\n ...(semantic ? { code: node.code, language: node.language } : {}),\r\n },\r\n { default: () => [node.code] },\r\n )\r\n}\r\n\r\nfunction renderCode(node: MarkdownCodeNode, ctx: RenderContext): VNodeChild {\r\n // `components.pre` wraps the code element; it does not replace it.\r\n const tagComponent = ctx.components.pre\r\n if (typeof tagComponent === 'function' || isComponentValue(tagComponent)) {\r\n return renderComponent(\r\n tagComponent as Component | string,\r\n node,\r\n ctx,\r\n {},\r\n {},\r\n () => [renderCodeElement(node, ctx)],\r\n )\r\n }\r\n\r\n // Host code-element overrides keep the legacy `pre` wrapper and inner\r\n // resolution path. The default path uses the richer CodeBlock.\r\n if (\r\n isComponentValue(ctx.components.code) ||\r\n isComponentValue(ctx.nodeComponents?.code) ||\r\n isNodeRenderer(ctx.nodeComponents?.code)\r\n ) {\r\n return renderComponent(\r\n MarkdownCode,\r\n node,\r\n ctx,\r\n {},\r\n {},\r\n () => [renderCodeElement(node, ctx)],\r\n )\r\n }\r\n\r\n return h(CodeBlock, { node, key: node.key })\r\n}\r\n\r\nfunction renderTaskItem(\r\n node: MarkdownElementNode,\r\n ctx: RenderContext,\r\n): VNodeChild {\r\n const input = directTaskInput(node)\r\n const checked =\r\n input?.attrs.checked !== undefined && input.attrs.checked !== 'false'\r\n const children = node.children.filter((child) => child !== input)\r\n\r\n return h(\r\n MarkdownTaskItem,\r\n {\r\n node,\r\n key: node.key,\r\n checked,\r\n children: node.children,\r\n },\r\n { default: () => renderNodes(children, ctx) },\r\n )\r\n}\r\n\r\nfunction renderFootnotes(\r\n node: MarkdownElementNode,\r\n ctx: RenderContext,\r\n): VNodeChild {\r\n return h(\r\n MarkdownFootnotes,\r\n { node, key: node.key },\r\n { default: () => renderNodes(node.children, ctx) },\r\n )\r\n}\r\n\r\nfunction renderFootnoteReference(\r\n node: MarkdownElementNode,\r\n ctx: RenderContext,\r\n): VNodeChild {\r\n const target = footnoteTarget(node)\r\n const missing =\r\n target !== undefined && ctx.document !== undefined\r\n ? !hasNodeId(ctx.document.nodes, target)\r\n : false\r\n\r\n return h(\r\n MarkdownFootnoteReference,\r\n { node, key: node.key, missing },\r\n { default: () => renderNodes(node.children, ctx) },\r\n )\r\n}\r\n\r\nfunction renderSpecialElement(\r\n node: MarkdownElementNode,\r\n ctx: RenderContext,\r\n key: string,\r\n): VNodeChild | undefined {\r\n if (key === 'taskItem') return renderTaskItem(node, ctx)\r\n if (key === 'footnotes') return renderFootnotes(node, ctx)\r\n if (key === 'footnoteReference') return renderFootnoteReference(node, ctx)\r\n return undefined\r\n}\r\n\r\nfunction renderCustom(node: MarkdownCustomTagNode, ctx: RenderContext): VNodeChild {\r\n // The semantic override wins; otherwise MarkdownCustomTag resolves the host\r\n // tag component so click payloads and normalized props stay wired.\r\n const semantic =\r\n resolveKindComponent(node.tag, ctx) ?? resolveKindComponent('custom', ctx)\r\n const component = semantic ?? MarkdownCustomTag\r\n\r\n return renderComponent(\r\n component,\r\n node,\r\n ctx,\r\n node.attrs,\r\n { tag: node.tag, customProps: node.props },\r\n childrenRenderer(node, ctx),\r\n )\r\n}\r\n\r\nfunction renderNodeDefault(node: MarkdownNode, ctx: RenderContext): VNodeChild {\r\n switch (node.kind) {\r\n case 'text':\r\n return renderText(node, ctx)\r\n case 'element': {\r\n const component = resolveNodeComponent(node, ctx)\r\n if (!component) {\r\n const special = specialNodeKey(node)\r\n const rendered = special\r\n ? renderSpecialElement(node, ctx, special)\r\n : undefined\r\n if (rendered !== undefined) return rendered\r\n }\r\n const resolved = component ?? BUILTINS[node.tag]\r\n if (!resolved) {\r\n const attrs = { ...node.attrs }\r\n // A string tag cannot receive a `children` prop; keep it out of the DOM\r\n // attribute set even if a custom pipeline or schema added one.\r\n delete attrs.children\r\n return h(\r\n node.tag,\r\n { ...attrs, key: node.key },\r\n childrenRenderer(node, ctx),\r\n )\r\n }\r\n return renderComponent(\r\n resolved,\r\n node,\r\n ctx,\r\n node.attrs,\r\n { children: node.children },\r\n childrenRenderer(node, ctx),\r\n )\r\n }\r\n case 'code':\r\n return renderCode(node, ctx)\r\n case 'custom':\r\n return renderCustom(node, ctx)\r\n case 'math':\r\n return renderComponent(\r\n resolveNodeComponent(node, ctx) ?? semanticBuiltin('math') ?? 'span',\r\n node,\r\n ctx,\r\n {},\r\n {\r\n tex: node.tex,\r\n displayMode: node.displayMode,\r\n rendered: node.rendered,\r\n },\r\n )\r\n case 'mermaid':\r\n return renderComponent(\r\n resolveNodeComponent(node, ctx) ?? semanticBuiltin('mermaid') ?? 'pre',\r\n node,\r\n ctx,\r\n {},\r\n { code: node.code },\r\n )\r\n case 'plugin':\r\n return renderComponent(\r\n resolveNodeComponent(node, ctx) ??\r\n semanticBuiltin(node.type) ??\r\n 'div',\r\n node,\r\n ctx,\r\n {},\r\n { payload: node.payload },\r\n node.children ? () => renderNodes(node.children!, ctx) : () => [],\r\n )\r\n default:\r\n return null\r\n }\r\n}\r\n\r\nexport function renderNode(node: MarkdownNode, ctx: RenderContext): VNodeChild {\r\n if (node.kind === 'text') return renderText(node, ctx)\r\n\r\n // A function value in `nodeComponents` is the advanced renderer escape hatch.\r\n // Fenced code keeps `nodeComponents.code` as the inner code override, so the\r\n // whole code node is never replaced by that renderer.\r\n if (node.kind !== 'code') {\r\n const renderer = resolveNodeRenderer(node, ctx)\r\n if (renderer) {\r\n const call = renderer as unknown as NodeRenderer\r\n const childSource =\r\n node.kind === 'element' || node.kind === 'custom'\r\n ? childrenRenderer(node, ctx)\r\n : undefined\r\n return call({\r\n node,\r\n ...rendererShape(node),\r\n key: node.key,\r\n children: () => (childSource ? childSource() : []),\r\n defaultRender: () => renderNodeDefault(node, ctx),\r\n context: ctx,\r\n })\r\n }\r\n }\r\n\r\n return renderNodeDefault(node, ctx)\r\n}\r\n\r\nexport function renderNodes(\r\n nodes: readonly MarkdownNode[],\r\n ctx: RenderContext,\r\n): VNodeChild[] {\r\n return nodes.map((node) => renderNode(node, ctx))\r\n}\r\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-DJMnzjah.js","names":["_asyncToGenerator","ALLOWED_TAGS","SVG_TAG_NAMES","ALLOWED_ATTRIBUTES","DROPPED_TAGS","UNSAFE_CSS","CSS_URL","SCOPED_AT_RULES","SCOPED_STATEMENT_AT_RULES","isFragmentReference","value","reference","quote","attributeName","key","safeAttributes","_element$properties","attrs","properties","element","name","_properties$key","rawText","node","nodes","atRuleName","match","prelude","hasSiblingCombinator","depth","index","selector","char","isScopedSelector","scope","rest","splitSelectors","selectors","current","findBlockEnd","start","limit","css","close","isScopedBlock","isScopedStyleSheet","body","open","semicolon","end","sanitizeStyleSheet","safe","collectLabelLines","lines","buffer","flush","line","visit","tag","child","convertForeignObject","source","sanitizeNodes","result","_SVG_TAG_NAMES$tag","path","svgScope","_element$properties2","id","modelScope","_svg$attrs","svg","sanitizeSvg","root","fromHtml","svgElement","safeModelAttributes","modelText","sanitizeModelNodes","_SVG_TAG_NAMES$tag2","children","sanitizeMermaidNodes","mermaidPromise","initializedTheme","queue","counter","prefersDark","themeName","theme","loadMermaid","_loadMermaid","_module$default","module","initialize","_initialize","api","missingMermaid","message","classifyMermaidError","error","createMermaidRenderId","renderMermaid","_renderMermaid","run","_ref","_options$id","options","resetMermaidRuntime"],"sources":["../../src/mermaid/sanitize.ts","../../src/mermaid/runtime.ts"],"sourcesContent":["import { fromHtml } from 'hast-util-from-html'\r\nimport type { Element, RootContent } from 'hast'\r\nimport type { MarkdownNode } from '../core/types'\r\n\r\nconst ALLOWED_TAGS = new Set([\r\n 'svg',\r\n 'g',\r\n 'path',\r\n 'rect',\r\n 'circle',\r\n 'ellipse',\r\n 'line',\r\n 'polyline',\r\n 'polygon',\r\n 'text',\r\n 'tspan',\r\n 'defs',\r\n 'marker',\r\n 'use',\r\n 'title',\r\n 'desc',\r\n 'clippath',\r\n 'lineargradient',\r\n 'radialgradient',\r\n 'stop',\r\n 'pattern',\r\n 'mask',\r\n 'symbol',\r\n 'textpath',\r\n 'style',\r\n])\r\n\r\n// Hast lowercases element lookups while SVG element names are case-sensitive.\r\nconst SVG_TAG_NAMES: Record<string, string> = {\r\n clippath: 'clipPath',\r\n lineargradient: 'linearGradient',\r\n radialgradient: 'radialGradient',\r\n textpath: 'textPath',\r\n}\r\n\r\n// Keys are normalized with `attributeName` (lowercase, without `-`, `_`, or\r\n// `:`), values are the case-sensitive SVG attribute names. Hast exposes SVG\r\n// properties in camelCase (`strokeWidth`, `stopColor`, `viewBox`, ...), while\r\n// Vue writes the keys it receives with `setAttribute`, so both sides must be\r\n// converted back to their SVG spelling.\r\nconst ALLOWED_ATTRIBUTES: Record<string, string> = {\r\n id: 'id',\r\n class: 'class',\r\n d: 'd',\r\n fill: 'fill',\r\n fillopacity: 'fill-opacity',\r\n fillrule: 'fill-rule',\r\n stroke: 'stroke',\r\n strokewidth: 'stroke-width',\r\n strokedasharray: 'stroke-dasharray',\r\n strokedashoffset: 'stroke-dashoffset',\r\n strokelinecap: 'stroke-linecap',\r\n strokelinejoin: 'stroke-linejoin',\r\n strokemiterlimit: 'stroke-miterlimit',\r\n strokeopacity: 'stroke-opacity',\r\n x: 'x',\r\n y: 'y',\r\n x1: 'x1',\r\n y1: 'y1',\r\n x2: 'x2',\r\n y2: 'y2',\r\n cx: 'cx',\r\n cy: 'cy',\r\n r: 'r',\r\n rx: 'rx',\r\n ry: 'ry',\r\n width: 'width',\r\n height: 'height',\r\n viewbox: 'viewBox',\r\n preserveaspectratio: 'preserveAspectRatio',\r\n transform: 'transform',\r\n transformorigin: 'transform-origin',\r\n points: 'points',\r\n pathlength: 'pathLength',\r\n offset: 'offset',\r\n stopcolor: 'stop-color',\r\n stopopacity: 'stop-opacity',\r\n markerstart: 'marker-start',\r\n markermid: 'marker-mid',\r\n markerend: 'marker-end',\r\n markerwidth: 'markerWidth',\r\n markerheight: 'markerHeight',\r\n markerunits: 'markerUnits',\r\n refx: 'refX',\r\n refy: 'refY',\r\n orient: 'orient',\r\n gradientunits: 'gradientUnits',\r\n gradienttransform: 'gradientTransform',\r\n spreadmethod: 'spreadMethod',\r\n fx: 'fx',\r\n fy: 'fy',\r\n fr: 'fr',\r\n patternunits: 'patternUnits',\r\n patterncontentunits: 'patternContentUnits',\r\n patterntransform: 'patternTransform',\r\n clippathunits: 'clipPathUnits',\r\n clippath: 'clip-path',\r\n cliprule: 'clip-rule',\r\n mask: 'mask',\r\n maskunits: 'maskUnits',\r\n maskcontentunits: 'maskContentUnits',\r\n textlength: 'textLength',\r\n lengthadjust: 'lengthAdjust',\r\n textanchor: 'text-anchor',\r\n dominantbaseline: 'dominant-baseline',\r\n alignmentbaseline: 'alignment-baseline',\r\n baselineshift: 'baseline-shift',\r\n fontfamily: 'font-family',\r\n fontsize: 'font-size',\r\n fontweight: 'font-weight',\r\n fontstyle: 'font-style',\r\n fontvariant: 'font-variant',\r\n letterspacing: 'letter-spacing',\r\n wordspacing: 'word-spacing',\r\n textdecoration: 'text-decoration',\r\n whitespace: 'white-space',\r\n texttransform: 'text-transform',\r\n direction: 'direction',\r\n writingmode: 'writing-mode',\r\n lineheight: 'line-height',\r\n dx: 'dx',\r\n dy: 'dy',\r\n rotate: 'rotate',\r\n startoffset: 'startOffset',\r\n method: 'method',\r\n spacing: 'spacing',\r\n side: 'side',\r\n color: 'color',\r\n display: 'display',\r\n visibility: 'visibility',\r\n overflow: 'overflow',\r\n opacity: 'opacity',\r\n role: 'role',\r\n arialabel: 'aria-label',\r\n ariahidden: 'aria-hidden',\r\n ariahaspopup: 'aria-haspopup',\r\n arialabelledby: 'aria-labelledby',\r\n ariadescribedby: 'aria-describedby',\r\n ariaroledescription: 'aria-roledescription',\r\n focusable: 'focusable',\r\n tabindex: 'tabindex',\r\n href: 'href',\r\n xlinkhref: 'xlink:href',\r\n xmlspace: 'xml:space',\r\n vectoreffect: 'vector-effect',\r\n paintorder: 'paint-order',\r\n shaperendering: 'shape-rendering',\r\n pointerevents: 'pointer-events',\r\n filter: 'filter',\r\n cursor: 'cursor',\r\n}\r\n\r\nconst DROPPED_TAGS = new Set([\r\n 'script',\r\n 'foreignobject',\r\n 'iframe',\r\n 'object',\r\n 'embed',\r\n 'image',\r\n 'audio',\r\n 'video',\r\n])\r\n\r\n// Mermaid scopes its generated stylesheet to the SVG id. Keep that scoped\r\n// theme CSS, but remove constructs that could load remote resources or execute\r\n// in older engines.\r\nconst UNSAFE_CSS =\r\n /@import|@font-face|expression\\s*\\(|javascript\\s*:|-moz-binding|behavior\\s*:/i\r\nconst CSS_URL = /url\\(\\s*([^)]*)\\)/gi\r\nconst SCOPED_AT_RULES = new Set(['media', 'supports', 'layer'])\r\nconst SCOPED_STATEMENT_AT_RULES = new Set(['charset', 'layer'])\r\n\r\nfunction isFragmentReference(reference: string): boolean {\r\n let value = reference.trim()\r\n const quote = value.charAt(0)\r\n if (\r\n (quote === '\"' || quote === \"'\") &&\r\n value.charAt(value.length - 1) === quote\r\n ) {\r\n value = value.slice(1, -1).trim()\r\n }\r\n return value.startsWith('#')\r\n}\r\n\r\nfunction attributeName(key: string): string | undefined {\r\n if (key === 'className') return 'class'\r\n if (key.startsWith('data-')) return key\r\n if (\r\n key.startsWith('data') &&\r\n key.length > 4 &&\r\n key.charAt(4) >= 'A' &&\r\n key.charAt(4) <= 'Z'\r\n ) {\r\n return key.replace(/([A-Z])/g, '-$1').toLowerCase()\r\n }\r\n const normalized = key.toLowerCase().replace(/[-_:]/g, '')\r\n return ALLOWED_ATTRIBUTES[normalized]\r\n}\r\n\r\nfunction safeAttributes(element: Element): Record<string, string> {\r\n const attrs: Record<string, string> = {}\r\n const properties = element.properties ?? {}\r\n for (const key of Object.keys(properties)) {\r\n const name = attributeName(key)\r\n if (!name) continue\r\n if (name === 'href' || name === 'xlink:href') {\r\n const value = String(properties[key] ?? '')\r\n if (value.startsWith('#')) attrs[name] = value\r\n continue\r\n }\r\n const value = properties[key]\r\n if (value === null || value === undefined || value === false) continue\r\n attrs[name] = Array.isArray(value)\r\n ? value.map(String).join(' ')\r\n : String(value)\r\n }\r\n return attrs\r\n}\r\n\r\nfunction rawText(nodes: readonly RootContent[]): string {\r\n let value = ''\r\n for (const node of nodes) {\r\n if (node.type === 'text') value += node.value\r\n else if (node.type === 'element') value += rawText(node.children)\r\n }\r\n return value\r\n}\r\n\r\nfunction atRuleName(prelude: string): string {\r\n const match = /^@([-a-zA-Z]+)/.exec(prelude)\r\n return match ? match[1].toLowerCase() : ''\r\n}\r\n\r\nfunction hasSiblingCombinator(selector: string): boolean {\r\n let depth = 0\r\n let quote = ''\r\n for (let index = 0; index < selector.length; index++) {\r\n const char = selector.charAt(index)\r\n if (quote) {\r\n if (char === '\\\\') index++\r\n else if (char === quote) quote = ''\r\n continue\r\n }\r\n if (char === '\"' || char === \"'\") {\r\n quote = char\r\n continue\r\n }\r\n if (char === '(' || char === '[') depth++\r\n else if (char === ')' || char === ']') depth = Math.max(0, depth - 1)\r\n else if (depth === 0 && (char === '+' || char === '~')) return true\r\n }\r\n return false\r\n}\r\n\r\nfunction isScopedSelector(selector: string, scope: string): boolean {\r\n const value = selector.trim()\r\n if (!value.startsWith(scope)) return false\r\n const rest = value.charAt(scope.length)\r\n if (rest !== '' && /[a-zA-Z0-9_-]/.test(rest)) return false\r\n // Descendant and child combinators stay inside the SVG. Sibling combinators\r\n // could reach host-page elements next to the diagram.\r\n return !hasSiblingCombinator(value)\r\n}\r\n\r\nfunction splitSelectors(prelude: string): string[] {\r\n const selectors: string[] = []\r\n let current = ''\r\n let depth = 0\r\n let quote = ''\r\n for (let index = 0; index < prelude.length; index++) {\r\n const char = prelude.charAt(index)\r\n if (quote) {\r\n current += char\r\n if (char === '\\\\') {\r\n current += prelude.charAt(++index)\r\n } else if (char === quote) {\r\n quote = ''\r\n }\r\n continue\r\n }\r\n if (char === '\"' || char === \"'\") {\r\n quote = char\r\n current += char\r\n continue\r\n }\r\n if (char === '(' || char === '[') depth++\r\n else if (char === ')' || char === ']') depth = Math.max(0, depth - 1)\r\n else if (char === ',' && depth === 0) {\r\n selectors.push(current)\r\n current = ''\r\n continue\r\n }\r\n current += char\r\n }\r\n selectors.push(current)\r\n return selectors\r\n}\r\n\r\nfunction findBlockEnd(css: string, start: number, limit: number): number {\r\n let depth = 0\r\n let quote = ''\r\n for (let index = start; index < limit; index++) {\r\n const char = css.charAt(index)\r\n if (quote) {\r\n if (char === '\\\\') index++\r\n else if (char === quote) quote = ''\r\n continue\r\n }\r\n if (char === '\"' || char === \"'\") {\r\n quote = char\r\n continue\r\n }\r\n if (char === '/' && css.charAt(index + 1) === '*') {\r\n const close = css.indexOf('*/', index + 2)\r\n if (close === -1 || close >= limit) return -1\r\n index = close + 1\r\n continue\r\n }\r\n if (char === '{') depth++\r\n else if (char === '}') {\r\n depth--\r\n if (depth === 0) return index\r\n }\r\n }\r\n return -1\r\n}\r\n\r\nfunction isScopedBlock(\r\n prelude: string,\r\n body: string,\r\n scope: string,\r\n): boolean {\r\n if (prelude.startsWith('@')) {\r\n const name = atRuleName(prelude)\r\n if (name.endsWith('keyframes')) return true\r\n return SCOPED_AT_RULES.has(name) && isScopedStyleSheet(body, scope)\r\n }\r\n if (!prelude) return false\r\n return splitSelectors(prelude).every((selector) =>\r\n isScopedSelector(selector, scope),\r\n )\r\n}\r\n\r\nfunction isScopedStyleSheet(css: string, scope: string): boolean {\r\n let index = 0\r\n while (index < css.length) {\r\n while (index < css.length && /[\\s;]/.test(css.charAt(index))) {\r\n index++\r\n }\r\n if (index >= css.length) break\r\n\r\n const start = index\r\n let quote = ''\r\n let depth = 0\r\n let open = -1\r\n let semicolon = -1\r\n for (; index < css.length; index++) {\r\n const char = css.charAt(index)\r\n if (quote) {\r\n if (char === '\\\\') index++\r\n else if (char === quote) quote = ''\r\n continue\r\n }\r\n if (char === '\"' || char === \"'\") {\r\n quote = char\r\n continue\r\n }\r\n if (char === '/' && css.charAt(index + 1) === '*') {\r\n const close = css.indexOf('*/', index + 2)\r\n if (close === -1) return false\r\n index = close + 1\r\n continue\r\n }\r\n if (char === '(' || char === '[') depth++\r\n else if (char === ')' || char === ']') depth = Math.max(0, depth - 1)\r\n else if (depth === 0) {\r\n if (char === '{') {\r\n open = index\r\n break\r\n }\r\n if (char === ';') {\r\n semicolon = index\r\n break\r\n }\r\n if (char === '}') return false\r\n }\r\n }\r\n if (quote) return false\r\n\r\n const prelude = css.slice(start, open !== -1 ? open : semicolon).trim()\r\n if (open !== -1) {\r\n const end = findBlockEnd(css, open, css.length)\r\n if (end === -1) return false\r\n if (!isScopedBlock(prelude, css.slice(open + 1, end), scope)) {\r\n return false\r\n }\r\n index = end + 1\r\n continue\r\n }\r\n if (semicolon !== -1) {\r\n if (\r\n !prelude.startsWith('@') ||\r\n !SCOPED_STATEMENT_AT_RULES.has(atRuleName(prelude))\r\n ) {\r\n return false\r\n }\r\n index = semicolon + 1\r\n continue\r\n }\r\n if (prelude !== '') return false\r\n break\r\n }\r\n return true\r\n}\r\n\r\nfunction sanitizeStyleSheet(\r\n css: string,\r\n scope: string | undefined,\r\n): string | undefined {\r\n if (!scope || !css.trim() || UNSAFE_CSS.test(css)) return undefined\r\n if (!isScopedStyleSheet(css, scope)) return undefined\r\n const safe = css.replace(CSS_URL, (match, reference: string) =>\r\n isFragmentReference(reference) ? match : 'none',\r\n )\r\n return safe.trim() ? safe : undefined\r\n}\r\n\r\nfunction collectLabelLines(nodes: readonly RootContent[]): string[] {\r\n const lines: string[] = []\r\n let buffer = ''\r\n\r\n const flush = (): void => {\r\n const line = buffer.replace(/\\s+/g, ' ').trim()\r\n if (line) lines.push(line)\r\n buffer = ''\r\n }\r\n\r\n const visit = (node: RootContent): void => {\r\n if (node.type === 'text') {\r\n buffer += node.value\r\n return\r\n }\r\n if (node.type !== 'element') return\r\n const tag = node.tagName.toLowerCase()\r\n if (tag === 'br') {\r\n flush()\r\n return\r\n }\r\n if (tag === 'div' || tag === 'p' || tag === 'li' || tag === 'tr') {\r\n flush()\r\n for (const child of node.children) visit(child)\r\n flush()\r\n return\r\n }\r\n for (const child of node.children) visit(child)\r\n }\r\n\r\n for (const node of nodes) visit(node)\r\n flush()\r\n return lines\r\n}\r\n\r\nfunction convertForeignObject(node: Element, key: string): MarkdownNode[] {\r\n const lines = collectLabelLines(node.children)\r\n if (lines.length === 0) return []\r\n\r\n const source = safeAttributes(node)\r\n const attrs: Record<string, string> = {}\r\n for (const name of ['x', 'y', 'transform', 'class']) {\r\n if (source[name] !== undefined) attrs[name] = source[name]\r\n }\r\n if (attrs.x === undefined) attrs.x = '0'\r\n if (attrs.y === undefined) attrs.y = '0'\r\n\r\n return [\r\n {\r\n kind: 'element',\r\n key,\r\n tag: 'text',\r\n attrs,\r\n children: lines.map((line, index) => ({\r\n kind: 'element',\r\n key: `${key}.${index}`,\r\n tag: 'tspan',\r\n attrs: {\r\n x: attrs.x,\r\n dy: index === 0 ? '1em' : '1.2em',\r\n },\r\n children: [\r\n {\r\n kind: 'text',\r\n key: `${key}.${index}.text`,\r\n value: line,\r\n },\r\n ],\r\n })),\r\n },\r\n ]\r\n}\r\n\r\nfunction sanitizeNodes(\r\n nodes: readonly RootContent[],\r\n path = '',\r\n scope?: string,\r\n): MarkdownNode[] {\r\n const result: MarkdownNode[] = []\r\n nodes.forEach((node, index) => {\r\n const key = path ? `${path}.${index}` : String(index)\r\n if (node.type === 'text') {\r\n if (node.value.trim() !== '') {\r\n result.push({ kind: 'text', key, value: node.value })\r\n }\r\n return\r\n }\r\n if (node.type !== 'element') return\r\n const tag = node.tagName.toLowerCase()\r\n if (tag === 'foreignobject') {\r\n result.push(...convertForeignObject(node, key))\r\n return\r\n }\r\n if (tag === 'style') {\r\n const css = sanitizeStyleSheet(rawText(node.children), scope)\r\n if (css) {\r\n result.push({\r\n kind: 'element',\r\n key,\r\n tag: 'style',\r\n attrs: {},\r\n children: [{ kind: 'text', key: `${key}.css`, value: css }],\r\n })\r\n }\r\n return\r\n }\r\n if (DROPPED_TAGS.has(tag)) return\r\n if (!ALLOWED_TAGS.has(tag)) {\r\n result.push(...sanitizeNodes(node.children, key, scope))\r\n return\r\n }\r\n result.push({\r\n kind: 'element',\r\n key,\r\n tag: SVG_TAG_NAMES[tag] ?? tag,\r\n attrs: safeAttributes(node),\r\n children: sanitizeNodes(node.children, key, scope),\r\n })\r\n })\r\n return result\r\n}\r\n\r\nfunction svgScope(element: Element): string | undefined {\r\n const id = element.properties?.id\r\n return typeof id === 'string' && id !== '' ? `#${id}` : undefined\r\n}\r\n\r\nfunction modelScope(nodes: readonly MarkdownNode[]): string | undefined {\r\n const svg = nodes.find(\r\n (node): node is Extract<MarkdownNode, { kind: 'element' }> =>\r\n node.kind === 'element' && node.tag.toLowerCase() === 'svg',\r\n )\r\n const id = svg?.attrs?.id\r\n return typeof id === 'string' && id !== '' ? `#${id}` : undefined\r\n}\r\n\r\n/** Sanitize Mermaid SVG output into normalized nodes. */\r\nexport function sanitizeSvg(svg: string): MarkdownNode[] {\r\n const root = fromHtml(svg, { fragment: true })\r\n const svgElement = root.children.find(\r\n (node): node is Element =>\r\n node.type === 'element' && node.tagName.toLowerCase() === 'svg',\r\n )\r\n return svgElement\r\n ? sanitizeNodes([svgElement], '', svgScope(svgElement))\r\n : sanitizeNodes(root.children)\r\n}\r\n\r\nfunction safeModelAttributes(\r\n attrs: Record<string, string> | undefined,\r\n): Record<string, string> {\r\n const safe: Record<string, string> = {}\r\n if (!attrs || typeof attrs !== 'object') return safe\r\n for (const key of Object.keys(attrs)) {\r\n const name = attributeName(key)\r\n if (!name) continue\r\n const value = String(attrs[key])\r\n if (name === 'href' || name === 'xlink:href') {\r\n if (value.startsWith('#')) safe[name] = value\r\n continue\r\n }\r\n safe[name] = value\r\n }\r\n return safe\r\n}\r\n\r\nfunction modelText(nodes: readonly MarkdownNode[]): string {\r\n let value = ''\r\n if (!Array.isArray(nodes)) return value\r\n for (const node of nodes) {\r\n if (node.kind === 'text') value += node.value\r\n else if (node.kind === 'element') value += modelText(node.children)\r\n }\r\n return value\r\n}\r\n\r\nfunction sanitizeModelNodes(\r\n nodes: readonly MarkdownNode[],\r\n path = '',\r\n scope?: string,\r\n): MarkdownNode[] {\r\n const result: MarkdownNode[] = []\r\n if (!Array.isArray(nodes)) return result\r\n nodes.forEach((node, index) => {\r\n const key = path ? `${path}.${index}` : String(index)\r\n if (node.kind === 'text') {\r\n result.push({ kind: 'text', key, value: node.value })\r\n return\r\n }\r\n if (node.kind !== 'element' || typeof node.tag !== 'string') return\r\n const children = Array.isArray(node.children) ? node.children : []\r\n const tag = node.tag.toLowerCase()\r\n if (tag === 'style') {\r\n const css = sanitizeStyleSheet(modelText(children), scope)\r\n if (css) {\r\n result.push({\r\n kind: 'element',\r\n key,\r\n tag: 'style',\r\n attrs: {},\r\n children: [{ kind: 'text', key: `${key}.css`, value: css }],\r\n })\r\n }\r\n return\r\n }\r\n if (DROPPED_TAGS.has(tag)) return\r\n if (!ALLOWED_TAGS.has(tag)) {\r\n result.push(...sanitizeModelNodes(children, key, scope))\r\n return\r\n }\r\n result.push({\r\n kind: 'element',\r\n key,\r\n tag: SVG_TAG_NAMES[tag] ?? tag,\r\n attrs: safeModelAttributes(node.attrs),\r\n children: sanitizeModelNodes(children, key, scope),\r\n })\r\n })\r\n return result\r\n}\r\n\r\n/**\r\n * Sanitize nodes returned by an injected Mermaid renderer. Renderer output is\r\n * treated as untrusted even when it looks like normalized SVG nodes. A\r\n * stylesheet is kept only when the root SVG has an id and every selector is\r\n * scoped to it.\r\n */\r\nexport function sanitizeMermaidNodes(\r\n nodes: readonly MarkdownNode[],\r\n): MarkdownNode[] {\r\n const scope = Array.isArray(nodes) ? modelScope(nodes) : undefined\r\n return sanitizeModelNodes(nodes, '', scope)\r\n}\r\n\r\nexport { ALLOWED_TAGS as MERMAID_ALLOWED_TAGS }\r\n","import type {\r\n MarkdownTheme,\r\n MermaidRenderOptions,\r\n MermaidRenderResult,\r\n} from '../core/types'\r\nimport { sanitizeSvg } from './sanitize'\r\n\r\ninterface MermaidApi {\r\n initialize(config: Record<string, unknown>): void | Promise<void>\r\n render(id: string, source: string): Promise<{ svg: string }>\r\n}\r\n\r\nlet mermaidPromise: Promise<MermaidApi> | undefined\r\nlet initializedTheme: MarkdownTheme | null | undefined = null\r\nlet queue: Promise<unknown> = Promise.resolve()\r\nlet counter = 0\r\n\r\nfunction prefersDark(): boolean {\r\n return (\r\n typeof window !== 'undefined' &&\r\n typeof window.matchMedia === 'function' &&\r\n window.matchMedia('(prefers-color-scheme: dark)').matches\r\n )\r\n}\r\n\r\nfunction themeName(theme: MarkdownTheme | undefined): string {\r\n if (theme === 'dark' || (theme === 'auto' && prefersDark())) return 'dark'\r\n if (theme === 'custom') return 'neutral'\r\n return 'default'\r\n}\r\n\r\nasync function loadMermaid(): Promise<MermaidApi> {\r\n if (!mermaidPromise) {\r\n mermaidPromise = import('mermaid').then((module) => {\r\n const api = (module as { default?: MermaidApi }).default ?? module\r\n return api as MermaidApi\r\n })\r\n }\r\n return mermaidPromise\r\n}\r\n\r\nasync function initialize(api: MermaidApi, theme: MarkdownTheme | undefined): Promise<void> {\r\n if (initializedTheme !== null && initializedTheme === theme) return\r\n await api.initialize({\r\n startOnLoad: false,\r\n securityLevel: 'strict',\r\n htmlLabels: false,\r\n theme: themeName(theme),\r\n fontFamily: 'var(--vmd-font-sans)',\r\n })\r\n initializedTheme = theme\r\n}\r\n\r\nfunction missingMermaid(message: string): boolean {\r\n return /(cannot find module|failed to resolve module|failed to fetch dynamically imported module|err_module_not_found|not installed)/i.test(\r\n message,\r\n ) && /mermaid/i.test(message)\r\n}\r\n\r\n/** Report the actual failure, adding an install hint for a missing peer. */\r\nexport function classifyMermaidError(error: unknown): string {\r\n const message = error instanceof Error\r\n ? error.message\r\n : typeof error === 'string'\r\n ? error\r\n : 'Mermaid rendering failed.'\r\n if (missingMermaid(message)) {\r\n return 'Mermaid is not available. Install the optional `mermaid` peer dependency to render diagrams.'\r\n }\r\n return message\r\n}\r\n\r\n/** Create a unique DOM-safe identifier for one Mermaid render. */\r\nexport function createMermaidRenderId(): string {\r\n return `vmd-mermaid-${++counter}`\r\n}\r\n\r\n/**\r\n * Render one diagram through a single lazy Mermaid instance. Renders are\r\n * serialized so Mermaid's global state cannot interleave.\r\n */\r\nexport async function renderMermaid(\r\n source: string,\r\n options: MermaidRenderOptions = {},\r\n): Promise<MermaidRenderResult> {\r\n if (typeof window === 'undefined' || typeof DOMParser === 'undefined') {\r\n return { nodes: [], error: 'Mermaid requires a browser environment.' }\r\n }\r\n if (!source.trim()) {\r\n return { nodes: [], error: 'Mermaid source is empty.' }\r\n }\r\n\r\n const run = async (): Promise<MermaidRenderResult> => {\r\n try {\r\n const api = await loadMermaid()\r\n await initialize(api, options.theme)\r\n const id = options.id ?? createMermaidRenderId()\r\n const { svg } = await api.render(id, source)\r\n return { svg, nodes: sanitizeSvg(svg) }\r\n } catch (error) {\r\n return { nodes: [], error: classifyMermaidError(error) }\r\n }\r\n }\r\n\r\n const result = queue.then(run, run)\r\n queue = result.catch(() => undefined)\r\n return result\r\n}\r\n\r\nexport function resetMermaidRuntime(): void {\r\n mermaidPromise = undefined\r\n initializedTheme = null\r\n queue = Promise.resolve()\r\n counter = 0\r\n}\r\n\r\nexport default renderMermaid\r\n"],"mappings":"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"}
|