@simon_he/vue-tui 1.1.3 → 1.1.5

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 (52) hide show
  1. package/README.md +18 -18
  2. package/dist/{TMermaidText-frVr8Ysb.js → TMermaidText-wLnMMvVS.js} +1 -1
  3. package/dist/{TSelect-Dx34M1pF.js → TSelect-CMBOOFwK.js} +5 -5
  4. package/dist/{TTree-DdAjCPHu.js → TTree-kk8ntrpg.js} +6 -5
  5. package/dist/agent/mermaid.d.cts +2 -2
  6. package/dist/agent/mermaid.d.ts +2 -2
  7. package/dist/agent.cjs +542 -266
  8. package/dist/agent.js +25 -82
  9. package/dist/{block-source-Crro3mxi.js → block-source-DhzajB9H.js} +299 -239
  10. package/dist/cli.cjs +57 -16
  11. package/dist/cli.js +70 -15
  12. package/dist/core.js +3 -3
  13. package/dist/{hyperlink-_1FAj7Wq.js → create-terminal-Db_-UGVQ.js} +474 -102
  14. package/dist/{dom-renderer-DXx8fWzD.js → dom-renderer-BfwAEQMf.js} +3 -2
  15. package/dist/experimental.cjs +103 -66
  16. package/dist/experimental.js +20 -74
  17. package/dist/hyperlink-clbb_ha_.js +100 -0
  18. package/dist/index.js +8 -8
  19. package/dist/{linkify-BjI4zVfY.js → linkify-CL9wwnZN.js} +3 -3
  20. package/dist/markdown.cjs +521 -212
  21. package/dist/markdown.d.cts +3 -0
  22. package/dist/markdown.d.ts +3 -0
  23. package/dist/markdown.js +75 -8
  24. package/dist/math-image-BZhmfUeu.js +308 -0
  25. package/dist/mermaid-N3kGTHFy.js +1697 -0
  26. package/dist/mermaid.cjs +1460 -6
  27. package/dist/mermaid.d.cts +4 -0
  28. package/dist/mermaid.d.ts +4 -0
  29. package/dist/mermaid.js +7 -5
  30. package/dist/{rect-DUpeDfBg.js → rect-JzWMJxxc.js} +1 -1
  31. package/dist/renderer/cli/stdout-renderer.d.ts +44 -0
  32. package/dist/renderer/terminal-graphics.d.ts +61 -0
  33. package/dist/renderer-dom.js +4 -4
  34. package/dist/{terminal-graphics-Bbe83wSr.js → terminal-graphics-2FTRg9x3.js} +90 -2
  35. package/dist/{tlog-theme-i6S_Oftd.js → tlog-theme-B91Wv7Zj.js} +5 -4
  36. package/dist/vue/components/TAgentTerminalGraphic.d.ts +1 -1
  37. package/dist/vue/components/TMarkdownText.d.ts +70 -2
  38. package/dist/vue/components/TMermaidImage.d.ts +920 -0
  39. package/dist/vue/components/TMermaidText.d.ts +2 -2
  40. package/dist/vue/components/TVirtualMarkdown.d.ts +70 -2
  41. package/dist/vue/markdown/ast.d.ts +5 -0
  42. package/dist/vue/markdown/document.d.ts +3 -0
  43. package/dist/vue/markdown/math-image.d.ts +68 -0
  44. package/dist/vue/markdown/theme.d.ts +12 -0
  45. package/dist/vue/markdown/types.d.ts +12 -2
  46. package/dist/vue/mermaid/beautiful-mermaid.d.ts +284 -240
  47. package/dist/vue/mermaid/mermaid-image.d.ts +73 -0
  48. package/dist/vue.js +9 -9
  49. package/package.json +24 -10
  50. package/dist/mermaid-BNhM1jAZ.js +0 -123
  51. package/dist/width-GqllnV8C.js +0 -474
  52. /package/dist/{ansi-palette-CH6jc2Z7.js → ansi-palette-BHF1rN7R.js} +0 -0
package/dist/agent.cjs CHANGED
@@ -6152,6 +6152,95 @@ 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
+ let transmissionPlacement = options.cropTransmission !== !1 ? placement : {
6197
+ columns: options.transmissionColumns ?? options.placementColumns,
6198
+ rows: options.transmissionRows ?? options.placementRows
6199
+ };
6200
+ return {
6201
+ type: "sequence",
6202
+ protocol: "kitty",
6203
+ sequence: createKittyGraphicsSequence(options.base64, {
6204
+ imageId: options.imageId,
6205
+ placementId: options.placementId,
6206
+ zIndex: options.zIndex,
6207
+ ...transmissionPlacement
6208
+ }),
6209
+ resizeSequence: createKittyPlacementSequence({
6210
+ imageId: options.imageId,
6211
+ placementId: options.placementId,
6212
+ zIndex: options.zIndex,
6213
+ ...placement
6214
+ }),
6215
+ clearSequence: createKittyDeleteGraphicsSequence({
6216
+ imageId: options.imageId,
6217
+ placementId: options.placementId,
6218
+ freeImageData: options.freeImageData
6219
+ }),
6220
+ ...options.fallback != null ? { fallback: options.fallback } : {},
6221
+ ...options.cols != null ? { cols: options.cols } : {},
6222
+ ...options.rows != null ? { rows: options.rows } : {},
6223
+ ...options.sourceWidth != null ? { sourceWidth: options.sourceWidth } : {},
6224
+ ...options.sourceHeight != null ? { sourceHeight: options.sourceHeight } : {},
6225
+ ...options.zIndex != null ? { zIndex: options.zIndex } : {}
6226
+ };
6227
+ }
6228
+ return options.protocol === "iterm2" ? {
6229
+ type: "sequence",
6230
+ protocol: "iterm2",
6231
+ sequence: createIterm2InlineImageSequence(options.base64, {
6232
+ width: options.cols,
6233
+ height: options.rows,
6234
+ preserveAspectRatio: !0,
6235
+ doNotMoveCursor: !0
6236
+ }),
6237
+ ...options.fallback != null ? { fallback: options.fallback } : {},
6238
+ ...options.cols != null ? { cols: options.cols } : {},
6239
+ ...options.rows != null ? { rows: options.rows } : {},
6240
+ ...options.sourceWidth != null ? { sourceWidth: options.sourceWidth } : {},
6241
+ ...options.sourceHeight != null ? { sourceHeight: options.sourceHeight } : {}
6242
+ } : null;
6243
+ }
6155
6244
 
