markstream-svelte 0.0.1-beta.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.
Files changed (233) hide show
  1. package/README.md +77 -0
  2. package/dist/components/AdmonitionNode.svelte +8 -0
  3. package/dist/components/AdmonitionNode.svelte.d.ts +23 -0
  4. package/dist/components/AdmonitionNode.svelte.d.ts.map +1 -0
  5. package/dist/components/BlockquoteNode.svelte +10 -0
  6. package/dist/components/BlockquoteNode.svelte.d.ts +24 -0
  7. package/dist/components/BlockquoteNode.svelte.d.ts.map +1 -0
  8. package/dist/components/CheckboxNode.svelte +5 -0
  9. package/dist/components/CheckboxNode.svelte.d.ts +22 -0
  10. package/dist/components/CheckboxNode.svelte.d.ts.map +1 -0
  11. package/dist/components/CodeBlockNode.svelte +944 -0
  12. package/dist/components/CodeBlockNode.svelte.d.ts +43 -0
  13. package/dist/components/CodeBlockNode.svelte.d.ts.map +1 -0
  14. package/dist/components/D2BlockNode.svelte +272 -0
  15. package/dist/components/D2BlockNode.svelte.d.ts +33 -0
  16. package/dist/components/D2BlockNode.svelte.d.ts.map +1 -0
  17. package/dist/components/DefinitionListNode.svelte +8 -0
  18. package/dist/components/DefinitionListNode.svelte.d.ts +23 -0
  19. package/dist/components/DefinitionListNode.svelte.d.ts.map +1 -0
  20. package/dist/components/EmojiNode.svelte +7 -0
  21. package/dist/components/EmojiNode.svelte.d.ts +22 -0
  22. package/dist/components/EmojiNode.svelte.d.ts.map +1 -0
  23. package/dist/components/EmphasisNode.svelte +8 -0
  24. package/dist/components/EmphasisNode.svelte.d.ts +24 -0
  25. package/dist/components/EmphasisNode.svelte.d.ts.map +1 -0
  26. package/dist/components/FallbackComponent.svelte +8 -0
  27. package/dist/components/FallbackComponent.svelte.d.ts +23 -0
  28. package/dist/components/FallbackComponent.svelte.d.ts.map +1 -0
  29. package/dist/components/FootnoteAnchorNode.svelte +21 -0
  30. package/dist/components/FootnoteAnchorNode.svelte.d.ts +22 -0
  31. package/dist/components/FootnoteAnchorNode.svelte.d.ts.map +1 -0
  32. package/dist/components/FootnoteNode.svelte +19 -0
  33. package/dist/components/FootnoteNode.svelte.d.ts +24 -0
  34. package/dist/components/FootnoteNode.svelte.d.ts.map +1 -0
  35. package/dist/components/FootnoteReferenceNode.svelte +26 -0
  36. package/dist/components/FootnoteReferenceNode.svelte.d.ts +22 -0
  37. package/dist/components/FootnoteReferenceNode.svelte.d.ts.map +1 -0
  38. package/dist/components/HardBreakNode.svelte +1 -0
  39. package/dist/components/HardBreakNode.svelte.d.ts +27 -0
  40. package/dist/components/HardBreakNode.svelte.d.ts.map +1 -0
  41. package/dist/components/HeadingNode.svelte +15 -0
  42. package/dist/components/HeadingNode.svelte.d.ts +24 -0
  43. package/dist/components/HeadingNode.svelte.d.ts.map +1 -0
  44. package/dist/components/HighlightNode.svelte +8 -0
  45. package/dist/components/HighlightNode.svelte.d.ts +24 -0
  46. package/dist/components/HighlightNode.svelte.d.ts.map +1 -0
  47. package/dist/components/HtmlBlockNode.svelte +8 -0
  48. package/dist/components/HtmlBlockNode.svelte.d.ts +23 -0
  49. package/dist/components/HtmlBlockNode.svelte.d.ts.map +1 -0
  50. package/dist/components/HtmlInlineNode.svelte +8 -0
  51. package/dist/components/HtmlInlineNode.svelte.d.ts +23 -0
  52. package/dist/components/HtmlInlineNode.svelte.d.ts.map +1 -0
  53. package/dist/components/HtmlPreviewFrame.svelte +13 -0
  54. package/dist/components/HtmlPreviewFrame.svelte.d.ts +26 -0
  55. package/dist/components/HtmlPreviewFrame.svelte.d.ts.map +1 -0
  56. package/dist/components/ImageNode.svelte +86 -0
  57. package/dist/components/ImageNode.svelte.d.ts +25 -0
  58. package/dist/components/ImageNode.svelte.d.ts.map +1 -0
  59. package/dist/components/InfographicBlockNode.svelte +429 -0
  60. package/dist/components/InfographicBlockNode.svelte.d.ts +34 -0
  61. package/dist/components/InfographicBlockNode.svelte.d.ts.map +1 -0
  62. package/dist/components/InlineCodeNode.svelte +7 -0
  63. package/dist/components/InlineCodeNode.svelte.d.ts +22 -0
  64. package/dist/components/InlineCodeNode.svelte.d.ts.map +1 -0
  65. package/dist/components/InlineWrapNode.svelte +10 -0
  66. package/dist/components/InlineWrapNode.svelte.d.ts +25 -0
  67. package/dist/components/InlineWrapNode.svelte.d.ts.map +1 -0
  68. package/dist/components/InsertNode.svelte +8 -0
  69. package/dist/components/InsertNode.svelte.d.ts +24 -0
  70. package/dist/components/InsertNode.svelte.d.ts.map +1 -0
  71. package/dist/components/LinkNode.svelte +41 -0
  72. package/dist/components/LinkNode.svelte.d.ts +25 -0
  73. package/dist/components/LinkNode.svelte.d.ts.map +1 -0
  74. package/dist/components/ListItemNode.svelte +9 -0
  75. package/dist/components/ListItemNode.svelte.d.ts +24 -0
  76. package/dist/components/ListItemNode.svelte.d.ts.map +1 -0
  77. package/dist/components/ListNode.svelte +16 -0
  78. package/dist/components/ListNode.svelte.d.ts +24 -0
  79. package/dist/components/ListNode.svelte.d.ts.map +1 -0
  80. package/dist/components/MarkdownCodeBlockNode.svelte +7 -0
  81. package/dist/components/MarkdownCodeBlockNode.svelte.d.ts +23 -0
  82. package/dist/components/MarkdownCodeBlockNode.svelte.d.ts.map +1 -0
  83. package/dist/components/MathBlockNode.svelte +96 -0
  84. package/dist/components/MathBlockNode.svelte.d.ts +22 -0
  85. package/dist/components/MathBlockNode.svelte.d.ts.map +1 -0
  86. package/dist/components/MathInlineNode.svelte +103 -0
  87. package/dist/components/MathInlineNode.svelte.d.ts +22 -0
  88. package/dist/components/MathInlineNode.svelte.d.ts.map +1 -0
  89. package/dist/components/MermaidBlockNode.svelte +557 -0
  90. package/dist/components/MermaidBlockNode.svelte.d.ts +40 -0
  91. package/dist/components/MermaidBlockNode.svelte.d.ts.map +1 -0
  92. package/dist/components/NodeOutlet.svelte +192 -0
  93. package/dist/components/NodeOutlet.svelte.d.ts +24 -0
  94. package/dist/components/NodeOutlet.svelte.d.ts.map +1 -0
  95. package/dist/components/NodeRenderer.svelte +349 -0
  96. package/dist/components/NodeRenderer.svelte.d.ts +64 -0
  97. package/dist/components/NodeRenderer.svelte.d.ts.map +1 -0
  98. package/dist/components/ParagraphNode.svelte +21 -0
  99. package/dist/components/ParagraphNode.svelte.d.ts +24 -0
  100. package/dist/components/ParagraphNode.svelte.d.ts.map +1 -0
  101. package/dist/components/PreCodeNode.svelte +13 -0
  102. package/dist/components/PreCodeNode.svelte.d.ts +22 -0
  103. package/dist/components/PreCodeNode.svelte.d.ts.map +1 -0
  104. package/dist/components/ReferenceNode.svelte +8 -0
  105. package/dist/components/ReferenceNode.svelte.d.ts +23 -0
  106. package/dist/components/ReferenceNode.svelte.d.ts.map +1 -0
  107. package/dist/components/RenderChildren.svelte +12 -0
  108. package/dist/components/RenderChildren.svelte.d.ts +24 -0
  109. package/dist/components/RenderChildren.svelte.d.ts.map +1 -0
  110. package/dist/components/StrikethroughNode.svelte +8 -0
  111. package/dist/components/StrikethroughNode.svelte.d.ts +24 -0
  112. package/dist/components/StrikethroughNode.svelte.d.ts.map +1 -0
  113. package/dist/components/StrongNode.svelte +8 -0
  114. package/dist/components/StrongNode.svelte.d.ts +24 -0
  115. package/dist/components/StrongNode.svelte.d.ts.map +1 -0
  116. package/dist/components/SubscriptNode.svelte +8 -0
  117. package/dist/components/SubscriptNode.svelte.d.ts +24 -0
  118. package/dist/components/SubscriptNode.svelte.d.ts.map +1 -0
  119. package/dist/components/SuperscriptNode.svelte +8 -0
  120. package/dist/components/SuperscriptNode.svelte.d.ts +24 -0
  121. package/dist/components/SuperscriptNode.svelte.d.ts.map +1 -0
  122. package/dist/components/TableNode.svelte +8 -0
  123. package/dist/components/TableNode.svelte.d.ts +23 -0
  124. package/dist/components/TableNode.svelte.d.ts.map +1 -0
  125. package/dist/components/TextNode.svelte +37 -0
  126. package/dist/components/TextNode.svelte.d.ts +25 -0
  127. package/dist/components/TextNode.svelte.d.ts.map +1 -0
  128. package/dist/components/ThematicBreakNode.svelte +1 -0
  129. package/dist/components/ThematicBreakNode.svelte.d.ts +27 -0
  130. package/dist/components/ThematicBreakNode.svelte.d.ts.map +1 -0
  131. package/dist/components/Tooltip.svelte +4 -0
  132. package/dist/components/Tooltip.svelte.d.ts +21 -0
  133. package/dist/components/Tooltip.svelte.d.ts.map +1 -0
  134. package/dist/components/VmrContainerNode.svelte +8 -0
  135. package/dist/components/VmrContainerNode.svelte.d.ts +23 -0
  136. package/dist/components/VmrContainerNode.svelte.d.ts.map +1 -0
  137. package/dist/components/shared/diagram-height.d.ts +10 -0
  138. package/dist/components/shared/diagram-height.d.ts.map +1 -0
  139. package/dist/components/shared/diagram-height.js +52 -0
  140. package/dist/components/shared/node-helpers.d.ts +108 -0
  141. package/dist/components/shared/node-helpers.d.ts.map +1 -0
  142. package/dist/components/shared/node-helpers.js +220 -0
  143. package/dist/components/shared/node-outlet-helpers.d.ts +9 -0
  144. package/dist/components/shared/node-outlet-helpers.d.ts.map +1 -0
  145. package/dist/components/shared/node-outlet-helpers.js +92 -0
  146. package/dist/components/shared/render-window.d.ts +19 -0
  147. package/dist/components/shared/render-window.d.ts.map +1 -0
  148. package/dist/components/shared/render-window.js +63 -0
  149. package/dist/components/shared/renderNodeHtml.d.ts +4 -0
  150. package/dist/components/shared/renderNodeHtml.d.ts.map +1 -0
  151. package/dist/components/shared/renderNodeHtml.js +19 -0
  152. package/dist/components/shared/rich-block-helpers.d.ts +7 -0
  153. package/dist/components/shared/rich-block-helpers.d.ts.map +1 -0
  154. package/dist/components/shared/rich-block-helpers.js +76 -0
  155. package/dist/customComponents.d.ts +10 -0
  156. package/dist/customComponents.d.ts.map +1 -0
  157. package/dist/customComponents.js +66 -0
  158. package/dist/enhanceRenderedHtml.d.ts +21 -0
  159. package/dist/enhanceRenderedHtml.d.ts.map +1 -0
  160. package/dist/enhanceRenderedHtml.js +768 -0
  161. package/dist/hydrateCustomTagContent.d.ts +3 -0
  162. package/dist/hydrateCustomTagContent.d.ts.map +1 -0
  163. package/dist/hydrateCustomTagContent.js +130 -0
  164. package/dist/i18n/useSafeI18n.d.ts +5 -0
  165. package/dist/i18n/useSafeI18n.d.ts.map +1 -0
  166. package/dist/i18n/useSafeI18n.js +42 -0
  167. package/dist/index.css +2009 -0
  168. package/dist/index.d.ts +78 -0
  169. package/dist/index.d.ts.map +1 -0
  170. package/dist/index.js +66 -0
  171. package/dist/index.px.css +2009 -0
  172. package/dist/index.tailwind.css +2009 -0
  173. package/dist/optional/d2.d.ts +7 -0
  174. package/dist/optional/d2.d.ts.map +1 -0
  175. package/dist/optional/d2.js +67 -0
  176. package/dist/optional/infographic.d.ts +2 -0
  177. package/dist/optional/infographic.d.ts.map +1 -0
  178. package/dist/optional/infographic.js +29 -0
  179. package/dist/optional/katex.d.ts +7 -0
  180. package/dist/optional/katex.d.ts.map +1 -0
  181. package/dist/optional/katex.js +93 -0
  182. package/dist/optional/mermaid.d.ts +7 -0
  183. package/dist/optional/mermaid.d.ts.map +1 -0
  184. package/dist/optional/mermaid.js +171 -0
  185. package/dist/optional/monaco.d.ts +5 -0
  186. package/dist/optional/monaco.d.ts.map +1 -0
  187. package/dist/optional/monaco.js +70 -0
  188. package/dist/parseNestedMarkdownToNodes.d.ts +15 -0
  189. package/dist/parseNestedMarkdownToNodes.d.ts.map +1 -0
  190. package/dist/parseNestedMarkdownToNodes.js +66 -0
  191. package/dist/renderMarkdownHtml.d.ts +31 -0
  192. package/dist/renderMarkdownHtml.d.ts.map +1 -0
  193. package/dist/renderMarkdownHtml.js +465 -0
  194. package/dist/sanitizeHtmlContent.d.ts +3 -0
  195. package/dist/sanitizeHtmlContent.d.ts.map +1 -0
  196. package/dist/sanitizeHtmlContent.js +175 -0
  197. package/dist/sanitizeSvg.d.ts +3 -0
  198. package/dist/sanitizeSvg.d.ts.map +1 -0
  199. package/dist/sanitizeSvg.js +76 -0
  200. package/dist/tailwind-entry.d.ts +2 -0
  201. package/dist/tailwind-entry.d.ts.map +1 -0
  202. package/dist/tailwind-entry.js +1 -0
  203. package/dist/tooltip/singletonTooltip.d.ts +8 -0
  204. package/dist/tooltip/singletonTooltip.d.ts.map +1 -0
  205. package/dist/tooltip/singletonTooltip.js +124 -0
  206. package/dist/types/monaco.d.ts +66 -0
  207. package/dist/types/monaco.d.ts.map +1 -0
  208. package/dist/types/monaco.js +1 -0
  209. package/dist/utils/languageIcon.d.ts +8 -0
  210. package/dist/utils/languageIcon.d.ts.map +1 -0
  211. package/dist/utils/languageIcon.js +182 -0
  212. package/dist/utils/normalizeKaTeXRenderInput.d.ts +2 -0
  213. package/dist/utils/normalizeKaTeXRenderInput.d.ts.map +1 -0
  214. package/dist/utils/normalizeKaTeXRenderInput.js +7 -0
  215. package/dist/workers/katexCdnWorker.d.ts +21 -0
  216. package/dist/workers/katexCdnWorker.d.ts.map +1 -0
  217. package/dist/workers/katexCdnWorker.js +193 -0
  218. package/dist/workers/katexRenderer.worker.d.ts +2 -0
  219. package/dist/workers/katexRenderer.worker.d.ts.map +1 -0
  220. package/dist/workers/katexRenderer.worker.js +55 -0
  221. package/dist/workers/katexWorkerClient.d.ts +36 -0
  222. package/dist/workers/katexWorkerClient.d.ts.map +1 -0
  223. package/dist/workers/katexWorkerClient.js +270 -0
  224. package/dist/workers/mermaidCdnWorker.d.ts +16 -0
  225. package/dist/workers/mermaidCdnWorker.d.ts.map +1 -0
  226. package/dist/workers/mermaidCdnWorker.js +235 -0
  227. package/dist/workers/mermaidParser.worker.d.ts +2 -0
  228. package/dist/workers/mermaidParser.worker.d.ts.map +1 -0
  229. package/dist/workers/mermaidParser.worker.js +85 -0
  230. package/dist/workers/mermaidWorkerClient.d.ts +16 -0
  231. package/dist/workers/mermaidWorkerClient.d.ts.map +1 -0
  232. package/dist/workers/mermaidWorkerClient.js +170 -0
  233. package/package.json +95 -0
