@simon_he/vue-tui 1.1.3 → 1.1.4

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 (51) hide show
  1. package/dist/{TMermaidText-frVr8Ysb.js → TMermaidText-wLnMMvVS.js} +1 -1
  2. package/dist/{TSelect-Dx34M1pF.js → TSelect-CMBOOFwK.js} +5 -5
  3. package/dist/{TTree-DdAjCPHu.js → TTree-kk8ntrpg.js} +6 -5
  4. package/dist/agent/mermaid.d.cts +2 -2
  5. package/dist/agent/mermaid.d.ts +2 -2
  6. package/dist/agent.cjs +538 -266
  7. package/dist/agent.js +25 -82
  8. package/dist/{block-source-Crro3mxi.js → block-source-D3YGTErb.js} +299 -239
  9. package/dist/cli.cjs +52 -15
  10. package/dist/cli.js +69 -14
  11. package/dist/core.js +3 -3
  12. package/dist/{hyperlink-_1FAj7Wq.js → create-terminal-Db_-UGVQ.js} +474 -102
  13. package/dist/{dom-renderer-DXx8fWzD.js → dom-renderer-BfwAEQMf.js} +3 -2
  14. package/dist/experimental.cjs +99 -66
  15. package/dist/experimental.js +20 -74
  16. package/dist/hyperlink-clbb_ha_.js +100 -0
  17. package/dist/index.js +8 -8
  18. package/dist/{linkify-BjI4zVfY.js → linkify-CL9wwnZN.js} +3 -3
  19. package/dist/markdown.cjs +521 -212
  20. package/dist/markdown.d.cts +3 -0
  21. package/dist/markdown.d.ts +3 -0
  22. package/dist/markdown.js +75 -8
  23. package/dist/math-image-BZhmfUeu.js +308 -0
  24. package/dist/mermaid-uEfRItDe.js +1205 -0
  25. package/dist/mermaid.cjs +1089 -3
  26. package/dist/mermaid.d.cts +4 -0
  27. package/dist/mermaid.d.ts +4 -0
  28. package/dist/mermaid.js +7 -5
  29. package/dist/{rect-DUpeDfBg.js → rect-JzWMJxxc.js} +1 -1
  30. package/dist/renderer/cli/stdout-renderer.d.ts +44 -0
  31. package/dist/renderer/terminal-graphics.d.ts +44 -0
  32. package/dist/renderer-dom.js +4 -4
  33. package/dist/{terminal-graphics-Bbe83wSr.js → terminal-graphics-DWZrl3oh.js} +85 -2
  34. package/dist/{tlog-theme-i6S_Oftd.js → tlog-theme-DqnF_zNe.js} +5 -4
  35. package/dist/vue/components/TAgentTerminalGraphic.d.ts +1 -1
  36. package/dist/vue/components/TMarkdownText.d.ts +70 -2
  37. package/dist/vue/components/TMermaidImage.d.ts +733 -0
  38. package/dist/vue/components/TMermaidText.d.ts +2 -2
  39. package/dist/vue/components/TVirtualMarkdown.d.ts +70 -2
  40. package/dist/vue/markdown/ast.d.ts +5 -0
  41. package/dist/vue/markdown/document.d.ts +3 -0
  42. package/dist/vue/markdown/math-image.d.ts +68 -0
  43. package/dist/vue/markdown/theme.d.ts +12 -0
  44. package/dist/vue/markdown/types.d.ts +12 -2
  45. package/dist/vue/mermaid/beautiful-mermaid.d.ts +4 -4
  46. package/dist/vue/mermaid/mermaid-image.d.ts +65 -0
  47. package/dist/vue.js +9 -9
  48. package/package.json +14 -1
  49. package/dist/mermaid-BNhM1jAZ.js +0 -123
  50. package/dist/width-GqllnV8C.js +0 -474
  51. /package/dist/{ansi-palette-CH6jc2Z7.js → ansi-palette-BHF1rN7R.js} +0 -0
package/dist/agent.cjs CHANGED
@@ -6152,6 +6152,91 @@ function formatItermDimension(value) {
6152
6152
  let raw = String(value ?? "").trim();
6153
6153
  return validateIterm2Dimension(raw) ? raw : "auto";
6154
6154
  }
6155
+ function resolveKittyPngSourceCrop(rect, fullRect, sourceWidth, sourceHeight) {
6156
+ if (fullRect.w <= 0 || fullRect.h <= 0)
6157
+ return null;
6158
+ let offsetX = Math.max(0, rect.x - fullRect.x), offsetY = Math.max(0, rect.y - fullRect.y), visibleW = Math.max(0, Math.min(rect.w, fullRect.w - offsetX)), visibleH = Math.max(0, Math.min(rect.h, fullRect.h - offsetY));
6159
+ if (offsetX <= 0 && offsetY <= 0 && visibleW >= fullRect.w && visibleH >= fullRect.h)
6160
+ return null;
6161
+ let sourceX = Math.max(
6162
+ 0,
6163
+ Math.min(sourceWidth - 1, Math.floor(offsetX * sourceWidth / fullRect.w))
6164
+ ), sourceY = Math.max(
6165
+ 0,
6166
+ Math.min(sourceHeight - 1, Math.floor(offsetY * sourceHeight / fullRect.h))
6167
+ ), sourceRight = Math.max(
6168
+ sourceX + 1,
6169
+ Math.min(sourceWidth, Math.ceil((offsetX + visibleW) * sourceWidth / fullRect.w))
6170
+ ), sourceBottom = Math.max(
6171
+ sourceY + 1,
6172
+ Math.min(sourceHeight, Math.ceil((offsetY + visibleH) * sourceHeight / fullRect.h))
6173
+ );
6174
+ return {
6175
+ sourceX,
6176
+ sourceY,
6177
+ sourceWidth: sourceRight - sourceX,
6178
+ sourceHeight: sourceBottom - sourceY
6179
+ };
6180
+ }
6181
+ function createTerminalGraphicPngSequence(options) {
6182
+ if (options.protocol === "kitty") {
6183
+ let placement = {
6184
+ columns: options.placementColumns,
6185
+ rows: options.placementRows
6186
+ };
6187
+ if (options.rect && options.fullRect && options.sourceWidth && options.sourceHeight) {
6188
+ let crop = resolveKittyPngSourceCrop(
6189
+ options.rect,
6190
+ options.fullRect,
6191
+ options.sourceWidth,
6192
+ options.sourceHeight
6193
+ );
6194
+ crop && (placement = { ...placement, ...crop });
6195
+ }
6196
+ return {
6197
+ type: "sequence",
6198
+ protocol: "kitty",
6199
+ sequence: createKittyGraphicsSequence(options.base64, {
6200
+ imageId: options.imageId,
6201
+ placementId: options.placementId,
6202
+ zIndex: options.zIndex,
6203
+ ...placement
6204
+ }),
6205
+ resizeSequence: createKittyPlacementSequence({
6206
+ imageId: options.imageId,
6207
+ placementId: options.placementId,
6208
+ zIndex: options.zIndex,
6209
+ ...placement
6210
+ }),
6211
+ clearSequence: createKittyDeleteGraphicsSequence({
6212
+ imageId: options.imageId,
6213
+ placementId: options.placementId,
6214
+ freeImageData: options.freeImageData
6215
+ }),
6216
+ ...options.fallback != null ? { fallback: options.fallback } : {},
6217
+ ...options.cols != null ? { cols: options.cols } : {},
6218
+ ...options.rows != null ? { rows: options.rows } : {},
6219
+ ...options.sourceWidth != null ? { sourceWidth: options.sourceWidth } : {},
6220
+ ...options.sourceHeight != null ? { sourceHeight: options.sourceHeight } : {},
6221
+ ...options.zIndex != null ? { zIndex: options.zIndex } : {}
6222
+ };
6223
+ }
6224
+ return options.protocol === "iterm2" ? {
6225
+ type: "sequence",
6226
+ protocol: "iterm2",
6227
+ sequence: createIterm2InlineImageSequence(options.base64, {
6228
+ width: options.cols,
6229
+ height: options.rows,
6230
+ preserveAspectRatio: !0,
6231
+ doNotMoveCursor: !0
6232
+ }),
6233
+ ...options.fallback != null ? { fallback: options.fallback } : {},
6234
+ ...options.cols != null ? { cols: options.cols } : {},
6235
+ ...options.rows != null ? { rows: options.rows } : {},
6236
+ ...options.sourceWidth != null ? { sourceWidth: options.sourceWidth } : {},
6237
+ ...options.sourceHeight != null ? { sourceHeight: options.sourceHeight } : {}
6238
+ } : null;
6239
+ }
6155
6240
 