6156
6245
  // src/vue/components/TAgentTerminalGraphic.ts
6157
6246
  var NO_GRAPHICS_CAPABILITIES = Object.freeze({
@@ -14790,185 +14879,236 @@ function readMarkdownImageDimensions(base64) {
14790
14879
  return null;
14791
14880
  }
14792
14881
 
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;
14882
+ // src/vue/markdown/math-image.ts
14883
+ var DEFAULT_MATH_IMAGE_OPTIONS = Object.freeze({
14884
+ cellWidthPx: 8,
14885
+ cellHeightPx: 16,
14886
+ scale: 2,
14887
+ color: "#f8f8f2",
14888
+ maxWidthCells: 0,
14889
+ baselineRatio: 0.78
14890
+ }), 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({
14891
+ black: "#000000",
14892
+ red: "#e53935",
14893
+ green: "#43a047",
14894
+ yellow: "#fdd835",
14895
+ blue: "#1e88e5",
14896
+ magenta: "#d81b60",
14897
+ cyan: "#00acc1",
14898
+ white: "#ffffff",
14899
+ gray: "#9e9e9e",
14900
+ grey: "#9e9e9e",
14901
+ blackBright: "#4a4a4a",
14902
+ redBright: "#ff6e6e",
14903
+ greenBright: "#69db7c",
14904
+ yellowBright: "#ffe066",
14905
+ blueBright: "#74c0fc",
14906
+ magentaBright: "#f783ac",
14907
+ cyanBright: "#3bc9db",
14908
+ whiteBright: "#f8f8f2",
14909
+ grayBright: "#bdbdbd",
14910
+ greyBright: "#bdbdbd"
14911
+ });
14912
+ function resolveMarkdownMathColor(fg) {
14913
+ if (typeof fg != "string" || !fg)
14914
+ return;
14915
+ let trimmed = fg.trim();
14916
+ return trimmed.startsWith("#") && /^#[0-9a-f]{3,8}$/i.test(trimmed) ? trimmed.toLowerCase() : NAMED_STYLE_FG_HEX[trimmed.toLowerCase()];
14800
14917
  }
14801
- function subscribeMarkdownMathRenderer(listener) {
14802
- return katexListeners.add(listener), () => katexListeners.delete(listener);
14918
+ function normalizeMathImageOptions(options) {
14919
+ return {
14920
+ cellWidthPx: Math.max(
14921
+ 1,
14922
+ Math.floor(options?.cellWidthPx ?? DEFAULT_MATH_IMAGE_OPTIONS.cellWidthPx)
14923
+ ),
14924
+ cellHeightPx: Math.max(
14925
+ 1,
14926
+ Math.floor(options?.cellHeightPx ?? DEFAULT_MATH_IMAGE_OPTIONS.cellHeightPx)
14927
+ ),
14928
+ scale: Math.max(1, Math.floor(options?.scale ?? DEFAULT_MATH_IMAGE_OPTIONS.scale)),
14929
+ color: options?.color ?? DEFAULT_MATH_IMAGE_OPTIONS.color,
14930
+ maxWidthCells: Math.max(0, Math.floor(options?.maxWidthCells ?? 0)),
14931
+ baselineRatio: clamp01(options?.baselineRatio ?? DEFAULT_MATH_IMAGE_OPTIONS.baselineRatio)
14932
+ };
14803
14933
  }
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);
14934
+ function clamp01(value) {
14935
+ return Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 0.78;
14814
14936
  }
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
- });
14937
+ function subscribeMarkdownMathImage(listener) {
14938
+ return mathImageListeners.add(listener), () => mathImageListeners.delete(listener);
14894
14939
  }
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();
14940
+ function isMarkdownMathImageRendererReady() {
14941
+ return customRasterizer != null || builtinRasterizerReady;
14905
14942
  }
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()
14943
+ async function loadMarkdownMathImageRenderer() {
14944
+ return isMarkdownMathImageRendererReady() ? !0 : (builtinRasterizerReady = (customRasterizer ?? await loadBuiltinMathRasterizer()) != null, builtinRasterizerReady);
14945
+ }
14946
+ function hashMathImageKey(value) {
14947
+ let hash = 2166136261;
14948
+ for (let i = 0; i < value.length; i++)
14949
+ hash ^= value.charCodeAt(i), hash = Math.imul(hash, 16777619);
14950
+ return (hash >>> 0).toString(36);
14951
+ }
14952
+ function mathImageCacheKey(tex, mode, options) {
14953
+ return hashMathImageKey(
14954
+ [
14955
+ mode,
14956
+ tex,
14957
+ options.cellWidthPx,
14958
+ options.cellHeightPx,
14959
+ options.scale,
14960
+ options.maxWidthCells,
14961
+ options.color,
14962
+ options.baselineRatio
14963
+ ].join("")
14928
14964
  );
14929
14965
  }
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, ""));
14966
+ function notifyMathImageListeners() {
14967
+ for (let listener of mathImageListeners)
14968
+ try {
14969
+ listener();
14970
+ } catch {
14971
+ }
14972
+ }
14973
+ function getCachedMarkdownMathImage(tex, mode, options) {
14974
+ return mathImageCache.get(mathImageCacheKey(tex, mode, normalizeMathImageOptions(options))) ?? null;
14975
+ }
14976
+ function evictOldestMathImageEntry() {
14977
+ let oldest = mathImageCache.keys().next().value;
14978
+ oldest != null && mathImageCache.delete(oldest);
14936
14979
  }