@@ -0,0 +1,768 @@
1
+ import { getD2 } from './optional/d2';
2
+ import { getInfographic } from './optional/infographic';
3
+ import { getKatex } from './optional/katex';
4
+ import { getMermaid } from './optional/mermaid';
5
+ import { getUseMonaco } from './optional/monaco';
6
+ import { extractRenderedSvg, toSafeSvgMarkup } from './sanitizeSvg';
7
+ import { hideTooltip, showTooltipForAnchor } from './tooltip/singletonTooltip';
8
+ import { normalizeKaTeXRenderInput } from './utils/normalizeKaTeXRenderInput';
9
+ import { renderKaTeXWithBackpressure, setKaTeXCache, WORKER_BUSY_CODE } from './workers/katexWorkerClient';
10
+ import { canParseOffthread, findPrefixOffthread } from './workers/mermaidWorkerClient';
11
+ let mermaidRenderId = 0;
12
+ const rootHandles = new WeakMap();
13
+ const DARK_THEME_OVERRIDES = {
14
+ N1: '#E5E7EB',
15
+ N2: '#CBD5E1',
16
+ N3: '#94A3B8',
17
+ N4: '#64748B',
18
+ N5: '#475569',
19
+ N6: '#334155',
20
+ N7: '#0B1220',
21
+ B1: '#60A5FA',
22
+ B2: '#3B82F6',
23
+ B3: '#2563EB',
24
+ B4: '#1D4ED8',
25
+ B5: '#1E40AF',
26
+ B6: '#111827',
27
+ AA2: '#22D3EE',
28
+ AA4: '#0EA5E9',
29
+ AA5: '#0284C7',
30
+ AB4: '#FBBF24',
31
+ AB5: '#F59E0B',
32
+ };
33
+ const MONACO_LANGUAGE_ALIASES = {
34
+ cjs: 'javascript',
35
+ cts: 'typescript',
36
+ d2lang: 'plaintext',
37
+ js: 'javascript',
38
+ jsonc: 'json',
39
+ jsx: 'javascript',
40
+ md: 'markdown',
41
+ mjs: 'javascript',
42
+ sh: 'shell',
43
+ text: 'plaintext',
44
+ ts: 'typescript',
45
+ tsx: 'typescript',
46
+ txt: 'plaintext',
47
+ vue: 'html',
48
+ yml: 'yaml',
49
+ };
50
+ export async function enhanceRenderedHtml(root, options = {}) {
51
+ disposeRenderedHtmlEnhancements(root);
52
+ const cleanupFns = [];
53
+ let disposed = false;
54
+ const isActive = () => { var _a; return !disposed && ((_a = options.isCancelled) === null || _a === void 0 ? void 0 : _a.call(options)) !== true; };
55
+ const handle = {
56
+ dispose: () => {
57
+ var _a;
58
+ if (disposed)
59
+ return;
60
+ disposed = true;
61
+ for (let index = cleanupFns.length - 1; index >= 0; index -= 1) {
62
+ try {
63
+ (_a = cleanupFns[index]) === null || _a === void 0 ? void 0 : _a.call(cleanupFns);
64
+ }
65
+ catch {
66
+ // Best-effort cleanup only.
67
+ }
68
+ }
69
+ if (rootHandles.get(root) === handle)
70
+ rootHandles.delete(root);
71
+ },
72
+ };
73
+ rootHandles.set(root, handle);
74
+ if (!isActive())
75
+ return handle;
76
+ await renderKatex(root, isActive);
77
+ if (!isActive())
78
+ return handle;
79
+ await renderMermaid(root, cleanupFns, options, isActive);
80
+ if (!isActive())
81
+ return handle;
82
+ if (options.final !== false) {
83
+ await renderInfographic(root, cleanupFns, options, isActive);
84
+ if (!isActive())
85
+ return handle;
86
+ await renderD2(root, cleanupFns, options, isActive);
87
+ if (!isActive())
88
+ return handle;
89
+ if (!options.renderCodeBlocksAsPre)
90
+ await renderMonaco(root, cleanupFns, options, isActive);
91
+ }
92
+ enhanceFootnotes(root, cleanupFns);
93
+ enhanceTooltips(root, cleanupFns, options);
94
+ return handle;
95
+ }
96
+ export function disposeRenderedHtmlEnhancements(root) {
97
+ if (!root)
98
+ return;
99
+ const existing = rootHandles.get(root);
100
+ existing === null || existing === void 0 ? void 0 : existing.dispose();
101
+ }
102
+ function readKatexSource(node, selector) {
103
+ const sourceElement = node.querySelector(selector);
104
+ return {
105
+ sourceElement,
106
+ source: ((sourceElement === null || sourceElement === void 0 ? void 0 : sourceElement.textContent) || (!sourceElement ? node.textContent : '') || '').trim(),
107
+ };
108
+ }
109
+ function resolveKatexRenderTarget(node, selector) {
110
+ return node.querySelector(selector);
111
+ }
112
+ function hasRenderedKatex(node, selector) {
113
+ const renderTarget = resolveKatexRenderTarget(node, selector);
114
+ const scope = renderTarget || node;
115
+ return !!scope.querySelector('.katex, .katex-display');
116
+ }
117
+ function writeKatexMarkup(node, renderTarget, markup, options = {}) {
118
+ if (renderTarget)
119
+ renderTarget.innerHTML = markup;
120
+ else
121
+ node.innerHTML = markup;
122
+ node.dataset.markstreamKatex = '1';
123
+ if (options.renderedClass)
124
+ node.classList.add(options.renderedClass);
125
+ }
126
+ function clearKatexMarkup(node, renderTarget, options = {}) {
127
+ if (renderTarget)
128
+ renderTarget.innerHTML = '';
129
+ delete node.dataset.markstreamKatex;
130
+ delete node.dataset.markstreamKatexSource;
131
+ if (options.renderedClass)
132
+ node.classList.remove(options.renderedClass);
133
+ }
134
+ async function renderKatex(root, isActive) {
135
+ const inlineNodes = Array.from(root.querySelectorAll('.markstream-nested-math'));
136
+ for (const node of inlineNodes) {
137
+ if (!isActive())
138
+ return;
139
+ if (node.dataset.markstreamKatexManaged === '1')
140
+ continue;
141
+ const { source } = readKatexSource(node, '.markstream-nested-math__source');
142
+ const renderTarget = resolveKatexRenderTarget(node, '.markstream-nested-math__render');
143
+ if (!source) {
144
+ clearKatexMarkup(node, renderTarget);
145
+ continue;
146
+ }
147
+ if (node.dataset.markstreamKatex === '1'
148
+ && node.dataset.markstreamKatexSource === source
149
+ && hasRenderedKatex(node, '.markstream-nested-math__render')) {
150
+ continue;
151
+ }
152
+ try {
153
+ writeKatexMarkup(node, renderTarget, await renderKatexMarkup(source, node.dataset.display === 'block'));
154
+ node.dataset.markstreamKatexSource = source;
155
+ }
156
+ catch {
157
+ clearKatexMarkup(node, renderTarget);
158
+ }
159
+ }
160
+ const blockNodes = Array.from(root.querySelectorAll('.markstream-nested-math-block'));
161
+ for (const node of blockNodes) {
162
+ if (!isActive())
163
+ return;
164
+ if (node.dataset.markstreamKatexManaged === '1')
165
+ continue;
166
+ const { source } = readKatexSource(node, '.markstream-nested-math-block__source');
167
+ const renderTarget = resolveKatexRenderTarget(node, '.markstream-nested-math-block__render');
168
+ if (!source) {
169
+ clearKatexMarkup(node, renderTarget, { renderedClass: 'markstream-nested-math-block--rendered' });
170
+ continue;
171
+ }
172
+ if (node.dataset.markstreamKatex === '1'
173
+ && node.dataset.markstreamKatexSource === source
174
+ && hasRenderedKatex(node, '.markstream-nested-math-block__render')) {
175
+ continue;
176
+ }
177
+ try {
178
+ writeKatexMarkup(node, renderTarget, await renderKatexMarkup(source, true), {
179
+ renderedClass: 'markstream-nested-math-block--rendered',
180
+ });
181
+ node.dataset.markstreamKatexSource = source;
182
+ }
183
+ catch {
184
+ clearKatexMarkup(node, renderTarget, { renderedClass: 'markstream-nested-math-block--rendered' });
185
+ }
186
+ }
187
+ }
188
+ async function renderKatexMarkup(source, displayMode) {
189
+ const normalizedSource = normalizeKaTeXRenderInput(source);
190
+ try {
191
+ return await renderKaTeXWithBackpressure(normalizedSource, displayMode, {
192
+ timeout: 1500,
193
+ waitTimeout: 0,
194
+ maxRetries: 0,
195
+ });
196
+ }
197
+ catch (error) {
198
+ const code = (error === null || error === void 0 ? void 0 : error.code) || (error === null || error === void 0 ? void 0 : error.name);
199
+ const isWorkerInitFailure = code === 'WORKER_INIT_ERROR' || (error === null || error === void 0 ? void 0 : error.fallbackToRenderer);
200
+ const isBusyOrTimeout = code === WORKER_BUSY_CODE || code === 'WORKER_TIMEOUT';
201
+ if (!isWorkerInitFailure && !isBusyOrTimeout)
202
+ throw error;
203
+ }
204
+ const katex = await getKatex();
205
+ if (!katex)
206
+ throw new Error('KaTeX renderer is not available.');
207
+ const html = katex.renderToString(normalizedSource, {
208
+ displayMode,
209
+ throwOnError: false,
210
+ });
211
+ setKaTeXCache(normalizedSource, displayMode, html);
212
+ return html;
213
+ }
214
+ async function renderMermaid(root, cleanupFns, options, isActive) {
215
+ var _a, _b, _c, _d, _e, _f, _g;
216
+ const strictMode = ((_a = options.mermaidProps) === null || _a === void 0 ? void 0 : _a.isStrict) !== false;
217
+ const mermaid = await getMermaid({
218
+ startOnLoad: false,
219
+ securityLevel: strictMode ? 'strict' : 'loose',
220
+ suppressErrorRendering: true,
221
+ ...(strictMode ? { flowchart: { htmlLabels: false } } : {}),
222
+ });
223
+ if (!mermaid || !isActive())
224
+ return;
225
+ const codeNodes = Array.from(root.querySelectorAll('pre > code.language-mermaid'));
226
+ for (const codeNode of codeNodes) {
227
+ if (!isActive())
228
+ return;
229
+ const pre = codeNode.parentElement;
230
+ const source = (codeNode.textContent || '').trim();
231
+ if (!pre || !source)
232
+ continue;
233
+ const originalPre = pre.cloneNode(true);
234
+ const shell = createEnhancedBlockShell('mermaid', 'Mermaid', source, true, options, {
235
+ showHeader: ((_b = options.mermaidProps) === null || _b === void 0 ? void 0 : _b.showHeader) !== false,
236
+ });
237
+ pre.replaceWith(shell.wrapper);
238
+ try {
239
+ const theme = options.isDark ? 'dark' : 'light';
240
+ let sourceToRender = source;
241
+ if (options.final === false) {
242
+ try {
243
+ await canParseMermaidWithFallback(source, theme, mermaid, options);
244
+ }
245
+ catch (error) {
246
+ if ((error === null || error === void 0 ? void 0 : error.name) === 'AbortError')
247
+ return;
248
+ const prefix = await findMermaidPrefixCandidate(source, theme, options);
249
+ if (!isActive())
250
+ return;
251
+ if (!prefix) {
252
+ shell.wrapper.replaceWith(originalPre);
253
+ continue;
254
+ }
255
+ sourceToRender = prefix;
256
+ }
257
+ }
258
+ const renderId = `markstream-svelte-mermaid-${++mermaidRenderId}`;
259
+ const rendered = await withTimeout(() => Promise.resolve(mermaid.render(renderId, applyMermaidThemeTo(sourceToRender, theme))), options.final === false
260
+ ? Number((_d = (_c = options.mermaidProps) === null || _c === void 0 ? void 0 : _c.renderTimeoutMs) !== null && _d !== void 0 ? _d : 2500)
261
+ : Number((_f = (_e = options.mermaidProps) === null || _e === void 0 ? void 0 : _e.fullRenderTimeoutMs) !== null && _f !== void 0 ? _f : 4000));
262
+ if (!isActive())
263
+ return;
264
+ const svg = typeof rendered === 'string' ? rendered : rendered === null || rendered === void 0 ? void 0 : rendered.svg;
265
+ if (!svg)
266
+ continue;
267
+ const safeSvg = strictMode ? toSafeSvgMarkup(svg) : svg;
268
+ if (!safeSvg)
269
+ continue;
270
+ shell.body.innerHTML = safeSvg;
271
+ shell.body.classList.add('markstream-svelte-mermaid');
272
+ shell.wrapper.dataset.markstreamMermaid = '1';
273
+ (_g = rendered === null || rendered === void 0 ? void 0 : rendered.bindFunctions) === null || _g === void 0 ? void 0 : _g.call(rendered, shell.body);
274
+ cleanupFns.push(() => {
275
+ if (shell.wrapper.isConnected)
276
+ shell.wrapper.replaceWith(originalPre.cloneNode(true));
277
+ });
278
+ }
279
+ catch {
280
+ shell.wrapper.replaceWith(originalPre);
281
+ }
282
+ }
283
+ }
284
+ function applyMermaidThemeTo(source, theme) {
285
+ const trimmed = source.trimStart();
286
+ if (trimmed.startsWith('%%{'))
287
+ return source;
288
+ const themeValue = theme === 'dark' ? 'dark' : 'default';
289
+ return `%%{init: {"theme": "${themeValue}"}}%%\n${source}`;
290
+ }
291
+ async function canParseMermaidWithFallback(source, theme, mermaid, options) {
292
+ var _a, _b, _c, _d;
293
+ const workerTimeout = Number((_b = (_a = options.mermaidProps) === null || _a === void 0 ? void 0 : _a.workerTimeoutMs) !== null && _b !== void 0 ? _b : 1400);
294
+ const parseTimeout = Number((_d = (_c = options.mermaidProps) === null || _c === void 0 ? void 0 : _c.parseTimeoutMs) !== null && _d !== void 0 ? _d : 1800);
295
+ try {
296
+ const ok = await canParseOffthread(source, theme, workerTimeout);
297
+ if (ok)
298
+ return true;
299
+ }
300
+ catch (error) {
301
+ if ((error === null || error === void 0 ? void 0 : error.name) === 'AbortError')
302
+ throw error;
303
+ }
304
+ const themedSource = applyMermaidThemeTo(source, theme);
305
+ if (typeof (mermaid === null || mermaid === void 0 ? void 0 : mermaid.parse) === 'function') {
306
+ await withTimeout(() => Promise.resolve(mermaid.parse(themedSource)), parseTimeout);
307
+ return true;
308
+ }
309
+ const renderId = `markstream-svelte-mermaid-parse-${++mermaidRenderId}`;
310
+ await withTimeout(() => Promise.resolve(mermaid.render(renderId, themedSource)), parseTimeout);
311
+ return true;
312
+ }
313
+ async function findMermaidPrefixCandidate(source, theme, options) {
314
+ var _a, _b;
315
+ const workerTimeout = Number((_b = (_a = options.mermaidProps) === null || _a === void 0 ? void 0 : _a.workerTimeoutMs) !== null && _b !== void 0 ? _b : 1400);
316
+ try {
317
+ const prefix = await findPrefixOffthread(source, theme, workerTimeout);
318
+ if (prefix)
319
+ return prefix;
320
+ }
321
+ catch (error) {
322
+ if ((error === null || error === void 0 ? void 0 : error.name) === 'AbortError')
323
+ throw error;
324
+ }
325
+ return getSafeMermaidPrefixCandidate(source);
326
+ }
327
+ function getSafeMermaidPrefixCandidate(source) {
328
+ const lines = source.split('\n');
329
+ while (lines.length > 0) {
330
+ const lastRaw = lines[lines.length - 1];
331
+ const last = lastRaw.trimEnd();
332
+ if (!last) {
333
+ lines.pop();
334
+ continue;
335
+ }
336
+ const looksDangling = /^[-=~>|<\s]+$/.test(last.trim())
337
+ || /(?:--|==|~~|->|<-|-\||-\)|-x|o-|\|-|\.-)\s*$/.test(last)
338
+ || /[-|><]$/.test(last)
339
+ || /(?:graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt)\s*$/i.test(last);
340
+ if (!looksDangling)
341
+ break;
342
+ lines.pop();
343
+ }
344
+ return lines.join('\n');
345
+ }
346
+ function withTimeout(run, timeoutMs) {
347
+ if (!timeoutMs || timeoutMs <= 0)
348
+ return run();
349
+ return new Promise((resolve, reject) => {
350
+ let settled = false;
351
+ const timer = globalThis.setTimeout(() => {
352
+ if (settled)
353
+ return;
354
+ settled = true;
355
+ reject(new Error('Operation timed out'));
356
+ }, timeoutMs);
357
+ run()
358
+ .then((value) => {
359
+ if (settled)
360
+ return;
361
+ settled = true;
362
+ clearTimeout(timer);
363
+ resolve(value);
364
+ })
365
+ .catch((error) => {
366
+ if (settled)
367
+ return;
368
+ settled = true;
369
+ clearTimeout(timer);
370
+ reject(error);
371
+ });
372
+ });
373
+ }
374
+ async function renderInfographic(root, cleanupFns, options, isActive) {
375
+ var _a;
376
+ const codeNodes = Array.from(root.querySelectorAll('pre[data-markstream-code-block="1"] > code.language-infographic'));
377
+ if (!codeNodes.length)
378
+ return;
379
+ const InfographicClass = await getInfographic();
380
+ if (!InfographicClass || !isActive())
381
+ return;
382
+ for (const codeNode of codeNodes) {
383
+ if (!isActive())
384
+ return;
385
+ const pre = codeNode.parentElement;
386
+ const source = codeNode.textContent || '';
387
+ if (!pre || !source.trim())
388
+ continue;
389
+ const originalPre = pre.cloneNode(true);
390
+ const shell = createEnhancedBlockShell('infographic', 'Infographic', source, true, options, {
391
+ showHeader: ((_a = options.infographicProps) === null || _a === void 0 ? void 0 : _a.showHeader) !== false,
392
+ });
393
+ shell.body.style.minHeight = '320px';
394
+ shell.body.style.height = '360px';
395
+ pre.replaceWith(shell.wrapper);
396
+ try {
397
+ const instance = new InfographicClass({
398
+ container: shell.body,
399
+ width: '100%',
400
+ height: '100%',
401
+ });
402
+ instance.render(source);
403
+ let frameId = null;
404
+ if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
405
+ frameId = window.requestAnimationFrame(() => {
406
+ const actualHeight = shell.body.scrollHeight;
407
+ if (actualHeight > 0)
408
+ shell.body.style.height = `${Math.min(Math.max(actualHeight, 260), 720)}px`;
409
+ });
410
+ }
411
+ cleanupFns.push(() => {
412
+ var _a;
413
+ if (frameId != null && typeof window !== 'undefined')
414
+ window.cancelAnimationFrame(frameId);
415
+ (_a = instance.destroy) === null || _a === void 0 ? void 0 : _a.call(instance);
416
+ if (shell.wrapper.isConnected)
417
+ shell.wrapper.replaceWith(originalPre.cloneNode(true));
418
+ });
419
+ shell.wrapper.dataset.markstreamInfographic = '1';
420
+ }
421
+ catch {
422
+ shell.wrapper.replaceWith(originalPre);
423
+ }
424
+ }
425
+ }
426
+ async function renderD2(root, cleanupFns, options, isActive) {
427
+ var _a, _b, _c, _d, _e, _f;
428
+ const D2Ctor = await getD2();
429
+ if (!D2Ctor || !isActive())
430
+ return;
431
+ const codeNodes = Array.from(root.querySelectorAll('pre[data-markstream-code-block="1"] > code.language-d2, pre[data-markstream-code-block="1"] > code.language-d2lang'));
432
+ for (const codeNode of codeNodes) {
433
+ if (!isActive())
434
+ return;
435
+ const pre = codeNode.parentElement;
436
+ const source = codeNode.textContent || '';
437
+ if (!pre || !source.trim())
438
+ continue;
439
+ const originalPre = pre.cloneNode(true);
440
+ const shell = createEnhancedBlockShell('d2', 'D2', source, true, options, {
441
+ showHeader: ((_a = options.d2Props) === null || _a === void 0 ? void 0 : _a.showHeader) !== false,
442
+ });
443
+ pre.replaceWith(shell.wrapper);
444
+ try {
445
+ const instance = createD2Instance(D2Ctor);
446
+ if (!instance || typeof instance.compile !== 'function' || typeof instance.render !== 'function')
447
+ throw new TypeError('D2 instance is missing compile/render methods.');
448
+ const compileResult = await instance.compile(source);
449
+ const diagram = (_b = compileResult === null || compileResult === void 0 ? void 0 : compileResult.diagram) !== null && _b !== void 0 ? _b : compileResult;
450
+ const baseRenderOptions = (_d = (_c = compileResult === null || compileResult === void 0 ? void 0 : compileResult.renderOptions) !== null && _c !== void 0 ? _c : compileResult === null || compileResult === void 0 ? void 0 : compileResult.options) !== null && _d !== void 0 ? _d : {};
451
+ const resolvedThemeId = (_e = options.d2ThemeId) !== null && _e !== void 0 ? _e : baseRenderOptions.themeID;
452
+ const resolvedDarkThemeId = (_f = options.d2DarkThemeId) !== null && _f !== void 0 ? _f : baseRenderOptions.darkThemeID;
453
+ const renderOptions = { ...baseRenderOptions };
454
+ renderOptions.themeID = options.isDark && resolvedDarkThemeId != null
455
+ ? resolvedDarkThemeId
456
+ : resolvedThemeId;
457
+ renderOptions.darkThemeID = null;
458
+ renderOptions.darkThemeOverrides = null;
459
+ if (options.isDark) {
460
+ const baseOverrides = baseRenderOptions.themeOverrides && typeof baseRenderOptions.themeOverrides === 'object'
461
+ ? baseRenderOptions.themeOverrides
462
+ : null;
463
+ renderOptions.themeOverrides = {
464
+ ...DARK_THEME_OVERRIDES,
465
+ ...(baseOverrides || {}),
466
+ };
467
+ }
468
+ const renderResult = await instance.render(diagram, renderOptions);
469
+ if (!isActive())
470
+ return;
471
+ const safeSvg = toSafeSvgMarkup(extractRenderedSvg(renderResult));
472
+ if (!safeSvg)
473
+ throw new Error('D2 render returned empty output.');
474
+ shell.body.innerHTML = safeSvg;
475
+ shell.wrapper.dataset.markstreamD2 = '1';
476
+ cleanupFns.push(() => {
477
+ if (shell.wrapper.isConnected)
478
+ shell.wrapper.replaceWith(originalPre.cloneNode(true));
479
+ });
480
+ }
481
+ catch {
482
+ shell.wrapper.replaceWith(originalPre);
483
+ }
484
+ }
485
+ }
486
+ async function renderMonaco(root, cleanupFns, options, isActive) {
487
+ var _a, _b;
488
+ const monacoModule = await getUseMonaco();
489
+ if (!monacoModule || typeof monacoModule.useMonaco !== 'function' || !isActive())
490
+ return;
491
+ const preNodes = Array.from(root.querySelectorAll('pre[data-markstream-code-block="1"]'));
492
+ for (const pre of preNodes) {
493
+ if (!isActive())
494
+ return;
495
+ const codeNode = pre.querySelector('code');
496
+ if (!codeNode)
497
+ continue;
498
+ const rawLanguage = resolveCodeLanguage(pre, codeNode);
499
+ const normalizedLanguage = rawLanguage.trim().toLowerCase();
500
+ if (normalizedLanguage === 'mermaid' || normalizedLanguage === 'infographic' || normalizedLanguage === 'd2' || normalizedLanguage === 'd2lang')
501
+ continue;
502
+ const source = codeNode.textContent || '';
503
+ const diff = pre.dataset.markstreamDiff === '1';
504
+ const updatedCode = decodeDataPayload(pre.dataset.markstreamUpdated);
505
+ const monacoLanguage = resolveMonacoLanguage(rawLanguage);
506
+ const renderLanguage = diff ? 'plaintext' : monacoLanguage;
507
+ const shell = createEnhancedBlockShell('code', diff ? `Diff / ${monacoLanguage}` : `Code / ${monacoLanguage}`, source, false, options, {
508
+ showHeader: ((_a = options.codeBlockProps) === null || _a === void 0 ? void 0 : _a.showHeader) !== false,
509
+ });
510
+ shell.body.classList.add('markstream-svelte-enhanced-block__body--code');
511
+ shell.body.style.minHeight = `${estimateCodeBlockHeight(diff ? updatedCode || source : source, diff)}px`;
512
+ const originalPre = pre.cloneNode(true);
513
+ let helpers = null;
514
+ let restored = false;
515
+ const restoreOriginalPre = () => {
516
+ var _a;
517
+ if (restored)
518
+ return;
519
+ restored = true;
520
+ try {
521
+ (_a = helpers === null || helpers === void 0 ? void 0 : helpers.cleanupEditor) === null || _a === void 0 ? void 0 : _a.call(helpers);
522
+ }
523
+ catch {
524
+ // Ignore cleanup failures during fallback.
525
+ }
526
+ if (shell.wrapper.isConnected)
527
+ shell.wrapper.replaceWith(originalPre.cloneNode(true));
528
+ };
529
+ pre.replaceWith(shell.wrapper);
530
+ helpers = monacoModule.useMonaco({
531
+ themes: ['vitesse-dark', 'vitesse-light'],
532
+ languages: Array.from(new Set([monacoLanguage, 'plaintext'])),
533
+ readOnly: true,
534
+ minimap: { enabled: false },
535
+ lineNumbers: 'on',
536
+ wordWrap: 'off',
537
+ revealDebounceMs: 75,
538
+ MAX_HEIGHT: 500,
539
+ fontSize: 13,
540
+ ...(options.monacoOptions || {}),
541
+ });
542
+ cleanupFns.push(restoreOriginalPre);
543
+ try {
544
+ // Vue/React wire Monaco diff editors through dedicated components.
545
+ // Svelte currently enhances static HTML after the fact, and the diff
546
+ // editor path in stream-monaco can leave an empty shell or raise
547
+ // "no diff result available" during worker setup. Prefer a stable
548
+ // single-editor fallback that still preserves the diff source text.
549
+ await helpers.createEditor(shell.body, source, renderLanguage);
550
+ if (!isActive()) {
551
+ restoreOriginalPre();
552
+ return;
553
+ }
554
+ await ((_b = helpers.setTheme) === null || _b === void 0 ? void 0 : _b.call(helpers, options.isDark ? 'vitesse-dark' : 'vitesse-light'));
555
+ if (!isActive()) {
556
+ restoreOriginalPre();
557
+ return;
558
+ }
559
+ await waitForRenderFrame();
560
+ if (!hasVisibleMonacoContent(shell.body, source))
561
+ throw new Error('Monaco editor rendered no visible code content.');
562
+ shell.wrapper.dataset.markstreamMonaco = '1';
563
+ if (diff)
564
+ shell.wrapper.dataset.markstreamMonacoDiff = '1';
565
+ }
566
+ catch {
567
+ restoreOriginalPre();
568
+ }
569
+ }
570
+ }
571
+ function createD2Instance(D2Ctor) {
572
+ if (typeof D2Ctor === 'function') {
573
+ const instance = new D2Ctor();
574
+ if (instance && typeof instance.compile === 'function')
575
+ return instance;
576
+ if (typeof D2Ctor.compile === 'function')
577
+ return D2Ctor;
578
+ }
579
+ if ((D2Ctor === null || D2Ctor === void 0 ? void 0 : D2Ctor.D2) && typeof D2Ctor.D2 === 'function')
580
+ return new D2Ctor.D2();
581
+ if (typeof (D2Ctor === null || D2Ctor === void 0 ? void 0 : D2Ctor.compile) === 'function')
582
+ return D2Ctor;
583
+ return null;
584
+ }
585
+ function resolveCodeLanguage(pre, codeNode) {
586
+ var _a;
587
+ const explicit = (_a = pre.dataset.markstreamLanguage) === null || _a === void 0 ? void 0 : _a.trim();
588
+ if (explicit)
589
+ return explicit;
590
+ const languageClass = Array.from(codeNode.classList).find(className => className.startsWith('language-'));
591
+ return languageClass ? languageClass.slice('language-'.length) : 'plaintext';
592
+ }
593
+ function resolveMonacoLanguage(language) {
594
+ const normalized = language.trim().toLowerCase();
595
+ return MONACO_LANGUAGE_ALIASES[normalized] || normalized || 'plaintext';
596
+ }
597
+ function estimateCodeBlockHeight(source, diff) {
598
+ const lineCount = Math.max(1, source.split('\n').length);
599
+ const perLine = diff ? 20 : 18;
600
+ const base = diff ? 180 : 96;
601
+ return Math.min(520, base + lineCount * perLine);
602
+ }
603
+ function hasVisibleMonacoContent(body, source) {
604
+ var _a;
605
+ const editor = body.querySelector('.monaco-editor');
606
+ if (!editor)
607
+ return false;
608
+ const rect = editor.getBoundingClientRect();
609
+ if (rect.width <= 0 || rect.height <= 0)
610
+ return false;
611
+ const expected = (_a = source.split('\n').find(line => line.trim())) === null || _a === void 0 ? void 0 : _a.trim();
612
+ if (!expected)
613
+ return true;
614
+ const normalizedVisible = normalizeVisibleCodeText(body.textContent || '');
615
+ const normalizedExpected = normalizeVisibleCodeText(expected);
616
+ return normalizedVisible.includes(normalizedExpected);
617
+ }
618
+ function normalizeVisibleCodeText(value) {
619
+ return value.replace(/\s+/g, '');
620
+ }
621
+ async function waitForRenderFrame() {
622
+ if (typeof window === 'undefined' || typeof window.requestAnimationFrame !== 'function')
623
+ return;
624
+ await new Promise(resolve => window.requestAnimationFrame(() => resolve()));
625
+ }
626
+ function decodeDataPayload(value) {
627
+ var _a, _b;
628
+ if (!value)
629
+ return '';
630
+ const globalBuffer = (_b = (_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.require) === null || _a === void 0 ? void 0 : _a.call(globalThis, 'buffer')) === null || _b === void 0 ? void 0 : _b.Buffer;
631
+ if (globalBuffer === null || globalBuffer === void 0 ? void 0 : globalBuffer.from)
632
+ return globalBuffer.from(value, 'base64').toString('utf8');
633
+ if (typeof globalThis.atob === 'function' && typeof TextDecoder !== 'undefined') {
634
+ const binary = globalThis.atob(value);
635
+ const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
636
+ return new TextDecoder().decode(bytes);
637
+ }
638
+ return '';
639
+ }
640
+ function createEnhancedBlockShell(kind, label, source, showSourceDetails, options, shellOptions = {}) {
641
+ const wrapper = document.createElement('div');
642
+ wrapper.className = `markstream-svelte-enhanced-block markstream-svelte-enhanced-block--${kind}`;
643
+ if (shellOptions.showHeader !== false) {
644
+ const header = document.createElement('div');
645
+ header.className = 'markstream-svelte-enhanced-block__header';
646
+ const badge = document.createElement('span');
647
+ badge.className = 'markstream-svelte-enhanced-block__badge';
648
+ badge.textContent = label;
649
+ header.appendChild(badge);
650
+ header.appendChild(createHeaderActions(source, options));
651
+ wrapper.appendChild(header);
652
+ }
653
+ const body = document.createElement('div');
654
+ body.className = 'markstream-svelte-enhanced-block__body';
655
+ wrapper.appendChild(body);
656
+ if (showSourceDetails) {
657
+ const details = document.createElement('details');
658
+ details.className = 'markstream-svelte-enhanced-block__details';
659
+ const summary = document.createElement('summary');
660
+ summary.textContent = 'Source';
661
+ details.appendChild(summary);
662
+ const sourcePre = document.createElement('pre');
663
+ sourcePre.className = 'markstream-svelte-enhanced-block__source';
664
+ const code = document.createElement('code');
665
+ code.textContent = source;
666
+ sourcePre.appendChild(code);
667
+ details.appendChild(sourcePre);
668
+ wrapper.appendChild(details);
669
+ }
670
+ return { wrapper, body };
671
+ }
672
+ function createHeaderActions(source, options) {
673
+ const actions = document.createElement('div');
674
+ actions.className = 'markstream-svelte-enhanced-block__actions';
675
+ const copyButton = document.createElement('button');
676
+ copyButton.type = 'button';
677
+ copyButton.className = 'markstream-svelte-enhanced-block__action';
678
+ copyButton.textContent = 'Copy';
679
+ if (options.showTooltips !== false)
680
+ copyButton.title = 'Copy source';
681
+ copyButton.addEventListener('click', () => {
682
+ var _a;
683
+ void copyText(source);
684
+ (_a = options.onCopy) === null || _a === void 0 ? void 0 : _a.call(options, source);
685
+ });
686
+ actions.appendChild(copyButton);
687
+ return actions;
688
+ }
689
+ function enhanceTooltips(root, cleanupFns, options) {
690
+ if (options.showTooltips === false)
691
+ return;
692
+ const targets = Array.from(root.querySelectorAll('[data-markstream-tooltip], [title]'));
693
+ if (targets.length === 0)
694
+ return;
695
+ for (const target of targets) {
696
+ if (target.matches('.footnote-link, .footnote-anchor'))
697
+ continue;
698
+ const title = target.getAttribute('title');
699
+ const text = (target.dataset.markstreamTooltip || title || '').trim();
700
+ if (!text)
701
+ continue;
702
+ if (title != null)
703
+ target.removeAttribute('title');
704
+ const show = () => showTooltipForAnchor(target, text, 'top', false, undefined, options.isDark);
705
+ const hide = () => hideTooltip();
706
+ target.addEventListener('mouseenter', show);
707
+ target.addEventListener('focus', show);
708
+ target.addEventListener('mouseleave', hide);
709
+ target.addEventListener('blur', hide);
710
+ cleanupFns.push(() => {
711
+ const ownsVisibleTooltip = target.getAttribute('aria-describedby') != null;
712
+ target.removeEventListener('mouseenter', show);
713
+ target.removeEventListener('focus', show);
714
+ target.removeEventListener('mouseleave', hide);
715
+ target.removeEventListener('blur', hide);
716
+ if (ownsVisibleTooltip)
717
+ hideTooltip(true);
718
+ if (title != null && target.getAttribute('title') == null)
719
+ target.setAttribute('title', title);
720
+ });
721
+ }
722
+ }
723
+ function enhanceFootnotes(root, cleanupFns) {
724
+ const links = Array.from(root.querySelectorAll('.footnote-reference .footnote-link[href^="#"]'));
725
+ for (const link of links) {
726
+ const handleClick = (event) => {
727
+ const href = link.getAttribute('href');
728
+ if (!href)
729
+ return;
730
+ event.preventDefault();
731
+ const target = document.getElementById(href.slice(1));
732
+ target === null || target === void 0 ? void 0 : target.scrollIntoView({ behavior: 'smooth', block: 'start' });
733
+ };
734
+ link.addEventListener('click', handleClick);
735
+ cleanupFns.push(() => link.removeEventListener('click', handleClick));
736
+ }
737
+ }
738
+ async function copyText(source) {
739
+ var _a;
740
+ try {
741
+ if (typeof navigator !== 'undefined' && ((_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText)) {
742
+ await navigator.clipboard.writeText(source);
743
+ return;
744
+ }
745
+ }
746
+ catch {
747
+ // Fall through to the textarea fallback below.
748
+ }
749
+ if (typeof document === 'undefined')
750
+ return;
751
+ const textarea = document.createElement('textarea');
752
+ textarea.value = source;
753
+ textarea.setAttribute('readonly', 'true');
754
+ textarea.style.position = 'fixed';
755
+ textarea.style.opacity = '0';
756
+ textarea.style.pointerEvents = 'none';
757
+ document.body.appendChild(textarea);
758
+ textarea.select();
759
+ try {
760
+ document.execCommand('copy');
761
+ }
762
+ catch {
763
+ // Ignore copy failures; the output callback still fires.
764
+ }
765
+ finally {
766
+ textarea.remove();
767
+ }
768
+ }