markdown-flow-ui 0.1.86 → 0.1.87

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 (78) hide show
  1. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.cjs.js +1 -1
  2. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.es.js +1 -1
  3. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.cjs.js +1 -1
  4. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/hast-util-to-jsx-runtime@2.3.6/node_modules/hast-util-to-jsx-runtime/lib/index.es.js +1 -1
  5. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YG6GDRKO.cjs.js +1 -1
  6. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-YG6GDRKO.es.js +1 -1
  7. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-S3R3BYOJ.cjs.js +1 -1
  8. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-S3R3BYOJ.es.js +1 -1
  9. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-TZMSLE5B.cjs.js +1 -1
  10. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/chunk-TZMSLE5B.es.js +1 -1
  11. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-LVOFAZNH.cjs.js +1 -1
  12. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-LVOFAZNH.es.js +1 -1
  13. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-WL72ISMW.cjs.js +1 -1
  14. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/mermaid@11.12.1/node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-WL72ISMW.es.js +1 -1
  15. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-input@1.8.0_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-input/es/BaseInput.cjs.js +1 -1
  16. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-input@1.8.0_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-input/es/BaseInput.es.js +1 -1
  17. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/ResizableTextArea.cjs.js +1 -1
  18. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/ResizableTextArea.es.js +1 -1
  19. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/TextArea.cjs.js +1 -1
  20. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/TextArea.es.js +1 -1
  21. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/index.cjs.js +1 -1
  22. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/rc-textarea@1.10.2_react-dom@19.0.1_react@19.0.1__react@19.0.1/node_modules/rc-textarea/es/index.es.js +1 -1
  23. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/index.cjs.js +1 -1
  24. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/index.es.js +1 -1
  25. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/remark-custom-variable.cjs.js +1 -1
  26. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/remark-custom-variable.es.js +1 -1
  27. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/remark-interaction.cjs.js +1 -1
  28. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/remark-flow@0.1.6/node_modules/remark-flow/dist/remark-interaction.es.js +1 -1
  29. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.cjs.js +1 -1
  30. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.cjs.js.map +1 -1
  31. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/style-to-object@1.0.11/node_modules/style-to-object/cjs/index.es.js +1 -1
  32. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.cjs.js +1 -1
  33. package/dist/Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.es.js +1 -1
  34. package/dist/_virtual/index.cjs10.js +1 -1
  35. package/dist/_virtual/index.cjs2.js +1 -1
  36. package/dist/_virtual/index.cjs3.js +1 -1
  37. package/dist/_virtual/index.cjs4.js +1 -1
  38. package/dist/_virtual/index.cjs5.js +1 -1
  39. package/dist/_virtual/index.cjs6.js +1 -1
  40. package/dist/_virtual/index.cjs7.js +1 -1
  41. package/dist/_virtual/index.cjs8.js +1 -1
  42. package/dist/_virtual/index.es10.js +2 -2
  43. package/dist/_virtual/index.es2.js +2 -5
  44. package/dist/_virtual/index.es2.js.map +1 -1
  45. package/dist/_virtual/index.es3.js +4 -2
  46. package/dist/_virtual/index.es3.js.map +1 -1
  47. package/dist/_virtual/index.es4.js +5 -4
  48. package/dist/_virtual/index.es4.js.map +1 -1
  49. package/dist/_virtual/index.es5.js +5 -3
  50. package/dist/_virtual/index.es5.js.map +1 -1
  51. package/dist/_virtual/index.es6.js +5 -2
  52. package/dist/_virtual/index.es6.js.map +1 -1
  53. package/dist/_virtual/index.es7.js +2 -5
  54. package/dist/_virtual/index.es7.js.map +1 -1
  55. package/dist/_virtual/index.es8.js +3 -5
  56. package/dist/_virtual/index.es8.js.map +1 -1
  57. package/dist/assets/markdown-flow-ui.css +1 -1
  58. package/dist/components/ContentRender/ContentRender.cjs.js +2 -2
  59. package/dist/components/ContentRender/ContentRender.cjs.js.map +1 -1
  60. package/dist/components/ContentRender/ContentRender.es.js +158 -143
  61. package/dist/components/ContentRender/ContentRender.es.js.map +1 -1
  62. package/dist/components/ContentRender/IframeSandbox.cjs.js +3 -2
  63. package/dist/components/ContentRender/IframeSandbox.cjs.js.map +1 -1
  64. package/dist/components/ContentRender/IframeSandbox.es.js +13 -12
  65. package/dist/components/ContentRender/IframeSandbox.es.js.map +1 -1
  66. package/dist/components/ContentRender/SandboxApp.cjs.js +7 -1
  67. package/dist/components/ContentRender/SandboxApp.cjs.js.map +1 -1
  68. package/dist/components/ContentRender/SandboxApp.d.ts +0 -1
  69. package/dist/components/ContentRender/SandboxApp.es.js +66 -60
  70. package/dist/components/ContentRender/SandboxApp.es.js.map +1 -1
  71. package/dist/components/ContentRender/utils/split-content.cjs.js +3 -3
  72. package/dist/components/ContentRender/utils/split-content.cjs.js.map +1 -1
  73. package/dist/components/ContentRender/utils/split-content.es.js +100 -46
  74. package/dist/components/ContentRender/utils/split-content.es.js.map +1 -1
  75. package/dist/components/ui/inputGroup/textarea.cjs.js +1 -1
  76. package/dist/components/ui/inputGroup/textarea.es.js +1 -1
  77. package/dist/markdown-flow-ui-lib.css +1 -1
  78. package/package.json +1 -1