14937
- function canRenderTerminalMath(tex, katex) {
14980
+ async function getMarkdownMathImage(tex, mode, options) {
14938
14981
  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;
14982
+ if (!source)
14983
+ return null;
14984
+ let normalized = normalizeMathImageOptions(options), key = mathImageCacheKey(source, mode, normalized), cached = mathImageCache.get(key);
14985
+ if (cached)
14986
+ return cached;
14987
+ if (mathImageFailed.has(key))
14988
+ return null;
14989
+ let inflight = mathImageInflight.get(key);
14990
+ if (inflight)
14991
+ return inflight;
14992
+ let pending = (async () => {
14993
+ try {
14994
+ let rasterizer = customRasterizer ?? await loadBuiltinMathRasterizer();
14995
+ if (!rasterizer)
14996
+ return null;
14997
+ let result = await rasterizer(source, mode, normalized);
14998
+ if (result && result.base64)
14999
+ mathImageCache.set(key, result), mathImageCache.size > MAX_CACHE_ENTRIES && evictOldestMathImageEntry(), notifyMathImageListeners();
15000
+ else if (result === null && (mathImageFailed.add(key), mathImageFailed.size > MAX_FAILED_ENTRIES)) {
15001
+ let oldest = mathImageFailed.values().next().value;
15002
+ oldest != null && mathImageFailed.delete(oldest);
15003
+ }
15004
+ return result;
15005
+ } catch {
15006
+ return null;
15007
+ } finally {
15008
+ mathImageInflight.delete(key);
15009
+ }
15010
+ })();
15011
+ return mathImageInflight.set(key, pending), pending;
15012
+ }
15013
+ function enqueueMarkdownMathImages(rows, options, viewport) {
15014
+ let first = Math.max(0, Math.floor(viewport?.firstRow ?? 0)), last = Math.min(rows.length, Math.max(first, Math.ceil(viewport?.lastRow ?? rows.length)));
15015
+ for (let index = first; index < last; index++) {
15016
+ let row = rows[index];
15017
+ if (row)
15018
+ for (let segment of row.segments) {
15019
+ let graphic = segment.graphic;
15020
+ if (graphic?.kind === "math") {
15021
+ !graphic.base64 && graphic.tex && getMarkdownMathImage(graphic.tex, "display", options);
15022
+ continue;
15023
+ }
15024
+ segment.mathAction?.pendingImage && segment.mathAction?.source && getMarkdownMathImage(
15025
+ segment.mathAction.source,
15026
+ segment.mathAction.mode ?? "display",
15027
+ options
15028
+ );
15029
+ }
14951
15030
  }
14952
- return !0;
14953
15031
  }
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 };
15032
+ function base64FromBytes(bytes) {
15033
+ let binary = "";
15034
+ for (let offset = 0; offset < bytes.length; offset += 32768)
15035
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 32768));
15036
+ return typeof btoa == "function" ? btoa(binary) : Buffer.from(bytes).toString("base64");
15037
+ }
15038
+ function extractSvgMarkup(containerMarkup) {
15039
+ let start = containerMarkup.indexOf("<svg");
15040
+ if (start < 0)
15041
+ return "";
15042
+ let end = containerMarkup.lastIndexOf("</svg>");
15043
+ return end < start ? "" : containerMarkup.slice(start, end + 6);
15044
+ }
15045
+ var RESVG_MODULE_ID = "@resvg/resvg-js";
15046
+ function loadBuiltinMathRasterizer() {
15047
+ return builtinRasterizerLoad || (builtinRasterizerLoad = (async () => {
15048
+ try {
15049
+ let [
15050
+ { mathjax },
15051
+ { TeX },
15052
+ { SVG },
15053
+ { liteAdaptor },
15054
+ { RegisterHTMLHandler },
15055
+ { AllPackages },
15056
+ { Resvg }
15057
+ ] = await Promise.all([
15058
+ import("mathjax-full/js/mathjax.js"),
15059
+ import("mathjax-full/js/input/tex.js"),
15060
+ import("mathjax-full/js/output/svg.js"),
15061
+ import("mathjax-full/js/adaptors/liteAdaptor.js"),
15062
+ import("mathjax-full/js/handlers/html.js"),
15063
+ import("mathjax-full/js/input/tex/AllPackages.js"),
15064
+ import(RESVG_MODULE_ID)
15065
+ ]), adaptor = liteAdaptor();
15066
+ RegisterHTMLHandler(adaptor);
15067
+ let texInput = new TeX({
15068
+ packages: AllPackages,
15069
+ formatError: () => {
15070
+ throw new Error("Malformed TeX");
15071
+ }
15072
+ }), svgOutput = new SVG({ fontCache: "none" }), document2 = mathjax.document("", { InputJax: texInput, OutputJax: svgOutput });
15073
+ return async (source, mode, options) => {
15074
+ let node = document2.convert(source, { display: mode === "display" }), svg = extractSvgMarkup(adaptor.outerHTML(node));
15075
+ if (!svg)
15076
+ return null;
15077
+ let widthEx = Number(/width="([\d.]+)ex"/.exec(svg)?.[1] ?? 0), heightEx = Number(/height="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
15078
+ if (!(widthEx > 0) || !(heightEx > 0))
15079
+ return null;
15080
+ let exPx = options.cellHeightPx / 2 * options.scale;
15081
+ if (mode === "inline") {
15082
+ let naturalH = heightEx * exPx, naturalW = widthEx * exPx;
15083
+ if (naturalH > options.cellHeightPx * options.scale * 2)
15084
+ return null;
15085
+ let rectH = options.cellHeightPx * options.scale, k = rectH / naturalH, contentW = Math.max(1, Math.round(naturalW * k)), widthCells = Math.max(
15086
+ 1,
15087
+ Math.ceil(contentW / (options.cellWidthPx * options.scale))
15088
+ ), 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();
15089
+ return !pngInline || pngInline.length < 8 ? null : {
15090
+ base64: base64FromBytes(pngInline),
15091
+ widthCells,
15092
+ heightCells: 1
15093
+ };
15094
+ }
15095
+ let widthPx = Math.max(1, Math.round(widthEx * exPx)), heightPx = Math.max(1, Math.round(heightEx * exPx));
15096
+ if (options.maxWidthCells > 0) {
15097
+ let maxPx = options.maxWidthCells * options.cellWidthPx * options.scale;
15098
+ widthPx > maxPx && (heightPx = Math.max(1, Math.round(heightPx * (maxPx / widthPx))), widthPx = maxPx);
15099
+ }
15100
+ 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}"`);
15101
+ let png = new Resvg(svg, { background: "rgba(0,0,0,0)" }).render().asPng();
15102
+ return !png || png.length < 8 ? null : {
15103
+ base64: base64FromBytes(png),
15104
+ widthCells: Math.max(1, Math.round(widthPx / (options.cellWidthPx * options.scale))),
15105
+ heightCells: Math.max(1, Math.round(heightPx / (options.cellHeightPx * options.scale)))
15106
+ };
15107
+ };
15108
+ } catch {
15109
+ return null;
15110
+ }
15111
+ })()), builtinRasterizerLoad;
14972
15112
  }