6156
6241
  // src/vue/components/TAgentTerminalGraphic.ts
6157
6242
  var NO_GRAPHICS_CAPABILITIES = Object.freeze({
@@ -14790,185 +14875,236 @@ function readMarkdownImageDimensions(base64) {
14790
14875
  return null;
14791
14876
  }
14792
14877
 
14793
- // src/vue/markdown/math.ts
14794
- var loadedKatex = null, katexLoad = null, katexListeners = /* @__PURE__ */ new Set();
14795
- function resolveKatexRenderer(value) {
14796
- if (!value || typeof value != "object")
14797
- return null;
14798
- let renderToString = value.renderToString;
14799
- return typeof renderToString == "function" ? { renderToString } : null;
14878
+ // src/vue/markdown/math-image.ts
14879
+ var DEFAULT_MATH_IMAGE_OPTIONS = Object.freeze({
14880
+ cellWidthPx: 8,
14881
+ cellHeightPx: 16,
14882
+ scale: 2,
14883
+ color: "#f8f8f2",
14884
+ maxWidthCells: 0,
14885
+ baselineRatio: 0.78
14886
+ }), MAX_CACHE_ENTRIES = 64, MAX_FAILED_ENTRIES = 128, mathImageCache = /* @__PURE__ */ new Map(), mathImageFailed = /* @__PURE__ */ new Set(), mathImageInflight = /* @__PURE__ */ new Map(), mathImageListeners = /* @__PURE__ */ new Set(), customRasterizer = null, builtinRasterizerLoad = null, builtinRasterizerReady = !1, NAMED_STYLE_FG_HEX = Object.freeze({
14887
+ black: "#000000",
14888
+ red: "#e53935",
14889
+ green: "#43a047",
14890
+ yellow: "#fdd835",
14891
+ blue: "#1e88e5",
14892
+ magenta: "#d81b60",
14893
+ cyan: "#00acc1",
14894
+ white: "#ffffff",
14895
+ gray: "#9e9e9e",
14896
+ grey: "#9e9e9e",
14897
+ blackBright: "#4a4a4a",
14898
+ redBright: "#ff6e6e",
14899
+ greenBright: "#69db7c",
14900
+ yellowBright: "#ffe066",
14901
+ blueBright: "#74c0fc",
14902
+ magentaBright: "#f783ac",
14903
+ cyanBright: "#3bc9db",
14904
+ whiteBright: "#f8f8f2",
14905
+ grayBright: "#bdbdbd",
14906
+ greyBright: "#bdbdbd"
14907
+ });
14908
+ function resolveMarkdownMathColor(fg) {
14909
+ if (typeof fg != "string" || !fg)
14910
+ return;
14911
+ let trimmed = fg.trim();
14912
+ return trimmed.startsWith("#") && /^#[0-9a-f]{3,8}$/i.test(trimmed) ? trimmed.toLowerCase() : NAMED_STYLE_FG_HEX[trimmed.toLowerCase()];
14800
14913
  }
14801
- function subscribeMarkdownMathRenderer(listener) {
14802
- return katexListeners.add(listener), () => katexListeners.delete(listener);
14914
+ function normalizeMathImageOptions(options) {
14915
+ return {
14916
+ cellWidthPx: Math.max(
14917
+ 1,
14918
+ Math.floor(options?.cellWidthPx ?? DEFAULT_MATH_IMAGE_OPTIONS.cellWidthPx)
14919
+ ),
14920
+ cellHeightPx: Math.max(
14921
+ 1,
14922
+ Math.floor(options?.cellHeightPx ?? DEFAULT_MATH_IMAGE_OPTIONS.cellHeightPx)
14923
+ ),
14924
+ scale: Math.max(1, Math.floor(options?.scale ?? DEFAULT_MATH_IMAGE_OPTIONS.scale)),
14925
+ color: options?.color ?? DEFAULT_MATH_IMAGE_OPTIONS.color,
14926
+ maxWidthCells: Math.max(0, Math.floor(options?.maxWidthCells ?? 0)),
14927
+ baselineRatio: clamp01(options?.baselineRatio ?? DEFAULT_MATH_IMAGE_OPTIONS.baselineRatio)
14928
+ };
14803
14929
  }
14804
- async function loadMarkdownMathRenderer() {
14805
- return loadedKatex ? !0 : (katexLoad || (katexLoad = import("katex").then((mod) => {
14806
- let renderer = resolveKatexRenderer(mod.default) ?? resolveKatexRenderer(mod);
14807
- if (!renderer)
14808
- return !1;
14809
- loadedKatex = renderer;
14810
- for (let listener of katexListeners)
14811
- listener();
14812
- return !0;
14813
- }).catch(() => !1)), katexLoad);
14930
+ function clamp01(value) {
14931
+ return Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 0.78;
14814
14932
  }
14815
- var KATEX_TEXT_OPTIONS = Object.freeze({
14816
- output: "mathml",
14817
- throwOnError: !1,
14818
- strict: "ignore",
14819
- trust: !1,
14820
- maxSize: 20,
14821
- maxExpand: 200
14822
- }), KATEX_VALIDATE_OPTIONS = Object.freeze({
14823
- ...KATEX_TEXT_OPTIONS,
14824
- throwOnError: !0
14825
- }), TEX_SYMBOLS = Object.freeze({
14826
- alpha: "\u03B1",
14827
- beta: "\u03B2",
14828
- gamma: "\u03B3",
14829
- delta: "\u03B4",
14830
- epsilon: "\u03B5",
14831
- theta: "\u03B8",
14832
- lambda: "\u03BB",
14833
- mu: "\u03BC",
14834
- pi: "\u03C0",
14835
- rho: "\u03C1",
14836
- sigma: "\u03C3",
14837
- tau: "\u03C4",
14838
- phi: "\u03C6",
14839
- omega: "\u03C9",
14840
- Gamma: "\u0393",
14841
- Delta: "\u0394",
14842
- Theta: "\u0398",
14843
- Lambda: "\u039B",
14844
- Pi: "\u03A0",
14845
- Sigma: "\u03A3",
14846
- Phi: "\u03A6",
14847
- Omega: "\u03A9",
14848
- int: "\u222B",
14849
- sum: "\u2211",
14850
- prod: "\u220F",
14851
- infty: "\u221E",
14852
- infinity: "\u221E",
14853
- pm: "\xB1",
14854
- times: "\xD7",
14855
- cdot: "\xB7",
14856
- div: "\xF7",
14857
- le: "\u2264",
14858
- leq: "\u2264",
14859
- ge: "\u2265",
14860
- geq: "\u2265",
14861
- neq: "\u2260",
14862
- ne: "\u2260",
14863
- approx: "\u2248",
14864
- equiv: "\u2261",
14865
- to: "\u2192",
14866
- rightarrow: "\u2192",
14867
- leftarrow: "\u2190",
14868
- leftrightarrow: "\u2194",
14869
- partial: "\u2202",
14870
- nabla: "\u2207",
14871
- sqrt: "\u221A"
14872
- }), SUPPORTED_COMMANDS = /* @__PURE__ */ new Set([...Object.keys(TEX_SYMBOLS), "frac", "sqrt"]);
14873
- function decodeXmlEntities(value) {
14874
- return value.replace(/&(?:#(\d+)|#x([0-9a-f]+)|([a-z]+));/gi, (match, dec, hex, named) => {
14875
- if (dec)
14876
- return String.fromCodePoint(Number(dec));
14877
- if (hex)
14878
- return String.fromCodePoint(Number.parseInt(hex, 16));
14879
- switch (String(named).toLowerCase()) {
14880
- case "amp":
14881
- return "&";
14882
- case "lt":
14883
- return "<";
14884
- case "gt":
14885
- return ">";
14886
- case "quot":
14887
- return '"';
14888
- case "apos":
14889
- return "'";
14890
- default:
14891
- return match;
14892
- }
14893
- });
14933
+ function subscribeMarkdownMathImage(listener) {
14934
+ return mathImageListeners.add(listener), () => mathImageListeners.delete(listener);
14894
14935
  }
14895
- function mathmlTagName(tag) {
14896
- let start = tag.startsWith("/") ? 1 : 0, end = start;
14897
- for (; end < tag.length; ) {
14898
- let ch = tag[end];
14899
- if (ch === " " || ch === " " || ch === `
14900
- ` || ch === "\r" || ch === "/")
14901
- break;
14902
- end++;
14903
- }
14904
- return tag.slice(start, end).toLowerCase();
14936
+ function isMarkdownMathImageRendererReady() {
14937
+ return customRasterizer != null || builtinRasterizerReady;
14905
14938
  }
14906
- function textFromKatexMathml(html) {
14907
- let readable = "", offset = 0, lowerHtml = html.toLowerCase();
14908
- for (; offset < html.length; ) {
14909
- let tagStart = html.indexOf("<", offset);
14910
- if (tagStart < 0) {
14911
- readable += html.slice(offset);
14912
- break;
14913
- }
14914
- readable += html.slice(offset, tagStart);
14915
- let tagEnd = html.indexOf(">", tagStart + 1);
14916
- if (tagEnd < 0)
14917
- break;
14918
- let tag = html.slice(tagStart + 1, tagEnd).trim(), tagName = mathmlTagName(tag), closing = tag.startsWith("/");
14919
- if (!closing && tagName === "annotation") {
14920
- let annotationEnd = lowerHtml.indexOf("</annotation>", tagEnd + 1);
14921
- offset = annotationEnd < 0 ? tagEnd + 1 : annotationEnd + 13;
14922
- continue;
14923
- }
14924
- !closing && tagName === "mfrac" ? readable += "(" : closing && tagName === "mfrac" ? readable += ")" : !closing && tagName === "mspace" && (readable += " "), offset = tagEnd + 1;
14925
- }
14926
- return sanitizeInlineText(
14927
- decodeXmlEntities(readable).replace(/[<>]/g, "").replace(/\s+/g, " ").trim()
14939
+ async function loadMarkdownMathImageRenderer() {
14940
+ return isMarkdownMathImageRendererReady() ? !0 : (builtinRasterizerReady = (customRasterizer ?? await loadBuiltinMathRasterizer()) != null, builtinRasterizerReady);
14941
+ }
14942
+ function hashMathImageKey(value) {
14943
+ let hash = 2166136261;
14944
+ for (let i = 0; i < value.length; i++)
14945
+ hash ^= value.charCodeAt(i), hash = Math.imul(hash, 16777619);
14946
+ return (hash >>> 0).toString(36);
14947
+ }
14948
+ function mathImageCacheKey(tex, mode, options) {
14949
+ return hashMathImageKey(
14950
+ [
14951
+ mode,
14952
+ tex,
14953
+ options.cellWidthPx,
14954
+ options.cellHeightPx,
14955
+ options.scale,
14956
+ options.maxWidthCells,
14957
+ options.color,
14958
+ options.baselineRatio
14959
+ ].join("")
14928
14960
  );
14929
14961
  }
14930
- function approximateTexToUnicode(tex) {
14931
- let out = String(tex ?? "");
14932
- return out = out.replace(/\\frac\s*\{([^{}]*)\}\s*\{([^{}]*)\}/g, "$1/$2"), out = out.replace(/\\sqrt\s*\{([^{}]*)\}/g, "\u221A($1)"), out = out.replace(
14933
- /\\([A-Za-z]+)\b/g,
14934
- (_match, command) => TEX_SYMBOLS[command] ?? command
14935
- ), out = out.replace(/\\([^A-Za-z])/g, "$1"), out = out.replace(/[{}]/g, ""), out = out.replace(/\s+/g, " ").trim(), sanitizeInlineText(out.replace(/[<>]/g, ""));
14962
+ function notifyMathImageListeners() {
14963
+ for (let listener of mathImageListeners)
14964
+ try {
14965
+ listener();
14966
+ } catch {
14967
+ }
14968
+ }
14969
+ function getCachedMarkdownMathImage(tex, mode, options) {
14970
+ return mathImageCache.get(mathImageCacheKey(tex, mode, normalizeMathImageOptions(options))) ?? null;
14971
+ }
14972
+ function evictOldestMathImageEntry() {
14973
+ let oldest = mathImageCache.keys().next().value;
14974
+ oldest != null && mathImageCache.delete(oldest);
14936
14975
  }
14937
- function canRenderTerminalMath(tex, katex) {
14976
+ async function getMarkdownMathImage(tex, mode, options) {
14938
14977
  let source = String(tex ?? "").trim();
14939
- if (!source || source.length > 160 || /\\(?:begin|end|left|right|matrix|cases|array|align|color|href|html|includegraphics|class|style|tag|text|operatorname)\b/.test(
14940
- source
14941
- ))
14942
- return !1;
14943
- let commands = source.matchAll(/\\([A-Za-z]+)\b/g);
14944
- for (let match of commands)
14945
- if (!SUPPORTED_COMMANDS.has(match[1] ?? ""))
14946
- return !1;
14947
- try {
14948
- katex.renderToString(source, KATEX_VALIDATE_OPTIONS);
14949
- } catch {
14950
- return !1;
14978
+ if (!source)
14979
+ return null;
14980
+ let normalized = normalizeMathImageOptions(options), key = mathImageCacheKey(source, mode, normalized), cached = mathImageCache.get(key);
14981
+ if (cached)
14982
+ return cached;
14983
+ if (mathImageFailed.has(key))
14984
+ return null;
14985
+ let inflight = mathImageInflight.get(key);
14986
+ if (inflight)
14987
+ return inflight;
14988
+ let pending = (async () => {
14989
+ try {
14990
+ let rasterizer = customRasterizer ?? await loadBuiltinMathRasterizer();
14991
+ if (!rasterizer)
14992
+ return null;
14993
+ let result = await rasterizer(source, mode, normalized);
14994
+ if (result && result.base64)
14995
+ mathImageCache.set(key, result), mathImageCache.size > MAX_CACHE_ENTRIES && evictOldestMathImageEntry(), notifyMathImageListeners();
14996
+ else if (result === null && (mathImageFailed.add(key), mathImageFailed.size > MAX_FAILED_ENTRIES)) {
14997
+ let oldest = mathImageFailed.values().next().value;
14998
+ oldest != null && mathImageFailed.delete(oldest);
14999
+ }
15000
+ return result;
15001
+ } catch {
15002
+ return null;
15003
+ } finally {
15004
+ mathImageInflight.delete(key);
15005
+ }
15006
+ })();
15007
+ return mathImageInflight.set(key, pending), pending;
15008
+ }
15009
+ function enqueueMarkdownMathImages(rows, options, viewport) {
15010
+ let first = Math.max(0, Math.floor(viewport?.firstRow ?? 0)), last = Math.min(rows.length, Math.max(first, Math.ceil(viewport?.lastRow ?? rows.length)));
15011
+ for (let index = first; index < last; index++) {
15012
+ let row = rows[index];
15013
+ if (row)
15014
+ for (let segment of row.segments) {
15015
+ let graphic = segment.graphic;
15016
+ if (graphic?.kind === "math") {
15017
+ !graphic.base64 && graphic.tex && getMarkdownMathImage(graphic.tex, "display", options);
15018
+ continue;
15019
+ }
15020
+ segment.mathAction?.pendingImage && segment.mathAction?.source && getMarkdownMathImage(
15021
+ segment.mathAction.source,
15022
+ segment.mathAction.mode ?? "display",
15023
+ options
15024
+ );
15025
+ }
14951
15026
  }
14952
- return !0;
14953
15027
  }
14954
- function renderMarkdownInlineMathSegment(tex) {
14955
- let source = String(tex ?? "");
14956
- if (!source.trim())
14957
- return { text: "", supported: !1 };
14958
- let katex = loadedKatex;
14959
- if (!katex)
14960
- return loadMarkdownMathRenderer(), { text: "", supported: !1 };
14961
- if (!canRenderTerminalMath(source, katex))
14962
- return { text: "", supported: !1 };
14963
- try {
14964
- let html = katex.renderToString(source, KATEX_TEXT_OPTIONS), rendered = /\\frac\b/.test(source) ? approximateTexToUnicode(source) : textFromKatexMathml(html);
14965
- if (rendered && !rendered.includes("\\"))
14966
- return { text: rendered, supported: !0 };
14967
- } catch {
14968
- return { text: "", supported: !1 };
14969
- }
14970
- let approximate = approximateTexToUnicode(source);
14971
- return approximate && !approximate.includes("\\") ? { text: approximate, supported: !0 } : { text: "", supported: !1 };
15028
+ function base64FromBytes(bytes) {
15029
+ let binary = "";
15030
+ for (let offset = 0; offset < bytes.length; offset += 32768)
15031
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 32768));
15032
+ return typeof btoa == "function" ? btoa(binary) : Buffer.from(bytes).toString("base64");
15033
+ }
15034
+ function extractSvgMarkup(containerMarkup) {
15035
+ let start = containerMarkup.indexOf("<svg");
15036
+ if (start < 0)
15037
+ return "";
15038
+ let end = containerMarkup.lastIndexOf("</svg>");
15039
+ return end < start ? "" : containerMarkup.slice(start, end + 6);
15040
+ }
15041
+ var RESVG_MODULE_ID = "@resvg/resvg-js";
15042
+ function loadBuiltinMathRasterizer() {
15043
+ return builtinRasterizerLoad || (builtinRasterizerLoad = (async () => {
15044
+ try {
15045
+ let [
15046
+ { mathjax },
15047
+ { TeX },
15048
+ { SVG },
15049
+ { liteAdaptor },
15050
+ { RegisterHTMLHandler },
15051
+ { AllPackages },
15052
+ { Resvg }
15053
+ ] = await Promise.all([
15054
+ import("mathjax-full/js/mathjax.js"),
15055
+ import("mathjax-full/js/input/tex.js"),
15056
+ import("mathjax-full/js/output/svg.js"),
15057
+ import("mathjax-full/js/adaptors/liteAdaptor.js"),
15058
+ import("mathjax-full/js/handlers/html.js"),
15059
+ import("mathjax-full/js/input/tex/AllPackages.js"),
15060
+ import(RESVG_MODULE_ID)
15061
+ ]), adaptor = liteAdaptor();
15062
+ RegisterHTMLHandler(adaptor);
15063
+ let texInput = new TeX({
15064
+ packages: AllPackages,
15065
+ formatError: () => {
15066
+ throw new Error("Malformed TeX");
15067
+ }
15068
+ }), svgOutput = new SVG({ fontCache: "none" }), document2 = mathjax.document("", { InputJax: texInput, OutputJax: svgOutput });
15069
+ return async (source, mode, options) => {
15070
+ let node = document2.convert(source, { display: mode === "display" }), svg = extractSvgMarkup(adaptor.outerHTML(node));
15071
+ if (!svg)
15072
+ return null;
15073
+ let widthEx = Number(/width="([\d.]+)ex"/.exec(svg)?.[1] ?? 0), heightEx = Number(/height="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
15074
+ if (!(widthEx > 0) || !(heightEx > 0))
15075
+ return null;
15076
+ let exPx = options.cellHeightPx / 2 * options.scale;
15077
+ if (mode === "inline") {
15078
+ let naturalH = heightEx * exPx, naturalW = widthEx * exPx;
15079
+ if (naturalH > options.cellHeightPx * options.scale * 2)
15080
+ return null;
15081
+ let rectH = options.cellHeightPx * options.scale, k = rectH / naturalH, contentW = Math.max(1, Math.round(naturalW * k)), widthCells = Math.max(
15082
+ 1,
15083
+ Math.ceil(contentW / (options.cellWidthPx * options.scale))
15084
+ ), rectW = widthCells * options.cellWidthPx * options.scale, verticalAlignEx = Number(/vertical-align:\s*(-?[\d.]+)ex/.exec(svg)?.[1] ?? 0), formulaBaseline = (heightEx - Math.abs(verticalAlignEx)) * exPx * k, offsetY = options.baselineRatio * rectH - formulaBaseline, inner = svg.replace(/style="vertical-align:[^"]*"/, "").replace(/width="[\d.]+ex"/, `width="${contentW}px"`).replace(/height="[\d.]+ex"/, `height="${rectH}px"`), wrapped = `<svg xmlns="http://www.w3.org/2000/svg" color="${options.color}" width="${rectW}px" height="${rectH}px" viewBox="0 0 ${rectW} ${rectH}"><g transform="translate(0 ${offsetY.toFixed(2)})">${inner}</g></svg>`, pngInline = new Resvg(wrapped, { background: "rgba(0,0,0,0)" }).render().asPng();
15085
+ return !pngInline || pngInline.length < 8 ? null : {
15086
+ base64: base64FromBytes(pngInline),
15087
+ widthCells,
15088
+ heightCells: 1
15089
+ };
15090
+ }
15091
+ let widthPx = Math.max(1, Math.round(widthEx * exPx)), heightPx = Math.max(1, Math.round(heightEx * exPx));
15092
+ if (options.maxWidthCells > 0) {
15093
+ let maxPx = options.maxWidthCells * options.cellWidthPx * options.scale;
15094
+ widthPx > maxPx && (heightPx = Math.max(1, Math.round(heightPx * (maxPx / widthPx))), widthPx = maxPx);
15095
+ }
15096
+ svg = svg.replace(/style="vertical-align:[^"]*"/, "").replace(/width="[\d.]+ex"/, `width="${widthPx}px"`).replace(/height="[\d.]+ex"/, `height="${heightPx}px"`).replace(/<svg/, `<svg color="${options.color}"`);
15097
+ let png = new Resvg(svg, { background: "rgba(0,0,0,0)" }).render().asPng();
15098
+ return !png || png.length < 8 ? null : {
15099
+ base64: base64FromBytes(png),
15100
+ widthCells: Math.max(1, Math.round(widthPx / (options.cellWidthPx * options.scale))),
15101
+ heightCells: Math.max(1, Math.round(heightPx / (options.cellHeightPx * options.scale)))
15102
+ };
15103
+ };
15104
+ } catch {
15105
+ return null;
15106
+ }
15107
+ })()), builtinRasterizerLoad;
14972
15108
  }
14973
15109
 
14974
15110
  // node_modules/.pnpm/stream-markdown-parser@1.1.9/node_modules/stream-markdown-parser/dist/index.js
@@ -32196,17 +32332,26 @@ function inlineNodeSegments(nodes, theme, inheritedStyle, options = {}) {
32196
32332
  break;
32197
32333
  case "math_inline":
32198
32334
  {
32199
- let source = stringProp(node, "content"), raw = stringProp(node, "raw") || `$${source}$`, rendered = renderMarkdownInlineMathSegment(source);
32200
- pushTextSegments(
32335
+ let source = stringProp(node, "content"), markup = stringProp(node, "markup") || "$", raw = stringProp(node, "raw") || `${markup}${source}${markup}`, mathStyle = mergeStyle10(inheritedStyle, theme.inlineCode), tex = sanitizeInlineText(source), mathEnabled = options.math?.enabled !== !1, cached = tex && mathEnabled ? getCachedMarkdownMathImage(tex, "inline", options.math) : null;
32336
+ cached ? pushTextSegments(
32201
32337
  out,
32202
- rendered.supported ? rendered.text : raw,
32203
- mergeStyle10(inheritedStyle, theme.inlineCode),
32204
- void 0,
32338
+ raw,
32339
+ mathStyle,
32205
32340
  {
32206
- source,
32341
+ kind: "math",
32342
+ tex,
32207
32343
  raw,
32208
- rendered: rendered.supported
32209
- }
32344
+ base64: cached.base64,
32345
+ displayWidth: cached.widthCells,
32346
+ displayHeight: cached.heightCells
32347
+ },
32348
+ { source: tex, raw, rendered: !0 }
32349
+ ) : pushTextSegments(
32350
+ out,
32351
+ raw,
32352
+ mathStyle,
32353
+ void 0,
32354
+ tex && mathEnabled ? { source: tex, raw, rendered: !1, pendingImage: !0, mode: "inline" } : { source, raw, rendered: !1 }
32210
32355
  );
32211
32356
  }
32212
32357
  break;
@@ -32246,7 +32391,8 @@ function blockFromParagraph(node, key, context, theme) {
32246
32391
  key,
32247
32392
  inlineNodeSegments(nodeChildren(node), theme, void 0, {
32248
32393
  imageResolver: context.imageResolver,
32249
- imageSize: context.imageSize
32394
+ imageSize: context.imageSize,
32395
+ math: context.math
32250
32396
  }),
32251
32397
  context
32252
32398
  );
@@ -32257,7 +32403,8 @@ function blockFromHeading(node, key, context, theme) {
32257
32403
  key,
32258
32404
  inlineNodeSegments(nodeChildren(node), theme, theme.heading[level - 1], {
32259
32405
  imageResolver: context.imageResolver,
32260
- imageSize: context.imageSize
32406
+ imageSize: context.imageSize,
32407
+ math: context.math
32261
32408
  }),
32262
32409
  context
32263
32410
  );
@@ -32287,7 +32434,7 @@ function blockFromHtmlBlock(node, key, context, theme) {
32287
32434
  ],
32288
32435
  theme,
32289
32436
  void 0,
32290
- { imageResolver: context.imageResolver }
32437
+ { imageResolver: context.imageResolver, math: context.math }
32291
32438
  ),
32292
32439
  context
32293
32440
  );
@@ -32310,14 +32457,16 @@ function blockFromTable(node, key, context, theme) {
32310
32457
  ).map((cell) => ({
32311
32458
  segments: inlineNodeSegments(nodeChildren(cell), theme, theme.strong, {
32312
32459
  imageResolver: context.imageResolver,
32313
- imageSize: context.imageSize
32460
+ imageSize: context.imageSize,
32461
+ math: context.math
32314
32462
  }),
32315
32463
  align: tableCellAlign(cell)
32316
32464
  })), rows = tableRows(node, "rows").map(
32317
32465
  (row) => tableCells(row).map((cell) => ({
32318
32466
  segments: inlineNodeSegments(nodeChildren(cell), theme, void 0, {
32319
32467
  imageResolver: context.imageResolver,
32320
- imageSize: context.imageSize
32468
+ imageSize: context.imageSize,
32469
+ math: context.math
32321
32470
  }),
32322
32471
  align: tableCellAlign(cell)
32323
32472
  }))
@@ -32347,10 +32496,12 @@ function listItemBlocks(item, index, ordered, start, context, theme, keyPrefix)
32347
32496
  text: spaces(markerCells)
32348
32497
  }, firstContext = {
32349
32498
  prefixSegments: [...context.prefixSegments, markerSegment],
32350
- continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment]
32499
+ continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment],
32500
+ math: context.math
32351
32501
  }, nestedContext = {
32352
32502
  prefixSegments: [...context.continuationPrefixSegments, indentSegment],
32353
- continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment]
32503
+ continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment],
32504
+ math: context.math
32354
32505
  }, children = nodeChildren(item);
32355
32506
  if (!children.length)
32356
32507
  return [inlineBlock(`${keyPrefix}-empty`, [], firstContext)];
@@ -32389,6 +32540,37 @@ function listBlocks(node, context, theme, keyPrefix) {
32389
32540
  );
32390
32541
  return out;
32391
32542
  }
32543
+ function blockMathSegments(source, raw, math, theme) {
32544
+ let tex = sanitizeInlineText(source), canUseImage = !!tex && math.enabled !== !1, cached = canUseImage ? getCachedMarkdownMathImage(tex, "display", math) : null;
32545
+ if (canUseImage && cached)
32546
+ return [
32547
+ {
32548
+ text: raw,
32549
+ style: theme.math,
32550
+ graphic: {
32551
+ kind: "math",
32552
+ tex,
32553
+ raw,
32554
+ base64: cached.base64,
32555
+ displayWidth: cached.widthCells,
32556
+ displayHeight: cached.heightCells
32557
+ },
32558
+ mathAction: { source: tex, raw, rendered: !0 }
32559
+ }
32560
+ ];
32561
+ let maxWidth = Math.max(8, Math.floor(math.maxWidthCells ?? 0) || 40), rawCells = textCellWidth(raw), inner = Math.min(Math.max(1, rawCells + 2), maxWidth), pad = Math.max(0, inner - rawCells);
32562
+ return [
32563
+ { text: `\u250C${"\u2500".repeat(inner)}\u2510`, style: theme.math },
32564
+ HARD_BREAK_SEGMENT,
32565
+ {
32566
+ text: `\u2502 ${raw}${" ".repeat(pad)}\u2502`,
32567
+ style: theme.math,
32568
+ mathAction: { source: tex, raw, rendered: !1, pendingImage: !0 }
32569
+ },
32570
+ HARD_BREAK_SEGMENT,
32571
+ { text: `\u2514${"\u2500".repeat(inner)}\u2518`, style: theme.math }
32572
+ ];
32573
+ }
32392
32574
  function nodeToBlocks(node, context, theme, keyPrefix) {
32393
32575
  switch (node.type) {
32394
32576
  case "paragraph":
@@ -32413,6 +32595,19 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32413
32595
  prefixSegments: context.prefixSegments
32414
32596
  }
32415
32597
  ];
32598
+ case "math_block":
32599
+ return [
32600
+ inlineBlock(
32601
+ keyPrefix,
32602
+ blockMathSegments(
32603
+ stringProp(node, "content"),
32604
+ stringProp(node, "raw") || `$${stringProp(node, "content")}$`,
32605
+ context.math ?? { enabled: !0 },
32606
+ theme
32607
+ ),
32608
+ context
32609
+ )
32610
+ ];
32416
32611
  case "blockquote": {
32417
32612
  let quoteSegment = {
32418
32613
  text: "\u2502 ",
@@ -32421,7 +32616,8 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32421
32616
  prefixSegments: [...context.prefixSegments, quoteSegment],
32422
32617
  continuationPrefixSegments: [...context.continuationPrefixSegments, quoteSegment],
32423
32618
  imageResolver: context.imageResolver,
32424
- imageSize: context.imageSize
32619
+ imageSize: context.imageSize,
32620
+ math: context.math
32425
32621
  };
32426
32622
  return childSequenceToBlocks(nodeChildren(node), quoteContext, theme, keyPrefix);
32427
32623
  }
@@ -32437,7 +32633,8 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32437
32633
  keyPrefix,
32438
32634
  inlineNodeSegments(nodeChildren(node), theme, void 0, {
32439
32635
  imageResolver: context.imageResolver,
32440
- imageSize: context.imageSize
32636
+ imageSize: context.imageSize,
32637
+ math: context.math
32441
32638
  }),
32442
32639
  context
32443
32640
  )
@@ -32450,7 +32647,10 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32450
32647
  return [
32451
32648
  inlineBlock(
32452
32649
  keyPrefix,
32453
- inlineNodeSegments([node], theme, void 0, { imageResolver: context.imageResolver }),
32650
+ inlineNodeSegments([node], theme, void 0, {
32651
+ imageResolver: context.imageResolver,
32652
+ math: context.math
32653
+ }),
32454
32654
  context
32455
32655
  )
32456
32656
  ];
@@ -32458,7 +32658,10 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32458
32658
  return nodeChildren(node).length ? childSequenceToBlocks(nodeChildren(node), context, theme, keyPrefix) : [
32459
32659
  inlineBlock(
32460
32660
  keyPrefix,
32461
- inlineNodeSegments([node], theme, void 0, { imageResolver: context.imageResolver }),
32661
+ inlineNodeSegments([node], theme, void 0, {
32662
+ imageResolver: context.imageResolver,
32663
+ math: context.math
32664
+ }),
32462
32665
  context
32463
32666
  )
32464
32667
  ];
@@ -32471,7 +32674,8 @@ function markdownAstToBlocks(nodes, theme, options = {}) {
32471
32674
  prefixSegments: EMPTY_PREFIX,
32472
32675
  continuationPrefixSegments: EMPTY_PREFIX,
32473
32676
  imageResolver: options.imageResolver,
32474
- imageSize: options.imageSize
32677
+ imageSize: options.imageSize,
32678
+ math: options.math
32475
32679
  },
32476
32680
  theme,
32477
32681
  "md"
@@ -32592,7 +32796,8 @@ function wrapLineSegments(source, prefixSegments, continuationPrefixSegments, wi
32592
32796
  style: segment.style,
32593
32797
  cells,
32594
32798
  graphic: segment.graphic,
32595
- fallbackText: segment.text
32799
+ fallbackText: segment.text,
32800
+ ...segment.mathAction ? { mathAction: segment.mathAction } : {}
32596
32801
  }), row.remaining -= cells;
32597
32802
  continue;
32598
32803
  }
@@ -32818,7 +33023,8 @@ function styleSignature(style) {
32818
33023
  function inlineSegmentSignature(segment) {
32819
33024
  let graphic = segment.graphic ? [
32820
33025
  segment.graphic.kind,
32821
- segment.graphic.src,
33026
+ segment.graphic.src ?? "",
33027
+ segment.graphic.tex ?? "",
32822
33028
  segment.graphic.alt ?? "",
32823
33029
  segment.graphic.mime ?? "",
32824
33030
  segment.graphic.base64 ?? "",
@@ -32947,7 +33153,8 @@ var DEFAULT_HEADING = Object.freeze([
32947
33153
  listMarker: freezeStyle({ fg: "cyanBright", bold: !0 }),
32948
33154
  codeBlock: freezeStyle({ fg: "yellowBright" }),
32949
33155
  thematicBreak: freezeStyle({ dim: !0 }),
32950
- html: freezeStyle({ dim: !0 })
33156
+ html: freezeStyle({ dim: !0 }),
33157
+ math: freezeStyle({ fg: "cyanBright" })
32951
33158
  });
32952
33159
  function stableSerialize(value) {
32953
33160
  return value == null ? "null" : typeof value != "object" ? JSON.stringify(value) : Array.isArray(value) ? `[${value.map((item) => stableSerialize(item)).join(",")}]` : `{${Object.entries(value).sort(
@@ -32980,7 +33187,8 @@ function resolveTuiMarkdownTheme(overrides) {
32980
33187
  DEFAULT_TUI_MARKDOWN_THEME.thematicBreak,
32981
33188
  overrides.thematicBreak
32982
33189
  ),
32983
- html: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.html, overrides.html)
33190
+ html: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.html, overrides.html),
33191
+ math: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.math, overrides.math)
32984
33192
  });
32985
33193
  }
32986
33194
 
@@ -32990,7 +33198,8 @@ function buildMarkdownBlocks(content, parser, options) {
32990
33198
  try {
32991
33199
  let nodes = parser.parse(content, options?.final ?? !0), blocks = markdownAstToBlocks(nodes, theme, {
32992
33200
  imageResolver: options?.imageResolver,
32993
- imageSize: options?.imageSize
33201
+ imageSize: options?.imageSize,
33202
+ math: options?.math
32994
33203
  });
32995
33204
  return { nodes, blocks };
32996
33205
  } catch (error) {
@@ -33136,11 +33345,11 @@ function findMarkdownMathActionAt(rows, point, options) {
33136
33345
  let math = segment.mathAction;
33137
33346
  if (!math || segmentEnd <= clipStart || segmentStart >= clipEnd)
33138
33347
  continue;
33139
- let visibleStart = Math.max(segmentStart, clipStart), visibleEnd = Math.min(segmentEnd, clipEnd), rect = {
33348
+ let visibleStart = Math.max(segmentStart, clipStart), visibleEnd = Math.min(segmentEnd, clipEnd), graphicHeight = segment.graphic ? Math.max(1, Math.floor(segment.graphic.displayHeight ?? 1)) : 1, rect = {
33140
33349
  x: r.x + visibleStart - clipStart,
33141
33350
  y: r.y + rowIndex - firstRow,
33142
33351
  w: visibleEnd - visibleStart,
33143
- h: 1
33352
+ h: graphicHeight
33144
33353
  };
33145
33354
  if (!(point.cellX < rect.x || point.cellY < rect.y || point.cellX >= rect.x + rect.w || point.cellY >= rect.y + rect.h))
33146
33355
  return {
@@ -33156,6 +33365,70 @@ function findMarkdownMathActionAt(rows, point, options) {
33156
33365
  return null;
33157
33366
  }
33158
33367
 
33368
+ // src/vue/markdown/math.ts
33369
+ var katexListeners = /* @__PURE__ */ new Set();
33370
+ function subscribeMarkdownMathRenderer(listener) {
33371
+ return katexListeners.add(listener), () => katexListeners.delete(listener);
33372
+ }
33373
+ var KATEX_TEXT_OPTIONS = Object.freeze({
33374
+ output: "mathml",
33375
+ throwOnError: !1,
33376
+ strict: "ignore",
33377
+ trust: !1,
33378
+ maxSize: 20,
33379
+ maxExpand: 200
33380
+ }), KATEX_VALIDATE_OPTIONS = Object.freeze({
33381
+ ...KATEX_TEXT_OPTIONS,
33382
+ throwOnError: !0
33383
+ }), TEX_SYMBOLS = Object.freeze({
33384
+ alpha: "\u03B1",
33385
+ beta: "\u03B2",
33386
+ gamma: "\u03B3",
33387
+ delta: "\u03B4",
33388
+ epsilon: "\u03B5",
33389
+ theta: "\u03B8",
33390
+ lambda: "\u03BB",
33391
+ mu: "\u03BC",
33392
+ pi: "\u03C0",
33393
+ rho: "\u03C1",
33394
+ sigma: "\u03C3",
33395
+ tau: "\u03C4",
33396
+ phi: "\u03C6",
33397
+ omega: "\u03C9",
33398
+ Gamma: "\u0393",
33399
+ Delta: "\u0394",
33400
+ Theta: "\u0398",
33401
+ Lambda: "\u039B",
33402
+ Pi: "\u03A0",
33403
+ Sigma: "\u03A3",
33404
+ Phi: "\u03A6",
33405
+ Omega: "\u03A9",
33406
+ int: "\u222B",
33407
+ sum: "\u2211",
33408
+ prod: "\u220F",
33409
+ infty: "\u221E",
33410
+ infinity: "\u221E",
33411
+ pm: "\xB1",
33412
+ times: "\xD7",
33413
+ cdot: "\xB7",
33414
+ div: "\xF7",
33415
+ le: "\u2264",
33416
+ leq: "\u2264",
33417
+ ge: "\u2265",
33418
+ geq: "\u2265",
33419
+ neq: "\u2260",
33420
+ ne: "\u2260",
33421
+ approx: "\u2248",
33422
+ equiv: "\u2261",
33423
+ to: "\u2192",
33424
+ rightarrow: "\u2192",
33425
+ leftarrow: "\u2190",
33426
+ leftrightarrow: "\u2194",
33427
+ partial: "\u2202",
33428
+ nabla: "\u2207",
33429
+ sqrt: "\u221A"
33430
+ }), SUPPORTED_COMMANDS = /* @__PURE__ */ new Set([...Object.keys(TEX_SYMBOLS), "frac", "sqrt"]);
33431
+
33159
33432
  // src/utils/env.ts
33160
33433
  function firstNonEmptyEnv(env, primary, legacy) {
33161
33434
  let primaryValue = env?.[primary];
@@ -33261,7 +33534,7 @@ function mergeStyle11(base, overlay) {
33261
33534
  var activeMarkdownImageGraphics = /* @__PURE__ */ new WeakMap();
33262
33535
  function markdownImageGraphicId(segment, identity) {
33263
33536
  return `md-image:${stableTerminalGraphicNumericId(
33264
- `${identity}:${segment.src}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`
33537
+ `${identity}:${segment.src ?? segment.tex ?? ""}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`
33265
33538
  )}`;
33266
33539
  }
33267
33540
  function rememberMarkdownImageGraphic(terminal, id, rect) {
@@ -33282,7 +33555,7 @@ function clearStaleMarkdownImageGraphicsForRow(terminal, y, keepIds, keepVisible
33282
33555
  !(keepVisibleIds ? y >= rect.y && y < rect.y + rect.h : rect.y === y) || keepIds.has(id) || keepVisibleIds?.has(id) || clearTrackedMarkdownImageGraphic(terminal, id);
33283
33556
  }
33284
33557
  function canAttemptMarkdownImageGraphic(terminal, segment) {
33285
- if (segment.kind !== "image" || !segment.base64)
33558
+ if (!segment.base64)
33286
33559
  return !1;
33287
33560
  let output = getTerminalGraphicsOutput(terminal), protocol = output?.capabilities.preferredProtocol;
33288
33561
  return !!(output?.capabilities.supported && isTerminalGraphicsProtocol(protocol));
@@ -33294,7 +33567,7 @@ function clearMarkdownImageGraphics(terminal, rect) {
33294
33567
  rect && (item.x >= rect.x + rect.w || item.x + item.w <= rect.x || item.y >= rect.y + rect.h || item.y + item.h <= rect.y) || clearTrackedMarkdownImageGraphic(terminal, id);
33295
33568
  }
33296
33569
  function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
33297
- if (segment.kind !== "image" || !segment.base64)
33570
+ if (!segment.base64)
33298
33571
  return "unavailable";
33299
33572
  let output = getTerminalGraphicsOutput(terminal), protocol = output?.capabilities.preferredProtocol;
33300
33573
  if (!output?.capabilities.supported || !isTerminalGraphicsProtocol(protocol))
@@ -33331,7 +33604,7 @@ function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
33331
33604
  sequence,
33332
33605
  resizeSequence,
33333
33606
  clearSequence,
33334
- fallbackText: segment.alt ?? "image"
33607
+ fallbackText: segment.alt ?? (segment.kind === "math" ? segment.raw ?? segment.tex ?? "math" : "image")
33335
33608
  });
33336
33609
  return markdownImageDebug(
33337
33610
  `queue id=${id}`,
@@ -33416,7 +33689,7 @@ function paintMarkdownVisualRow(terminal, row, options) {
33416
33689
  }), graphicAvailable = queueResult || canAttemptMarkdownImageGraphic(terminal, segment.graphic), queuedGraphic = queueResult === "queued", suppressFallback = queuedGraphic || queueResult === "rejected" || graphicAvailable === !0;
33417
33690
  queuedGraphic && queuedGraphics.add(markdownImageGraphicId(segment.graphic, `${row.key}:${segmentIndex}`)), terminal.write(
33418
33691
  suppressFallback ? spaces(visibleCells) : sliceByCellsRange(
33419
- segment.fallbackText ?? segment.graphic.alt ?? "image",
33692
+ segment.fallbackText ?? segment.graphic.alt ?? (segment.graphic.kind === "math" ? segment.graphic.raw ?? segment.graphic.tex ?? "math" : "image"),
33420
33693
  0,
33421
33694
  visibleCells
33422
33695
  ) || spaces(visibleCells),
@@ -33549,6 +33822,13 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33549
33822
  imageMinHeight: { type: Number, default: void 0 },
33550
33823
  imageMaxHeight: { type: Number, default: void 0 },
33551
33824
  imagePreserveAspectRatio: { type: Boolean, default: !0 },
33825
+ mathImages: { type: Boolean, default: !0 },
33826
+ mathCellWidthPx: { type: Number, default: void 0 },
33827
+ mathCellHeightPx: { type: Number, default: void 0 },
33828
+ mathScale: { type: Number, default: void 0 },
33829
+ mathColor: { type: String, default: void 0 },
33830
+ mathMaxWidthCells: { type: Number, default: void 0 },
33831
+ mathBaselineRatio: { type: Number, default: void 0 },
33552
33832
  imageActions: { type: Boolean, default: !1 },
33553
33833
  mathActions: { type: Boolean, default: !1 },
33554
33834
  linkActions: { type: Boolean, default: !1 },
@@ -33576,10 +33856,41 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33576
33856
  })
33577
33857
  )
33578
33858
  ), graphicsOutputVersion = (0, import_vue33.shallowRef)(getTerminalGraphicsOutputVersion(terminal)), unsubscribeGraphicsOutput = subscribeTerminalGraphicsOutput(terminal, () => {
33579
- graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal);
33859
+ graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal), enqueuePendingMathImages();
33580
33860
  }), unsubscribeMathRenderer = subscribeMarkdownMathRenderer(() => {
33581
33861
  scheduleRebuild();
33862
+ }), unsubscribeMathImage = subscribeMarkdownMathImage(() => {
33863
+ scheduleRebuild();
33582
33864
  });
33865
+ function mathOptions() {
33866
+ if (props.mathImages === !1)
33867
+ return { enabled: !1 };
33868
+ let resolvedColor = props.mathColor ?? resolveMarkdownMathColor(defaultStyle.value.fg);
33869
+ return {
33870
+ enabled: !0,
33871
+ ...props.mathCellWidthPx != null ? { cellWidthPx: props.mathCellWidthPx } : {},
33872
+ ...props.mathCellHeightPx != null ? { cellHeightPx: props.mathCellHeightPx } : {},
33873
+ ...props.mathScale != null ? { scale: props.mathScale } : {},
33874
+ ...resolvedColor != null ? { color: resolvedColor } : {},
33875
+ ...props.mathBaselineRatio != null ? { baselineRatio: props.mathBaselineRatio } : {},
33876
+ maxWidthCells: props.mathMaxWidthCells ?? props.w
33877
+ };
33878
+ }
33879
+ function enqueuePendingMathImages() {
33880
+ if (props.mathImages === !1 || !getTerminalGraphicsOutput(terminal)?.capabilities.supported)
33881
+ return;
33882
+ if (!isMarkdownMathImageRendererReady()) {
33883
+ loadMarkdownMathImageRenderer().then((ready) => {
33884
+ ready && alive && scheduleRebuild();
33885
+ });
33886
+ return;
33887
+ }
33888
+ let h26 = Math.max(0, Math.floor(props.h ?? absRect.value.h));
33889
+ enqueueMarkdownMathImages(rows.value, mathOptions(), {
33890
+ firstRow: internalScrollTop.value,
33891
+ lastRow: internalScrollTop.value + h26
33892
+ });
33893
+ }
33583
33894
  (0, import_vue33.watch)(
33584
33895
  () => `${props.streaming ? 1 : 0}:${(props.customHtmlTags ?? []).join("\0")}`,
33585
33896
  () => {
@@ -33603,13 +33914,14 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33603
33914
  minHeight: props.imageMinHeight,
33604
33915
  maxHeight: props.imageMaxHeight,
33605
33916
  preserveAspectRatio: props.imagePreserveAspectRatio
33606
- }
33917
+ },
33918
+ math: mathOptions()
33607
33919
  }).blocks;
33608
33920
  return layoutMarkdownBlocksCached(blocks, props.w, layoutCache);
33609
33921
  });
33610
33922
  layoutCache = (0, import_vue33.markRaw)(nextLayout.cache);
33611
33923
  let nextRows = nextLayout.rows;
33612
- rows.value = (0, import_vue33.markRaw)(nextRows), reconcileScrollTop();
33924
+ rows.value = (0, import_vue33.markRaw)(nextRows), enqueuePendingMathImages(), reconcileScrollTop();
33613
33925
  let nextScrollTop = internalScrollTop.value, nextVisibleRows = visibleRowSignatures(nextRows, nextScrollTop), nextVisibleGraphics = visibleRowGraphics(nextRows, nextScrollTop), visibleChanged = prevVisibleRows.length !== nextVisibleRows.length || prevVisibleRows.some((row, index) => row !== nextVisibleRows[index]) || prevVisibleGraphics.some((row, index) => row !== nextVisibleGraphics[index]);
33614
33926
  (!builtOnce || prevScrollTop !== nextScrollTop || visibleChanged) && (documentVersion.value++, selection.refresh());
33615
33927
  }
@@ -33691,7 +34003,9 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33691
34003
  let remap = pendingSelectionScrollFocusRemap;
33692
34004
  pendingSelectionScrollFocusRemap = !1, applyControlledScrollTop(props.scrollTop, remap);
33693
34005
  }
33694
- ), (0, import_vue33.watch)(
34006
+ ), (0, import_vue33.watch)(internalScrollTop, () => {
34007
+ enqueuePendingMathImages();
34008
+ }), (0, import_vue33.watch)(
33695
34009
  [
33696
34010
  () => props.content,
33697
34011
  () => props.blocks,
@@ -33704,7 +34018,14 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33704
34018
  () => props.imageMaxWidth,
33705
34019
  () => props.imageMinHeight,
33706
34020
  () => props.imageMaxHeight,
33707
- () => props.imagePreserveAspectRatio
34021
+ () => props.imagePreserveAspectRatio,
34022
+ () => props.mathImages,
34023
+ () => props.mathCellWidthPx,
34024
+ () => props.mathCellHeightPx,
34025
+ () => props.mathScale,
34026
+ () => props.mathColor,
34027
+ () => props.mathMaxWidthCells,
34028
+ () => props.mathBaselineRatio
33708
34029
  ],
33709
34030
  () => {
33710
34031
  scheduleRebuild();
@@ -33885,7 +34206,7 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33885
34206
  let manager = events.value, nodeId = eventNode.id.value;
33886
34207
  nodeId && manager && manager.getFocused() !== nodeId && manager.focus(nodeId);
33887
34208
  }), (0, import_vue33.onBeforeUnmount)(() => {
33888
- alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), clearMarkdownImageGraphics(terminal, fullRect.value);
34209
+ alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), unsubscribeMathImage(), clearMarkdownImageGraphics(terminal, fullRect.value);
33889
34210
  }), useRenderNode(() => ({
33890
34211
  zIndex: props.zIndex,
33891
34212
  rect: visible.value ? normalizedRect() : { x: 0, y: 0, w: 0, h: 0 },
@@ -34867,29 +35188,6 @@ function normalizeCachedPngFrame(frame, context) {
34867
35188
  sourceHeight: dimensions?.height
34868
35189
  };
34869
35190
  }
34870
- function resolveKittyViewportPlacement(png, context) {
34871
- let rect = context.viewport.rect, full = context.viewport.fullRect, columns = positiveInt2(rect.w) ?? png.cols, rows = positiveInt2(rect.h) ?? png.rows, sourceWidth = positiveInt2(png.sourceWidth), sourceHeight = positiveInt2(png.sourceHeight);
34872
- if (!sourceWidth || !sourceHeight || full.w <= 0 || full.h <= 0)
34873
- return { columns, rows };
34874
- let offsetX = Math.max(0, rect.x - full.x), offsetY = Math.max(0, rect.y - full.y), visibleW = Math.max(0, Math.min(rect.w, full.w - offsetX)), visibleH = Math.max(0, Math.min(rect.h, full.h - offsetY));
34875
- if (offsetX <= 0 && offsetY <= 0 && visibleW >= full.w && visibleH >= full.h)
34876
- return { columns, rows };
34877
- let x0 = Math.max(0, Math.min(sourceWidth - 1, Math.floor(offsetX * sourceWidth / full.w))), y0 = Math.max(0, Math.min(sourceHeight - 1, Math.floor(offsetY * sourceHeight / full.h))), x1 = Math.max(
34878
- x0 + 1,
34879
- Math.min(sourceWidth, Math.ceil((offsetX + visibleW) * sourceWidth / full.w))
34880
- ), y1 = Math.max(
34881
- y0 + 1,
34882
- Math.min(sourceHeight, Math.ceil((offsetY + visibleH) * sourceHeight / full.h))
34883
- );
34884
- return {
34885
- columns,
34886
- rows,
34887
- sourceX: x0,
34888
- sourceY: y0,
34889
- sourceWidth: x1 - x0,
34890
- sourceHeight: y1 - y0
34891
- };
34892
- }
34893
35191
  function pngFrameBytes(frame) {
34894
35192
  return frame.base64.length + (frame.fallback?.length ?? 0);
34895
35193
  }
@@ -34942,50 +35240,24 @@ function createPngTerminalGraphicRenderer(options) {
34942
35240
  };
34943
35241
  if (!png.base64)
34944
35242
  return textFallbackResult(await fallback());
34945
- if (protocol === "kitty") {
34946
- let placement = resolveKittyViewportPlacement(png, context), sequence = createKittyGraphicsSequence(png.base64, {
34947
- imageId: context.imageId,
34948
- placementId: context.placementId,
34949
- zIndex: options.zIndex,
34950
- ...placement
34951
- }), resizeSequence = createKittyPlacementSequence({
35243
+ if (protocol === "kitty" || protocol === "iterm2") {
35244
+ let rect = context.viewport.rect, fullRect = context.viewport.fullRect, result = createTerminalGraphicPngSequence({
35245
+ protocol,
35246
+ base64: png.base64,
34952
35247
  imageId: context.imageId,
34953
35248
  placementId: context.placementId,
34954
- zIndex: options.zIndex,
34955
- ...placement
34956
- });
34957
- return isSafeTerminalGraphicsSequence(sequence, "kitty", "draw") ? {
34958
- type: "sequence",
34959
- protocol: "kitty",
34960
- sequence,
34961
- resizeSequence,
34962
- clearSequence: createKittyDeleteGraphicsSequence({
34963
- imageId: context.imageId,
34964
- placementId: context.placementId
34965
- }),
34966
- ...await sequenceFallback(),
34967
35249
  cols: png.cols,
34968
35250
  rows: png.rows,
34969
35251
  sourceWidth: png.sourceWidth,
34970
35252
  sourceHeight: png.sourceHeight,
34971
- zIndex: options.zIndex
34972
- } : textFallbackResult(await fallback());
34973
- }
34974
- if (protocol === "iterm2") {
34975
- let sequence = createIterm2InlineImageSequence(png.base64, {
34976
- width: png.cols,
34977
- height: png.rows,
34978
- preserveAspectRatio: !0,
34979
- doNotMoveCursor: !0
35253
+ placementColumns: positiveInt2(rect.w) ?? png.cols,
35254
+ placementRows: positiveInt2(rect.h) ?? png.rows,
35255
+ rect,
35256
+ fullRect,
35257
+ zIndex: options.zIndex,
35258
+ fallback: await fallback()
34980
35259
  });
34981
- return isSafeTerminalGraphicsSequence(sequence, "iterm2", "draw") ? {
34982
- type: "sequence",
34983
- protocol: "iterm2",
34984
- sequence,
34985
- ...await sequenceFallback(),
34986
- cols: png.cols,
34987
- rows: png.rows
34988
- } : textFallbackResult(await fallback());
35260
+ return result ? isSafeTerminalGraphicsSequence(result.sequence, protocol, "draw") ? result : textFallbackResult(await fallback()) : textFallbackResult(await fallback());
34989
35261
  }
34990
35262
  if (protocol === "sixel") {
34991
35263
  let sixel = await queue.cached(