@@ -1,133 +1,139 @@
1
- import { j as S } from "../../_virtual/jsx-runtime.es.js";
2
- import { useRef as n, useState as I, useEffect as L } from "react";
3
- import U from "../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/lucide-react@0.525.0_react@19.0.1/node_modules/lucide-react/dist/esm/icons/loader-circle.es.js";
4
- const ee = ({
1
+ import { j as v } from "../../_virtual/jsx-runtime.es.js";
2
+ import { useRef as n, useState as A, useEffect as N } from "react";
3
+ import K from "../../Documents/ai-shifu/markdown-flow-ui/node_modules/.pnpm/lucide-react@0.525.0_react@19.0.1/node_modules/lucide-react/dist/esm/icons/loader-circle.es.js";
4
+ const Z = ({
5
5
  html: u,
6
- loadingText: W,
7
- styleLoadingText: z,
8
- scriptLoadingText: k,
6
+ styleLoadingText: F,
7
+ scriptLoadingText: z,
9
8
  resetToken: f = 0,
10
- mode: q = "content"
9
+ mode: W = "content"
11
10
  }) => {
12
- const H = n(null), C = n(null), [V, N] = I(!0), [_, E] = I(!1), [O, b] = I(!1), w = n([]), R = n([]), j = n(0), D = n(0), p = n(null), d = n(null), m = n(!1), h = n(!1), A = n(!1), M = n(f), Q = 200, c = (t) => {
11
+ const k = n(null), S = n(null), [, I] = A(!0), [q, b] = A(!1), [H, C] = A(!1), w = n([]), E = n([]), j = n(0), L = n(0), p = n(null), d = n(null), m = n(!1), h = n(!1), R = n(!1), M = n(f), V = 200, c = (t) => {
13
12
  t.current && (clearTimeout(t.current), t.current = null);
14
- }, T = (t, s, o, v) => {
15
- const a = performance.now() - o.current, x = Math.max(0, Q - a);
13
+ }, D = (t, s, o, x) => {
14
+ const i = performance.now() - o.current, g = Math.max(0, V - i);
16
15
  c(s), s.current = window.setTimeout(() => {
17
- t(!1), v?.(), s.current = null;
18
- }, x);
16
+ t(!1), x?.(), s.current = null;
17
+ }, g);
19
18
  };
20
- L(() => {
21
- const t = C.current?.ownerDocument;
19
+ N(() => {
20
+ const t = S.current?.ownerDocument;
22
21
  if (!t) return;
23
22
  const s = "sandbox-spinner-style";
24
23
  let o = t.getElementById(s);
25
- o || (o = t.createElement("style"), o.id = s, o.textContent = "@keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }", t.head?.appendChild(o));
26
- }, []), L(() => {
27
- f !== M.current && (A.current = !1, M.current = f), c(p), c(d), m.current = !1, h.current = !1;
28
- const t = C.current;
24
+ o || (o = t.createElement("style"), o.id = s, t.head?.appendChild(o)), o.textContent = `
25
+ @keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }
26
+ .sandbox-wrapper { align-items: center; }
27
+ @media (max-width: 640px) {
28
+ .sandbox-wrapper { align-items: stretch; }
29
+ }
30
+ `;
31
+ }, []), N(() => {
32
+ f !== M.current && (R.current = !1, M.current = f), c(p), c(d), m.current = !1, h.current = !1;
33
+ const t = S.current;
29
34
  if (!t) return;
30
35
  const s = t.ownerDocument, o = s?.body;
31
36
  if (!o) return;
32
- w.current.forEach((e) => e.remove()), w.current = [], R.current.forEach((e) => e.remove()), R.current = [];
33
- const v = A.current;
34
- N(!v), E(!1), b(!1), t.innerHTML = "";
35
- const a = document.createElement("div");
36
- a.innerHTML = u;
37
- const x = (u.match(/<script[\s>]/gi) || []).length, J = (u.match(/<\/script>/gi) || []).length, K = x > 0 && x === J, l = [];
38
- Array.from(a.querySelectorAll("style, script")).forEach((e) => {
37
+ w.current.forEach((e) => e.remove()), w.current = [], E.current.forEach((e) => e.remove()), E.current = [];
38
+ const x = R.current;
39
+ I(!x), b(!1), C(!1), t.innerHTML = "";
40
+ const i = document.createElement("div");
41
+ i.innerHTML = u;
42
+ const g = (u.match(/<script[\s>]/gi) || []).length, O = (u.match(/<\/script>/gi) || []).length, Q = g > 0 && g === O, l = [];
43
+ Array.from(i.querySelectorAll("style, script")).forEach((e) => {
39
44
  if (e.tagName.toLowerCase() === "style") {
40
45
  const r = s.createElement("style");
41
- r.textContent = e.textContent || "", Array.from(e.attributes).forEach((i) => {
42
- r.setAttribute(i.name, i.value);
46
+ r.textContent = e.textContent || "", Array.from(e.attributes).forEach((a) => {
47
+ r.setAttribute(a.name, a.value);
43
48
  }), l.push(r);
44
49
  } else {
45
50
  const r = s.createElement("script");
46
- Array.from(e.attributes).forEach((i) => {
47
- r.setAttribute(i.name, i.value);
51
+ Array.from(e.attributes).forEach((a) => {
52
+ r.setAttribute(a.name, a.value);
48
53
  }), r.textContent = e.textContent || "", l.push(r);
49
54
  }
50
55
  e.remove();
51
56
  });
52
- const B = l.some(
57
+ const T = l.some(
53
58
  (e) => e.tagName.toLowerCase() === "style"
54
- ), F = l.some(
59
+ ), B = l.some(
55
60
  (e) => e.tagName.toLowerCase() === "script"
56
61
  );
57
- B && (m.current = !0, j.current = performance.now(), c(p), E(!0)), F && (h.current = !0, D.current = performance.now(), c(d), b(!0));
58
- const G = !!a.firstElementChild;
59
- N(!G && !v), G && (A.current = !0);
60
- const P = Array.from(a.childNodes);
61
- t.append(...P), l.forEach((e) => {
62
+ T && (m.current = !0, j.current = performance.now(), c(p), b(!0)), B && (h.current = !0, L.current = performance.now(), c(d), C(!0));
63
+ const G = !!i.firstElementChild;
64
+ I(!G && !x), G && (R.current = !0);
65
+ const J = Array.from(i.childNodes);
66
+ t.append(...J), l.forEach((e) => {
62
67
  if (e.tagName.toLowerCase() === "style") {
63
68
  s.head?.appendChild(e), w.current.push(e);
64
69
  return;
65
70
  }
66
- if (K) {
67
- const r = e, i = r.textContent || "";
71
+ if (Q) {
72
+ const r = e, a = r.textContent || "";
68
73
  if (!r.src)
69
74
  try {
70
- new Function(i);
75
+ new Function(a);
71
76
  } catch {
72
77
  r.remove();
73
78
  return;
74
79
  }
75
80
  try {
76
- o.appendChild(r), R.current.push(r);
81
+ o.appendChild(r), E.current.push(r);
77
82
  } catch {
78
83
  r.remove();
79
84
  }
80
85
  } else
81
86
  e.remove();
82
87
  }), requestAnimationFrame(() => {
83
- B && T(
84
- E,
88
+ T && D(
89
+ b,
85
90
  p,
86
91
  j,
87
92
  () => {
88
93
  m.current = !1;
89
94
  }
90
- ), F && T(
91
- b,
95
+ ), B && D(
96
+ C,
92
97
  d,
93
- D,
98
+ L,
94
99
  () => {
95
100
  h.current = !1;
96
101
  }
97
102
  );
98
103
  });
99
- }, [u, f]), L(
104
+ }, [u, f]), N(
100
105
  () => () => {
101
106
  c(p), c(d);
102
107
  },
103
108
  []
104
109
  );
105
- const y = O || h.current ? k || "Building scripts cache..." : _ || m.current ? z || "Building styles..." : V ? W || "Loading..." : null, g = q === "blackboard";
106
- return /* @__PURE__ */ S.jsxs(
110
+ const y = H || h.current ? z || "Building scripts cache..." : q || m.current ? F || "Building styles..." : null, _ = W === "blackboard";
111
+ return /* @__PURE__ */ v.jsxs(
107
112
  "div",
108
113
  {
109
- ref: H,
114
+ ref: k,
115
+ className: "sandbox-wrapper",
110
116
  style: {
111
117
  position: "relative",
112
118
  width: "100%",
113
- height: g ? "100vh" : void 0,
114
- display: g ? "flex" : void 0,
115
- flexDirection: g ? "column" : void 0,
119
+ height: _ ? "100vh" : void 0,
120
+ display: "flex",
121
+ flexDirection: "column",
116
122
  // if use center, too long iframe wont see header
117
- justifyContent: g ? "space-around" : void 0
123
+ justifyContent: "space-around"
118
124
  },
119
125
  "aria-busy": !!y,
120
126
  children: [
121
- /* @__PURE__ */ S.jsx(
127
+ /* @__PURE__ */ v.jsx(
122
128
  "div",
123
129
  {
124
- ref: C,
130
+ ref: S,
125
131
  style: {
126
132
  pointerEvents: y ? "none" : void 0
127
133
  }
128
134
  }
129
135
  ),
130
- y && /* @__PURE__ */ S.jsxs(
136
+ y && /* @__PURE__ */ v.jsxs(
131
137
  "div",
132
138
  {
133
139
  style: {
@@ -145,8 +151,8 @@ const ee = ({
145
151
  zIndex: 20
146
152
  },
147
153
  children: [
148
- /* @__PURE__ */ S.jsx(
149
- U,
154
+ /* @__PURE__ */ v.jsx(
155
+ K,
150
156
  {
151
157
  "aria-hidden": !0,
152
158
  size: 20,
@@ -162,6 +168,6 @@ const ee = ({
162
168
  );
163
169
  };
164
170
  export {
165
- ee as default
171
+ Z as default
166
172
  };
167
173
  //# sourceMappingURL=SandboxApp.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SandboxApp.es.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\n\nexport interface SandboxAppProps {\n html: string;\n loadingText?: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n}\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n loadingText,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [isWaitingFirstDiv, setIsWaitingFirstDiv] = useState(true);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const hasRenderedContentRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n styleEl.textContent =\n \"@keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }\";\n doc.head?.appendChild(styleEl);\n }\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n hasRenderedContentRef.current = false;\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n const hasRenderedBefore = hasRenderedContentRef.current;\n setIsWaitingFirstDiv(!hasRenderedBefore);\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n container.innerHTML = \"\";\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = html;\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const hasFirstElement = !!wrapper.firstElementChild;\n setIsWaitingFirstDiv(!hasFirstElement && !hasRenderedBefore);\n if (hasFirstElement) {\n hasRenderedContentRef.current = true;\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n container.append(...contentNodes);\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n }, [html, resetToken]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n const overlayMessage = (() => {\n if (isGeneratingScripts || hasScriptsRef.current)\n return scriptLoadingText || \"Building scripts cache...\";\n if (isGeneratingStyles || hasStylesRef.current)\n return styleLoadingText || \"Building styles...\";\n if (isWaitingFirstDiv) return loadingText || \"Loading...\";\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n\n return (\n <div\n ref={wrapperRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: isBlackboard ? \"100vh\" : undefined,\n display: isBlackboard ? \"flex\" : undefined,\n flexDirection: isBlackboard ? \"column\" : undefined,\n // if use center, too long iframe wont see header\n justifyContent: isBlackboard ? \"space-around\" : undefined,\n }}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n style={{\n pointerEvents: overlayMessage ? \"none\" : undefined,\n }}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(51, 51, 51, 0.80)\",\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: 700,\n gap: 10,\n pointerEvents: \"auto\",\n zIndex: 20,\n }}\n >\n <Loader2\n aria-hidden\n size={20}\n style={{ animation: \"sandbox-spin 1s linear infinite\" }}\n />\n {overlayMessage}\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["SandboxApp","html","loadingText","styleLoadingText","scriptLoadingText","resetToken","mode","wrapperRef","useRef","containerRef","isWaitingFirstDiv","setIsWaitingFirstDiv","useState","isGeneratingStyles","setIsGeneratingStyles","isGeneratingScripts","setIsGeneratingScripts","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","hasRenderedContentRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","node","hasRenderedBefore","wrapper","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","hasFirstElement","contentNodes","scriptNode","scriptText","overlayMessage","isBlackboard","jsxs","jsx","Loader2"],"mappings":"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"}
1
+ {"version":3,"file":"SandboxApp.es.js","sources":["../../../src/components/ContentRender/SandboxApp.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\n\nexport interface SandboxAppProps {\n html: string;\n styleLoadingText?: string;\n scriptLoadingText?: string;\n resetToken?: number;\n mode?: \"content\" | \"blackboard\";\n}\n\nconst SandboxApp: React.FC<SandboxAppProps> = ({\n html,\n styleLoadingText,\n scriptLoadingText,\n resetToken = 0,\n mode = \"content\",\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [, setIsWaitingFirstDiv] = useState(true);\n const [isGeneratingStyles, setIsGeneratingStyles] = useState(false);\n const [isGeneratingScripts, setIsGeneratingScripts] = useState(false);\n const appendedStylesRef = useRef<HTMLStyleElement[]>([]);\n const appendedScriptsRef = useRef<HTMLScriptElement[]>([]);\n const styleStartRef = useRef(0);\n const scriptStartRef = useRef(0);\n const styleTimerRef = useRef<number | null>(null);\n const scriptTimerRef = useRef<number | null>(null);\n const hasStylesRef = useRef(false);\n const hasScriptsRef = useRef(false);\n const hasRenderedContentRef = useRef(false);\n const prevResetTokenRef = useRef(resetToken);\n const MIN_LOADING_MS = 200;\n\n const clearTimer = (timerRef: React.MutableRefObject<number | null>) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n\n const settleStateWithMinimumDelay = (\n setter: React.Dispatch<React.SetStateAction<boolean>>,\n timerRef: React.MutableRefObject<number | null>,\n startRef: React.MutableRefObject<number>,\n onDone?: () => void\n ) => {\n const elapsed = performance.now() - startRef.current;\n const delay = Math.max(0, MIN_LOADING_MS - elapsed);\n clearTimer(timerRef);\n timerRef.current = window.setTimeout(() => {\n setter(false);\n onDone?.();\n timerRef.current = null;\n }, delay);\n };\n\n useEffect(() => {\n const doc = containerRef.current?.ownerDocument;\n if (!doc) return;\n const styleId = \"sandbox-spinner-style\";\n let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = doc.createElement(\"style\");\n styleEl.id = styleId;\n doc.head?.appendChild(styleEl);\n }\n styleEl.textContent = `\n @keyframes sandbox-spin { from { transform: rotate(0deg);} to { transform: rotate(360deg);} }\n .sandbox-wrapper { align-items: center; }\n @media (max-width: 640px) {\n .sandbox-wrapper { align-items: stretch; }\n }\n `;\n }, []);\n\n useEffect(() => {\n if (resetToken !== prevResetTokenRef.current) {\n hasRenderedContentRef.current = false;\n prevResetTokenRef.current = resetToken;\n }\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n hasStylesRef.current = false;\n hasScriptsRef.current = false;\n\n const container = containerRef.current;\n if (!container) return;\n const doc = container.ownerDocument;\n const body = doc?.body;\n if (!body) return;\n\n appendedStylesRef.current.forEach((node) => node.remove());\n appendedStylesRef.current = [];\n appendedScriptsRef.current.forEach((node) => node.remove());\n appendedScriptsRef.current = [];\n\n const hasRenderedBefore = hasRenderedContentRef.current;\n setIsWaitingFirstDiv(!hasRenderedBefore);\n setIsGeneratingStyles(false);\n setIsGeneratingScripts(false);\n container.innerHTML = \"\";\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = html;\n\n const openScriptCount = (html.match(/<script[\\s>]/gi) || []).length;\n const closeScriptCount = (html.match(/<\\/script>/gi) || []).length;\n const shouldExecuteScripts =\n openScriptCount > 0 && openScriptCount === closeScriptCount;\n\n const resourceQueue: HTMLElement[] = [];\n\n Array.from(wrapper.querySelectorAll(\"style, script\")).forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n const cloned = doc.createElement(\"style\");\n cloned.textContent = node.textContent || \"\";\n Array.from(node.attributes).forEach((attr) => {\n cloned.setAttribute(attr.name, attr.value);\n });\n resourceQueue.push(cloned);\n } else {\n const replacement = doc.createElement(\"script\");\n Array.from(node.attributes).forEach((attr) => {\n replacement.setAttribute(attr.name, attr.value);\n });\n replacement.textContent = node.textContent || \"\";\n resourceQueue.push(replacement);\n }\n node.remove();\n });\n\n const hasStyles = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"style\"\n );\n const hasScripts = resourceQueue.some(\n (node) => node.tagName.toLowerCase() === \"script\"\n );\n if (hasStyles) {\n hasStylesRef.current = true;\n styleStartRef.current = performance.now();\n clearTimer(styleTimerRef);\n setIsGeneratingStyles(true);\n }\n if (hasScripts) {\n hasScriptsRef.current = true;\n scriptStartRef.current = performance.now();\n clearTimer(scriptTimerRef);\n setIsGeneratingScripts(true);\n }\n\n const hasFirstElement = !!wrapper.firstElementChild;\n setIsWaitingFirstDiv(!hasFirstElement && !hasRenderedBefore);\n if (hasFirstElement) {\n hasRenderedContentRef.current = true;\n }\n\n const contentNodes = Array.from(wrapper.childNodes);\n container.append(...contentNodes);\n\n resourceQueue.forEach((node) => {\n if (node.tagName.toLowerCase() === \"style\") {\n doc.head?.appendChild(node);\n appendedStylesRef.current.push(node as HTMLStyleElement);\n return;\n }\n\n if (shouldExecuteScripts) {\n const scriptNode = node as HTMLScriptElement;\n const scriptText = scriptNode.textContent || \"\";\n const shouldValidate = !scriptNode.src;\n\n if (shouldValidate) {\n try {\n // Validate script is syntactically complete before executing\n\n new Function(scriptText);\n } catch {\n scriptNode.remove();\n return;\n }\n }\n\n try {\n body.appendChild(scriptNode);\n appendedScriptsRef.current.push(scriptNode);\n } catch {\n scriptNode.remove();\n }\n } else {\n // Defer execution until all script tags are fully received\n node.remove();\n }\n });\n requestAnimationFrame(() => {\n if (hasStyles) {\n settleStateWithMinimumDelay(\n setIsGeneratingStyles,\n styleTimerRef,\n styleStartRef,\n () => {\n hasStylesRef.current = false;\n }\n );\n }\n if (hasScripts) {\n settleStateWithMinimumDelay(\n setIsGeneratingScripts,\n scriptTimerRef,\n scriptStartRef,\n () => {\n hasScriptsRef.current = false;\n }\n );\n }\n });\n }, [html, resetToken]);\n\n useEffect(\n () => () => {\n clearTimer(styleTimerRef);\n clearTimer(scriptTimerRef);\n },\n []\n );\n\n const overlayMessage = (() => {\n if (isGeneratingScripts || hasScriptsRef.current)\n return scriptLoadingText || \"Building scripts cache...\";\n if (isGeneratingStyles || hasStylesRef.current)\n return styleLoadingText || \"Building styles...\";\n return null;\n })();\n\n const isBlackboard = mode === \"blackboard\";\n\n return (\n <div\n ref={wrapperRef}\n className=\"sandbox-wrapper\"\n style={{\n position: \"relative\",\n width: \"100%\",\n height: isBlackboard ? \"100vh\" : undefined,\n display: \"flex\",\n flexDirection: \"column\",\n // if use center, too long iframe wont see header\n justifyContent: \"space-around\",\n }}\n aria-busy={!!overlayMessage}\n >\n <div\n ref={containerRef}\n style={{\n pointerEvents: overlayMessage ? \"none\" : undefined,\n }}\n />\n {overlayMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(51, 51, 51, 0.80)\",\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: 700,\n gap: 10,\n pointerEvents: \"auto\",\n zIndex: 20,\n }}\n >\n <Loader2\n aria-hidden\n size={20}\n style={{ animation: \"sandbox-spin 1s linear infinite\" }}\n />\n {overlayMessage}\n </div>\n )}\n </div>\n );\n};\n\nexport default SandboxApp;\n"],"names":["SandboxApp","html","styleLoadingText","scriptLoadingText","resetToken","mode","wrapperRef","useRef","containerRef","setIsWaitingFirstDiv","useState","isGeneratingStyles","setIsGeneratingStyles","isGeneratingScripts","setIsGeneratingScripts","appendedStylesRef","appendedScriptsRef","styleStartRef","scriptStartRef","styleTimerRef","scriptTimerRef","hasStylesRef","hasScriptsRef","hasRenderedContentRef","prevResetTokenRef","MIN_LOADING_MS","clearTimer","timerRef","settleStateWithMinimumDelay","setter","startRef","onDone","elapsed","delay","useEffect","doc","styleId","styleEl","container","body","node","hasRenderedBefore","wrapper","openScriptCount","closeScriptCount","shouldExecuteScripts","resourceQueue","cloned","attr","replacement","hasStyles","hasScripts","hasFirstElement","contentNodes","scriptNode","scriptText","overlayMessage","isBlackboard","jsxs","jsx","Loader2"],"mappings":";;;AAWA,MAAMA,IAAwC,CAAC;AAAA,EAC7C,MAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,MAAAC,IAAO;AACT,MAAM;AACJ,QAAMC,IAAaC,EAAuB,IAAI,GACxCC,IAAeD,EAAuB,IAAI,GAC1C,GAAGE,CAAoB,IAAIC,EAAS,EAAI,GACxC,CAACC,GAAoBC,CAAqB,IAAIF,EAAS,EAAK,GAC5D,CAACG,GAAqBC,CAAsB,IAAIJ,EAAS,EAAK,GAC9DK,IAAoBR,EAA2B,EAAE,GACjDS,IAAqBT,EAA4B,EAAE,GACnDU,IAAgBV,EAAO,CAAC,GACxBW,IAAiBX,EAAO,CAAC,GACzBY,IAAgBZ,EAAsB,IAAI,GAC1Ca,IAAiBb,EAAsB,IAAI,GAC3Cc,IAAed,EAAO,EAAK,GAC3Be,IAAgBf,EAAO,EAAK,GAC5BgB,IAAwBhB,EAAO,EAAK,GACpCiB,IAAoBjB,EAAOH,CAAU,GACrCqB,IAAiB,KAEjBC,IAAa,CAACC,MAAoD;AACtE,IAAIA,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU;AAAA,EAEvB,GAEMC,IAA8B,CAClCC,GACAF,GACAG,GACAC,MACG;AACH,UAAMC,IAAU,YAAY,IAAA,IAAQF,EAAS,SACvCG,IAAQ,KAAK,IAAI,GAAGR,IAAiBO,CAAO;AAClD,IAAAN,EAAWC,CAAQ,GACnBA,EAAS,UAAU,OAAO,WAAW,MAAM;AACzC,MAAAE,EAAO,EAAK,GACZE,IAAA,GACAJ,EAAS,UAAU;AAAA,IACrB,GAAGM,CAAK;AAAA,EACV;AAEA,EAAAC,EAAU,MAAM;AACd,UAAMC,IAAM3B,EAAa,SAAS;AAClC,QAAI,CAAC2B,EAAK;AACV,UAAMC,IAAU;AAChB,QAAIC,IAAUF,EAAI,eAAeC,CAAO;AACxC,IAAKC,MACHA,IAAUF,EAAI,cAAc,OAAO,GACnCE,EAAQ,KAAKD,GACbD,EAAI,MAAM,YAAYE,CAAO,IAE/BA,EAAQ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOxB,GAAG,CAAA,CAAE,GAELH,EAAU,MAAM;AACd,IAAI9B,MAAeoB,EAAkB,YACnCD,EAAsB,UAAU,IAChCC,EAAkB,UAAUpB,IAE9BsB,EAAWP,CAAa,GACxBO,EAAWN,CAAc,GACzBC,EAAa,UAAU,IACvBC,EAAc,UAAU;AAExB,UAAMgB,IAAY9B,EAAa;AAC/B,QAAI,CAAC8B,EAAW;AAChB,UAAMH,IAAMG,EAAU,eAChBC,IAAOJ,GAAK;AAClB,QAAI,CAACI,EAAM;AAEX,IAAAxB,EAAkB,QAAQ,QAAQ,CAACyB,MAASA,EAAK,QAAQ,GACzDzB,EAAkB,UAAU,CAAA,GAC5BC,EAAmB,QAAQ,QAAQ,CAACwB,MAASA,EAAK,QAAQ,GAC1DxB,EAAmB,UAAU,CAAA;AAE7B,UAAMyB,IAAoBlB,EAAsB;AAChD,IAAAd,EAAqB,CAACgC,CAAiB,GACvC7B,EAAsB,EAAK,GAC3BE,EAAuB,EAAK,GAC5BwB,EAAU,YAAY;AACtB,UAAMI,IAAU,SAAS,cAAc,KAAK;AAC5C,IAAAA,EAAQ,YAAYzC;AAEpB,UAAM0C,KAAmB1C,EAAK,MAAM,gBAAgB,KAAK,CAAA,GAAI,QACvD2C,KAAoB3C,EAAK,MAAM,cAAc,KAAK,CAAA,GAAI,QACtD4C,IACJF,IAAkB,KAAKA,MAAoBC,GAEvCE,IAA+B,CAAA;AAErC,UAAM,KAAKJ,EAAQ,iBAAiB,eAAe,CAAC,EAAE,QAAQ,CAACF,MAAS;AACtE,UAAIA,EAAK,QAAQ,YAAA,MAAkB,SAAS;AAC1C,cAAMO,IAASZ,EAAI,cAAc,OAAO;AACxC,QAAAY,EAAO,cAAcP,EAAK,eAAe,IACzC,MAAM,KAAKA,EAAK,UAAU,EAAE,QAAQ,CAACQ,MAAS;AAC5C,UAAAD,EAAO,aAAaC,EAAK,MAAMA,EAAK,KAAK;AAAA,QAC3C,CAAC,GACDF,EAAc,KAAKC,CAAM;AAAA,MAC3B,OAAO;AACL,cAAME,IAAcd,EAAI,cAAc,QAAQ;AAC9C,cAAM,KAAKK,EAAK,UAAU,EAAE,QAAQ,CAACQ,MAAS;AAC5C,UAAAC,EAAY,aAAaD,EAAK,MAAMA,EAAK,KAAK;AAAA,QAChD,CAAC,GACDC,EAAY,cAAcT,EAAK,eAAe,IAC9CM,EAAc,KAAKG,CAAW;AAAA,MAChC;AACA,MAAAT,EAAK,OAAA;AAAA,IACP,CAAC;AAED,UAAMU,IAAYJ,EAAc;AAAA,MAC9B,CAACN,MAASA,EAAK,QAAQ,kBAAkB;AAAA,IAAA,GAErCW,IAAaL,EAAc;AAAA,MAC/B,CAACN,MAASA,EAAK,QAAQ,kBAAkB;AAAA,IAAA;AAE3C,IAAIU,MACF7B,EAAa,UAAU,IACvBJ,EAAc,UAAU,YAAY,IAAA,GACpCS,EAAWP,CAAa,GACxBP,EAAsB,EAAI,IAExBuC,MACF7B,EAAc,UAAU,IACxBJ,EAAe,UAAU,YAAY,IAAA,GACrCQ,EAAWN,CAAc,GACzBN,EAAuB,EAAI;AAG7B,UAAMsC,IAAkB,CAAC,CAACV,EAAQ;AAClC,IAAAjC,EAAqB,CAAC2C,KAAmB,CAACX,CAAiB,GACvDW,MACF7B,EAAsB,UAAU;AAGlC,UAAM8B,IAAe,MAAM,KAAKX,EAAQ,UAAU;AAClD,IAAAJ,EAAU,OAAO,GAAGe,CAAY,GAEhCP,EAAc,QAAQ,CAACN,MAAS;AAC9B,UAAIA,EAAK,QAAQ,YAAA,MAAkB,SAAS;AAC1C,QAAAL,EAAI,MAAM,YAAYK,CAAI,GAC1BzB,EAAkB,QAAQ,KAAKyB,CAAwB;AACvD;AAAA,MACF;AAEA,UAAIK,GAAsB;AACxB,cAAMS,IAAad,GACbe,IAAaD,EAAW,eAAe;AAG7C,YAFuB,CAACA,EAAW;AAGjC,cAAI;AAGF,gBAAI,SAASC,CAAU;AAAA,UACzB,QAAQ;AACN,YAAAD,EAAW,OAAA;AACX;AAAA,UACF;AAGF,YAAI;AACF,UAAAf,EAAK,YAAYe,CAAU,GAC3BtC,EAAmB,QAAQ,KAAKsC,CAAU;AAAA,QAC5C,QAAQ;AACN,UAAAA,EAAW,OAAA;AAAA,QACb;AAAA,MACF;AAEE,QAAAd,EAAK,OAAA;AAAA,IAET,CAAC,GACD,sBAAsB,MAAM;AAC1B,MAAIU,KACFtB;AAAA,QACEhB;AAAA,QACAO;AAAA,QACAF;AAAA,QACA,MAAM;AACJ,UAAAI,EAAa,UAAU;AAAA,QACzB;AAAA,MAAA,GAGA8B,KACFvB;AAAA,QACEd;AAAA,QACAM;AAAA,QACAF;AAAA,QACA,MAAM;AACJ,UAAAI,EAAc,UAAU;AAAA,QAC1B;AAAA,MAAA;AAAA,IAGN,CAAC;AAAA,EACH,GAAG,CAACrB,GAAMG,CAAU,CAAC,GAErB8B;AAAA,IACE,MAAM,MAAM;AACV,MAAAR,EAAWP,CAAa,GACxBO,EAAWN,CAAc;AAAA,IAC3B;AAAA,IACA,CAAA;AAAA,EAAC;AAGH,QAAMoC,IACA3C,KAAuBS,EAAc,UAChCnB,KAAqB,8BAC1BQ,KAAsBU,EAAa,UAC9BnB,KAAoB,uBACtB,MAGHuD,IAAepD,MAAS;AAE9B,SACEqD,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKpD;AAAA,MACL,WAAU;AAAA,MACV,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQmD,IAAe,UAAU;AAAA,QACjC,SAAS;AAAA,QACT,eAAe;AAAA;AAAA,QAEf,gBAAgB;AAAA,MAAA;AAAA,MAElB,aAAW,CAAC,CAACD;AAAA,MAEb,UAAA;AAAA,QAAAG,gBAAAA,EAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKnD;AAAA,YACL,OAAO;AAAA,cACL,eAAegD,IAAiB,SAAS;AAAA,YAAA;AAAA,UAC3C;AAAA,QAAA;AAAA,QAEDA,KACCE,gBAAAA,EAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,eAAe;AAAA,cACf,QAAQ;AAAA,YAAA;AAAA,YAGV,UAAA;AAAA,cAAAC,gBAAAA,EAAAA;AAAAA,gBAACC;AAAAA,gBAAA;AAAA,kBACC,eAAW;AAAA,kBACX,MAAM;AAAA,kBACN,OAAO,EAAE,WAAW,kCAAA;AAAA,gBAAkC;AAAA,cAAA;AAAA,cAEvDJ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR;"}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=/<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\s>]/i,k=[/<svg[\s\S]*?<\/svg>/i,/<img\b[^>]*?>/i,/```mermaid[\s\S]*?```/i,/```[a-zA-Z0-9]+[\s\S]*?```/i],v=/<\/[a-z][^>]*>\s*\n(?=[^\s<])/gi,I=(t,e)=>{let s=t.length,n;for(v.lastIndex=0;n=v.exec(t);)if(!(n.index<=e)){s=n.index+n[0].length;break}return s},B=t=>{let e=null;return k.forEach(s=>{const n=s.exec(t);if(!n||typeof n.index!="number")return;const i=n.index,r=n.index+n[0].length;(!e||i<e.start)&&(e={start:i,end:r})}),e},E=t=>{const e=t.match(/^\s*\|.+\|\s*$/m);if(!e||typeof e.index!="number")return null;const s=e[0].match(/^\s*/)?.[0].length??0,n=e.index+s,i=t.slice(n).split(`
2
- `),r=[];for(const c of i){if(!c.trim().startsWith("|"))break;r.push(c)}const o=r.join(`
3
- `);return{start:n,block:o,end:n+o.length}},u=(t,e=!1)=>{const s=t.indexOf("```");if(e&&s!==-1&&t.indexOf("```",s+3)===-1)return[{type:"markdown",value:t}];const n=t.search(/<svg\b/i);if(n!==-1&&t.indexOf("</svg>",n)===-1)return[{type:"markdown",value:t}];const i=E(t);if(i){const l=[],p=t.slice(0,i.start);e&&p.trim()&&l.push({type:"text",value:p}),l.push({type:"markdown",value:i.block});const m=t.slice(i.end),x=m.length<t.length;return m.trim()&&x&&l.push(...e?u(m,!0):u(m)),l}if(t.match(/<svg[\s\S]*?<\/svg>/i)&&e&&!(n>-1&&t.slice(0,n).trim().length>0))return t.trim().toLowerCase().endsWith("</svg>")?[{type:"markdown",value:t}]:[{type:"markdown",value:`${t}</svg>`}];const o=t.search(y),c=B(t);if(o===-1&&!c)return e&&t.trim()?[{type:"text",value:t}]:[];const a=!!c&&(o===-1||c.start<o),h=a?c.start:o,f=a?c.end:I(t,h),d=[],g=t.slice(0,h),S=t.slice(h,f),b=t.slice(f);return e&&g.trim()&&d.push({type:"text",value:g}),d.push({type:a?"markdown":"sandbox",value:S}),b.trim()&&d.push(...u(b,e)),d};exports.splitContentSegments=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=/<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\s>]/i,R=[/<svg[\s\S]*?<\/svg>/i,/<img\b[^>]*?>/i,/```mermaid[\s\S]*?```/i,/```[a-zA-Z0-9]+[\s\S]*?```/i],M=/!\[[^\]]*]\([^\s)\n]+(?:\s+"[^"]*")?\)/i,B=/<\/[a-z][^>]*>\s*\n(?=[^\s<])/gi,O=/<custom-button-after-content\b[\s\S]*?<\/custom-button-after-content>/gi,T=t=>{const e=[],n=/```/g;let s;for(;(s=n.exec(t))!==null;){const o=s.index,c=n.exec(t);if(!c){e.push({start:o,end:t.length});break}e.push({start:o,end:c.index+3})}return e},_=(t,e)=>e.some(({start:n,end:s})=>t>=n&&t<s),y=(t,e,n)=>{const s=e.flags.includes("g")?e.flags:`${e.flags}g`,o=new RegExp(e.source,s);let c;for(;(c=o.exec(t))!==null;)if(!_(c.index,n))return c.index;return-1},P=(t,e)=>{let n=t.length,s;for(B.lastIndex=0;s=B.exec(t);)if(!(s.index<=e)){n=s.index+s[0].length;break}return n},F=t=>{if(!t.length)return t;const e=[];return t.forEach(n=>{if(n.type!=="sandbox"){e.push(n);return}O.lastIndex=0;let s=0,o;for(;(o=O.exec(n.value))!==null;){const i=n.value.slice(s,o.index);i.trim()&&e.push({type:"sandbox",value:i}),e.push({type:"markdown",value:o[0]}),s=o.index+o[0].length}const c=n.value.slice(s);c.trim()&&e.push({type:"sandbox",value:c})}),e},C=t=>{let e=null;return R.forEach(n=>{const s=n.exec(t);if(!s||typeof s.index!="number")return;const o=s.index,c=s.index+s[0].length;(!e||o<e.start)&&(e={start:o,end:c})}),e},z=(t,e)=>{const n=y(t,M,e);if(n===-1)return null;const s=t.slice(n).match(M);return s?{start:n,end:n+s[0].length}:null},D=t=>{const e=t.match(/^\s*\|.+\|\s*$/m);if(!e||typeof e.index!="number")return null;const n=e[0].match(/^\s*/)?.[0].length??0,s=e.index+n,o=t.slice(s).split(`
2
+ `),c=[];for(const h of o){if(!h.trim().startsWith("|"))break;c.push(h)}const i=c.join(`
3
+ `);return{start:s,block:i,end:s+i.length}},f=(t,e=!1)=>{const n=l=>F(l),s=t.indexOf("```");if(e&&s!==-1&&t.indexOf("```",s+3)===-1)return n([{type:"markdown",value:t}]);const o=T(t),c=y(t,N,o),i=y(t,/<svg\b/i,o),h=c!==-1&&i!==-1&&c<i;if(i!==-1&&!h){const l=t.slice(0,i),r=t.indexOf("</svg>",i),a=r===-1?`${t.slice(i)}</svg>`:t.slice(i,r+6),b=r===-1?"":t.slice(r+6);if(e){const p=[];return l.trim()&&p.push({type:"text",value:l}),p.push({type:"markdown",value:a}),b.trim()&&p.push(...f(b,!0)),n(p)}if(r===-1)return n([{type:"markdown",value:a}])}const u=D(t);if(u){const l=[],r=t.slice(0,u.start);e&&r.trim()&&l.push({type:"text",value:r}),l.push({type:"markdown",value:u.block});const a=t.slice(u.end),b=a.length<t.length;return a.trim()&&b&&l.push(...e?f(a,!0):f(a)),n(l)}const m=C(t),g=z(t,o),d=m&&g?m.start<=g.start?m:g:m??g;if(c===-1&&!d)return e&&t.trim()?n([{type:"text",value:t}]):[];const v=!!d&&(c===-1||d.start<c),S=v?d.start:c,I=v?d.end:P(t,S),x=[],k=t.slice(0,S),A=t.slice(S,I),E=t.slice(I);return e&&k.trim()&&x.push({type:"text",value:k}),x.push({type:v?"markdown":"sandbox",value:A}),E.trim()&&x.push(...f(E,e)),n(x)};exports.splitContentSegments=f;
4
4
  //# sourceMappingURL=split-content.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"split-content.cjs.js","sources":["../../../../src/components/ContentRender/utils/split-content.ts"],"sourcesContent":["export type RenderSegment =\n | { type: \"markdown\"; value: string }\n | { type: \"sandbox\"; value: string }\n | { type: \"text\"; value: string };\n\nconst SANDBOX_START_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\\s>]/i;\n\nconst INLINE_SANDBOX_PATTERNS: RegExp[] = [\n /<svg[\\s\\S]*?<\\/svg>/i,\n /<img\\b[^>]*?>/i,\n /```mermaid[\\s\\S]*?```/i,\n /```[a-zA-Z0-9]+[\\s\\S]*?```/i,\n];\n\nconst closingBoundary = /<\\/[a-z][^>]*>\\s*\\n(?=[^\\s<])/gi;\n\ntype MatchResult = { start: number; end: number };\n\nconst findHtmlBlockEnd = (raw: string, startIndex: number) => {\n let blockEnd = raw.length;\n let match: RegExpExecArray | null;\n closingBoundary.lastIndex = 0;\n\n while ((match = closingBoundary.exec(raw))) {\n if (match.index <= startIndex) continue;\n blockEnd = match.index + match[0].length;\n break;\n }\n\n return blockEnd;\n};\n\nconst findInlineSandboxMatch = (raw: string): MatchResult | null => {\n let earliest: MatchResult | null = null;\n\n INLINE_SANDBOX_PATTERNS.forEach((pattern) => {\n const match = pattern.exec(raw);\n if (!match || typeof match.index !== \"number\") return;\n const start = match.index;\n const end = match.index + match[0].length;\n\n if (!earliest || start < earliest.start) {\n earliest = { start, end };\n }\n });\n\n return earliest;\n};\n\nconst extractTableBlock = (\n raw: string\n): { start: number; block: string; end: number } | null => {\n const tableMatch = raw.match(/^\\s*\\|.+\\|\\s*$/m);\n if (!tableMatch || typeof tableMatch.index !== \"number\") return null;\n\n const leadingSpaces = tableMatch[0].match(/^\\s*/)?.[0].length ?? 0;\n const tableStart = tableMatch.index + leadingSpaces;\n\n const lines = raw.slice(tableStart).split(\"\\n\");\n const tableLines: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\")) break;\n tableLines.push(line);\n }\n\n const block = tableLines.join(\"\\n\");\n return { start: tableStart, block, end: tableStart + block.length };\n};\n\n// Split incoming markdown content into markdown and sandbox HTML segments\nexport const splitContentSegments = (\n raw: string,\n keepText = false\n): RenderSegment[] => {\n const fenceStart = raw.indexOf(\"```\");\n if (keepText && fenceStart !== -1) {\n const closingFence = raw.indexOf(\"```\", fenceStart + 3);\n if (closingFence === -1) {\n return [{ type: \"markdown\", value: raw }];\n }\n }\n\n const svgOpenIndex = raw.search(/<svg\\b/i);\n if (svgOpenIndex !== -1 && raw.indexOf(\"</svg>\", svgOpenIndex) === -1) {\n return [{ type: \"markdown\", value: raw }];\n }\n\n const tableBlock = extractTableBlock(raw);\n if (tableBlock) {\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, tableBlock.start);\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n segments.push({ type: \"markdown\", value: tableBlock.block });\n const after = raw.slice(tableBlock.end);\n const hasProgress = after.length < raw.length;\n if (after.trim() && hasProgress) {\n segments.push(\n ...(keepText\n ? splitContentSegments(after, true)\n : splitContentSegments(after))\n );\n }\n return segments;\n }\n\n const completeSvgMatch = raw.match(/<svg[\\s\\S]*?<\\/svg>/i);\n if (completeSvgMatch && keepText) {\n const hasLeadingContent =\n svgOpenIndex > -1 && raw.slice(0, svgOpenIndex).trim().length > 0;\n if (!hasLeadingContent) {\n if (!raw.trim().toLowerCase().endsWith(\"</svg>\")) {\n return [{ type: \"markdown\", value: `${raw}</svg>` }];\n }\n return [{ type: \"markdown\", value: raw }];\n }\n }\n\n const sandboxStartIndex = raw.search(SANDBOX_START_PATTERN);\n const inlineMatch = findInlineSandboxMatch(raw);\n\n if (sandboxStartIndex === -1 && !inlineMatch) {\n if (keepText && raw.trim()) {\n return [{ type: \"text\", value: raw }];\n }\n return [];\n }\n\n const shouldUseInline =\n !!inlineMatch &&\n (sandboxStartIndex === -1 || inlineMatch.start < sandboxStartIndex);\n\n const startIndex = shouldUseInline ? inlineMatch!.start : sandboxStartIndex;\n const blockEnd = shouldUseInline\n ? inlineMatch!.end\n : findHtmlBlockEnd(raw, startIndex);\n\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, startIndex);\n const matchedBlock = raw.slice(startIndex, blockEnd);\n const after = raw.slice(blockEnd);\n\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n\n segments.push({\n type: shouldUseInline ? \"markdown\" : \"sandbox\",\n value: matchedBlock,\n });\n\n if (after.trim()) {\n segments.push(...splitContentSegments(after, keepText));\n }\n\n return segments;\n};\n"],"names":["SANDBOX_START_PATTERN","INLINE_SANDBOX_PATTERNS","closingBoundary","findHtmlBlockEnd","raw","startIndex","blockEnd","match","findInlineSandboxMatch","earliest","pattern","start","end","extractTableBlock","tableMatch","leadingSpaces","tableStart","lines","tableLines","line","block","splitContentSegments","keepText","fenceStart","svgOpenIndex","tableBlock","segments","before","after","hasProgress","sandboxStartIndex","inlineMatch","shouldUseInline","matchedBlock"],"mappings":"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"}
1
+ {"version":3,"file":"split-content.cjs.js","sources":["../../../../src/components/ContentRender/utils/split-content.ts"],"sourcesContent":["export type RenderSegment =\n | { type: \"markdown\"; value: string }\n | { type: \"sandbox\"; value: string }\n | { type: \"text\"; value: string };\n\nconst SANDBOX_START_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\\s>]/i;\n\nconst INLINE_SANDBOX_PATTERNS: RegExp[] = [\n /<svg[\\s\\S]*?<\\/svg>/i,\n /<img\\b[^>]*?>/i,\n /```mermaid[\\s\\S]*?```/i,\n /```[a-zA-Z0-9]+[\\s\\S]*?```/i,\n];\nconst MARKDOWN_IMAGE_PATTERN = /!\\[[^\\]]*]\\([^\\s)\\n]+(?:\\s+\"[^\"]*\")?\\)/i;\n\nconst closingBoundary = /<\\/[a-z][^>]*>\\s*\\n(?=[^\\s<])/gi;\nconst CUSTOM_BUTTON_PATTERN =\n /<custom-button-after-content\\b[\\s\\S]*?<\\/custom-button-after-content>/gi;\n\ntype MatchResult = { start: number; end: number };\ntype FenceRange = { start: number; end: number };\n\nconst getFenceRanges = (raw: string): FenceRange[] => {\n const ranges: FenceRange[] = [];\n const fencePattern = /```/g;\n let match: RegExpExecArray | null;\n\n while ((match = fencePattern.exec(raw)) !== null) {\n const start = match.index;\n const closeMatch = fencePattern.exec(raw);\n if (!closeMatch) {\n ranges.push({ start, end: raw.length });\n break;\n }\n ranges.push({ start, end: closeMatch.index + 3 });\n }\n\n return ranges;\n};\n\nconst isIndexInRanges = (index: number, ranges: FenceRange[]) =>\n ranges.some(({ start, end }) => index >= start && index < end);\n\nconst findFirstMatchOutsideFence = (\n raw: string,\n pattern: RegExp,\n fenceRanges: FenceRange[]\n) => {\n const flags = pattern.flags.includes(\"g\")\n ? pattern.flags\n : `${pattern.flags}g`;\n const matcher = new RegExp(pattern.source, flags);\n let match: RegExpExecArray | null;\n\n while ((match = matcher.exec(raw)) !== null) {\n if (!isIndexInRanges(match.index, fenceRanges)) {\n return match.index;\n }\n }\n\n return -1;\n};\n\nconst findHtmlBlockEnd = (raw: string, startIndex: number) => {\n let blockEnd = raw.length;\n let match: RegExpExecArray | null;\n closingBoundary.lastIndex = 0;\n\n while ((match = closingBoundary.exec(raw))) {\n if (match.index <= startIndex) continue;\n blockEnd = match.index + match[0].length;\n break;\n }\n\n return blockEnd;\n};\n\nconst splitCustomButtonsFromSandbox = (segments: RenderSegment[]) => {\n if (!segments.length) return segments;\n const output: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type !== \"sandbox\") {\n output.push(segment);\n return;\n }\n\n CUSTOM_BUTTON_PATTERN.lastIndex = 0;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = CUSTOM_BUTTON_PATTERN.exec(segment.value)) !== null) {\n const before = segment.value.slice(lastIndex, match.index);\n if (before.trim()) {\n output.push({ type: \"sandbox\", value: before });\n }\n output.push({ type: \"markdown\", value: match[0] });\n lastIndex = match.index + match[0].length;\n }\n\n const rest = segment.value.slice(lastIndex);\n if (rest.trim()) {\n output.push({ type: \"sandbox\", value: rest });\n }\n });\n\n return output;\n};\n\nconst findInlineSandboxMatch = (raw: string): MatchResult | null => {\n let earliest: MatchResult | null = null;\n\n INLINE_SANDBOX_PATTERNS.forEach((pattern) => {\n const match = pattern.exec(raw);\n if (!match || typeof match.index !== \"number\") return;\n const start = match.index;\n const end = match.index + match[0].length;\n\n if (!earliest || start < earliest.start) {\n earliest = { start, end };\n }\n });\n\n return earliest;\n};\n\nconst findMarkdownImageMatch = (\n raw: string,\n fenceRanges: FenceRange[]\n): MatchResult | null => {\n const start = findFirstMatchOutsideFence(\n raw,\n MARKDOWN_IMAGE_PATTERN,\n fenceRanges\n );\n\n if (start === -1) return null;\n const match = raw.slice(start).match(MARKDOWN_IMAGE_PATTERN);\n if (!match) return null;\n\n return { start, end: start + match[0].length };\n};\n\nconst extractTableBlock = (\n raw: string\n): { start: number; block: string; end: number } | null => {\n const tableMatch = raw.match(/^\\s*\\|.+\\|\\s*$/m);\n if (!tableMatch || typeof tableMatch.index !== \"number\") return null;\n\n const leadingSpaces = tableMatch[0].match(/^\\s*/)?.[0].length ?? 0;\n const tableStart = tableMatch.index + leadingSpaces;\n\n const lines = raw.slice(tableStart).split(\"\\n\");\n const tableLines: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\")) break;\n tableLines.push(line);\n }\n\n const block = tableLines.join(\"\\n\");\n return { start: tableStart, block, end: tableStart + block.length };\n};\n\n// Split incoming markdown content into markdown and sandbox HTML segments\nexport const splitContentSegments = (\n raw: string,\n keepText = false\n): RenderSegment[] => {\n const finalizeSegments = (segments: RenderSegment[]) =>\n splitCustomButtonsFromSandbox(segments);\n\n const fenceStart = raw.indexOf(\"```\");\n if (keepText && fenceStart !== -1) {\n const closingFence = raw.indexOf(\"```\", fenceStart + 3);\n if (closingFence === -1) {\n return finalizeSegments([{ type: \"markdown\", value: raw }]);\n }\n }\n\n const fenceRanges = getFenceRanges(raw);\n // Avoid treating fenced code blocks as sandbox content.\n const sandboxStartIndex = findFirstMatchOutsideFence(\n raw,\n SANDBOX_START_PATTERN,\n fenceRanges\n );\n const svgOpenIndex = findFirstMatchOutsideFence(raw, /<svg\\b/i, fenceRanges);\n const hasSandboxBeforeSvg =\n sandboxStartIndex !== -1 &&\n svgOpenIndex !== -1 &&\n sandboxStartIndex < svgOpenIndex;\n if (svgOpenIndex !== -1 && !hasSandboxBeforeSvg) {\n const before = raw.slice(0, svgOpenIndex);\n const closeIdx = raw.indexOf(\"</svg>\", svgOpenIndex);\n const svgBlock =\n closeIdx === -1\n ? `${raw.slice(svgOpenIndex)}</svg>`\n : raw.slice(svgOpenIndex, closeIdx + \"</svg>\".length);\n const after = closeIdx === -1 ? \"\" : raw.slice(closeIdx + \"</svg>\".length);\n\n if (keepText) {\n const segments: RenderSegment[] = [];\n if (before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n segments.push({ type: \"markdown\", value: svgBlock });\n if (after.trim()) {\n segments.push(...splitContentSegments(after, true));\n }\n return finalizeSegments(segments);\n }\n\n if (closeIdx === -1) {\n return finalizeSegments([{ type: \"markdown\", value: svgBlock }]);\n }\n }\n\n const tableBlock = extractTableBlock(raw);\n if (tableBlock) {\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, tableBlock.start);\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n segments.push({ type: \"markdown\", value: tableBlock.block });\n const after = raw.slice(tableBlock.end);\n const hasProgress = after.length < raw.length;\n if (after.trim() && hasProgress) {\n segments.push(\n ...(keepText\n ? splitContentSegments(after, true)\n : splitContentSegments(after))\n );\n }\n return finalizeSegments(segments);\n }\n\n const inlineMatch = findInlineSandboxMatch(raw);\n const markdownImageMatch = findMarkdownImageMatch(raw, fenceRanges);\n const inlineCandidate =\n inlineMatch && markdownImageMatch\n ? inlineMatch.start <= markdownImageMatch.start\n ? inlineMatch\n : markdownImageMatch\n : (inlineMatch ?? markdownImageMatch);\n\n if (sandboxStartIndex === -1 && !inlineCandidate) {\n if (keepText && raw.trim()) {\n return finalizeSegments([{ type: \"text\", value: raw }]);\n }\n return [];\n }\n\n const shouldUseInline =\n !!inlineCandidate &&\n (sandboxStartIndex === -1 || inlineCandidate.start < sandboxStartIndex);\n\n const startIndex = shouldUseInline\n ? inlineCandidate!.start\n : sandboxStartIndex;\n const blockEnd = shouldUseInline\n ? inlineCandidate!.end\n : findHtmlBlockEnd(raw, startIndex);\n\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, startIndex);\n const matchedBlock = raw.slice(startIndex, blockEnd);\n const after = raw.slice(blockEnd);\n\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n\n segments.push({\n type: shouldUseInline ? \"markdown\" : \"sandbox\",\n value: matchedBlock,\n });\n\n if (after.trim()) {\n segments.push(...splitContentSegments(after, keepText));\n }\n\n return finalizeSegments(segments);\n};\n"],"names":["SANDBOX_START_PATTERN","INLINE_SANDBOX_PATTERNS","MARKDOWN_IMAGE_PATTERN","closingBoundary","CUSTOM_BUTTON_PATTERN","getFenceRanges","raw","ranges","fencePattern","match","start","closeMatch","isIndexInRanges","index","end","findFirstMatchOutsideFence","pattern","fenceRanges","flags","matcher","findHtmlBlockEnd","startIndex","blockEnd","splitCustomButtonsFromSandbox","segments","output","segment","lastIndex","before","rest","findInlineSandboxMatch","earliest","findMarkdownImageMatch","extractTableBlock","tableMatch","leadingSpaces","tableStart","lines","tableLines","line","block","splitContentSegments","keepText","finalizeSegments","fenceStart","sandboxStartIndex","svgOpenIndex","hasSandboxBeforeSvg","closeIdx","svgBlock","after","tableBlock","hasProgress","inlineMatch","markdownImageMatch","inlineCandidate","shouldUseInline","matchedBlock"],"mappings":"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"}
@@ -1,64 +1,118 @@
1
- const y = /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\s>]/i, k = [
1
+ const O = /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\s>]/i, R = [
2
2
  /<svg[\s\S]*?<\/svg>/i,
3
3
  /<img\b[^>]*?>/i,
4
4
  /```mermaid[\s\S]*?```/i,
5
5
  /```[a-zA-Z0-9]+[\s\S]*?```/i
6
- ], v = /<\/[a-z][^>]*>\s*\n(?=[^\s<])/gi, I = (t, n) => {
7
- let s = t.length, e;
8
- for (v.lastIndex = 0; e = v.exec(t); )
9
- if (!(e.index <= n)) {
10
- s = e.index + e[0].length;
6
+ ], B = /!\[[^\]]*]\([^\s)\n]+(?:\s+"[^"]*")?\)/i, M = /<\/[a-z][^>]*>\s*\n(?=[^\s<])/gi, A = /<custom-button-after-content\b[\s\S]*?<\/custom-button-after-content>/gi, T = (t) => {
7
+ const n = [], e = /```/g;
8
+ let s;
9
+ for (; (s = e.exec(t)) !== null; ) {
10
+ const o = s.index, c = e.exec(t);
11
+ if (!c) {
12
+ n.push({ start: o, end: t.length });
11
13
  break;
12
14
  }
13
- return s;
14
- }, B = (t) => {
15
+ n.push({ start: o, end: c.index + 3 });
16
+ }
17
+ return n;
18
+ }, _ = (t, n) => n.some(({ start: e, end: s }) => t >= e && t < s), y = (t, n, e) => {
19
+ const s = n.flags.includes("g") ? n.flags : `${n.flags}g`, o = new RegExp(n.source, s);
20
+ let c;
21
+ for (; (c = o.exec(t)) !== null; )
22
+ if (!_(c.index, e))
23
+ return c.index;
24
+ return -1;
25
+ }, F = (t, n) => {
26
+ let e = t.length, s;
27
+ for (M.lastIndex = 0; s = M.exec(t); )
28
+ if (!(s.index <= n)) {
29
+ e = s.index + s[0].length;
30
+ break;
31
+ }
32
+ return e;
33
+ }, P = (t) => {
34
+ if (!t.length) return t;
35
+ const n = [];
36
+ return t.forEach((e) => {
37
+ if (e.type !== "sandbox") {
38
+ n.push(e);
39
+ return;
40
+ }
41
+ A.lastIndex = 0;
42
+ let s = 0, o;
43
+ for (; (o = A.exec(e.value)) !== null; ) {
44
+ const i = e.value.slice(s, o.index);
45
+ i.trim() && n.push({ type: "sandbox", value: i }), n.push({ type: "markdown", value: o[0] }), s = o.index + o[0].length;
46
+ }
47
+ const c = e.value.slice(s);
48
+ c.trim() && n.push({ type: "sandbox", value: c });
49
+ }), n;
50
+ }, C = (t) => {
15
51
  let n = null;
16
- return k.forEach((s) => {
17
- const e = s.exec(t);
18
- if (!e || typeof e.index != "number") return;
19
- const i = e.index, r = e.index + e[0].length;
20
- (!n || i < n.start) && (n = { start: i, end: r });
52
+ return R.forEach((e) => {
53
+ const s = e.exec(t);
54
+ if (!s || typeof s.index != "number") return;
55
+ const o = s.index, c = s.index + s[0].length;
56
+ (!n || o < n.start) && (n = { start: o, end: c });
21
57
  }), n;
22
- }, E = (t) => {
58
+ }, z = (t, n) => {
59
+ const e = y(
60
+ t,
61
+ B,
62
+ n
63
+ );
64
+ if (e === -1) return null;
65
+ const s = t.slice(e).match(B);
66
+ return s ? { start: e, end: e + s[0].length } : null;
67
+ }, D = (t) => {
23
68
  const n = t.match(/^\s*\|.+\|\s*$/m);
24
69
  if (!n || typeof n.index != "number") return null;
25
- const s = n[0].match(/^\s*/)?.[0].length ?? 0, e = n.index + s, i = t.slice(e).split(`
26
- `), r = [];
27
- for (const c of i) {
28
- if (!c.trim().startsWith("|")) break;
29
- r.push(c);
70
+ const e = n[0].match(/^\s*/)?.[0].length ?? 0, s = n.index + e, o = t.slice(s).split(`
71
+ `), c = [];
72
+ for (const f of o) {
73
+ if (!f.trim().startsWith("|")) break;
74
+ c.push(f);
30
75
  }
31
- const o = r.join(`
76
+ const i = c.join(`
32
77
  `);
33
- return { start: e, block: o, end: e + o.length };
34
- }, u = (t, n = !1) => {
35
- const s = t.indexOf("```");
78
+ return { start: s, block: i, end: s + i.length };
79
+ }, p = (t, n = !1) => {
80
+ const e = (l) => P(l), s = t.indexOf("```");
36
81
  if (n && s !== -1 && t.indexOf("```", s + 3) === -1)
37
- return [{ type: "markdown", value: t }];
38
- const e = t.search(/<svg\b/i);
39
- if (e !== -1 && t.indexOf("</svg>", e) === -1)
40
- return [{ type: "markdown", value: t }];
41
- const i = E(t);
42
- if (i) {
43
- const l = [], p = t.slice(0, i.start);
44
- n && p.trim() && l.push({ type: "text", value: p }), l.push({ type: "markdown", value: i.block });
45
- const m = t.slice(i.end), S = m.length < t.length;
46
- return m.trim() && S && l.push(
47
- ...n ? u(m, !0) : u(m)
48
- ), l;
82
+ return e([{ type: "markdown", value: t }]);
83
+ const o = T(t), c = y(
84
+ t,
85
+ O,
86
+ o
87
+ ), i = y(t, /<svg\b/i, o), f = c !== -1 && i !== -1 && c < i;
88
+ if (i !== -1 && !f) {
89
+ const l = t.slice(0, i), a = t.indexOf("</svg>", i), r = a === -1 ? `${t.slice(i)}</svg>` : t.slice(i, a + 6), x = a === -1 ? "" : t.slice(a + 6);
90
+ if (n) {
91
+ const b = [];
92
+ return l.trim() && b.push({ type: "text", value: l }), b.push({ type: "markdown", value: r }), x.trim() && b.push(...p(x, !0)), e(b);
93
+ }
94
+ if (a === -1)
95
+ return e([{ type: "markdown", value: r }]);
96
+ }
97
+ const u = D(t);
98
+ if (u) {
99
+ const l = [], a = t.slice(0, u.start);
100
+ n && a.trim() && l.push({ type: "text", value: a }), l.push({ type: "markdown", value: u.block });
101
+ const r = t.slice(u.end), x = r.length < t.length;
102
+ return r.trim() && x && l.push(
103
+ ...n ? p(r, !0) : p(r)
104
+ ), e(l);
49
105
  }
50
- if (t.match(/<svg[\s\S]*?<\/svg>/i) && n && !(e > -1 && t.slice(0, e).trim().length > 0))
51
- return t.trim().toLowerCase().endsWith("</svg>") ? [{ type: "markdown", value: t }] : [{ type: "markdown", value: `${t}</svg>` }];
52
- const o = t.search(y), c = B(t);
53
- if (o === -1 && !c)
54
- return n && t.trim() ? [{ type: "text", value: t }] : [];
55
- const a = !!c && (o === -1 || c.start < o), h = a ? c.start : o, f = a ? c.end : I(t, h), d = [], g = t.slice(0, h), x = t.slice(h, f), b = t.slice(f);
56
- return n && g.trim() && d.push({ type: "text", value: g }), d.push({
57
- type: a ? "markdown" : "sandbox",
58
- value: x
59
- }), b.trim() && d.push(...u(b, n)), d;
106
+ const h = C(t), m = z(t, o), d = h && m ? h.start <= m.start ? h : m : h ?? m;
107
+ if (c === -1 && !d)
108
+ return n && t.trim() ? e([{ type: "text", value: t }]) : [];
109
+ const v = !!d && (c === -1 || d.start < c), S = v ? d.start : c, I = v ? d.end : F(t, S), g = [], k = t.slice(0, S), N = t.slice(S, I), E = t.slice(I);
110
+ return n && k.trim() && g.push({ type: "text", value: k }), g.push({
111
+ type: v ? "markdown" : "sandbox",
112
+ value: N
113
+ }), E.trim() && g.push(...p(E, n)), e(g);
60
114
  };
61
115
  export {
62
- u as splitContentSegments
116
+ p as splitContentSegments
63
117
  };
64
118
  //# sourceMappingURL=split-content.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"split-content.es.js","sources":["../../../../src/components/ContentRender/utils/split-content.ts"],"sourcesContent":["export type RenderSegment =\n | { type: \"markdown\"; value: string }\n | { type: \"sandbox\"; value: string }\n | { type: \"text\"; value: string };\n\nconst SANDBOX_START_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\\s>]/i;\n\nconst INLINE_SANDBOX_PATTERNS: RegExp[] = [\n /<svg[\\s\\S]*?<\\/svg>/i,\n /<img\\b[^>]*?>/i,\n /```mermaid[\\s\\S]*?```/i,\n /```[a-zA-Z0-9]+[\\s\\S]*?```/i,\n];\n\nconst closingBoundary = /<\\/[a-z][^>]*>\\s*\\n(?=[^\\s<])/gi;\n\ntype MatchResult = { start: number; end: number };\n\nconst findHtmlBlockEnd = (raw: string, startIndex: number) => {\n let blockEnd = raw.length;\n let match: RegExpExecArray | null;\n closingBoundary.lastIndex = 0;\n\n while ((match = closingBoundary.exec(raw))) {\n if (match.index <= startIndex) continue;\n blockEnd = match.index + match[0].length;\n break;\n }\n\n return blockEnd;\n};\n\nconst findInlineSandboxMatch = (raw: string): MatchResult | null => {\n let earliest: MatchResult | null = null;\n\n INLINE_SANDBOX_PATTERNS.forEach((pattern) => {\n const match = pattern.exec(raw);\n if (!match || typeof match.index !== \"number\") return;\n const start = match.index;\n const end = match.index + match[0].length;\n\n if (!earliest || start < earliest.start) {\n earliest = { start, end };\n }\n });\n\n return earliest;\n};\n\nconst extractTableBlock = (\n raw: string\n): { start: number; block: string; end: number } | null => {\n const tableMatch = raw.match(/^\\s*\\|.+\\|\\s*$/m);\n if (!tableMatch || typeof tableMatch.index !== \"number\") return null;\n\n const leadingSpaces = tableMatch[0].match(/^\\s*/)?.[0].length ?? 0;\n const tableStart = tableMatch.index + leadingSpaces;\n\n const lines = raw.slice(tableStart).split(\"\\n\");\n const tableLines: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\")) break;\n tableLines.push(line);\n }\n\n const block = tableLines.join(\"\\n\");\n return { start: tableStart, block, end: tableStart + block.length };\n};\n\n// Split incoming markdown content into markdown and sandbox HTML segments\nexport const splitContentSegments = (\n raw: string,\n keepText = false\n): RenderSegment[] => {\n const fenceStart = raw.indexOf(\"```\");\n if (keepText && fenceStart !== -1) {\n const closingFence = raw.indexOf(\"```\", fenceStart + 3);\n if (closingFence === -1) {\n return [{ type: \"markdown\", value: raw }];\n }\n }\n\n const svgOpenIndex = raw.search(/<svg\\b/i);\n if (svgOpenIndex !== -1 && raw.indexOf(\"</svg>\", svgOpenIndex) === -1) {\n return [{ type: \"markdown\", value: raw }];\n }\n\n const tableBlock = extractTableBlock(raw);\n if (tableBlock) {\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, tableBlock.start);\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n segments.push({ type: \"markdown\", value: tableBlock.block });\n const after = raw.slice(tableBlock.end);\n const hasProgress = after.length < raw.length;\n if (after.trim() && hasProgress) {\n segments.push(\n ...(keepText\n ? splitContentSegments(after, true)\n : splitContentSegments(after))\n );\n }\n return segments;\n }\n\n const completeSvgMatch = raw.match(/<svg[\\s\\S]*?<\\/svg>/i);\n if (completeSvgMatch && keepText) {\n const hasLeadingContent =\n svgOpenIndex > -1 && raw.slice(0, svgOpenIndex).trim().length > 0;\n if (!hasLeadingContent) {\n if (!raw.trim().toLowerCase().endsWith(\"</svg>\")) {\n return [{ type: \"markdown\", value: `${raw}</svg>` }];\n }\n return [{ type: \"markdown\", value: raw }];\n }\n }\n\n const sandboxStartIndex = raw.search(SANDBOX_START_PATTERN);\n const inlineMatch = findInlineSandboxMatch(raw);\n\n if (sandboxStartIndex === -1 && !inlineMatch) {\n if (keepText && raw.trim()) {\n return [{ type: \"text\", value: raw }];\n }\n return [];\n }\n\n const shouldUseInline =\n !!inlineMatch &&\n (sandboxStartIndex === -1 || inlineMatch.start < sandboxStartIndex);\n\n const startIndex = shouldUseInline ? inlineMatch!.start : sandboxStartIndex;\n const blockEnd = shouldUseInline\n ? inlineMatch!.end\n : findHtmlBlockEnd(raw, startIndex);\n\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, startIndex);\n const matchedBlock = raw.slice(startIndex, blockEnd);\n const after = raw.slice(blockEnd);\n\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n\n segments.push({\n type: shouldUseInline ? \"markdown\" : \"sandbox\",\n value: matchedBlock,\n });\n\n if (after.trim()) {\n segments.push(...splitContentSegments(after, keepText));\n }\n\n return segments;\n};\n"],"names":["SANDBOX_START_PATTERN","INLINE_SANDBOX_PATTERNS","closingBoundary","findHtmlBlockEnd","raw","startIndex","blockEnd","match","findInlineSandboxMatch","earliest","pattern","start","end","extractTableBlock","tableMatch","leadingSpaces","tableStart","lines","tableLines","line","block","splitContentSegments","keepText","fenceStart","svgOpenIndex","tableBlock","segments","before","after","hasProgress","sandboxStartIndex","inlineMatch","shouldUseInline","matchedBlock"],"mappings":"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"}
1
+ {"version":3,"file":"split-content.es.js","sources":["../../../../src/components/ContentRender/utils/split-content.ts"],"sourcesContent":["export type RenderSegment =\n | { type: \"markdown\"; value: string }\n | { type: \"sandbox\"; value: string }\n | { type: \"text\"; value: string };\n\nconst SANDBOX_START_PATTERN =\n /<(script|style|link|iframe|html|head|body|meta|title|base|template|div|section|article|main)[\\s>]/i;\n\nconst INLINE_SANDBOX_PATTERNS: RegExp[] = [\n /<svg[\\s\\S]*?<\\/svg>/i,\n /<img\\b[^>]*?>/i,\n /```mermaid[\\s\\S]*?```/i,\n /```[a-zA-Z0-9]+[\\s\\S]*?```/i,\n];\nconst MARKDOWN_IMAGE_PATTERN = /!\\[[^\\]]*]\\([^\\s)\\n]+(?:\\s+\"[^\"]*\")?\\)/i;\n\nconst closingBoundary = /<\\/[a-z][^>]*>\\s*\\n(?=[^\\s<])/gi;\nconst CUSTOM_BUTTON_PATTERN =\n /<custom-button-after-content\\b[\\s\\S]*?<\\/custom-button-after-content>/gi;\n\ntype MatchResult = { start: number; end: number };\ntype FenceRange = { start: number; end: number };\n\nconst getFenceRanges = (raw: string): FenceRange[] => {\n const ranges: FenceRange[] = [];\n const fencePattern = /```/g;\n let match: RegExpExecArray | null;\n\n while ((match = fencePattern.exec(raw)) !== null) {\n const start = match.index;\n const closeMatch = fencePattern.exec(raw);\n if (!closeMatch) {\n ranges.push({ start, end: raw.length });\n break;\n }\n ranges.push({ start, end: closeMatch.index + 3 });\n }\n\n return ranges;\n};\n\nconst isIndexInRanges = (index: number, ranges: FenceRange[]) =>\n ranges.some(({ start, end }) => index >= start && index < end);\n\nconst findFirstMatchOutsideFence = (\n raw: string,\n pattern: RegExp,\n fenceRanges: FenceRange[]\n) => {\n const flags = pattern.flags.includes(\"g\")\n ? pattern.flags\n : `${pattern.flags}g`;\n const matcher = new RegExp(pattern.source, flags);\n let match: RegExpExecArray | null;\n\n while ((match = matcher.exec(raw)) !== null) {\n if (!isIndexInRanges(match.index, fenceRanges)) {\n return match.index;\n }\n }\n\n return -1;\n};\n\nconst findHtmlBlockEnd = (raw: string, startIndex: number) => {\n let blockEnd = raw.length;\n let match: RegExpExecArray | null;\n closingBoundary.lastIndex = 0;\n\n while ((match = closingBoundary.exec(raw))) {\n if (match.index <= startIndex) continue;\n blockEnd = match.index + match[0].length;\n break;\n }\n\n return blockEnd;\n};\n\nconst splitCustomButtonsFromSandbox = (segments: RenderSegment[]) => {\n if (!segments.length) return segments;\n const output: RenderSegment[] = [];\n\n segments.forEach((segment) => {\n if (segment.type !== \"sandbox\") {\n output.push(segment);\n return;\n }\n\n CUSTOM_BUTTON_PATTERN.lastIndex = 0;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = CUSTOM_BUTTON_PATTERN.exec(segment.value)) !== null) {\n const before = segment.value.slice(lastIndex, match.index);\n if (before.trim()) {\n output.push({ type: \"sandbox\", value: before });\n }\n output.push({ type: \"markdown\", value: match[0] });\n lastIndex = match.index + match[0].length;\n }\n\n const rest = segment.value.slice(lastIndex);\n if (rest.trim()) {\n output.push({ type: \"sandbox\", value: rest });\n }\n });\n\n return output;\n};\n\nconst findInlineSandboxMatch = (raw: string): MatchResult | null => {\n let earliest: MatchResult | null = null;\n\n INLINE_SANDBOX_PATTERNS.forEach((pattern) => {\n const match = pattern.exec(raw);\n if (!match || typeof match.index !== \"number\") return;\n const start = match.index;\n const end = match.index + match[0].length;\n\n if (!earliest || start < earliest.start) {\n earliest = { start, end };\n }\n });\n\n return earliest;\n};\n\nconst findMarkdownImageMatch = (\n raw: string,\n fenceRanges: FenceRange[]\n): MatchResult | null => {\n const start = findFirstMatchOutsideFence(\n raw,\n MARKDOWN_IMAGE_PATTERN,\n fenceRanges\n );\n\n if (start === -1) return null;\n const match = raw.slice(start).match(MARKDOWN_IMAGE_PATTERN);\n if (!match) return null;\n\n return { start, end: start + match[0].length };\n};\n\nconst extractTableBlock = (\n raw: string\n): { start: number; block: string; end: number } | null => {\n const tableMatch = raw.match(/^\\s*\\|.+\\|\\s*$/m);\n if (!tableMatch || typeof tableMatch.index !== \"number\") return null;\n\n const leadingSpaces = tableMatch[0].match(/^\\s*/)?.[0].length ?? 0;\n const tableStart = tableMatch.index + leadingSpaces;\n\n const lines = raw.slice(tableStart).split(\"\\n\");\n const tableLines: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\")) break;\n tableLines.push(line);\n }\n\n const block = tableLines.join(\"\\n\");\n return { start: tableStart, block, end: tableStart + block.length };\n};\n\n// Split incoming markdown content into markdown and sandbox HTML segments\nexport const splitContentSegments = (\n raw: string,\n keepText = false\n): RenderSegment[] => {\n const finalizeSegments = (segments: RenderSegment[]) =>\n splitCustomButtonsFromSandbox(segments);\n\n const fenceStart = raw.indexOf(\"```\");\n if (keepText && fenceStart !== -1) {\n const closingFence = raw.indexOf(\"```\", fenceStart + 3);\n if (closingFence === -1) {\n return finalizeSegments([{ type: \"markdown\", value: raw }]);\n }\n }\n\n const fenceRanges = getFenceRanges(raw);\n // Avoid treating fenced code blocks as sandbox content.\n const sandboxStartIndex = findFirstMatchOutsideFence(\n raw,\n SANDBOX_START_PATTERN,\n fenceRanges\n );\n const svgOpenIndex = findFirstMatchOutsideFence(raw, /<svg\\b/i, fenceRanges);\n const hasSandboxBeforeSvg =\n sandboxStartIndex !== -1 &&\n svgOpenIndex !== -1 &&\n sandboxStartIndex < svgOpenIndex;\n if (svgOpenIndex !== -1 && !hasSandboxBeforeSvg) {\n const before = raw.slice(0, svgOpenIndex);\n const closeIdx = raw.indexOf(\"</svg>\", svgOpenIndex);\n const svgBlock =\n closeIdx === -1\n ? `${raw.slice(svgOpenIndex)}</svg>`\n : raw.slice(svgOpenIndex, closeIdx + \"</svg>\".length);\n const after = closeIdx === -1 ? \"\" : raw.slice(closeIdx + \"</svg>\".length);\n\n if (keepText) {\n const segments: RenderSegment[] = [];\n if (before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n segments.push({ type: \"markdown\", value: svgBlock });\n if (after.trim()) {\n segments.push(...splitContentSegments(after, true));\n }\n return finalizeSegments(segments);\n }\n\n if (closeIdx === -1) {\n return finalizeSegments([{ type: \"markdown\", value: svgBlock }]);\n }\n }\n\n const tableBlock = extractTableBlock(raw);\n if (tableBlock) {\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, tableBlock.start);\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n segments.push({ type: \"markdown\", value: tableBlock.block });\n const after = raw.slice(tableBlock.end);\n const hasProgress = after.length < raw.length;\n if (after.trim() && hasProgress) {\n segments.push(\n ...(keepText\n ? splitContentSegments(after, true)\n : splitContentSegments(after))\n );\n }\n return finalizeSegments(segments);\n }\n\n const inlineMatch = findInlineSandboxMatch(raw);\n const markdownImageMatch = findMarkdownImageMatch(raw, fenceRanges);\n const inlineCandidate =\n inlineMatch && markdownImageMatch\n ? inlineMatch.start <= markdownImageMatch.start\n ? inlineMatch\n : markdownImageMatch\n : (inlineMatch ?? markdownImageMatch);\n\n if (sandboxStartIndex === -1 && !inlineCandidate) {\n if (keepText && raw.trim()) {\n return finalizeSegments([{ type: \"text\", value: raw }]);\n }\n return [];\n }\n\n const shouldUseInline =\n !!inlineCandidate &&\n (sandboxStartIndex === -1 || inlineCandidate.start < sandboxStartIndex);\n\n const startIndex = shouldUseInline\n ? inlineCandidate!.start\n : sandboxStartIndex;\n const blockEnd = shouldUseInline\n ? inlineCandidate!.end\n : findHtmlBlockEnd(raw, startIndex);\n\n const segments: RenderSegment[] = [];\n const before = raw.slice(0, startIndex);\n const matchedBlock = raw.slice(startIndex, blockEnd);\n const after = raw.slice(blockEnd);\n\n if (keepText && before.trim()) {\n segments.push({ type: \"text\", value: before });\n }\n\n segments.push({\n type: shouldUseInline ? \"markdown\" : \"sandbox\",\n value: matchedBlock,\n });\n\n if (after.trim()) {\n segments.push(...splitContentSegments(after, keepText));\n }\n\n return finalizeSegments(segments);\n};\n"],"names":["SANDBOX_START_PATTERN","INLINE_SANDBOX_PATTERNS","MARKDOWN_IMAGE_PATTERN","closingBoundary","CUSTOM_BUTTON_PATTERN","getFenceRanges","raw","ranges","fencePattern","match","start","closeMatch","isIndexInRanges","index","end","findFirstMatchOutsideFence","pattern","fenceRanges","flags","matcher","findHtmlBlockEnd","startIndex","blockEnd","splitCustomButtonsFromSandbox","segments","output","segment","lastIndex","before","rest","findInlineSandboxMatch","earliest","findMarkdownImageMatch","extractTableBlock","tableMatch","leadingSpaces","tableStart","lines","tableLines","line","block","splitContentSegments","keepText","finalizeSegments","fenceStart","sandboxStartIndex","svgOpenIndex","hasSandboxBeforeSvg","closeIdx","svgBlock","after","tableBlock","hasProgress","inlineMatch","markdownImageMatch","inlineCandidate","shouldUseInline","matchedBlock"],"mappings":"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"}