14973
15113
 
14974
15114
  // node_modules/.pnpm/stream-markdown-parser@1.1.9/node_modules/stream-markdown-parser/dist/index.js
@@ -32196,17 +32336,26 @@ function inlineNodeSegments(nodes, theme, inheritedStyle, options = {}) {
32196
32336
  break;
32197
32337
  case "math_inline":
32198
32338
  {
32199
- let source = stringProp(node, "content"), raw = stringProp(node, "raw") || `$${source}$`, rendered = renderMarkdownInlineMathSegment(source);
32200
- pushTextSegments(
32339
+ 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;
32340
+ cached ? pushTextSegments(
32201
32341
  out,
32202
- rendered.supported ? rendered.text : raw,
32203
- mergeStyle10(inheritedStyle, theme.inlineCode),
32204
- void 0,
32342
+ raw,
32343
+ mathStyle,
32205
32344
  {
32206
- source,
32345
+ kind: "math",
32346
+ tex,
32207
32347
  raw,
32208
- rendered: rendered.supported
32209
- }
32348
+ base64: cached.base64,
32349
+ displayWidth: cached.widthCells,
32350
+ displayHeight: cached.heightCells
32351
+ },
32352
+ { source: tex, raw, rendered: !0 }
32353
+ ) : pushTextSegments(
32354
+ out,
32355
+ raw,
32356
+ mathStyle,
32357
+ void 0,
32358
+ tex && mathEnabled ? { source: tex, raw, rendered: !1, pendingImage: !0, mode: "inline" } : { source, raw, rendered: !1 }
32210
32359
  );
32211
32360
  }
32212
32361
  break;
@@ -32246,7 +32395,8 @@ function blockFromParagraph(node, key, context, theme) {
32246
32395
  key,
32247
32396
  inlineNodeSegments(nodeChildren(node), theme, void 0, {
32248
32397
  imageResolver: context.imageResolver,
32249
- imageSize: context.imageSize
32398
+ imageSize: context.imageSize,
32399
+ math: context.math
32250
32400
  }),
32251
32401
  context
32252
32402
  );
@@ -32257,7 +32407,8 @@ function blockFromHeading(node, key, context, theme) {
32257
32407
  key,
32258
32408
  inlineNodeSegments(nodeChildren(node), theme, theme.heading[level - 1], {
32259
32409
  imageResolver: context.imageResolver,
32260
- imageSize: context.imageSize
32410
+ imageSize: context.imageSize,
32411
+ math: context.math
32261
32412
  }),
32262
32413
  context
32263
32414
  );
@@ -32287,7 +32438,7 @@ function blockFromHtmlBlock(node, key, context, theme) {
32287
32438
  ],
32288
32439
  theme,
32289
32440
  void 0,
32290
- { imageResolver: context.imageResolver }
32441
+ { imageResolver: context.imageResolver, math: context.math }
32291
32442
  ),
32292
32443
  context
32293
32444
  );
@@ -32310,14 +32461,16 @@ function blockFromTable(node, key, context, theme) {
32310
32461
  ).map((cell) => ({
32311
32462
  segments: inlineNodeSegments(nodeChildren(cell), theme, theme.strong, {
32312
32463
  imageResolver: context.imageResolver,
32313
- imageSize: context.imageSize
32464
+ imageSize: context.imageSize,
32465
+ math: context.math
32314
32466
  }),
32315
32467
  align: tableCellAlign(cell)
32316
32468
  })), rows = tableRows(node, "rows").map(
32317
32469
  (row) => tableCells(row).map((cell) => ({
32318
32470
  segments: inlineNodeSegments(nodeChildren(cell), theme, void 0, {
32319
32471
  imageResolver: context.imageResolver,
32320
- imageSize: context.imageSize
32472
+ imageSize: context.imageSize,
32473
+ math: context.math
32321
32474
  }),
32322
32475
  align: tableCellAlign(cell)
32323
32476
  }))
@@ -32347,10 +32500,12 @@ function listItemBlocks(item, index, ordered, start, context, theme, keyPrefix)
32347
32500
  text: spaces(markerCells)
32348
32501
  }, firstContext = {
32349
32502
  prefixSegments: [...context.prefixSegments, markerSegment],
32350
- continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment]
32503
+ continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment],
32504
+ math: context.math
32351
32505
  }, nestedContext = {
32352
32506
  prefixSegments: [...context.continuationPrefixSegments, indentSegment],
32353
- continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment]
32507
+ continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment],
32508
+ math: context.math
32354
32509
  }, children = nodeChildren(item);
32355
32510
  if (!children.length)
32356
32511
  return [inlineBlock(`${keyPrefix}-empty`, [], firstContext)];
@@ -32389,6 +32544,37 @@ function listBlocks(node, context, theme, keyPrefix) {
32389
32544
  );
32390
32545
  return out;
32391
32546
  }
32547
+ function blockMathSegments(source, raw, math, theme) {
32548
+ let tex = sanitizeInlineText(source), canUseImage = !!tex && math.enabled !== !1, cached = canUseImage ? getCachedMarkdownMathImage(tex, "display", math) : null;
32549
+ if (canUseImage && cached)
32550
+ return [
32551
+ {
32552
+ text: raw,
32553
+ style: theme.math,
32554
+ graphic: {
32555
+ kind: "math",
32556
+ tex,
32557
+ raw,
32558
+ base64: cached.base64,
32559
+ displayWidth: cached.widthCells,
32560
+ displayHeight: cached.heightCells
32561
+ },
32562
+ mathAction: { source: tex, raw, rendered: !0 }
32563
+ }
32564
+ ];
32565
+ 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);
32566
+ return [
32567
+ { text: `\u250C${"\u2500".repeat(inner)}\u2510`, style: theme.math },
32568
+ HARD_BREAK_SEGMENT,
32569
+ {
32570
+ text: `\u2502 ${raw}${" ".repeat(pad)}\u2502`,
32571
+ style: theme.math,
32572
+ mathAction: { source: tex, raw, rendered: !1, pendingImage: !0 }
32573
+ },
32574
+ HARD_BREAK_SEGMENT,
32575
+ { text: `\u2514${"\u2500".repeat(inner)}\u2518`, style: theme.math }
32576
+ ];
32577
+ }
32392
32578
  function nodeToBlocks(node, context, theme, keyPrefix) {
32393
32579
  switch (node.type) {
32394
32580
  case "paragraph":
@@ -32413,6 +32599,19 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32413
32599
  prefixSegments: context.prefixSegments
32414
32600
  }
32415
32601
  ];
32602
+ case "math_block":
32603
+ return [
32604
+ inlineBlock(
32605
+ keyPrefix,
32606
+ blockMathSegments(
32607
+ stringProp(node, "content"),
32608
+ stringProp(node, "raw") || `$${stringProp(node, "content")}$`,
32609
+ context.math ?? { enabled: !0 },
32610
+ theme
32611
+ ),
32612
+ context
32613
+ )
32614
+ ];
32416
32615
  case "blockquote": {
32417
32616
  let quoteSegment = {
32418
32617
  text: "\u2502 ",
@@ -32421,7 +32620,8 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32421
32620
  prefixSegments: [...context.prefixSegments, quoteSegment],
32422
32621
  continuationPrefixSegments: [...context.continuationPrefixSegments, quoteSegment],
32423
32622
  imageResolver: context.imageResolver,
32424
- imageSize: context.imageSize
32623
+ imageSize: context.imageSize,
32624
+ math: context.math
32425
32625
  };
32426
32626
  return childSequenceToBlocks(nodeChildren(node), quoteContext, theme, keyPrefix);
32427
32627
  }
@@ -32437,7 +32637,8 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32437
32637
  keyPrefix,
32438
32638
  inlineNodeSegments(nodeChildren(node), theme, void 0, {
32439
32639
  imageResolver: context.imageResolver,
32440
- imageSize: context.imageSize
32640
+ imageSize: context.imageSize,
32641
+ math: context.math
32441
32642
  }),
32442
32643
  context
32443
32644
  )
@@ -32450,7 +32651,10 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32450
32651
  return [
32451
32652
  inlineBlock(
32452
32653
  keyPrefix,
32453
- inlineNodeSegments([node], theme, void 0, { imageResolver: context.imageResolver }),
32654
+ inlineNodeSegments([node], theme, void 0, {
32655
+ imageResolver: context.imageResolver,
32656
+ math: context.math
32657
+ }),
32454
32658
  context
32455
32659
  )
32456
32660
  ];
@@ -32458,7 +32662,10 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
32458
32662
  return nodeChildren(node).length ? childSequenceToBlocks(nodeChildren(node), context, theme, keyPrefix) : [
32459
32663
  inlineBlock(
32460
32664
  keyPrefix,
32461
- inlineNodeSegments([node], theme, void 0, { imageResolver: context.imageResolver }),
32665
+ inlineNodeSegments([node], theme, void 0, {
32666
+ imageResolver: context.imageResolver,
32667
+ math: context.math
32668
+ }),
32462
32669
  context
32463
32670
  )
32464
32671
  ];
@@ -32471,7 +32678,8 @@ function markdownAstToBlocks(nodes, theme, options = {}) {
32471
32678
  prefixSegments: EMPTY_PREFIX,
32472
32679
  continuationPrefixSegments: EMPTY_PREFIX,
32473
32680
  imageResolver: options.imageResolver,
32474
- imageSize: options.imageSize
32681
+ imageSize: options.imageSize,
32682
+ math: options.math
32475
32683
  },
32476
32684
  theme,
32477
32685
  "md"
@@ -32592,7 +32800,8 @@ function wrapLineSegments(source, prefixSegments, continuationPrefixSegments, wi
32592
32800
  style: segment.style,
32593
32801
  cells,
32594
32802
  graphic: segment.graphic,
32595
- fallbackText: segment.text
32803
+ fallbackText: segment.text,
32804
+ ...segment.mathAction ? { mathAction: segment.mathAction } : {}
32596
32805
  }), row.remaining -= cells;
32597
32806
  continue;
32598
32807
  }
@@ -32818,7 +33027,8 @@ function styleSignature(style) {
32818
33027
  function inlineSegmentSignature(segment) {
32819
33028
  let graphic = segment.graphic ? [
32820
33029
  segment.graphic.kind,
32821
- segment.graphic.src,
33030
+ segment.graphic.src ?? "",
33031
+ segment.graphic.tex ?? "",
32822
33032
  segment.graphic.alt ?? "",
32823
33033
  segment.graphic.mime ?? "",
32824
33034
  segment.graphic.base64 ?? "",
@@ -32947,7 +33157,8 @@ var DEFAULT_HEADING = Object.freeze([
32947
33157
  listMarker: freezeStyle({ fg: "cyanBright", bold: !0 }),
32948
33158
  codeBlock: freezeStyle({ fg: "yellowBright" }),
32949
33159
  thematicBreak: freezeStyle({ dim: !0 }),
32950
- html: freezeStyle({ dim: !0 })
33160
+ html: freezeStyle({ dim: !0 }),
33161
+ math: freezeStyle({ fg: "cyanBright" })
32951
33162
  });
32952
33163
  function stableSerialize(value) {
32953
33164
  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 +33191,8 @@ function resolveTuiMarkdownTheme(overrides) {
32980
33191
  DEFAULT_TUI_MARKDOWN_THEME.thematicBreak,
32981
33192
  overrides.thematicBreak
32982
33193
  ),
32983
- html: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.html, overrides.html)
33194
+ html: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.html, overrides.html),
33195
+ math: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.math, overrides.math)
32984
33196
  });
32985
33197
  }
32986
33198
 
@@ -32990,7 +33202,8 @@ function buildMarkdownBlocks(content, parser, options) {
32990
33202
  try {
32991
33203
  let nodes = parser.parse(content, options?.final ?? !0), blocks = markdownAstToBlocks(nodes, theme, {
32992
33204
  imageResolver: options?.imageResolver,
32993
- imageSize: options?.imageSize
33205
+ imageSize: options?.imageSize,
33206
+ math: options?.math
32994
33207
  });
32995
33208
  return { nodes, blocks };
32996
33209
  } catch (error) {
@@ -33136,11 +33349,11 @@ function findMarkdownMathActionAt(rows, point, options) {
33136
33349
  let math = segment.mathAction;
33137
33350
  if (!math || segmentEnd <= clipStart || segmentStart >= clipEnd)
33138
33351
  continue;
33139
- let visibleStart = Math.max(segmentStart, clipStart), visibleEnd = Math.min(segmentEnd, clipEnd), rect = {
33352
+ 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
33353
  x: r.x + visibleStart - clipStart,
33141
33354
  y: r.y + rowIndex - firstRow,
33142
33355
  w: visibleEnd - visibleStart,
33143
- h: 1
33356
+ h: graphicHeight
33144
33357
  };
33145
33358
  if (!(point.cellX < rect.x || point.cellY < rect.y || point.cellX >= rect.x + rect.w || point.cellY >= rect.y + rect.h))
33146
33359
  return {
@@ -33156,6 +33369,70 @@ function findMarkdownMathActionAt(rows, point, options) {
33156
33369
  return null;
33157
33370
  }
33158
33371
 
33372
+ // src/vue/markdown/math.ts
33373
+ var katexListeners = /* @__PURE__ */ new Set();
33374
+ function subscribeMarkdownMathRenderer(listener) {
33375
+ return katexListeners.add(listener), () => katexListeners.delete(listener);
33376
+ }
33377
+ var KATEX_TEXT_OPTIONS = Object.freeze({
33378
+ output: "mathml",
33379
+ throwOnError: !1,
33380
+ strict: "ignore",
33381
+ trust: !1,
33382
+ maxSize: 20,
33383
+ maxExpand: 200
33384
+ }), KATEX_VALIDATE_OPTIONS = Object.freeze({
33385
+ ...KATEX_TEXT_OPTIONS,
33386
+ throwOnError: !0
33387
+ }), TEX_SYMBOLS = Object.freeze({
33388
+ alpha: "\u03B1",
33389
+ beta: "\u03B2",
33390
+ gamma: "\u03B3",
33391
+ delta: "\u03B4",
33392
+ epsilon: "\u03B5",
33393
+ theta: "\u03B8",
33394
+ lambda: "\u03BB",
33395
+ mu: "\u03BC",
33396
+ pi: "\u03C0",
33397
+ rho: "\u03C1",
33398
+ sigma: "\u03C3",
33399
+ tau: "\u03C4",
33400
+ phi: "\u03C6",
33401
+ omega: "\u03C9",
33402
+ Gamma: "\u0393",
33403
+ Delta: "\u0394",
33404
+ Theta: "\u0398",
33405
+ Lambda: "\u039B",
33406
+ Pi: "\u03A0",
33407
+ Sigma: "\u03A3",
33408
+ Phi: "\u03A6",
33409
+ Omega: "\u03A9",
33410
+ int: "\u222B",
33411
+ sum: "\u2211",
33412
+ prod: "\u220F",
33413
+ infty: "\u221E",
33414
+ infinity: "\u221E",
33415
+ pm: "\xB1",
33416
+ times: "\xD7",
33417
+ cdot: "\xB7",
33418
+ div: "\xF7",
33419
+ le: "\u2264",
33420
+ leq: "\u2264",
33421
+ ge: "\u2265",
33422
+ geq: "\u2265",
33423
+ neq: "\u2260",
33424
+ ne: "\u2260",
33425
+ approx: "\u2248",
33426
+ equiv: "\u2261",
33427
+ to: "\u2192",
33428
+ rightarrow: "\u2192",
33429
+ leftarrow: "\u2190",
33430
+ leftrightarrow: "\u2194",
33431
+ partial: "\u2202",
33432
+ nabla: "\u2207",
33433
+ sqrt: "\u221A"
33434
+ }), SUPPORTED_COMMANDS = /* @__PURE__ */ new Set([...Object.keys(TEX_SYMBOLS), "frac", "sqrt"]);
33435
+
33159
33436
  // src/utils/env.ts
33160
33437
  function firstNonEmptyEnv(env, primary, legacy) {
33161
33438
  let primaryValue = env?.[primary];
@@ -33261,7 +33538,7 @@ function mergeStyle11(base, overlay) {
33261
33538
  var activeMarkdownImageGraphics = /* @__PURE__ */ new WeakMap();
33262
33539
  function markdownImageGraphicId(segment, identity) {
33263
33540
  return `md-image:${stableTerminalGraphicNumericId(
33264
- `${identity}:${segment.src}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`
33541
+ `${identity}:${segment.src ?? segment.tex ?? ""}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`
33265
33542
  )}`;
33266
33543
  }
33267
33544
  function rememberMarkdownImageGraphic(terminal, id, rect) {
@@ -33282,7 +33559,7 @@ function clearStaleMarkdownImageGraphicsForRow(terminal, y, keepIds, keepVisible
33282
33559
  !(keepVisibleIds ? y >= rect.y && y < rect.y + rect.h : rect.y === y) || keepIds.has(id) || keepVisibleIds?.has(id) || clearTrackedMarkdownImageGraphic(terminal, id);
33283
33560
  }
33284
33561
  function canAttemptMarkdownImageGraphic(terminal, segment) {
33285
- if (segment.kind !== "image" || !segment.base64)
33562
+ if (!segment.base64)
33286
33563
  return !1;
33287
33564
  let output = getTerminalGraphicsOutput(terminal), protocol = output?.capabilities.preferredProtocol;
33288
33565
  return !!(output?.capabilities.supported && isTerminalGraphicsProtocol(protocol));
@@ -33294,7 +33571,7 @@ function clearMarkdownImageGraphics(terminal, rect) {
33294
33571
  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
33572
  }
33296
33573
  function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
33297
- if (segment.kind !== "image" || !segment.base64)
33574
+ if (!segment.base64)
33298
33575
  return "unavailable";
33299
33576
  let output = getTerminalGraphicsOutput(terminal), protocol = output?.capabilities.preferredProtocol;
33300
33577
  if (!output?.capabilities.supported || !isTerminalGraphicsProtocol(protocol))
@@ -33331,7 +33608,7 @@ function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
33331
33608
  sequence,
33332
33609
  resizeSequence,
33333
33610
  clearSequence,
33334
- fallbackText: segment.alt ?? "image"
33611
+ fallbackText: segment.alt ?? (segment.kind === "math" ? segment.raw ?? segment.tex ?? "math" : "image")
33335
33612
  });
33336
33613
  return markdownImageDebug(
33337
33614
  `queue id=${id}`,
@@ -33416,7 +33693,7 @@ function paintMarkdownVisualRow(terminal, row, options) {
33416
33693
  }), graphicAvailable = queueResult || canAttemptMarkdownImageGraphic(terminal, segment.graphic), queuedGraphic = queueResult === "queued", suppressFallback = queuedGraphic || queueResult === "rejected" || graphicAvailable === !0;
33417
33694
  queuedGraphic && queuedGraphics.add(markdownImageGraphicId(segment.graphic, `${row.key}:${segmentIndex}`)), terminal.write(
33418
33695
  suppressFallback ? spaces(visibleCells) : sliceByCellsRange(
33419
- segment.fallbackText ?? segment.graphic.alt ?? "image",
33696
+ segment.fallbackText ?? segment.graphic.alt ?? (segment.graphic.kind === "math" ? segment.graphic.raw ?? segment.graphic.tex ?? "math" : "image"),
33420
33697
  0,
33421
33698
  visibleCells
33422
33699
  ) || spaces(visibleCells),
@@ -33549,6 +33826,13 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33549
33826
  imageMinHeight: { type: Number, default: void 0 },
33550
33827
  imageMaxHeight: { type: Number, default: void 0 },
33551
33828
  imagePreserveAspectRatio: { type: Boolean, default: !0 },
33829
+ mathImages: { type: Boolean, default: !0 },
33830
+ mathCellWidthPx: { type: Number, default: void 0 },
33831
+ mathCellHeightPx: { type: Number, default: void 0 },
33832
+ mathScale: { type: Number, default: void 0 },
33833
+ mathColor: { type: String, default: void 0 },
33834
+ mathMaxWidthCells: { type: Number, default: void 0 },
33835
+ mathBaselineRatio: { type: Number, default: void 0 },
33552
33836
  imageActions: { type: Boolean, default: !1 },
33553
33837
  mathActions: { type: Boolean, default: !1 },
33554
33838
  linkActions: { type: Boolean, default: !1 },
@@ -33576,10 +33860,41 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33576
33860
  })
33577
33861
  )
33578
33862
  ), graphicsOutputVersion = (0, import_vue33.shallowRef)(getTerminalGraphicsOutputVersion(terminal)), unsubscribeGraphicsOutput = subscribeTerminalGraphicsOutput(terminal, () => {
33579
- graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal);
33863
+ graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal), enqueuePendingMathImages();
33580
33864
  }), unsubscribeMathRenderer = subscribeMarkdownMathRenderer(() => {
33581
33865
  scheduleRebuild();
33866
+ }), unsubscribeMathImage = subscribeMarkdownMathImage(() => {
33867
+ scheduleRebuild();
33582
33868
  });
33869
+ function mathOptions() {
33870
+ if (props.mathImages === !1)
33871
+ return { enabled: !1 };
33872
+ let resolvedColor = props.mathColor ?? resolveMarkdownMathColor(defaultStyle.value.fg);
33873
+ return {
33874
+ enabled: !0,
33875
+ ...props.mathCellWidthPx != null ? { cellWidthPx: props.mathCellWidthPx } : {},
33876
+ ...props.mathCellHeightPx != null ? { cellHeightPx: props.mathCellHeightPx } : {},
33877
+ ...props.mathScale != null ? { scale: props.mathScale } : {},
33878
+ ...resolvedColor != null ? { color: resolvedColor } : {},
33879
+ ...props.mathBaselineRatio != null ? { baselineRatio: props.mathBaselineRatio } : {},
33880
+ maxWidthCells: props.mathMaxWidthCells ?? props.w
33881
+ };
33882
+ }
33883
+ function enqueuePendingMathImages() {
33884
+ if (props.mathImages === !1 || !getTerminalGraphicsOutput(terminal)?.capabilities.supported)
33885
+ return;
33886
+ if (!isMarkdownMathImageRendererReady()) {
33887
+ loadMarkdownMathImageRenderer().then((ready) => {
33888
+ ready && alive && scheduleRebuild();
33889
+ });
33890
+ return;
33891
+ }
33892
+ let h26 = Math.max(0, Math.floor(props.h ?? absRect.value.h));
33893
+ enqueueMarkdownMathImages(rows.value, mathOptions(), {
33894
+ firstRow: internalScrollTop.value,
33895
+ lastRow: internalScrollTop.value + h26
33896
+ });
33897
+ }
33583
33898
  (0, import_vue33.watch)(
33584
33899
  () => `${props.streaming ? 1 : 0}:${(props.customHtmlTags ?? []).join("\0")}`,
33585
33900
  () => {
@@ -33603,13 +33918,14 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33603
33918
  minHeight: props.imageMinHeight,
33604
33919
  maxHeight: props.imageMaxHeight,
33605
33920
  preserveAspectRatio: props.imagePreserveAspectRatio
33606
- }
33921
+ },
33922
+ math: mathOptions()
33607
33923
  }).blocks;
33608
33924
  return layoutMarkdownBlocksCached(blocks, props.w, layoutCache);
33609
33925
  });
33610
33926
  layoutCache = (0, import_vue33.markRaw)(nextLayout.cache);
33611
33927
  let nextRows = nextLayout.rows;
33612
- rows.value = (0, import_vue33.markRaw)(nextRows), reconcileScrollTop();
33928
+ rows.value = (0, import_vue33.markRaw)(nextRows), enqueuePendingMathImages(), reconcileScrollTop();
33613
33929
  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
33930
  (!builtOnce || prevScrollTop !== nextScrollTop || visibleChanged) && (documentVersion.value++, selection.refresh());
33615
33931
  }
@@ -33691,7 +34007,9 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33691
34007
  let remap = pendingSelectionScrollFocusRemap;
33692
34008
  pendingSelectionScrollFocusRemap = !1, applyControlledScrollTop(props.scrollTop, remap);
33693
34009
  }
33694
- ), (0, import_vue33.watch)(
34010
+ ), (0, import_vue33.watch)(internalScrollTop, () => {
34011
+ enqueuePendingMathImages();
34012
+ }), (0, import_vue33.watch)(
33695
34013
  [
33696
34014
  () => props.content,
33697
34015
  () => props.blocks,
@@ -33704,7 +34022,14 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33704
34022
  () => props.imageMaxWidth,
33705
34023
  () => props.imageMinHeight,
33706
34024
  () => props.imageMaxHeight,
33707
- () => props.imagePreserveAspectRatio
34025
+ () => props.imagePreserveAspectRatio,
34026
+ () => props.mathImages,
34027
+ () => props.mathCellWidthPx,
34028
+ () => props.mathCellHeightPx,
34029
+ () => props.mathScale,
34030
+ () => props.mathColor,
34031
+ () => props.mathMaxWidthCells,
34032
+ () => props.mathBaselineRatio
33708
34033
  ],
33709
34034
  () => {
33710
34035
  scheduleRebuild();
@@ -33885,7 +34210,7 @@ var TVirtualMarkdown = (0, import_vue33.defineComponent)({
33885
34210
  let manager = events.value, nodeId = eventNode.id.value;
33886
34211
  nodeId && manager && manager.getFocused() !== nodeId && manager.focus(nodeId);
33887
34212
  }), (0, import_vue33.onBeforeUnmount)(() => {
33888
- alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), clearMarkdownImageGraphics(terminal, fullRect.value);
34213
+ alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), unsubscribeMathImage(), clearMarkdownImageGraphics(terminal, fullRect.value);
33889
34214
  }), useRenderNode(() => ({
33890
34215
  zIndex: props.zIndex,
33891
34216
  rect: visible.value ? normalizedRect() : { x: 0, y: 0, w: 0, h: 0 },
@@ -34867,29 +35192,6 @@ function normalizeCachedPngFrame(frame, context) {
34867
35192
  sourceHeight: dimensions?.height
34868
35193
  };
34869
35194
  }
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
35195
  function pngFrameBytes(frame) {
34894
35196
  return frame.base64.length + (frame.fallback?.length ?? 0);
34895
35197
  }
@@ -34942,50 +35244,24 @@ function createPngTerminalGraphicRenderer(options) {
34942
35244
  };
34943
35245
  if (!png.base64)
34944
35246
  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({
35247
+ if (protocol === "kitty" || protocol === "iterm2") {
35248
+ let rect = context.viewport.rect, fullRect = context.viewport.fullRect, result = createTerminalGraphicPngSequence({
35249
+ protocol,
35250
+ base64: png.base64,
34952
35251
  imageId: context.imageId,
34953
35252
  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
35253
  cols: png.cols,
34968
35254
  rows: png.rows,
34969
35255
  sourceWidth: png.sourceWidth,
34970
35256
  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
35257
+ placementColumns: positiveInt2(rect.w) ?? png.cols,
35258
+ placementRows: positiveInt2(rect.h) ?? png.rows,
35259
+ rect,
35260
+ fullRect,
35261
+ zIndex: options.zIndex,
35262
+ fallback: await fallback()
34980
35263
  });
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());
35264
+ return result ? isSafeTerminalGraphicsSequence(result.sequence, protocol, "draw") ? result : textFallbackResult(await fallback()) : textFallbackResult(await fallback());
34989
35265
  }
34990
35266
  if (protocol === "sixel") {
34991
35267
  let sixel = await queue.cached(