llm-message-react 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -2
- package/dist/index.cjs +50 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +50 -16
- package/dist/index.js.map +1 -1
- package/dist/styles.css +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,8 +14,6 @@ A single React component that renders LLM markdown output the way a polished cha
|
|
|
14
14
|
npm install llm-message-react
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`react` and `react-dom` (>=18) are peer dependencies.
|
|
18
|
-
|
|
19
17
|
## Usage
|
|
20
18
|
|
|
21
19
|
```tsx
|
|
@@ -114,6 +112,38 @@ Notes:
|
|
|
114
112
|
|
|
115
113
|
`LLMMessage` repairs partially-streamed markdown/LaTeX by default, so unterminated tokens (`**bold`, `` `code ``, `[label](http`, `$E = mc^2`, `\[ ... `) don't flash as raw delimiters while a response streams in. Disable it with `completePartialTokens={false}`.
|
|
116
114
|
|
|
115
|
+
### Turn repair off once streaming is done
|
|
116
|
+
|
|
117
|
+
The repair only helps _while_ text is still arriving. On a finished message it can do harm: a single trailing `$` (or a stray `\`) that is really part of the content gets read as the start of an unterminated math token and "completed", so a final string like `Pay $12\at the door` is mistaken for LaTeX and mangled.
|
|
118
|
+
|
|
119
|
+
If you know when a message has finished streaming, gate `completePartialTokens` on that. Keep it `true` while streaming, then flip it to `false` once the stream closes so the final, complete text is rendered verbatim:
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { useEffect, useState } from "react";
|
|
123
|
+
import { LLMMessage } from "llm-message-react";
|
|
124
|
+
import "llm-message-react/styles.css";
|
|
125
|
+
|
|
126
|
+
export function StreamedMessage({ messageId }: { messageId: string }) {
|
|
127
|
+
const [content, setContent] = useState("");
|
|
128
|
+
const [isStreaming, setIsStreaming] = useState(true);
|
|
129
|
+
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
const stream = subscribeToMessage(messageId, {
|
|
132
|
+
onToken: (token) => setContent((prev) => prev + token),
|
|
133
|
+
onDone: () => setIsStreaming(false), // stream finished
|
|
134
|
+
});
|
|
135
|
+
return () => stream.close();
|
|
136
|
+
}, [messageId]);
|
|
137
|
+
|
|
138
|
+
// Repair partial tokens while streaming, render verbatim once done.
|
|
139
|
+
return (
|
|
140
|
+
<LLMMessage completePartialTokens={isStreaming}>{content}</LLMMessage>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This way half-streamed tokens are still repaired mid-stream, but the completed message is never "fixed" into something it isn't.
|
|
146
|
+
|
|
117
147
|
### Unfinished block math
|
|
118
148
|
|
|
119
149
|
By default, unterminated **block** math (`\[ ... `, `$$ ... `) is rendered _progressively_: the open environments/braces are closed and the largest prefix KaTeX accepts is shown, so a long aligned block reveals itself row by row instead of popping in only once the closing delimiter arrives.
|
package/dist/index.cjs
CHANGED
|
@@ -132,7 +132,7 @@ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
|
|
|
132
132
|
opens.push({
|
|
133
133
|
index: text.lastIndexOf("\\("),
|
|
134
134
|
open: "\\(",
|
|
135
|
-
close: "",
|
|
135
|
+
close: "\\)",
|
|
136
136
|
block: false,
|
|
137
137
|
display: false
|
|
138
138
|
});
|
|
@@ -155,16 +155,12 @@ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
|
|
|
155
155
|
/(?<!\\)\$(?!\$)\d[\d\s.,+\-*/=]*\$/g,
|
|
156
156
|
(m) => " ".repeat(m.length)
|
|
157
157
|
);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
lastDollar = match.index;
|
|
161
|
-
}
|
|
162
|
-
const singles = masked.match(/(?<!\\)\$(?!\d)/g) ?? [];
|
|
163
|
-
if (singles.length % 2 === 1 && lastDollar !== -1) {
|
|
158
|
+
const dollars = inlineMathDollarIndices(masked);
|
|
159
|
+
if (dollars.length % 2 === 1) {
|
|
164
160
|
opens.push({
|
|
165
|
-
index:
|
|
161
|
+
index: dollars[dollars.length - 1],
|
|
166
162
|
open: "$",
|
|
167
|
-
close: "",
|
|
163
|
+
close: "$",
|
|
168
164
|
block: false,
|
|
169
165
|
display: false
|
|
170
166
|
});
|
|
@@ -174,14 +170,11 @@ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
|
|
|
174
170
|
if (valid.length === 0) return text;
|
|
175
171
|
const open = valid.reduce((a, b) => b.index < a.index ? b : a);
|
|
176
172
|
const before = text.slice(0, open.index);
|
|
177
|
-
if (!open.block) {
|
|
178
|
-
return before;
|
|
179
|
-
}
|
|
180
173
|
if (!showUnfinishedLatexBlocks) {
|
|
181
174
|
return before;
|
|
182
175
|
}
|
|
183
176
|
const inner = text.slice(open.index + open.open.length);
|
|
184
|
-
const body = bestRenderableMathBody(inner, open.display);
|
|
177
|
+
const body = bestRenderableMathBody(inner, open.display, open.block);
|
|
185
178
|
if (body == null) return before;
|
|
186
179
|
const blockLayout = /^[ \t]*\r?\n/.test(inner);
|
|
187
180
|
if (!blockLayout) {
|
|
@@ -192,14 +185,51 @@ ${open.open}`;
|
|
|
192
185
|
return `${before}${opener}${body.replace(/\s+$/, "")}
|
|
193
186
|
${open.close}`;
|
|
194
187
|
}
|
|
195
|
-
function
|
|
188
|
+
function inlineMathDollarIndices(masked) {
|
|
189
|
+
const indices = [];
|
|
190
|
+
const pattern = /(?<!\\)\$/g;
|
|
191
|
+
let match;
|
|
192
|
+
while ((match = pattern.exec(masked)) != null) {
|
|
193
|
+
const index = match.index;
|
|
194
|
+
if (/\d/.test(masked[index + 1] ?? "")) {
|
|
195
|
+
const rest = masked.slice(index + 1);
|
|
196
|
+
const end = rest.search(/(?<!\\)\$|\n/);
|
|
197
|
+
const span = end === -1 ? rest : rest.slice(0, end);
|
|
198
|
+
if (!/\\[a-zA-Z]/.test(span)) continue;
|
|
199
|
+
}
|
|
200
|
+
indices.push(index);
|
|
201
|
+
}
|
|
202
|
+
return indices;
|
|
203
|
+
}
|
|
204
|
+
function bestRenderableMathBody(inner, display, block) {
|
|
196
205
|
const candidates = unclosedEnvironments(inner).length > 0 ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))] : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];
|
|
206
|
+
if (!block) {
|
|
207
|
+
candidates.unshift(
|
|
208
|
+
closeOpenMathConstructs(
|
|
209
|
+
trimIncompleteMathTail(dropIncompleteBraceGroup(inner))
|
|
210
|
+
)
|
|
211
|
+
);
|
|
212
|
+
}
|
|
197
213
|
for (const candidate of candidates) {
|
|
198
214
|
if (!hasRenderableMathContent(candidate)) continue;
|
|
199
215
|
if (isRenderableMath(candidate, display)) return candidate;
|
|
200
216
|
}
|
|
201
217
|
return null;
|
|
202
218
|
}
|
|
219
|
+
function dropIncompleteBraceGroup(text) {
|
|
220
|
+
const stack = [];
|
|
221
|
+
for (let i = 0; i < text.length; i++) {
|
|
222
|
+
const char = text[i];
|
|
223
|
+
if (char === "\\") {
|
|
224
|
+
i++;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (char === "{") stack.push(i);
|
|
228
|
+
else if (char === "}" && stack.length > 0) stack.pop();
|
|
229
|
+
}
|
|
230
|
+
if (stack.length === 0) return text;
|
|
231
|
+
return text.slice(0, stack[0]);
|
|
232
|
+
}
|
|
203
233
|
function hasRenderableMathContent(body) {
|
|
204
234
|
const stripped = body.replace(/\\(?:begin|end)\s*\{[^}]*\}/g, "").replace(/[\s{}]/g, "");
|
|
205
235
|
return stripped.length > 0;
|
|
@@ -309,9 +339,13 @@ function closeDoubleUnderscore(text) {
|
|
|
309
339
|
if (!opensAtWordBoundary(text, lastIndex)) return text;
|
|
310
340
|
return insertBeforeTrailingWhitespace(text, "__");
|
|
311
341
|
}
|
|
342
|
+
function maskBlockAsterisks(text) {
|
|
343
|
+
return text.replace(/^[ \t]*\*(?:[ \t]*\*){2,}[ \t]*$/gm, (m) => " ".repeat(m.length)).replace(/^[ \t]*\*(?=[ \t])/gm, (m) => " ".repeat(m.length));
|
|
344
|
+
}
|
|
312
345
|
function closeRunMarker(text, marker) {
|
|
313
346
|
const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
314
|
-
const
|
|
347
|
+
const countSource = marker.includes("*") ? maskBlockAsterisks(text) : text;
|
|
348
|
+
const count = (countSource.match(new RegExp(escaped, "g")) ?? []).length;
|
|
315
349
|
if (count % 2 === 0) return text;
|
|
316
350
|
const lastIndex = text.lastIndexOf(marker);
|
|
317
351
|
const after = text.slice(lastIndex + marker.length);
|
|
@@ -319,7 +353,7 @@ function closeRunMarker(text, marker) {
|
|
|
319
353
|
return insertBeforeTrailingWhitespace(text, marker);
|
|
320
354
|
}
|
|
321
355
|
function closeSingleAsterisk(text) {
|
|
322
|
-
const masked = text.replace(/\*\*/g, "");
|
|
356
|
+
const masked = maskBlockAsterisks(text).replace(/\*\*/g, "");
|
|
323
357
|
const count = (masked.match(/\*/g) ?? []).length;
|
|
324
358
|
if (count % 2 === 0) return text;
|
|
325
359
|
const lastIndex = text.lastIndexOf("*");
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/completePartialTokens.ts","../src/CopyButton.tsx","../src/preprocess.ts","../src/LLMMessage.tsx","../src/createShikiHighlighter.tsx"],"names":["katex","jsxs","jsx","useState","useRef","useEffect","remarkGfm","remarkMath","rehypeKatex","clsx","Fragment","useMemo","ReactMarkdown"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsCO,SAAS,qBAAA,CACd,MACA,OAAA,EACQ;AACR,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,EAAA,MAAM,yBAAA,GAA4B,SAAS,yBAAA,IAA6B,IAAA;AAKxE,EAAA,IAAI,oBAAA,CAAqB,IAAI,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,iBAA2B,EAAC;AAClC,EAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KACf,CAAA,OAAA,EAAc,eAAe,IAAA,CAAK,KAAK,IAAI,CAAC,CAAA,EAAA,CAAA;AAM9C,EAAA,IAAI,OAAA,GAAU,KAAK,OAAA,CAAQ,iBAAA,EAAmB,CAAC,KAAA,KAAU,OAAA,CAAQ,KAAK,CAAC,CAAA;AACvE,EAAA,OAAA,GAAU,QAAQ,OAAA,CAAQ,eAAA,EAAiB,CAAC,KAAA,KAAU,OAAA,CAAQ,KAAK,CAAC,CAAA;AACpE,EAAA,OAAA,GAAU,QAAQ,OAAA,CAAQ,YAAA,EAAc,CAAC,KAAA,KAAU,OAAA,CAAQ,KAAK,CAAC,CAAA;AAIjE,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,WAAA,CAAY,GAAG,CAAA;AAC5C,EAAA,IAAI,iBAAiB,EAAA,EAAI;AAGvB,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,YAAY,CAAA;AAClD,IAAA,MAAM,GAAA,GAAM,OAAA,KAAY,EAAA,GAAK,OAAA,CAAQ,MAAA,GAAS,OAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,GAAG,CAAA;AAC5C,IAAA,OAAA,GACE,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,YAAY,CAAA,GAC7B,OAAA,CAAQ,CAAA,EAAG,IAAI,CAAA,EAAA,CAAI,CAAA,GACnB,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA;AAAA,EACrB;AAEA,EAAA,OAAA,GAAU,oBAAA,CAAqB,SAAS,yBAAyB,CAAA;AACjE,EAAA,OAAA,GAAU,mBAAmB,OAAO,CAAA;AACpC,EAAA,OAAA,GAAU,qBAAqB,OAAO,CAAA;AACtC,EAAA,OAAA,GAAU,uBAAuB,OAAO,CAAA;AACxC,EAAA,OAAA,GAAU,wBAAwB,OAAO,CAAA;AAEzC,EAAA,OAAO,OAAA,CAAQ,OAAA;AAAA,IACb,yBAAA;AAAA,IACA,CAAC,MAAA,EAAQ,KAAA,KAAkB,eAAe,MAAA,CAAO,KAAK,CAAC,CAAA,IAAK;AAAA,GAC9D;AACF;AAYA,SAAS,qBAAqB,IAAA,EAAsB;AAClD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAE7B,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAGnC,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,IAAK,CAAC,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAExD,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACrC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,GAAG,GAAG,OAAO,IAAA;AAMlC,EAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACzB,IAAA,IAAI,GAAA,CAAI,KAAK,IAAI,CAAA,IAAK,aAAa,IAAA,CAAK,IAAI,GAAG,OAAO,IAAA;AAAA,EACxD;AAEA,EAAA,MAAM,OAAA,GAAU,kBAAkB,MAAM,CAAA;AACxC,EAAA,KAAA,CAAM,MAAM,MAAA,GAAS,CAAC,CAAA,GAAI,iBAAA,CAAkB,MAAM,OAAO,CAAA;AACzD,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAGA,SAAS,kBAAkB,GAAA,EAAqB;AAC9C,EAAA,IAAI,KAAA,GAAQ,IAAI,IAAA,EAAK;AACrB,EAAA,IAAI,MAAM,UAAA,CAAW,GAAG,GAAG,KAAA,GAAQ,KAAA,CAAM,MAAM,CAAC,CAAA;AAChD,EAAA,IAAI,KAAA,CAAM,SAAS,GAAG,CAAA,UAAW,KAAA,CAAM,KAAA,CAAM,GAAG,EAAE,CAAA;AAClD,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA;AAC1B;AAMA,SAAS,iBAAA,CAAkB,UAAkB,OAAA,EAAyB;AACpE,EAAA,IAAI,KAAA,GAAQ,SAAS,IAAA,EAAK;AAC1B,EAAA,IAAI,MAAM,UAAA,CAAW,GAAG,GAAG,KAAA,GAAQ,KAAA,CAAM,MAAM,CAAC,CAAA;AAChD,EAAA,IAAI,KAAA,CAAM,SAAS,GAAG,CAAA,UAAW,KAAA,CAAM,KAAA,CAAM,GAAG,EAAE,CAAA;AAClD,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,CAAA;AAE3D,EAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,EAAE,QAAQ,OAAA,EAAQ,EAAG,CAAC,OAAA,EAAS,KAAA,KAAU;AAChE,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,KAAK,CAAA,IAAK,EAAA;AAChC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA;AAC/B,IAAA,IAAI,IAAA,IAAQ,OAAO,OAAO,OAAA;AAC1B,IAAA,IAAI,OAAO,OAAO,MAAA;AAClB,IAAA,IAAI,MAAM,OAAO,MAAA;AACjB,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO,CAAA,EAAA,EAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA,EAAA,CAAA;AAC/B;AAYA,SAAS,uBAAuB,IAAA,EAAsB;AACpD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,uBAAuB,CAAA;AAChD,EAAA,IAAI,KAAA,EAAO,KAAA,IAAS,IAAA,EAAM,OAAO,IAAA;AAEjC,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,MAAM,KAAK,CAAA;AACxC,EAAA,MAAM,WAAW,MAAA,CAAO,KAAA,CAAM,OAAO,WAAA,CAAY,IAAI,IAAI,CAAC,CAAA;AAC1D,EAAA,IAAI,QAAA,CAAS,IAAA,EAAK,KAAM,EAAA,EAAI,OAAO,IAAA;AAEnC,EAAA,OAAO,MAAA;AACT;AAOA,SAAS,qBAAqB,IAAA,EAAuB;AACnD,EAAA,MAAM,aAAa,IAAA,CAAK,KAAA,CAAM,kBAAkB,CAAA,IAAK,EAAC,EAAG,MAAA;AACzD,EAAA,MAAM,UAAU,IAAA,CAAK,KAAA,CAAM,kBAAkB,CAAA,IAAK,EAAC,EAAG,MAAA;AACtD,EAAA,OAAO,SAAA,GAAY,CAAA,KAAM,CAAA,IAAK,MAAA,GAAS,CAAA,KAAM,CAAA;AAC/C;AAOA,SAAS,mBAAmB,IAAA,EAAsB;AAEhD,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,KAAA,IAAS,IAAI,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACzC,IAAA,IAAI,IAAA,CAAK,CAAC,CAAA,KAAM,GAAA,IAAO,KAAK,CAAA,GAAI,CAAC,MAAM,IAAA,EAAM;AAC3C,MAAA,IAAA,GAAO,CAAA;AACP,MAAA;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,IAAA,KAAS,IAAI,OAAO,IAAA;AAExB,EAAA,MAAM,KAAA,GAAQ,OAAO,CAAA,IAAK,IAAA,CAAK,OAAO,CAAC,CAAA,KAAM,GAAA,GAAM,IAAA,GAAO,CAAA,GAAI,IAAA;AAC9D,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAG5B,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAAA,EAC5B;AAEA,EAAA,IAAI,qBAAA,CAAsB,IAAA,CAAK,IAAI,CAAA,EAAG;AACpC,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,IAAA;AACT;AAyBA,SAAS,oBAAA,CACP,MACA,yBAAA,EACQ;AACR,EAAA,MAAM,OAAA,GAAU,CAAC,OAAA,KAAA,CACd,IAAA,CAAK,MAAM,OAAO,CAAA,IAAK,EAAC,EAAG,MAAA;AAE9B,EAAA,MAAM,QAAoB,EAAC;AAG3B,EAAA,IAAI,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA,CAAQ,OAAO,CAAA,EAAG;AACvC,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,IAAA,CAAK,WAAA,CAAY,KAAK,CAAA;AAAA,MAC7B,IAAA,EAAM,KAAA;AAAA,MACN,KAAA,EAAO,KAAA;AAAA,MACP,KAAA,EAAO,IAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA,CAAQ,OAAO,CAAA,EAAG;AACvC,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,IAAA,CAAK,WAAA,CAAY,KAAK,CAAA;AAAA,MAC7B,IAAA,EAAM,KAAA;AAAA,MACN,KAAA,EAAO,EAAA;AAAA,MACP,KAAA,EAAO,KAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,OAAA,CAAQ,OAAO,CAAA,GAAI,CAAA,KAAM,CAAA,EAAG;AAE9B,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AAAA,MAC5B,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO,IAAA;AAAA,MACP,KAAA,EAAO,IAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH,CAAA,MAAO;AAGL,IAAA,IAAI,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA;AAMvC,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA;AAAA,MACd,8CAAA;AAAA,MACA,CAAC,CAAA,KAAM,GAAA,CAAI,MAAA,CAAO,EAAE,MAAM;AAAA,KAC5B;AAOA,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA;AAAA,MACd,qCAAA;AAAA,MACA,CAAC,CAAA,KAAM,GAAA,CAAI,MAAA,CAAO,EAAE,MAAM;AAAA,KAC5B;AACA,IAAA,IAAI,UAAA,GAAa,EAAA;AACjB,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,QAAA,CAAS,kBAAkB,CAAA,EAAG;AACvD,MAAA,UAAA,GAAa,KAAA,CAAM,KAAA;AAAA,IACrB;AACA,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,kBAAkB,KAAK,EAAC;AACrD,IAAA,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,KAAM,CAAA,IAAK,eAAe,EAAA,EAAI;AACjD,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,KAAA,EAAO,UAAA;AAAA,QACP,IAAA,EAAM,GAAA;AAAA,QACN,KAAA,EAAO,EAAA;AAAA,QACP,KAAA,EAAO,KAAA;AAAA,QACP,OAAA,EAAS;AAAA,OACV,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAM,QAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,SAAS,CAAC,CAAA;AACtD,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAI/B,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,GAAQ,CAAA,GAAI,CAAE,CAAA;AAC/D,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,KAAK,CAAA;AAEvC,EAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AAEf,IAAA,OAAO,MAAA;AAAA,EACT;AAIA,EAAA,IAAI,CAAC,yBAAA,EAA2B;AAC9B,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,KAAA,GAAQ,IAAA,CAAK,KAAK,MAAM,CAAA;AACtD,EAAA,MAAM,IAAA,GAAO,sBAAA,CAAuB,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AACvD,EAAA,IAAI,IAAA,IAAQ,MAAM,OAAO,MAAA;AAOzB,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,IAAA,CAAK,KAAK,CAAA;AAC7C,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAO,MAAA,GAAS,IAAA,CAAK,IAAA,GAAO,IAAA,GAAO,IAAA,CAAK,KAAA;AAAA,EAC1C;AACA,EAAA,MAAM,MAAA,GACJ,WAAW,EAAA,IAAM,MAAA,CAAO,SAAS,IAAI,CAAA,GAAI,KAAK,IAAA,GAAO;AAAA,EAAK,KAAK,IAAI,CAAA,CAAA;AACrE,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,EAAG,MAAM,GAAG,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC;AAAA,EAAK,KAAK,KAAK,CAAA,CAAA;AACrE;AAWA,SAAS,sBAAA,CACP,OACA,OAAA,EACe;AACf,EAAA,MAAM,UAAA,GAAa,qBAAqB,KAAK,CAAA,CAAE,SAAS,CAAA,GACpD,CAAC,uBAAA,CAAwB,iBAAA,CAAkB,KAAK,CAAC,GAAG,uBAAA,CAAwB,sBAAA,CAAuB,KAAK,CAAC,CAAC,CAAA,GAC1G,CAAC,uBAAA,CAAwB,sBAAA,CAAuB,KAAK,CAAC,CAAC,CAAA;AAE3D,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,IAAI,CAAC,wBAAA,CAAyB,SAAS,CAAA,EAAG;AAC1C,IAAA,IAAI,gBAAA,CAAiB,SAAA,EAAW,OAAO,CAAA,EAAG,OAAO,SAAA;AAAA,EACnD;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,yBAAyB,IAAA,EAAuB;AACvD,EAAA,MAAM,QAAA,GAAW,KACd,OAAA,CAAQ,8BAAA,EAAgC,EAAE,CAAA,CAC1C,OAAA,CAAQ,WAAW,EAAE,CAAA;AACxB,EAAA,OAAO,SAAS,MAAA,GAAS,CAAA;AAC3B;AASA,SAAS,gBAAA,CAAiB,MAAc,OAAA,EAA2B;AACjE,EAAA,IAAI;AACF,IAAAA,sBAAA,CAAM,eAAe,IAAA,EAAM;AAAA,MACzB,WAAA,EAAa,OAAA;AAAA,MACb,YAAA,EAAc,IAAA;AAAA,MACd,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAOA,SAAS,kBAAkB,KAAA,EAAuB;AAChD,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,WAAA,CAAY,MAAM,CAAA;AACxC,EAAA,IAAI,OAAA,KAAY,IAAI,OAAO,EAAA;AAC3B,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,OAAA,GAAU,CAAC,CAAA;AACnC;AAQA,SAAS,uBAAuB,KAAA,EAAuB;AACrD,EAAA,IAAI,MAAA,GAAS,KAAA;AACb,EAAA,IAAI,QAAA;AACJ,EAAA,GAAG;AACD,IAAA,QAAA,GAAW,MAAA;AACX,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAGlC,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA;AACvC,IAAA,IAAI,eAAe,IAAA,IAAQ,WAAA,CAAY,CAAC,CAAA,CAAE,MAAA,GAAS,MAAM,CAAA,EAAG;AAC1D,MAAA,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,IAC7B;AAGA,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,iBAAA,EAAmB,EAAE,CAAA;AAE7C,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA;AAAA,EACrC,SAAS,MAAA,KAAW,QAAA;AACpB,EAAA,OAAO,MAAA;AACT;AAOA,SAAS,wBAAwB,KAAA,EAAuB;AACtD,EAAA,IAAI,MAAA,GAAS,KAAA;AAEb,EAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,qBAAqB,CAAA,IAAK,EAAC,EAAG,MAAA;AAC1D,EAAA,MAAM,UAAU,MAAA,CAAO,KAAA,CAAM,sBAAsB,CAAA,IAAK,EAAC,EAAG,MAAA;AAC5D,EAAA,MAAA,IAAU,WAAW,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,KAAA,GAAQ,MAAM,CAAC,CAAA;AAEvD,EAAA,MAAA,IAAU,GAAA,CAAI,MAAA,CAAO,cAAA,CAAe,MAAM,CAAC,CAAA;AAE3C,EAAA,MAAM,YAAA,GAAe,qBAAqB,MAAM,CAAA;AAChD,EAAA,KAAA,IAAS,IAAI,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACjD,IAAA,MAAA,IAAU,CAAA,MAAA,EAAS,YAAA,CAAa,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,MAAA;AACT;AAGA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,IAAA,GAAO,KAAK,CAAC,CAAA;AACnB,IAAA,IAAI,SAAS,IAAA,EAAM;AACjB,MAAA,CAAA,EAAA;AACA,MAAA;AAAA,IACF;AACA,IAAA,IAAI,SAAS,GAAA,EAAK,KAAA,EAAA;AAAA,SAAA,IACT,IAAA,KAAS,GAAA,IAAO,KAAA,GAAQ,CAAA,EAAG,KAAA,EAAA;AAAA,EACtC;AACA,EAAA,OAAO,KAAA;AACT;AAMA,SAAS,qBAAqB,IAAA,EAAwB;AACpD,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,OAAA,GAAU,8BAAA;AAChB,EAAA,IAAI,KAAA;AACJ,EAAA,OAAA,CAAQ,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,IAAI,MAAM,IAAA,EAAM;AAC3C,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,IAAI,KAAA,CAAM,CAAC,CAAA,KAAM,OAAA,EAAS;AACxB,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACjB,CAAA,MAAO;AACL,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA;AACpC,MAAA,IAAI,KAAA,KAAU,EAAA,EAAI,KAAA,CAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,iBAC5B,GAAA,EAAI;AAAA,IACjB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAMA,SAAS,wBAAwB,IAAA,EAAsB;AACrD,EAAA,IAAI,MAAA,GAAS,IAAA;AACb,EAAA,MAAA,GAAS,cAAA,CAAe,QAAQ,IAAI,CAAA;AAGpC,EAAA,MAAA,GAAS,oBAAoB,MAAM,CAAA;AACnC,EAAA,MAAA,GAAS,cAAA,CAAe,QAAQ,IAAI,CAAA;AACpC,EAAA,MAAA,GAAS,sBAAsB,MAAM,CAAA;AACrC,EAAA,MAAA,GAAS,sBAAsB,MAAM,CAAA;AACrC,EAAA,OAAO,MAAA;AACT;AASA,SAAS,mBAAA,CAAoB,MAAc,KAAA,EAAwB;AACjE,EAAA,IAAI,KAAA,IAAS,GAAG,OAAO,IAAA;AAKvB,EAAA,OAAO,CAAC,gBAAA,CAAiB,IAAA,CAAK,IAAA,CAAK,KAAA,GAAQ,CAAC,CAAC,CAAA;AAC/C;AAOA,SAAS,sBAAsB,IAAA,EAAsB;AACnD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACrC,EAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,IAAK,EAAC,EAAG,MAAA;AACzC,EAAA,IAAI,KAAA,GAAQ,CAAA,KAAM,CAAA,EAAG,OAAO,IAAA;AAE5B,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,CAAC,CAAA;AACtC,EAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAK,GAAG,OAAO,IAAA;AACvD,EAAA,IAAI,CAAC,mBAAA,CAAoB,IAAA,EAAM,SAAS,GAAG,OAAO,IAAA;AAElD,EAAA,OAAO,8BAAA,CAA+B,MAAM,GAAG,CAAA;AACjD;AAOA,SAAS,sBAAsB,IAAA,EAAsB;AACnD,EAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,IAAK,EAAC,EAAG,MAAA;AACxC,EAAA,IAAI,KAAA,GAAQ,CAAA,KAAM,CAAA,EAAG,OAAO,IAAA;AAE5B,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,CAAC,CAAA;AACtC,EAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,MAAM,IAAA,CAAK,KAAK,GAAG,OAAO,IAAA;AACpD,EAAA,IAAI,CAAC,mBAAA,CAAoB,IAAA,EAAM,SAAS,GAAG,OAAO,IAAA;AAElD,EAAA,OAAO,8BAAA,CAA+B,MAAM,IAAI,CAAA;AAClD;AAOA,SAAS,cAAA,CAAe,MAAc,MAAA,EAAwB;AAC5D,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AAC5D,EAAA,MAAM,KAAA,GAAA,CAAS,IAAA,CAAK,KAAA,CAAM,IAAI,MAAA,CAAO,SAAS,GAAG,CAAC,CAAA,IAAK,EAAC,EAAG,MAAA;AAC3D,EAAA,IAAI,KAAA,GAAQ,CAAA,KAAM,CAAA,EAAG,OAAO,IAAA;AAE5B,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AACzC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,OAAO,MAAM,CAAA;AAClD,EAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,MAAM,IAAA,CAAK,KAAK,GAAG,OAAO,IAAA;AAEpD,EAAA,OAAO,8BAAA,CAA+B,MAAM,MAAM,CAAA;AACpD;AAOA,SAAS,oBAAoB,IAAA,EAAsB;AACjD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA;AACvC,EAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,IAAK,EAAC,EAAG,MAAA;AAC1C,EAAA,IAAI,KAAA,GAAQ,CAAA,KAAM,CAAA,EAAG,OAAO,IAAA;AAE5B,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,CAAC,CAAA;AACtC,EAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,SAAS,IAAA,CAAK,KAAK,GAAG,OAAO,IAAA;AAEvD,EAAA,OAAO,8BAAA,CAA+B,MAAM,GAAG,CAAA;AACjD;AAQA,SAAS,8BAAA,CAA+B,MAAc,MAAA,EAAwB;AAC5E,EAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,GAAI,CAAC,CAAA,IAAK,EAAA;AAC5C,EAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAM,GAAG,IAAA,CAAK,MAAA,GAAS,SAAS,MAAM,CAAA;AACxD,EAAA,OAAO,OAAO,MAAA,GAAS,QAAA;AACzB;ACvmBA,SAAS,QAAA,GAAW;AAClB,EAAA,uBACEC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,WAAA;AAAA,MACR,KAAA,EAAM,KAAA;AAAA,MACN,MAAA,EAAO,KAAA;AAAA,MACP,IAAA,EAAK,MAAA;AAAA,MACL,MAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAY,GAAA;AAAA,MACZ,aAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAe,OAAA;AAAA,MACf,aAAA,EAAY,MAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,wBACvDA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,yDAAA,EAA0D;AAAA;AAAA;AAAA,GACpE;AAEJ;AAEA,SAAS,SAAA,GAAY;AACnB,EAAA,uBACEA,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,WAAA;AAAA,MACR,KAAA,EAAM,KAAA;AAAA,MACN,MAAA,EAAO,KAAA;AAAA,MACP,IAAA,EAAK,MAAA;AAAA,MACL,MAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAY,GAAA;AAAA,MACZ,aAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAe,OAAA;AAAA,MACf,aAAA,EAAY,MAAA;AAAA,MAEZ,QAAA,kBAAAA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAA,EAAkB;AAAA;AAAA,GAC5B;AAEJ;AAEO,SAAS,UAAA,CAAW,EAAE,IAAA,EAAM,SAAA,EAAU,EAAoB;AAC/D,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,eAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,UAAA,GAAaC,aAA6C,IAAI,CAAA;AAEpE,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAA,CAAW,OAAA,IAAW,IAAA,EAAM,YAAA,CAAa,WAAW,OAAO,CAAA;AAAA,IACjE,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAO,MAAM;AACjB,IAAA,MAAM,YAAY,SAAA,CAAU,SAAA;AAC5B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,KAAK,SAAA,CACF,SAAA,CAAU,IAAI,CAAA,CACd,KAAK,MAAM;AACV,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,IAAI,UAAA,CAAW,OAAA,IAAW,IAAA,EAAM,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/D,MAAA,UAAA,CAAW,UAAU,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,GAAG,GAAI,CAAA;AAAA,IAC9D,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,IAEb,CAAC,CAAA;AAAA,EACL,CAAA;AAEA,EAAA,uBACEH,cAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,SAAA;AAAA,MACA,YAAA,EAAY,SAAS,QAAA,GAAW,WAAA;AAAA,MAChC,aAAA,EAAa,SAAS,EAAA,GAAK,MAAA;AAAA,MAE1B,QAAA,EAAA,MAAA,mBAASA,cAAA,CAAC,SAAA,EAAA,EAAU,CAAA,kCAAM,QAAA,EAAA,EAAS;AAAA;AAAA,GACtC;AAEJ;;;ACzEA,IAAM,SAAA,GAAY,0BAAA;AAQX,SAAS,gBAAgB,OAAA,EAAyB;AAEvD,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,IAChB,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,SAAA,CAAU,MAAM,KAAK,GAAG,CAAA;AAAA,IACvC,CAAC,QAAQ,IAAA,KAAS;AAChB,MAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AACpB,MAAA,OAAO,CAAA,aAAA,EAAgB,UAAA,CAAW,MAAA,GAAS,CAAC,CAAA,EAAA,CAAA;AAAA,IAC9C;AAAA,GACF;AAgBA,EAAA,MAAM,mBAA6B,EAAC;AACpC,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,IAChB,mHAAA;AAAA,IACA,CAAC,KAAA,KAAU;AACT,MAAA,gBAAA,CAAiB,KAAK,KAAK,CAAA;AAC3B,MAAA,OAAO,CAAA,QAAA,EAAW,gBAAA,CAAiB,MAAA,GAAS,CAAC,CAAA,EAAA,CAAA;AAAA,IAC/C;AAAA,GACF;AAGA,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,KAAK,CAAA;AAG5C,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,IAChB,kBAAA;AAAA,IACA,CAAC,CAAA,EAAG,KAAA,KAAU,iBAAiB,QAAA,CAAS,KAAA,EAAO,EAAE,CAAC;AAAA,GACpD;AAGA,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,IAChB,uBAAA;AAAA,IACA,CAAC,CAAA,EAAG,KAAA,KAAU,WAAW,QAAA,CAAS,KAAA,EAAO,EAAE,CAAC;AAAA,GAC9C;AAGA,EAAA,OAAA,GAAU,eAAe,OAAO,CAAA;AAChC,EAAA,OAAA,GAAU,aAAa,OAAO,CAAA;AAE9B,EAAA,OAAO,OAAA;AACT;AAEO,SAAS,eAAe,IAAA,EAAsB;AACnD,EAAA,MAAM,UAAU,IAAI,MAAA;AAAA,IAClB,CAAA,CAAA,EAAI,SAAA,CAAU,MAAM,CAAA,EAAA,CAAA,GAClB,2CAAA,CAA4C,MAAA;AAAA,IAC9C;AAAA,GACF;AACA,EAAA,OAAO,IAAA,CAAK,OAAA;AAAA,IACV,OAAA;AAAA,IACA,CACE,KAAA,EACA,SAAA,EACA,aAAA,EACA,YAAA,KACW;AACX,MAAA,IAAI,aAAa,IAAA,EAAM;AACrB,QAAA,OAAO,SAAA;AAAA,MACT,CAAA,MAAA,IAAW,iBAAiB,IAAA,EAAM;AAChC,QAAA,OAAO,KAAK,aAAa,CAAA,EAAA,CAAA;AAAA,MAC3B,CAAA,MAAA,IAAW,gBAAgB,IAAA,EAAM;AAC/B,QAAA,OAAO,IAAI,YAAY,CAAA,CAAA,CAAA;AAAA,MACzB;AACA,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACF;AACF;AAEO,SAAS,aAAa,IAAA,EAAsB;AACjD,EAAA,OAAO,KAAK,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA,CAAE,UAAA,CAAW,UAAU,UAAU,CAAA;AAC9E;AC5CA,IAAM,aAAA,GAAgB,CAACI,0BAAA,EAAWC,2BAAU,CAAA;AAC5C,IAAM,aAAA,GAAgB,CAACC,4BAAW,CAAA;AAElC,SAAS,MAAM,MAAA,EAAuD;AACpE,EAAA,MAAM,MAAA,GAASC,UAAK,MAAM,CAAA;AAC1B,EAAA,OAAO,MAAA,KAAW,KAAK,MAAA,GAAY,MAAA;AACrC;AAEA,SAAS,eAAA,CACP,UAAA,EACA,SAAA,EACA,WAAA,EACY;AACZ,EAAA,MAAM,EAAA,GAAK,cAAc,EAAC;AAC1B,EAAA,MAAM,CAAA,GAAI,aAAa,EAAC;AACxB,EAAA,MAAM,WAAA,GAAc,WAAA;AAEpB,EAAA,OAAO;AAAA,IACL,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,WAAW,QAAA,EAAU,GAAG,OAAM,EAAG;AACnD,MAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,SAAA,IAAa,EAAE,CAAA;AACnD,MAAA,MAAM,WAAW,MAAA,CAAO,QAAQ,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AAKnD,MAAA,MAAM,UAAU,KAAA,IAAS,IAAA,IAAQ,OAAO,QAAQ,CAAA,CAAE,SAAS,IAAI,CAAA;AAE/D,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,MAAM,QAAA,GAAW,KAAA,GAAQ,CAAC,CAAA,IAAK,EAAA;AAC/B,QAAA,IAAI,EAAE,SAAA,EAAW;AACf,UAAA,MAAM,YAAY,CAAA,CAAE,SAAA;AACpB,UAAA,uBACEP,cAAAA;AAAA,YAAC,SAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAM,QAAA;AAAA,cACN,QAAA;AAAA,cACA,WAAW,EAAA,CAAG;AAAA;AAAA,WAChB;AAAA,QAEJ;AACA,QAAA,uBACED,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,gBAAA,EAAkB,EAAA,CAAG,SAAS,CAAA,EAC/C,QAAA,EAAA;AAAA,0BAAAA,gBAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,iBAAA,EAAmB,EAAA,CAAG,UAAU,CAAA,EACjD,QAAA,EAAA;AAAA,4BAAAC,cAAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,qBAAqB,EAAA,CAAG,YAAY,GACrD,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,YACC,CAAA,CAAE,UAAA,mBACDA,cAAAA,CAAC,CAAA,CAAE,UAAA,EAAF,EAAa,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,oBAExDA,cAAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAM,QAAA;AAAA,gBACN,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,EAAA,CAAG,UAAU;AAAA;AAAA;AAChD,WAAA,EAEJ,CAAA;AAAA,0BACAA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,eAAA,EACZ,QAAA,EAAA,WAAA,mBACCA,cAAAA,CAAC,WAAA,EAAA,EAAY,MAAM,QAAA,EAAU,QAAA,EAAoB,oBAEjDA,cAAAA,CAAC,UAAK,SAAA,EAAU,gBAAA,EAAkB,oBAAS,CAAA,EAE/C;AAAA,SAAA,EACF,CAAA;AAAA,MAEJ;AAEA,MAAA,IAAI,EAAE,IAAA,EAAM;AACV,QAAA,MAAM,aAAa,CAAA,CAAE,IAAA;AACrB,QAAA,uBACEA,cAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAW,EAAA,CAAG,YAAY,EAAA,CAAG,IAAA,EAAM,SAAS,CAAA,EACrD,QAAA,EACH,CAAA;AAAA,MAEJ;AAEA,MAAA,uBACEA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,EAAA,CAAG,IAAA,EAAM,SAAS,CAAA,EAAI,GAAG,KAAA,EACtD,QAAA,EACH,CAAA;AAAA,IAEJ,CAAA;AAAA,IACA,GAAA,CAAI,EAAE,QAAA,EAAS,EAAG;AAChB,MAAA,IAAI,EAAE,GAAA,EAAK;AACT,QAAA,uBAAOA,cAAAA,CAAC,CAAA,CAAE,GAAA,EAAF,EAAO,QAAA,EAAS,CAAA;AAAA,MAC1B;AAEA,MAAA,uBAAOA,cAAAA,CAAAQ,mBAAA,EAAA,EAAG,QAAA,EAAS,CAAA;AAAA,IACrB,CAAA;AAAA,IACA,KAAA,CAAM,EAAE,QAAA,EAAS,EAAG;AAClB,MAAA,IAAI,EAAE,KAAA,EAAO;AACX,QAAA,uBAAOR,eAAC,CAAA,CAAE,KAAA,EAAF,EAAQ,SAAA,EAAW,EAAA,CAAG,OAAQ,QAAA,EAAS,CAAA;AAAA,MACjD;AACA,MAAA,uBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,mBAAA,EAAqB,GAAG,YAAY,CAAA,EACrD,0BAAAA,cAAAA,CAAC,OAAA,EAAA,EAAM,WAAW,EAAA,CAAG,WAAA,EAAa,GAAG,KAAK,CAAA,EAAI,UAAS,CAAA,EACzD,CAAA;AAAA,IAEJ,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,UAAA,CAAW,EAAE,QAAA,EAAS,EAAG;AACvB,MAAA,IAAI,EAAE,UAAA,EAAY;AAChB,QAAA,uBAAOA,eAAC,CAAA,CAAE,UAAA,EAAF,EAAa,SAAA,EAAW,EAAA,CAAG,YAAa,QAAA,EAAS,CAAA;AAAA,MAC3D;AACA,MAAA,uBACEA,eAAC,YAAA,EAAA,EAAW,SAAA,EAAW,GAAG,gBAAA,EAAkB,EAAA,CAAG,UAAU,CAAA,EACtD,QAAA,EACH,CAAA;AAAA,IAEJ,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,CAAA,CAAE,EAAE,QAAA,EAAS,EAAG;AACd,MAAA,IAAI,EAAE,CAAA,EAAG;AACP,QAAA,uBAAOA,eAAC,CAAA,CAAE,CAAA,EAAF,EAAI,SAAA,EAAW,EAAA,CAAG,GAAI,QAAA,EAAS,CAAA;AAAA,MACzC;AACA,MAAA,uBAAOA,eAAC,GAAA,EAAA,EAAE,SAAA,EAAW,GAAG,OAAA,EAAS,EAAA,CAAG,CAAC,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACpD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,KAAA,CAAM,EAAE,IAAA,EAAM,KAAA,EAAO,MAAM,OAAA,EAAS,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG;AACxD,MAAA,IAAI,SAAS,UAAA,EAAY;AACvB,QAAA,IAAI,EAAE,QAAA,EAAU;AACd,UAAA,uBACEA,cAAAA,CAAC,CAAA,CAAE,QAAA,EAAF,EAAW,OAAA,EAAS,OAAA,CAAQ,OAAO,CAAA,EAAG,SAAA,EAAW,EAAA,CAAG,QAAA,EAAU,CAAA;AAAA,QAEnE;AACA,QAAA,uBACEA,cAAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,UAAA;AAAA,YACL,OAAA,EAAS,QAAQ,OAAO,CAAA;AAAA,YACxB,QAAA,EAAQ,IAAA;AAAA,YACR,YAAA,EAAY,UAAU,gBAAA,GAAmB,iBAAA;AAAA,YACzC,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,EAAA,CAAG,QAAQ,CAAA;AAAA,YACzC,QAAA,EAAQ;AAAA;AAAA,SACV;AAAA,MAEJ;AACA,MAAA,uBACEA,cAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,OAAA;AAAA,UACA,QAAA;AAAA,UACA,QAAA,EAAQ,IAAA;AAAA,UACP,GAAG;AAAA;AAAA,OACN;AAAA,IAEJ,CAAA;AAAA,IACA,CAAA,CAAE,EAAE,IAAA,EAAM,QAAA,EAAS,EAAG;AACpB,MAAA,IAAI,EAAE,CAAA,EAAG;AACP,QAAA,uBACEA,eAAC,CAAA,CAAE,CAAA,EAAF,EAAI,IAAA,EAAY,SAAA,EAAW,EAAA,CAAG,CAAA,EAC5B,QAAA,EACH,CAAA;AAAA,MAEJ;AACA,MAAA,uBACEA,cAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,MAAA,EAAO,QAAA;AAAA,UACP,GAAA,EAAI,qBAAA;AAAA,UACJ,SAAA,EAAW,EAAA,CAAG,OAAA,EAAS,EAAA,CAAG,CAAC,CAAA;AAAA,UAE1B;AAAA;AAAA,OACH;AAAA,IAEJ,CAAA;AAAA,IACA,GAAA,CAAI,EAAE,IAAA,EAAM,KAAA,EAAO,GAAA,EAAK,GAAA,EAAK,KAAA,EAAO,SAAA,EAAW,UAAA,EAAY,GAAG,KAAA,EAAM,EAAG;AACrE,MAAA,IAAI,EAAE,GAAA,EAAK;AACT,QAAA,MAAM,QAAQ,CAAA,CAAE,GAAA;AAChB,QAAA,uBACEA,cAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAM,MAAA;AAAA,YACrC,GAAA;AAAA,YACA,KAAA;AAAA,YACA,WAAW,EAAA,CAAG;AAAA;AAAA,SAChB;AAAA,MAEJ;AACA,MAAA,uBACEA,cAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAM,MAAA;AAAA,UACrC,GAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA,EAAW,EAAA,CAAG,SAAA,EAAW,EAAA,CAAG,GAAG,CAAA;AAAA,UAC9B,GAAG;AAAA;AAAA,OACN;AAAA,IAEJ,CAAA;AAAA,IACA,EAAA,GAAK;AACH,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,cAAAA,CAAC,CAAA,CAAE,IAAF,EAAK,SAAA,EAAW,GAAG,EAAA,EAAI,CAAA;AAAA,MACjC;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAG,CAAA;AAAA,IAC7C,CAAA;AAAA,IACA,MAAA,CAAO,EAAE,QAAA,EAAS,EAAG;AACnB,MAAA,IAAI,EAAE,MAAA,EAAQ;AACZ,QAAA,uBAAOA,eAAC,CAAA,CAAE,MAAA,EAAF,EAAS,SAAA,EAAW,EAAA,CAAG,QAAS,QAAA,EAAS,CAAA;AAAA,MACnD;AACA,MAAA,uBAAOA,eAAC,QAAA,EAAA,EAAO,SAAA,EAAW,GAAG,YAAA,EAAc,EAAA,CAAG,MAAM,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACnE,CAAA;AAAA,IACA,EAAA,CAAG,EAAE,QAAA,EAAS,EAAG;AACf,MAAA,IAAI,EAAE,EAAA,EAAI;AACR,QAAA,uBAAOA,eAAC,CAAA,CAAE,EAAA,EAAF,EAAK,SAAA,EAAW,EAAA,CAAG,IAAK,QAAA,EAAS,CAAA;AAAA,MAC3C;AACA,MAAA,uBAAOA,eAAC,IAAA,EAAA,EAAG,SAAA,EAAW,GAAG,QAAA,EAAU,EAAA,CAAG,EAAE,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,GAAA,CAAI,EAAE,QAAA,EAAS,EAAG;AAChB,MAAA,IAAI,EAAE,GAAA,EAAK;AACT,QAAA,uBAAOA,eAAC,CAAA,CAAE,GAAA,EAAF,EAAM,SAAA,EAAW,EAAA,CAAG,KAAM,QAAA,EAAS,CAAA;AAAA,MAC7C;AACA,MAAA,uBAAOA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,SAAA,EAAW,EAAA,CAAG,GAAG,CAAA,EAAI,QAAA,EAAS,CAAA;AAAA,IAC1D;AAAA,GACF;AACF;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,uBAAuB,mBAAA,GAAsB,IAAA;AAAA,EAC7C,yBAAA,GAA4B,IAAA;AAAA,EAC5B,WAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAoB;AAClB,EAAA,MAAM,MAAA,GAAS,WAAW,QAAA,IAAY,EAAA;AAEtC,EAAA,MAAM,kBAAA,GAAqBS,aAAA;AAAA,IACzB,MAAM,eAAA,CAAgB,UAAA,EAAY,UAAA,EAAY,WAAW,CAAA;AAAA,IACzD,CAAC,UAAA,EAAY,UAAA,EAAY,WAAW;AAAA,GACtC;AAEA,EAAA,MAAM,SAAA,GAAYA,cAAQ,MAAM;AAC9B,IAAA,MAAM,WAAW,mBAAA,GACb,qBAAA,CAAsB,QAAQ,EAAE,yBAAA,EAA2B,CAAA,GAC3D,MAAA;AACJ,IAAA,OAAO,gBAAgB,QAAQ,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,MAAA,EAAQ,mBAAA,EAAqB,yBAAyB,CAAC,CAAA;AAE3D,EAAA,uBACET,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,aAAA,EAAe,UAAA,EAAY,IAAA,EAAM,SAAS,CAAA,EAAI,GAAG,IAAA,EAClE,QAAA,kBAAAA,cAAAA;AAAA,IAACU,8BAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA,EAAY,kBAAA;AAAA,MAEX,QAAA,EAAA;AAAA;AAAA,GACH,EACF,CAAA;AAEJ;ACnWA,IAAM,cAAA,GAAiB,EAAE,KAAA,EAAO,cAAA,EAAgB,MAAM,aAAA,EAAc;AAe7D,SAAS,sBAAA,CACd,YACA,OAAA,EACiB;AACjB,EAAA,MAAM,MAAA,GAAS,SAAS,MAAA,IAAU,cAAA;AAElC,EAAA,OAAO,SAAS,gBAAA,CAAiB,EAAE,IAAA,EAAM,QAAA,EAAU,WAAU,EAAG;AAC9D,IAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIT,eAAwB,IAAI,CAAA;AAEpD,IAAAE,gBAAU,MAAM;AACd,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,OAAA,CAAQ,OAAA,CAAQ,UAAA,CAAW,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,CAAC,CAAA,CACzD,IAAA,CAAK,CAAC,MAAA,KAAW;AAChB,QAAA,IAAI,CAAC,SAAA,EAAW,OAAA,CAAQ,MAAM,CAAA;AAAA,MAChC,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAEX,QAAA,IAAI,CAAC,SAAA,EAAW,OAAA,CAAQ,IAAI,CAAA;AAAA,MAC9B,CAAC,CAAA;AACH,MAAA,OAAO,MAAM;AACX,QAAA,SAAA,GAAY,IAAA;AAAA,MACd,CAAA;AAAA,IAIF,CAAA,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEnB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,uBACEH,cAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,WAAW,SAAA,IAAa,WAAA;AAAA,UAExB,uBAAA,EAAyB,EAAE,MAAA,EAAQ,IAAA;AAAK;AAAA,OAC1C;AAAA,IAEJ;AAEA,IAAA,uBAAOA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAkB,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,EAChD,CAAA;AACF","file":"index.cjs","sourcesContent":["import katex from \"katex\";\n\n/** Options controlling how {@link completePartialTokens} repairs the stream. */\nexport interface CompletePartialTokensOptions {\n /**\n * Progressively render unterminated *block* math (`\\[…`, `$$…`) by closing\n * the open constructs and keeping the largest prefix KaTeX accepts. This is\n * convenient (a long block reveals row by row) but costs a synchronous KaTeX\n * parse on every chunk while the block streams. Set to `false` to instead\n * hide the block entirely until its closing delimiter arrives, skipping the\n * KaTeX work. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n}\n\n/**\n * Repairs partially-streamed markdown / LaTeX so that incomplete syntax does\n * not leak raw delimiter characters into the rendered output.\n *\n * While an LLM streams a response, the text often ends mid-token, e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2` or `\\(a + b`. Rendered\n * as-is, those dangling delimiters show up as literal junk (`**`, `` ` ``, `[`,\n * `$`, `\\(`). This function detects the unterminated constructs at the tail of\n * the string and:\n * - closes safe inline formatting so it renders as intended (`**bold` →\n * `**bold**`, `` `code `` → `` `code` ``);\n * - hides fragments that cannot be completed yet, namely incomplete links and\n * incomplete inline math (`$…`, `\\(…`);\n * - progressively renders incomplete *block* math (`\\[…`, `$$…`): instead of\n * hiding the whole block until it finishes streaming, it closes the open\n * environments/braces and renders the largest prefix KaTeX accepts, so a\n * long aligned block reveals row by row instead of popping in at the end.\n *\n * It is a no-op for already-complete text, so it is safe to run on every chunk.\n *\n * @param text The (possibly mid-stream) markdown string.\n * @returns The string with trailing incomplete tokens repaired.\n */\nexport function completePartialTokens(\n text: string,\n options?: CompletePartialTokensOptions,\n): string {\n if (!text) return text;\n\n const showUnfinishedLatexBlocks = options?.showUnfinishedLatexBlocks ?? true;\n\n // An unterminated fenced code block is fine on its own: remark renders it to\n // the end of the document and the partial content reads correctly as code,\n // so we must not touch any of the (markdown-looking) characters inside it.\n if (hasUnclosedCodeFence(text)) {\n return text;\n }\n\n const protectedSpans: string[] = [];\n const protect = (value: string): string =>\n `\\u0000llmph${protectedSpans.push(value) - 1}\\u0000`;\n\n // Protect complete fenced code blocks and complete inline code spans so their\n // contents are never mistaken for markdown/LaTeX markers. Double-backtick\n // spans are protected before single-backtick ones so a span that itself\n // contains a backtick (`` a`b ``) is not mangled by the single-backtick pass.\n let working = text.replace(/```[\\s\\S]*?```/g, (match) => protect(match));\n working = working.replace(/``[\\s\\S]*?``/g, (match) => protect(match));\n working = working.replace(/`[^`\\n]+`/g, (match) => protect(match));\n\n // A leftover single backtick starts an unterminated inline code span. Protect\n // the rest of the line and close it so the in-progress code renders cleanly.\n const lastBacktick = working.lastIndexOf(\"`\");\n if (lastBacktick !== -1) {\n // Bound the in-progress span to its own line so trailing markdown on later\n // lines is not swallowed into the protected code.\n const newline = working.indexOf(\"\\n\", lastBacktick);\n const end = newline === -1 ? working.length : newline;\n const span = working.slice(lastBacktick, end);\n working =\n working.slice(0, lastBacktick) +\n protect(`${span}\\``) +\n working.slice(end);\n }\n\n working = repairIncompleteMath(working, showUnfinishedLatexBlocks);\n working = hideIncompleteLink(working);\n working = completePartialTable(working);\n working = hideDanglingListMarker(working);\n working = closeUnbalancedEmphasis(working);\n\n return working.replace(\n /\\u0000llmph(\\d+)\\u0000/g,\n (_match, index: string) => protectedSpans[Number(index)] ?? \"\",\n );\n}\n\n/**\n * Completes a partially-streamed GFM table delimiter row.\n *\n * A table needs a full delimiter row (`| --- | --- |`) to be recognised, so\n * while it streams the buffer ends with a header row followed by a fragment like\n * `| ---`. Without a valid delimiter remark-gfm collapses both lines into a\n * paragraph (\"| Feature | Works | | ---\"). Once a delimiter fragment appears we\n * already know the column count from the header, so we expand the fragment to a\n * complete delimiter, preserving any alignment colons that have streamed in.\n */\nfunction completePartialTable(text: string): string {\n const lines = text.split(\"\\n\");\n if (lines.length < 2) return text;\n\n const last = lines[lines.length - 1];\n // The candidate delimiter must contain only delimiter characters and at least\n // one dash; anything else (letters, etc.) means it is a header or body row.\n if (!/-/.test(last) || !/^[\\s|:-]*$/.test(last)) return text;\n\n const header = lines[lines.length - 2];\n if (!header.includes(\"|\")) return text;\n\n // If the table already has a delimiter row at or above the candidate, then\n // the candidate is just a body row that happens to contain only dashes/pipes\n // (not a streaming delimiter), so the table is complete and must be left\n // untouched. Walk up the contiguous block of pipe rows to detect that.\n for (let i = lines.length - 2; i >= 0; i--) {\n const line = lines[i];\n if (!line.includes(\"|\")) break;\n if (/-/.test(line) && /^[\\s|:-]*$/.test(line)) return text;\n }\n\n const columns = countTableColumns(header);\n lines[lines.length - 1] = buildDelimiterRow(last, columns);\n return lines.join(\"\\n\");\n}\n\n/** Counts the cells in a GFM table row, ignoring the outer pipes. */\nfunction countTableColumns(row: string): number {\n let inner = row.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n return inner.split(\"|\").length;\n}\n\n/**\n * Builds a delimiter row with `columns` cells, reusing any alignment colons\n * already present in the streamed fragment.\n */\nfunction buildDelimiterRow(fragment: string, columns: number): string {\n let inner = fragment.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n const existing = inner.split(\"|\").map((cell) => cell.trim());\n\n const cells = Array.from({ length: columns }, (_unused, index) => {\n const spec = existing[index] ?? \"\";\n const left = spec.startsWith(\":\");\n const right = spec.endsWith(\":\");\n if (left && right) return \":---:\";\n if (right) return \"---:\";\n if (left) return \":---\";\n return \"---\";\n });\n\n return `| ${cells.join(\" | \")} |`;\n}\n\n/**\n * Hides a trailing line that would be parsed as a setext heading underline.\n *\n * Mid-stream a bullet list arrives a character at a time, so the buffer briefly\n * ends with `paragraph\\n-` before the item text follows. In CommonMark a lone\n * run of dashes directly beneath a non-blank line is a setext H2 underline, so\n * a line like \"Unordered list:\" would flash as a heading until \"- Item\" streams\n * in. We drop the dangling marker until it gains content. A blank line above the\n * dashes makes them a thematic break instead, which is left untouched.\n */\nfunction hideDanglingListMarker(text: string): string {\n const match = text.match(/\\n[ \\t]{0,3}-+[ \\t]*$/);\n if (match?.index == null) return text;\n\n const before = text.slice(0, match.index);\n const prevLine = before.slice(before.lastIndexOf(\"\\n\") + 1);\n if (prevLine.trim() === \"\") return text;\n\n return before;\n}\n\n/**\n * True when a code fence is left open. Backtick (```) and tilde (~~~) fences are\n * counted separately so that a complete block of one kind that happens to\n * contain a line of the other kind is not mistaken for an unbalanced fence.\n */\nfunction hasUnclosedCodeFence(text: string): boolean {\n const backticks = (text.match(/^[ \\t]{0,3}```/gm) ?? []).length;\n const tildes = (text.match(/^[ \\t]{0,3}~~~/gm) ?? []).length;\n return backticks % 2 === 1 || tildes % 2 === 1;\n}\n\n/**\n * Drops a trailing, still-incomplete link or image, e.g. `[label`, `: string {\n // Find the last \"[\" that is not an escaped LaTeX delimiter (\"\\[\").\n let open = -1;\n for (let i = text.length - 1; i >= 0; i--) {\n if (text[i] === \"[\" && text[i - 1] !== \"\\\\\") {\n open = i;\n break;\n }\n }\n if (open === -1) return text;\n\n const start = open > 0 && text[open - 1] === \"!\" ? open - 1 : open;\n const rest = text.slice(open);\n\n // Label is still open: \"[lab\" / \"![al\".\n if (!rest.includes(\"]\")) {\n return text.slice(0, start);\n }\n // Label closed, destination opened but not yet closed: \"[lab](http\".\n if (/^\\[[^\\]]*\\]\\([^)]*$/.test(rest)) {\n return text.slice(0, start);\n }\n return text;\n}\n\n/** A math delimiter that has been opened but not yet closed in the stream. */\ninterface OpenMath {\n /** Index of the opening delimiter in the source string. */\n index: number;\n /** The opening delimiter itself, e.g. `\"\\\\[\"` or `\"$$\"`. */\n open: string;\n /** The closing delimiter to append once repaired, empty for inline math. */\n close: string;\n /** Whether the math is block (display) math we try to render progressively. */\n block: boolean;\n /** Whether to render in KaTeX display mode when validating a candidate. */\n display: boolean;\n}\n\n/**\n * Repairs an unterminated LaTeX region at the tail of the stream.\n *\n * Inline math (`$…`, `\\(…`) is short, so it is simply hidden until it finishes\n * streaming. Block math (`\\[…`, `$$…`) is instead rendered progressively: we\n * close any open environments/braces and keep the largest leading slice that\n * KaTeX can parse, so a multi-line block reveals itself as it streams instead\n * of staying blank until the closing delimiter finally arrives.\n */\nfunction repairIncompleteMath(\n text: string,\n showUnfinishedLatexBlocks: boolean,\n): string {\n const countOf = (pattern: RegExp): number =>\n (text.match(pattern) ?? []).length;\n\n const opens: OpenMath[] = [];\n\n // Display math: \\[ ... \\]\n if (countOf(/\\\\\\[/g) > countOf(/\\\\\\]/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\[\"),\n open: \"\\\\[\",\n close: \"\\\\]\",\n block: true,\n display: true,\n });\n }\n\n // Inline math: \\( ... \\)\n if (countOf(/\\\\\\(/g) > countOf(/\\\\\\)/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\(\"),\n open: \"\\\\(\",\n close: \"\",\n block: false,\n display: false,\n });\n }\n\n if (countOf(/\\$\\$/g) % 2 === 1) {\n // Display math: $$ ... $$\n opens.push({\n index: text.lastIndexOf(\"$$\"),\n open: \"$$\",\n close: \"$$\",\n block: true,\n display: true,\n });\n } else {\n // Inline math: $ ... $. Mask complete \"$$\" pairs (keeping indices stable),\n // then ignore escaped \"\\$\" and currency like \"$5\" to avoid false positives.\n let masked = text.replace(/\\$\\$/g, \" \");\n // Also mask complete single-line \"$…$\" spans that contain a LaTeX command\n // (so they are real math, not \"$5\" currency). Their opening \"$\" may be\n // followed by a digit (e.g. \"$15 \\text{ г}$\"), which the currency guard\n // below would otherwise drop from the count while still counting the\n // closing \"$\", flipping the parity and hiding trailing content by mistake.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$/g,\n (m) => \" \".repeat(m.length),\n );\n // Same parity hazard for command-free numeric spans (e.g. \"$0$\", \"$15$\"):\n // the opening \"$\" is dropped by the currency guard below while the closing\n // \"$\" is still counted. Mask these balanced numeric spans too so neither\n // delimiter is counted. Plain currency (\"$5 and $10\") has prose between the\n // dollars, so it matches neither this nor the command mask and is left for\n // the currency guard to handle.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$/g,\n (m) => \" \".repeat(m.length),\n );\n let lastDollar = -1;\n for (const match of masked.matchAll(/(?<!\\\\)\\$(?!\\d)/g)) {\n lastDollar = match.index;\n }\n const singles = masked.match(/(?<!\\\\)\\$(?!\\d)/g) ?? [];\n if (singles.length % 2 === 1 && lastDollar !== -1) {\n opens.push({\n index: lastDollar,\n open: \"$\",\n close: \"\",\n block: false,\n display: false,\n });\n }\n }\n\n const valid = opens.filter((entry) => entry.index >= 0);\n if (valid.length === 0) return text;\n\n // The earliest opener marks where the incomplete math region begins; anything\n // after it is part of the unterminated construct.\n const open = valid.reduce((a, b) => (b.index < a.index ? b : a));\n const before = text.slice(0, open.index);\n\n if (!open.block) {\n // Inline math is hidden until it finishes streaming.\n return before;\n }\n\n // When progressive block rendering is disabled, hide the unterminated block\n // until its closing delimiter arrives, skipping the KaTeX validation cost.\n if (!showUnfinishedLatexBlocks) {\n return before;\n }\n\n const inner = text.slice(open.index + open.open.length);\n const body = bestRenderableMathBody(inner, open.display);\n if (body == null) return before;\n\n // Reproduce the original fenced layout so the markdown math parser can detect\n // the closing delimiter. When the block opens on its own line (`\\[\\n…`), the\n // closing delimiter must also sit on its own line; otherwise micromark treats\n // the run as inline math, never finds the closing fence, and KaTeX renders a\n // parse error that swallows the trailing delimiter.\n const blockLayout = /^[ \\t]*\\r?\\n/.test(inner);\n if (!blockLayout) {\n return before + open.open + body + open.close;\n }\n const opener =\n before === \"\" || before.endsWith(\"\\n\") ? open.open : `\\n${open.open}`;\n return `${before}${opener}${body.replace(/\\s+$/, \"\")}\\n${open.close}`;\n}\n\n/**\n * Returns the largest leading slice of incomplete block-math content that KaTeX\n * can render, with its open environments and braces closed, or `null` when no\n * usable prefix exists yet (in which case the caller hides the fragment).\n *\n * When an environment is still open (e.g. `\\begin{aligned}` mid-stream) we\n * prefer revealing only the complete rows so each equation appears fully formed,\n * falling back to a token-level repair so single-line blocks still stream in.\n */\nfunction bestRenderableMathBody(\n inner: string,\n display: boolean,\n): string | null {\n const candidates = unclosedEnvironments(inner).length > 0\n ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))]\n : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];\n\n for (const candidate of candidates) {\n if (!hasRenderableMathContent(candidate)) continue;\n if (isRenderableMath(candidate, display)) return candidate;\n }\n return null;\n}\n\n/** True when a math body contains something other than empty environment scaffolding. */\nfunction hasRenderableMathContent(body: string): boolean {\n const stripped = body\n .replace(/\\\\(?:begin|end)\\s*\\{[^}]*\\}/g, \"\")\n .replace(/[\\s{}]/g, \"\");\n return stripped.length > 0;\n}\n\n/**\n * True when KaTeX can render the math body without raising a parse error.\n *\n * Uses the public, stable `renderToString` entry point (with `throwOnError`)\n * rather than any internal parse-only API, so it keeps working across KaTeX\n * upgrades. We only care whether it throws; the produced string is discarded.\n */\nfunction isRenderableMath(body: string, display: boolean): boolean {\n try {\n katex.renderToString(body, {\n displayMode: display,\n throwOnError: true,\n strict: false,\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Keeps only the complete rows of a multi-line environment by cutting back to\n * the last row separator (`\\\\`), dropping the partially-streamed current row.\n * Returns an empty string when no full row has streamed yet.\n */\nfunction truncateToLastRow(inner: string): string {\n const lastRow = inner.lastIndexOf(\"\\\\\\\\\");\n if (lastRow === -1) return \"\";\n return inner.slice(0, lastRow + 2);\n}\n\n/**\n * Drops trailing tokens that cannot render on their own yet: surrounding\n * whitespace, a dangling backslash, an in-progress control word (`\\frac` may\n * still be `\\fra`), and a subscript/superscript with no argument. A complete\n * `\\\\` row separator is preserved.\n */\nfunction trimIncompleteMathTail(inner: string): string {\n let result = inner;\n let previous: string;\n do {\n previous = result;\n result = result.replace(/\\s+$/, \"\");\n // A trailing odd run of backslashes ends in a lone \"\\\" (an incomplete \"\\\\\"\n // or the start of a command); drop it. An even run is complete \"\\\\\".\n const backslashes = result.match(/\\\\+$/);\n if (backslashes != null && backslashes[0].length % 2 === 1) {\n result = result.slice(0, -1);\n }\n // A trailing control word is ambiguous mid-stream; drop it so it cannot be\n // an unknown (and therefore error-rendered) command.\n result = result.replace(/\\\\[a-zA-Z]+\\*?$/, \"\");\n // A subscript/superscript needs an argument that has not arrived yet.\n result = result.replace(/[_^]$/, \"\");\n } while (result !== previous);\n return result;\n}\n\n/**\n * Closes the constructs left open in a math fragment so KaTeX can parse it:\n * unmatched `\\left`, unbalanced `{` groups, and unclosed environments. Order is\n * a best effort; the caller validates the result with KaTeX regardless.\n */\nfunction closeOpenMathConstructs(inner: string): string {\n let result = inner;\n\n const lefts = (result.match(/\\\\left(?![a-zA-Z])/g) ?? []).length;\n const rights = (result.match(/\\\\right(?![a-zA-Z])/g) ?? []).length;\n result += \"\\\\right.\".repeat(Math.max(0, lefts - rights));\n\n result += \"}\".repeat(openBraceDepth(result));\n\n const environments = unclosedEnvironments(result);\n for (let i = environments.length - 1; i >= 0; i--) {\n result += `\\\\end{${environments[i]}}`;\n }\n return result;\n}\n\n/** Counts unclosed `{` groups, ignoring escaped braces (`\\{`, `\\}`). */\nfunction openBraceDepth(text: string): number {\n let depth = 0;\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === \"\\\\\") {\n i++;\n continue;\n }\n if (char === \"{\") depth++;\n else if (char === \"}\" && depth > 0) depth--;\n }\n return depth;\n}\n\n/**\n * Returns the names of environments opened with `\\begin{…}` but not yet closed\n * with a matching `\\end{…}`, outermost first.\n */\nfunction unclosedEnvironments(text: string): string[] {\n const stack: string[] = [];\n const pattern = /\\\\(begin|end)\\s*\\{([^}]*)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) != null) {\n const name = match[2];\n if (match[1] === \"begin\") {\n stack.push(name);\n } else {\n const index = stack.lastIndexOf(name);\n if (index !== -1) stack.splice(index, 1);\n else stack.pop();\n }\n }\n return stack;\n}\n\n/**\n * Closes unterminated emphasis runs: ~~strike~~, **bold**, *italic*, __bold__\n * and _italic_.\n */\nfunction closeUnbalancedEmphasis(text: string): string {\n let result = text;\n result = closeRunMarker(result, \"~~\");\n // Close a single \"*\" first so a \"***\" opener becomes \"*\" + \"**\" and both\n // halves get closed, yielding a balanced \"***…***\".\n result = closeSingleAsterisk(result);\n result = closeRunMarker(result, \"**\");\n result = closeSingleUnderscore(result);\n result = closeDoubleUnderscore(result);\n return result;\n}\n\n/**\n * True when the marker at `index` begins a delimiter run that could open\n * emphasis: it sits at the start of the string or directly after a non-word\n * character (whitespace or punctuation). Underscores require this so intra-word\n * usage (`snake_case`, `__init__`) is never treated as a dangling emphasis\n * opener.\n */\nfunction opensAtWordBoundary(text: string, index: number): boolean {\n if (index <= 0) return true;\n // Whitespace or punctuation before the marker counts as a boundary; an\n // alphanumeric character (or another underscore) does not, so intra-word\n // usage (`snake_case`, `__init__`) is never treated as a dangling opener\n // while a leading-punctuation case like `(_italic` still closes.\n return !/[\\p{L}\\p{N}_]/u.test(text[index - 1]);\n}\n\n/**\n * Closes a single `_` italic marker. `__` pairs are masked out first, and the\n * marker is only closed when it both opens at a word boundary and sits directly\n * before a non-space character, so `snake_case` is left alone.\n */\nfunction closeSingleUnderscore(text: string): string {\n const masked = text.replace(/__/g, \"\");\n const count = (masked.match(/_/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"_\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s_]/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"_\");\n}\n\n/**\n * Closes a `__` bold marker when it is unbalanced, opens at a word boundary,\n * and is directly followed by a non-space character (so `a__b` and `__init__`\n * are left untouched).\n */\nfunction closeDoubleUnderscore(text: string): string {\n const count = (text.match(/__/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"__\");\n const after = text.slice(lastIndex + 2);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"__\");\n}\n\n/**\n * Closes a two-character emphasis marker (`**` or `~~`) when it is unbalanced\n * and the final marker looks like an opener (immediately followed by a\n * non-space character), which avoids touching list markers or operators.\n */\nfunction closeRunMarker(text: string, marker: string): string {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const count = (text.match(new RegExp(escaped, \"g\")) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(marker);\n const after = text.slice(lastIndex + marker.length);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, marker);\n}\n\n/**\n * Closes a single `*` italic marker. `**` pairs are masked out first, and the\n * marker is only closed when it sits directly before a non-space character so\n * bullet markers (`* item`) and multiplication (`2 * 3`) are left alone.\n */\nfunction closeSingleAsterisk(text: string): string {\n const masked = text.replace(/\\*\\*/g, \"\");\n const count = (masked.match(/\\*/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"*\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s*]/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"*\");\n}\n\n/**\n * Appends a closing emphasis marker, but places it before any trailing\n * whitespace. A closer such as `**` is only valid when it directly follows a\n * non-space character, so `**bold ` must become `**bold** ` rather than the\n * un-renderable `**bold **`.\n */\nfunction insertBeforeTrailingWhitespace(text: string, marker: string): string {\n const trailing = text.match(/\\s+$/)?.[0] ?? \"\";\n const core = text.slice(0, text.length - trailing.length);\n return core + marker + trailing;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nimport type { CopyButtonProps } from \"./types\";\n\nfunction CopyIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport function CopyButton({ text, className }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const copy = () => {\n const clipboard = navigator.clipboard;\n if (!clipboard) return;\n // Only show the \"copied\" confirmation once the write actually succeeds.\n void clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n // Clipboard write failed; keep the idle state.\n });\n };\n\n return (\n <button\n type=\"button\"\n onClick={copy}\n className={className}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n data-copied={copied ? \"\" : undefined}\n >\n {copied ? <CheckIcon /> : <CopyIcon />}\n </button>\n );\n}\n","/**\n * Matches a fenced code block or an inline code span. Shared by\n * {@link preprocessLaTeX} and {@link escapeBrackets} so both functions treat\n * code identically; composed into the larger patterns below via `.source`.\n */\nconst CODE_SPAN = /```[\\s\\S]*?```|`[^`\\n]+`/;\n\n/**\n * Preprocesses LaTeX content by replacing delimiters and escaping certain characters.\n *\n * @param content The input string containing LaTeX expressions.\n * @returns The processed string with replaced delimiters and escaped characters.\n */\nexport function preprocessLaTeX(content: string): string {\n // Step 1: Protect code blocks\n const codeBlocks: string[] = [];\n content = content.replace(\n new RegExp(`(${CODE_SPAN.source})`, \"g\"),\n (_match, code) => {\n codeBlocks.push(code);\n return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;\n },\n );\n\n // Step 2: Protect existing LaTeX expressions. This is what makes the currency\n // escaping in Step 3 safe: by pulling complete `$$…$$` / `\\[…\\]` / `\\(…\\)`\n // regions out of the string first, the `\\$(?=\\d)` pass below cannot corrupt a\n // `$` that legitimately belongs to a math expression (e.g. `$$x = $5$$`).\n //\n // Single-dollar inline math whose content begins with a digit (e.g.\n // `$15 \\text{ г}$`) is protected too: without this its opening `$` would be\n // escaped as currency in Step 3, unbalancing the delimiters so remark-math\n // swallows the rest of the paragraph as one math region. Two shapes qualify:\n // 1. spans containing a LaTeX command (`\\…`), e.g. `$15 \\text{ г}$`;\n // 2. balanced spans whose content is purely numeric/math (digits, spaces\n // and basic operators, no prose letters), e.g. `$0$` or `$1288 / 3$`.\n // Both leave plain currency prose like `$5 and $10` for Step 3, because that\n // text contains letters between the dollars and so matches neither shape.\n const latexExpressions: string[] = [];\n content = content.replace(\n /(\\$\\$[\\s\\S]*?\\$\\$|\\\\\\[[\\s\\S]*?\\\\\\]|\\\\\\(.*?\\\\\\)|\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$|\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$)/g,\n (match) => {\n latexExpressions.push(match);\n return `<<LATEX_${latexExpressions.length - 1}>>`;\n },\n );\n\n // Step 3: Escape dollar signs that are likely currency indicators\n content = content.replace(/\\$(?=\\d)/g, \"\\\\$\");\n\n // Step 4: Restore LaTeX expressions\n content = content.replace(\n /<<LATEX_(\\d+)>>/g,\n (_, index) => latexExpressions[parseInt(index, 10)],\n );\n\n // Step 5: Restore code blocks\n content = content.replace(\n /<<CODE_BLOCK_(\\d+)>>/g,\n (_, index) => codeBlocks[parseInt(index, 10)],\n );\n\n // Step 6: Apply additional escaping functions\n content = escapeBrackets(content);\n content = escapeMhchem(content);\n\n return content;\n}\n\nexport function escapeBrackets(text: string): string {\n const pattern = new RegExp(\n `(${CODE_SPAN.source})|` +\n /\\\\\\[((?:[\\s\\S]*?[^\\\\])?)\\\\]|\\\\\\((.*?)\\\\\\)/.source,\n \"g\",\n );\n return text.replace(\n pattern,\n (\n match: string,\n codeBlock: string | undefined,\n squareBracket: string | undefined,\n roundBracket: string | undefined,\n ): string => {\n if (codeBlock != null) {\n return codeBlock;\n } else if (squareBracket != null) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket != null) {\n return `$${roundBracket}$`;\n }\n return match;\n },\n );\n}\n\nexport function escapeMhchem(text: string): string {\n return text.replaceAll(\"$\\\\ce{\", \"$\\\\\\\\ce{\").replaceAll(\"$\\\\pu{\", \"$\\\\\\\\pu{\");\n}\n","import { clsx } from \"clsx\";\nimport { useMemo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport ReactMarkdown, { type Components } from \"react-markdown\";\nimport rehypeKatex from \"rehype-katex\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\n\nimport { completePartialTokens } from \"./completePartialTokens\";\nimport { CopyButton } from \"./CopyButton\";\nimport { preprocessLaTeX } from \"./preprocess\";\nimport type {\n CodeHighlighter,\n LLMMessageClassNames,\n LLMMessageComponents,\n} from \"./types\";\n\nexport interface LLMMessageProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"content\"> {\n /** The LLM message content as a markdown string. */\n children?: string;\n /** Alias for `children`. */\n content?: string;\n /** Class applied to the root element (merged with the built-in class). */\n className?: string;\n /** Per-element class overrides (merged with the built-in classes). */\n classNames?: LLMMessageClassNames;\n /** Per-element component overrides for full markup control. */\n components?: LLMMessageComponents;\n /**\n * Repair partially-streamed markdown/LaTeX so unterminated tokens (e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2`) do not render as raw\n * delimiter junk while the response is still streaming. Defaults to `true`.\n */\n completePartialTokens?: boolean;\n /**\n * Progressively render unterminated *block* math (`\\[…`, `$$…`) while it\n * streams, instead of hiding it until the closing delimiter arrives. This is\n * nicer to watch (a long block reveals row by row) but costs a synchronous\n * KaTeX parse on every chunk that contains an open block. Set to `false` to\n * hide unfinished blocks and skip that work. Only relevant while\n * `completePartialTokens` is enabled. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n /**\n * Optional syntax highlighter for fenced code blocks. When omitted, code\n * blocks render as plain text (so no highlighter bundle is pulled in). Pass\n * `ShikiHighlighter` / `ShikiWebHighlighter`, or build your own with\n * `createShikiHighlighter`.\n */\n highlighter?: CodeHighlighter;\n}\n\nconst remarkPlugins = [remarkGfm, remarkMath];\nconst rehypePlugins = [rehypeKatex];\n\nfunction cx(...inputs: Array<string | undefined>): string | undefined {\n const result = clsx(inputs);\n return result === \"\" ? undefined : result;\n}\n\nfunction buildComponents(\n classNames: LLMMessageClassNames | undefined,\n overrides: LLMMessageComponents | undefined,\n highlighter: CodeHighlighter | undefined,\n): Components {\n const cn = classNames ?? {};\n const o = overrides ?? {};\n const Highlighter = highlighter;\n\n return {\n code({ node: _node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || \"\");\n const codeText = String(children).replace(/\\n$/, \"\");\n // A fenced block always spans its own lines (so its text contains a\n // newline) even when no language info string is present; inline code\n // never does. Relying on the `language-` class alone would misrender a\n // bare ``` fence as inline code.\n const isBlock = match != null || String(children).includes(\"\\n\");\n\n if (isBlock) {\n const language = match?.[1] ?? \"\";\n if (o.codeBlock) {\n const CodeBlock = o.codeBlock;\n return (\n <CodeBlock\n code={codeText}\n language={language}\n className={cn.codeBlock}\n />\n );\n }\n return (\n <div className={cx(\"llm-code-block\", cn.codeBlock)}>\n <div className={cx(\"llm-code-header\", cn.codeHeader)}>\n <span className={cx(\"llm-code-language\", cn.codeLanguage)}>\n {language}\n </span>\n {o.copyButton ? (\n <o.copyButton text={codeText} className={cn.copyButton} />\n ) : (\n <CopyButton\n text={codeText}\n className={cx(\"llm-copy-button\", cn.copyButton)}\n />\n )}\n </div>\n <div className=\"llm-code-body\">\n {Highlighter ? (\n <Highlighter code={codeText} language={language} />\n ) : (\n <code className=\"llm-code-plain\">{codeText}</code>\n )}\n </div>\n </div>\n );\n }\n\n if (o.code) {\n const InlineCode = o.code;\n return (\n <InlineCode className={cx(\"llm-code\", cn.code, className)}>\n {children}\n </InlineCode>\n );\n }\n\n return (\n <code className={cx(\"llm-code\", cn.code, className)} {...props}>\n {children}\n </code>\n );\n },\n pre({ children }) {\n if (o.pre) {\n return <o.pre>{children}</o.pre>;\n }\n // Let the code component handle fenced blocks.\n return <>{children}</>;\n },\n table({ children }) {\n if (o.table) {\n return <o.table className={cn.table}>{children}</o.table>;\n }\n return (\n <div className={cx(\"llm-table-wrapper\", cn.tableWrapper)}>\n <table className={cx(\"llm-table\", cn.table)}>{children}</table>\n </div>\n );\n },\n th({ children }) {\n if (o.th) {\n return <o.th className={cn.th}>{children}</o.th>;\n }\n return <th className={cx(\"llm-th\", cn.th)}>{children}</th>;\n },\n td({ children }) {\n if (o.td) {\n return <o.td className={cn.td}>{children}</o.td>;\n }\n return <td className={cx(\"llm-td\", cn.td)}>{children}</td>;\n },\n blockquote({ children }) {\n if (o.blockquote) {\n return <o.blockquote className={cn.blockquote}>{children}</o.blockquote>;\n }\n return (\n <blockquote className={cx(\"llm-blockquote\", cn.blockquote)}>\n {children}\n </blockquote>\n );\n },\n ul({ children }) {\n if (o.ul) {\n return <o.ul className={cn.ul}>{children}</o.ul>;\n }\n return <ul className={cx(\"llm-ul\", cn.ul)}>{children}</ul>;\n },\n ol({ children }) {\n if (o.ol) {\n return <o.ol className={cn.ol}>{children}</o.ol>;\n }\n return <ol className={cx(\"llm-ol\", cn.ol)}>{children}</ol>;\n },\n li({ children }) {\n if (o.li) {\n return <o.li className={cn.li}>{children}</o.li>;\n }\n return <li className={cx(\"llm-li\", cn.li)}>{children}</li>;\n },\n p({ children }) {\n if (o.p) {\n return <o.p className={cn.p}>{children}</o.p>;\n }\n return <p className={cx(\"llm-p\", cn.p)}>{children}</p>;\n },\n h1({ children }) {\n if (o.h1) {\n return <o.h1 className={cn.h1}>{children}</o.h1>;\n }\n return <h1 className={cx(\"llm-h1\", cn.h1)}>{children}</h1>;\n },\n h2({ children }) {\n if (o.h2) {\n return <o.h2 className={cn.h2}>{children}</o.h2>;\n }\n return <h2 className={cx(\"llm-h2\", cn.h2)}>{children}</h2>;\n },\n h3({ children }) {\n if (o.h3) {\n return <o.h3 className={cn.h3}>{children}</o.h3>;\n }\n return <h3 className={cx(\"llm-h3\", cn.h3)}>{children}</h3>;\n },\n h4({ children }) {\n if (o.h4) {\n return <o.h4 className={cn.h4}>{children}</o.h4>;\n }\n return <h4 className={cx(\"llm-h4\", cn.h4)}>{children}</h4>;\n },\n h5({ children }) {\n if (o.h5) {\n return <o.h5 className={cn.h5}>{children}</o.h5>;\n }\n return <h5 className={cx(\"llm-h5\", cn.h5)}>{children}</h5>;\n },\n h6({ children }) {\n if (o.h6) {\n return <o.h6 className={cn.h6}>{children}</o.h6>;\n }\n return <h6 className={cx(\"llm-h6\", cn.h6)}>{children}</h6>;\n },\n input({ node: _node, type, checked, disabled, ...props }) {\n if (type === \"checkbox\") {\n if (o.checkbox) {\n return (\n <o.checkbox checked={Boolean(checked)} className={cn.checkbox} />\n );\n }\n return (\n <input\n type=\"checkbox\"\n checked={Boolean(checked)}\n disabled\n aria-label={checked ? \"Completed task\" : \"Incomplete task\"}\n className={cx(\"llm-checkbox\", cn.checkbox)}\n readOnly\n />\n );\n }\n return (\n <input\n type={type}\n checked={checked}\n disabled={disabled}\n readOnly\n {...props}\n />\n );\n },\n a({ href, children }) {\n if (o.a) {\n return (\n <o.a href={href} className={cn.a}>\n {children}\n </o.a>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cx(\"llm-a\", cn.a)}\n >\n {children}\n </a>\n );\n },\n img({ node: _node, src, alt, title, className: _className, ...props }) {\n if (o.img) {\n const Image = o.img;\n return (\n <Image\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cn.img}\n />\n );\n }\n return (\n <img\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cx(\"llm-img\", cn.img)}\n {...props}\n />\n );\n },\n hr() {\n if (o.hr) {\n return <o.hr className={cn.hr} />;\n }\n return <hr className={cx(\"llm-hr\", cn.hr)} />;\n },\n strong({ children }) {\n if (o.strong) {\n return <o.strong className={cn.strong}>{children}</o.strong>;\n }\n return <strong className={cx(\"llm-strong\", cn.strong)}>{children}</strong>;\n },\n em({ children }) {\n if (o.em) {\n return <o.em className={cn.em}>{children}</o.em>;\n }\n return <em className={cx(\"llm-em\", cn.em)}>{children}</em>;\n },\n del({ children }) {\n if (o.del) {\n return <o.del className={cn.del}>{children}</o.del>;\n }\n return <del className={cx(\"llm-del\", cn.del)}>{children}</del>;\n },\n };\n}\n\nexport function LLMMessage({\n children,\n content,\n className,\n classNames,\n components,\n completePartialTokens: repairPartialTokens = true,\n showUnfinishedLatexBlocks = true,\n highlighter,\n ...rest\n}: LLMMessageProps) {\n const source = content ?? children ?? \"\";\n\n const markdownComponents = useMemo(\n () => buildComponents(classNames, components, highlighter),\n [classNames, components, highlighter],\n );\n\n const processed = useMemo(() => {\n const repaired = repairPartialTokens\n ? completePartialTokens(source, { showUnfinishedLatexBlocks })\n : source;\n return preprocessLaTeX(repaired);\n }, [source, repairPartialTokens, showUnfinishedLatexBlocks]);\n\n return (\n <div className={cx(\"llm-message\", classNames?.root, className)} {...rest}>\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={markdownComponents}\n >\n {processed}\n </ReactMarkdown>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\n\nimport type { CodeHighlighter, CodeToHtml } from \"./types\";\n\ninterface CreateShikiHighlighterOptions {\n /** Theme pair forwarded to `codeToHtml`. Defaults to GitHub light/dark. */\n themes?: { light: string; dark: string };\n}\n\nconst DEFAULT_THEMES = { light: \"github-light\", dark: \"github-dark\" };\n\n/**\n * Builds a {@link CodeHighlighter} from any `codeToHtml`-compatible function.\n *\n * This factory imports no Shiki bundle itself, so importing it never drags\n * highlighting code into your app. You decide which bundle to pay for by\n * passing the `codeToHtml` from `shiki` (full), `shiki/bundle/web` (web), or a\n * minimal `createHighlighterCore` instance.\n *\n * @example\n * import { codeToHtml } from \"shiki/bundle/web\";\n * const Highlighter = createShikiHighlighter(codeToHtml);\n * <LLMMessage highlighter={Highlighter}>{content}</LLMMessage>\n */\nexport function createShikiHighlighter(\n codeToHtml: CodeToHtml,\n options?: CreateShikiHighlighterOptions,\n): CodeHighlighter {\n const themes = options?.themes ?? DEFAULT_THEMES;\n\n return function ShikiHighlighter({ code, language, className }) {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n Promise.resolve(codeToHtml(code, { lang: language, themes }))\n .then((result) => {\n if (!cancelled) setHtml(result);\n })\n .catch(() => {\n // Fallback: if the language is unsupported, just show plain code.\n if (!cancelled) setHtml(null);\n });\n return () => {\n cancelled = true;\n };\n // `codeToHtml` and `themes` are fixed for the lifetime of a highlighter\n // instance (captured from the factory closure), so they are intentionally\n // not listed: they never change between renders of this component.\n }, [code, language]);\n\n if (html) {\n return (\n <div\n className={className ?? \"llm-shiki\"}\n // The HTML is generated by Shiki, which is safe.\n dangerouslySetInnerHTML={{ __html: html }}\n />\n );\n }\n\n return <code className=\"llm-code-plain\">{code}</code>;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/completePartialTokens.ts","../src/CopyButton.tsx","../src/preprocess.ts","../src/LLMMessage.tsx","../src/createShikiHighlighter.tsx"],"names":["katex","jsxs","jsx","useState","useRef","useEffect","remarkGfm","remarkMath","rehypeKatex","clsx","Fragment","useMemo","ReactMarkdown"],"mappings":"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","file":"index.cjs","sourcesContent":["import katex from \"katex\";\n\n/** Options controlling how {@link completePartialTokens} repairs the stream. */\nexport interface CompletePartialTokensOptions {\n /**\n * Progressively render unterminated math by closing the open constructs and\n * keeping the largest prefix KaTeX accepts. This applies to both *block* math\n * (`\\[…`, `$$…`, revealed row by row) and *inline* math (`$…`, `\\(…`, closed\n * in place). It is convenient but costs a synchronous KaTeX parse on every\n * chunk while the math streams. Set to `false` to instead hide the\n * unterminated math entirely until its closing delimiter arrives, skipping the\n * KaTeX work. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n}\n\n/**\n * Repairs partially-streamed markdown / LaTeX so that incomplete syntax does\n * not leak raw delimiter characters into the rendered output.\n *\n * While an LLM streams a response, the text often ends mid-token, e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2` or `\\(a + b`. Rendered\n * as-is, those dangling delimiters show up as literal junk (`**`, `` ` ``, `[`,\n * `$`, `\\(`). This function detects the unterminated constructs at the tail of\n * the string and:\n * - closes safe inline formatting so it renders as intended (`**bold` →\n * `**bold**`, `` `code `` → `` `code` ``);\n * - hides fragments that cannot be completed yet, namely incomplete links and\n * incomplete inline math (`$…`, `\\(…`);\n * - progressively renders incomplete *block* math (`\\[…`, `$$…`): instead of\n * hiding the whole block until it finishes streaming, it closes the open\n * environments/braces and renders the largest prefix KaTeX accepts, so a\n * long aligned block reveals row by row instead of popping in at the end.\n *\n * It is a no-op for already-complete text, so it is safe to run on every chunk.\n *\n * @param text The (possibly mid-stream) markdown string.\n * @returns The string with trailing incomplete tokens repaired.\n */\nexport function completePartialTokens(\n text: string,\n options?: CompletePartialTokensOptions,\n): string {\n if (!text) return text;\n\n const showUnfinishedLatexBlocks = options?.showUnfinishedLatexBlocks ?? true;\n\n // An unterminated fenced code block is fine on its own: remark renders it to\n // the end of the document and the partial content reads correctly as code,\n // so we must not touch any of the (markdown-looking) characters inside it.\n if (hasUnclosedCodeFence(text)) {\n return text;\n }\n\n const protectedSpans: string[] = [];\n const protect = (value: string): string =>\n `\\u0000llmph${protectedSpans.push(value) - 1}\\u0000`;\n\n // Protect complete fenced code blocks and complete inline code spans so their\n // contents are never mistaken for markdown/LaTeX markers. Double-backtick\n // spans are protected before single-backtick ones so a span that itself\n // contains a backtick (`` a`b ``) is not mangled by the single-backtick pass.\n let working = text.replace(/```[\\s\\S]*?```/g, (match) => protect(match));\n working = working.replace(/``[\\s\\S]*?``/g, (match) => protect(match));\n working = working.replace(/`[^`\\n]+`/g, (match) => protect(match));\n\n // A leftover single backtick starts an unterminated inline code span. Protect\n // the rest of the line and close it so the in-progress code renders cleanly.\n const lastBacktick = working.lastIndexOf(\"`\");\n if (lastBacktick !== -1) {\n // Bound the in-progress span to its own line so trailing markdown on later\n // lines is not swallowed into the protected code.\n const newline = working.indexOf(\"\\n\", lastBacktick);\n const end = newline === -1 ? working.length : newline;\n const span = working.slice(lastBacktick, end);\n working =\n working.slice(0, lastBacktick) +\n protect(`${span}\\``) +\n working.slice(end);\n }\n\n working = repairIncompleteMath(working, showUnfinishedLatexBlocks);\n working = hideIncompleteLink(working);\n working = completePartialTable(working);\n working = hideDanglingListMarker(working);\n working = closeUnbalancedEmphasis(working);\n\n return working.replace(\n /\\u0000llmph(\\d+)\\u0000/g,\n (_match, index: string) => protectedSpans[Number(index)] ?? \"\",\n );\n}\n\n/**\n * Completes a partially-streamed GFM table delimiter row.\n *\n * A table needs a full delimiter row (`| --- | --- |`) to be recognised, so\n * while it streams the buffer ends with a header row followed by a fragment like\n * `| ---`. Without a valid delimiter remark-gfm collapses both lines into a\n * paragraph (\"| Feature | Works | | ---\"). Once a delimiter fragment appears we\n * already know the column count from the header, so we expand the fragment to a\n * complete delimiter, preserving any alignment colons that have streamed in.\n */\nfunction completePartialTable(text: string): string {\n const lines = text.split(\"\\n\");\n if (lines.length < 2) return text;\n\n const last = lines[lines.length - 1];\n // The candidate delimiter must contain only delimiter characters and at least\n // one dash; anything else (letters, etc.) means it is a header or body row.\n if (!/-/.test(last) || !/^[\\s|:-]*$/.test(last)) return text;\n\n const header = lines[lines.length - 2];\n if (!header.includes(\"|\")) return text;\n\n // If the table already has a delimiter row at or above the candidate, then\n // the candidate is just a body row that happens to contain only dashes/pipes\n // (not a streaming delimiter), so the table is complete and must be left\n // untouched. Walk up the contiguous block of pipe rows to detect that.\n for (let i = lines.length - 2; i >= 0; i--) {\n const line = lines[i];\n if (!line.includes(\"|\")) break;\n if (/-/.test(line) && /^[\\s|:-]*$/.test(line)) return text;\n }\n\n const columns = countTableColumns(header);\n lines[lines.length - 1] = buildDelimiterRow(last, columns);\n return lines.join(\"\\n\");\n}\n\n/** Counts the cells in a GFM table row, ignoring the outer pipes. */\nfunction countTableColumns(row: string): number {\n let inner = row.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n return inner.split(\"|\").length;\n}\n\n/**\n * Builds a delimiter row with `columns` cells, reusing any alignment colons\n * already present in the streamed fragment.\n */\nfunction buildDelimiterRow(fragment: string, columns: number): string {\n let inner = fragment.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n const existing = inner.split(\"|\").map((cell) => cell.trim());\n\n const cells = Array.from({ length: columns }, (_unused, index) => {\n const spec = existing[index] ?? \"\";\n const left = spec.startsWith(\":\");\n const right = spec.endsWith(\":\");\n if (left && right) return \":---:\";\n if (right) return \"---:\";\n if (left) return \":---\";\n return \"---\";\n });\n\n return `| ${cells.join(\" | \")} |`;\n}\n\n/**\n * Hides a trailing line that would be parsed as a setext heading underline.\n *\n * Mid-stream a bullet list arrives a character at a time, so the buffer briefly\n * ends with `paragraph\\n-` before the item text follows. In CommonMark a lone\n * run of dashes directly beneath a non-blank line is a setext H2 underline, so\n * a line like \"Unordered list:\" would flash as a heading until \"- Item\" streams\n * in. We drop the dangling marker until it gains content. A blank line above the\n * dashes makes them a thematic break instead, which is left untouched.\n */\nfunction hideDanglingListMarker(text: string): string {\n const match = text.match(/\\n[ \\t]{0,3}-+[ \\t]*$/);\n if (match?.index == null) return text;\n\n const before = text.slice(0, match.index);\n const prevLine = before.slice(before.lastIndexOf(\"\\n\") + 1);\n if (prevLine.trim() === \"\") return text;\n\n return before;\n}\n\n/**\n * True when a code fence is left open. Backtick (```) and tilde (~~~) fences are\n * counted separately so that a complete block of one kind that happens to\n * contain a line of the other kind is not mistaken for an unbalanced fence.\n */\nfunction hasUnclosedCodeFence(text: string): boolean {\n const backticks = (text.match(/^[ \\t]{0,3}```/gm) ?? []).length;\n const tildes = (text.match(/^[ \\t]{0,3}~~~/gm) ?? []).length;\n return backticks % 2 === 1 || tildes % 2 === 1;\n}\n\n/**\n * Drops a trailing, still-incomplete link or image, e.g. `[label`, `: string {\n // Find the last \"[\" that is not an escaped LaTeX delimiter (\"\\[\").\n let open = -1;\n for (let i = text.length - 1; i >= 0; i--) {\n if (text[i] === \"[\" && text[i - 1] !== \"\\\\\") {\n open = i;\n break;\n }\n }\n if (open === -1) return text;\n\n const start = open > 0 && text[open - 1] === \"!\" ? open - 1 : open;\n const rest = text.slice(open);\n\n // Label is still open: \"[lab\" / \"![al\".\n if (!rest.includes(\"]\")) {\n return text.slice(0, start);\n }\n // Label closed, destination opened but not yet closed: \"[lab](http\".\n if (/^\\[[^\\]]*\\]\\([^)]*$/.test(rest)) {\n return text.slice(0, start);\n }\n return text;\n}\n\n/** A math delimiter that has been opened but not yet closed in the stream. */\ninterface OpenMath {\n /** Index of the opening delimiter in the source string. */\n index: number;\n /** The opening delimiter itself, e.g. `\"\\\\[\"` or `\"$$\"`. */\n open: string;\n /** The closing delimiter to append once repaired, empty for inline math. */\n close: string;\n /** Whether the math is block (display) math we try to render progressively. */\n block: boolean;\n /** Whether to render in KaTeX display mode when validating a candidate. */\n display: boolean;\n}\n\n/**\n * Repairs an unterminated LaTeX region at the tail of the stream.\n *\n * Both inline math (`$…`, `\\(…`) and block math (`\\[…`, `$$…`) are rendered\n * progressively: we close any open environments/braces and keep the largest\n * leading slice that KaTeX can parse, so the math reveals itself as it streams\n * instead of staying blank until the closing delimiter finally arrives. Inline\n * math additionally drops an incomplete trailing brace group (e.g. `\\text{ kc`)\n * rather than auto-closing it, so a half-streamed word does not flash in the\n * middle of running text. Set `showUnfinishedLatexBlocks` to `false` to instead\n * hide the unterminated math entirely until its closing delimiter arrives.\n */\nfunction repairIncompleteMath(\n text: string,\n showUnfinishedLatexBlocks: boolean,\n): string {\n const countOf = (pattern: RegExp): number =>\n (text.match(pattern) ?? []).length;\n\n const opens: OpenMath[] = [];\n\n // Display math: \\[ ... \\]\n if (countOf(/\\\\\\[/g) > countOf(/\\\\\\]/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\[\"),\n open: \"\\\\[\",\n close: \"\\\\]\",\n block: true,\n display: true,\n });\n }\n\n // Inline math: \\( ... \\)\n if (countOf(/\\\\\\(/g) > countOf(/\\\\\\)/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\(\"),\n open: \"\\\\(\",\n close: \"\\\\)\",\n block: false,\n display: false,\n });\n }\n\n if (countOf(/\\$\\$/g) % 2 === 1) {\n // Display math: $$ ... $$\n opens.push({\n index: text.lastIndexOf(\"$$\"),\n open: \"$$\",\n close: \"$$\",\n block: true,\n display: true,\n });\n } else {\n // Inline math: $ ... $. Mask complete \"$$\" pairs (keeping indices stable),\n // then ignore escaped \"\\$\" and currency like \"$5\" to avoid false positives.\n let masked = text.replace(/\\$\\$/g, \" \");\n // Also mask complete single-line \"$…$\" spans that contain a LaTeX command\n // (so they are real math, not \"$5\" currency). Their opening \"$\" may be\n // followed by a digit (e.g. \"$15 \\text{ g}$\"), which the currency guard\n // below would otherwise drop from the count while still counting the\n // closing \"$\", flipping the parity and hiding trailing content by mistake.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$/g,\n (m) => \" \".repeat(m.length),\n );\n // Same parity hazard for command-free numeric spans (e.g. \"$0$\", \"$15$\"):\n // the opening \"$\" is dropped by the currency guard below while the closing\n // \"$\" is still counted. Mask these balanced numeric spans too so neither\n // delimiter is counted. Plain currency (\"$5 and $10\") has prose between the\n // dollars, so it matches neither this nor the command mask and is left for\n // the currency guard to handle.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$/g,\n (m) => \" \".repeat(m.length),\n );\n const dollars = inlineMathDollarIndices(masked);\n if (dollars.length % 2 === 1) {\n opens.push({\n index: dollars[dollars.length - 1],\n open: \"$\",\n close: \"$\",\n block: false,\n display: false,\n });\n }\n }\n\n const valid = opens.filter((entry) => entry.index >= 0);\n if (valid.length === 0) return text;\n\n // The earliest opener marks where the incomplete math region begins; anything\n // after it is part of the unterminated construct.\n const open = valid.reduce((a, b) => (b.index < a.index ? b : a));\n const before = text.slice(0, open.index);\n\n // When progressive rendering is disabled, hide the unterminated math (inline\n // or block) until its closing delimiter arrives, skipping the KaTeX cost.\n if (!showUnfinishedLatexBlocks) {\n return before;\n }\n\n const inner = text.slice(open.index + open.open.length);\n const body = bestRenderableMathBody(inner, open.display, open.block);\n if (body == null) return before;\n\n // Reproduce the original fenced layout so the markdown math parser can detect\n // the closing delimiter. When the block opens on its own line (`\\[\\n…`), the\n // closing delimiter must also sit on its own line; otherwise micromark treats\n // the run as inline math, never finds the closing fence, and KaTeX renders a\n // parse error that swallows the trailing delimiter.\n const blockLayout = /^[ \\t]*\\r?\\n/.test(inner);\n if (!blockLayout) {\n return before + open.open + body + open.close;\n }\n const opener =\n before === \"\" || before.endsWith(\"\\n\") ? open.open : `\\n${open.open}`;\n return `${before}${opener}${body.replace(/\\s+$/, \"\")}\\n${open.close}`;\n}\n\n/**\n * Returns the indices of the unescaped single `$` characters that act as inline\n * math delimiters in `masked` (complete `$$`/`$…$` spans are expected to have\n * been blanked out by the caller already).\n *\n * A `$` directly followed by a digit is normally currency (`$5`) and ignored.\n * The exception is a span whose body merely *starts* with a number but contains\n * a LaTeX command, e.g. `$1288 \\text{ kcal}`: the `\\text` proves it is real\n * math, so the opening `$` must count as a delimiter instead of being mistaken\n * for `$1288` currency. The span is scanned only up to the next unescaped `$`,\n * a newline, or the end of the string, since inline math stays on one line.\n */\nfunction inlineMathDollarIndices(masked: string): number[] {\n const indices: number[] = [];\n const pattern = /(?<!\\\\)\\$/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(masked)) != null) {\n const index = match.index;\n if (/\\d/.test(masked[index + 1] ?? \"\")) {\n const rest = masked.slice(index + 1);\n const end = rest.search(/(?<!\\\\)\\$|\\n/);\n const span = end === -1 ? rest : rest.slice(0, end);\n if (!/\\\\[a-zA-Z]/.test(span)) continue;\n }\n indices.push(index);\n }\n return indices;\n}\n\n/**\n * Returns the largest leading slice of incomplete block-math content that KaTeX\n * can render, with its open environments and braces closed, or `null` when no\n * usable prefix exists yet (in which case the caller hides the fragment).\n *\n * When an environment is still open (e.g. `\\begin{aligned}` mid-stream) we\n * prefer revealing only the complete rows so each equation appears fully formed,\n * falling back to a token-level repair so single-line blocks still stream in.\n */\nfunction bestRenderableMathBody(\n inner: string,\n display: boolean,\n block: boolean,\n): string | null {\n const candidates = unclosedEnvironments(inner).length > 0\n ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))]\n : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];\n\n // Inline math is short and sits in running text, so a half-streamed brace\n // group (e.g. `\\text{ kc`) would flash a partial word that then changes. For\n // inline math we therefore prefer dropping the incomplete trailing group and\n // keeping the largest stable prefix, only falling back to the brace-closing\n // candidates above when that prefix cannot render on its own.\n if (!block) {\n candidates.unshift(\n closeOpenMathConstructs(\n trimIncompleteMathTail(dropIncompleteBraceGroup(inner)),\n ),\n );\n }\n\n for (const candidate of candidates) {\n if (!hasRenderableMathContent(candidate)) continue;\n if (isRenderableMath(candidate, display)) return candidate;\n }\n return null;\n}\n\n/**\n * Cuts a math fragment back to just before its first still-open `{`, dropping\n * the entire incomplete brace group. Escaped braces (`\\{`, `\\}`) are ignored.\n * Returns the input unchanged when every group is already balanced.\n */\nfunction dropIncompleteBraceGroup(text: string): string {\n const stack: number[] = [];\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === \"\\\\\") {\n i++;\n continue;\n }\n if (char === \"{\") stack.push(i);\n else if (char === \"}\" && stack.length > 0) stack.pop();\n }\n if (stack.length === 0) return text;\n return text.slice(0, stack[0]);\n}\n\n/** True when a math body contains something other than empty environment scaffolding. */\nfunction hasRenderableMathContent(body: string): boolean {\n const stripped = body\n .replace(/\\\\(?:begin|end)\\s*\\{[^}]*\\}/g, \"\")\n .replace(/[\\s{}]/g, \"\");\n return stripped.length > 0;\n}\n\n/**\n * True when KaTeX can render the math body without raising a parse error.\n *\n * Uses the public, stable `renderToString` entry point (with `throwOnError`)\n * rather than any internal parse-only API, so it keeps working across KaTeX\n * upgrades. We only care whether it throws; the produced string is discarded.\n */\nfunction isRenderableMath(body: string, display: boolean): boolean {\n try {\n katex.renderToString(body, {\n displayMode: display,\n throwOnError: true,\n strict: false,\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Keeps only the complete rows of a multi-line environment by cutting back to\n * the last row separator (`\\\\`), dropping the partially-streamed current row.\n * Returns an empty string when no full row has streamed yet.\n */\nfunction truncateToLastRow(inner: string): string {\n const lastRow = inner.lastIndexOf(\"\\\\\\\\\");\n if (lastRow === -1) return \"\";\n return inner.slice(0, lastRow + 2);\n}\n\n/**\n * Drops trailing tokens that cannot render on their own yet: surrounding\n * whitespace, a dangling backslash, an in-progress control word (`\\frac` may\n * still be `\\fra`), and a subscript/superscript with no argument. A complete\n * `\\\\` row separator is preserved.\n */\nfunction trimIncompleteMathTail(inner: string): string {\n let result = inner;\n let previous: string;\n do {\n previous = result;\n result = result.replace(/\\s+$/, \"\");\n // A trailing odd run of backslashes ends in a lone \"\\\" (an incomplete \"\\\\\"\n // or the start of a command); drop it. An even run is complete \"\\\\\".\n const backslashes = result.match(/\\\\+$/);\n if (backslashes != null && backslashes[0].length % 2 === 1) {\n result = result.slice(0, -1);\n }\n // A trailing control word is ambiguous mid-stream; drop it so it cannot be\n // an unknown (and therefore error-rendered) command.\n result = result.replace(/\\\\[a-zA-Z]+\\*?$/, \"\");\n // A subscript/superscript needs an argument that has not arrived yet.\n result = result.replace(/[_^]$/, \"\");\n } while (result !== previous);\n return result;\n}\n\n/**\n * Closes the constructs left open in a math fragment so KaTeX can parse it:\n * unmatched `\\left`, unbalanced `{` groups, and unclosed environments. Order is\n * a best effort; the caller validates the result with KaTeX regardless.\n */\nfunction closeOpenMathConstructs(inner: string): string {\n let result = inner;\n\n const lefts = (result.match(/\\\\left(?![a-zA-Z])/g) ?? []).length;\n const rights = (result.match(/\\\\right(?![a-zA-Z])/g) ?? []).length;\n result += \"\\\\right.\".repeat(Math.max(0, lefts - rights));\n\n result += \"}\".repeat(openBraceDepth(result));\n\n const environments = unclosedEnvironments(result);\n for (let i = environments.length - 1; i >= 0; i--) {\n result += `\\\\end{${environments[i]}}`;\n }\n return result;\n}\n\n/** Counts unclosed `{` groups, ignoring escaped braces (`\\{`, `\\}`). */\nfunction openBraceDepth(text: string): number {\n let depth = 0;\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === \"\\\\\") {\n i++;\n continue;\n }\n if (char === \"{\") depth++;\n else if (char === \"}\" && depth > 0) depth--;\n }\n return depth;\n}\n\n/**\n * Returns the names of environments opened with `\\begin{…}` but not yet closed\n * with a matching `\\end{…}`, outermost first.\n */\nfunction unclosedEnvironments(text: string): string[] {\n const stack: string[] = [];\n const pattern = /\\\\(begin|end)\\s*\\{([^}]*)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) != null) {\n const name = match[2];\n if (match[1] === \"begin\") {\n stack.push(name);\n } else {\n const index = stack.lastIndexOf(name);\n if (index !== -1) stack.splice(index, 1);\n else stack.pop();\n }\n }\n return stack;\n}\n\n/**\n * Closes unterminated emphasis runs: ~~strike~~, **bold**, *italic*, __bold__\n * and _italic_.\n */\nfunction closeUnbalancedEmphasis(text: string): string {\n let result = text;\n result = closeRunMarker(result, \"~~\");\n // Close a single \"*\" first so a \"***\" opener becomes \"*\" + \"**\" and both\n // halves get closed, yielding a balanced \"***…***\".\n result = closeSingleAsterisk(result);\n result = closeRunMarker(result, \"**\");\n result = closeSingleUnderscore(result);\n result = closeDoubleUnderscore(result);\n return result;\n}\n\n/**\n * True when the marker at `index` begins a delimiter run that could open\n * emphasis: it sits at the start of the string or directly after a non-word\n * character (whitespace or punctuation). Underscores require this so intra-word\n * usage (`snake_case`, `__init__`) is never treated as a dangling emphasis\n * opener.\n */\nfunction opensAtWordBoundary(text: string, index: number): boolean {\n if (index <= 0) return true;\n // Whitespace or punctuation before the marker counts as a boundary; an\n // alphanumeric character (or another underscore) does not, so intra-word\n // usage (`snake_case`, `__init__`) is never treated as a dangling opener\n // while a leading-punctuation case like `(_italic` still closes.\n return !/[\\p{L}\\p{N}_]/u.test(text[index - 1]);\n}\n\n/**\n * Closes a single `_` italic marker. `__` pairs are masked out first, and the\n * marker is only closed when it both opens at a word boundary and sits directly\n * before a non-space character, so `snake_case` is left alone.\n */\nfunction closeSingleUnderscore(text: string): string {\n const masked = text.replace(/__/g, \"\");\n const count = (masked.match(/_/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"_\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s_]/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"_\");\n}\n\n/**\n * Closes a `__` bold marker when it is unbalanced, opens at a word boundary,\n * and is directly followed by a non-space character (so `a__b` and `__init__`\n * are left untouched).\n */\nfunction closeDoubleUnderscore(text: string): string {\n const count = (text.match(/__/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"__\");\n const after = text.slice(lastIndex + 2);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"__\");\n}\n\n/**\n * Blanks out asterisks that belong to *block* constructs rather than inline\n * emphasis so they never skew the emphasis parity count: thematic breaks\n * (`***`, `* * *`) and line-leading list bullets (`* item`) at any\n * indentation. Each match is replaced with spaces of equal length so string\n * indices stay stable for the callers that still use the original text.\n */\nfunction maskBlockAsterisks(text: string): string {\n return text\n .replace(/^[ \\t]*\\*(?:[ \\t]*\\*){2,}[ \\t]*$/gm, (m) => \" \".repeat(m.length))\n .replace(/^[ \\t]*\\*(?=[ \\t])/gm, (m) => \" \".repeat(m.length));\n}\n\n/**\n * Closes a two-character emphasis marker (`**` or `~~`) when it is unbalanced\n * and the final marker looks like an opener (immediately followed by a\n * non-space character), which avoids touching list markers or operators.\n */\nfunction closeRunMarker(text: string, marker: string): string {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n // Asterisk runs share their character with bullets and thematic breaks, so\n // count them on a text whose block asterisks have been masked away.\n const countSource = marker.includes(\"*\") ? maskBlockAsterisks(text) : text;\n const count = (countSource.match(new RegExp(escaped, \"g\")) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(marker);\n const after = text.slice(lastIndex + marker.length);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, marker);\n}\n\n/**\n * Closes a single `*` italic marker. `**` pairs are masked out first, and the\n * marker is only closed when it sits directly before a non-space character so\n * bullet markers (`* item`) and multiplication (`2 * 3`) are left alone.\n */\nfunction closeSingleAsterisk(text: string): string {\n // Mask block-level asterisks (bullets, thematic breaks) and \"**\" pairs so the\n // marker is not miscounted as a dangling italic opener. Masking only affects\n // the parity count; `lastIndexOf` still operates on the original text.\n const masked = maskBlockAsterisks(text).replace(/\\*\\*/g, \"\");\n const count = (masked.match(/\\*/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"*\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s*]/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"*\");\n}\n\n/**\n * Appends a closing emphasis marker, but places it before any trailing\n * whitespace. A closer such as `**` is only valid when it directly follows a\n * non-space character, so `**bold ` must become `**bold** ` rather than the\n * un-renderable `**bold **`.\n */\nfunction insertBeforeTrailingWhitespace(text: string, marker: string): string {\n const trailing = text.match(/\\s+$/)?.[0] ?? \"\";\n const core = text.slice(0, text.length - trailing.length);\n return core + marker + trailing;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nimport type { CopyButtonProps } from \"./types\";\n\nfunction CopyIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport function CopyButton({ text, className }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const copy = () => {\n const clipboard = navigator.clipboard;\n if (!clipboard) return;\n // Only show the \"copied\" confirmation once the write actually succeeds.\n void clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n // Clipboard write failed; keep the idle state.\n });\n };\n\n return (\n <button\n type=\"button\"\n onClick={copy}\n className={className}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n data-copied={copied ? \"\" : undefined}\n >\n {copied ? <CheckIcon /> : <CopyIcon />}\n </button>\n );\n}\n","/**\n * Matches a fenced code block or an inline code span. Shared by\n * {@link preprocessLaTeX} and {@link escapeBrackets} so both functions treat\n * code identically; composed into the larger patterns below via `.source`.\n */\nconst CODE_SPAN = /```[\\s\\S]*?```|`[^`\\n]+`/;\n\n/**\n * Preprocesses LaTeX content by replacing delimiters and escaping certain characters.\n *\n * @param content The input string containing LaTeX expressions.\n * @returns The processed string with replaced delimiters and escaped characters.\n */\nexport function preprocessLaTeX(content: string): string {\n // Step 1: Protect code blocks\n const codeBlocks: string[] = [];\n content = content.replace(\n new RegExp(`(${CODE_SPAN.source})`, \"g\"),\n (_match, code) => {\n codeBlocks.push(code);\n return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;\n },\n );\n\n // Step 2: Protect existing LaTeX expressions. This is what makes the currency\n // escaping in Step 3 safe: by pulling complete `$$…$$` / `\\[…\\]` / `\\(…\\)`\n // regions out of the string first, the `\\$(?=\\d)` pass below cannot corrupt a\n // `$` that legitimately belongs to a math expression (e.g. `$$x = $5$$`).\n //\n // Single-dollar inline math whose content begins with a digit (e.g.\n // `$15 \\text{ g}$`) is protected too: without this its opening `$` would be\n // escaped as currency in Step 3, unbalancing the delimiters so remark-math\n // swallows the rest of the paragraph as one math region. Two shapes qualify:\n // 1. spans containing a LaTeX command (`\\…`), e.g. `$15 \\text{ g}$`;\n // 2. balanced spans whose content is purely numeric/math (digits, spaces\n // and basic operators, no prose letters), e.g. `$0$` or `$1288 / 3$`.\n // Both leave plain currency prose like `$5 and $10` for Step 3, because that\n // text contains letters between the dollars and so matches neither shape.\n const latexExpressions: string[] = [];\n content = content.replace(\n /(\\$\\$[\\s\\S]*?\\$\\$|\\\\\\[[\\s\\S]*?\\\\\\]|\\\\\\(.*?\\\\\\)|\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$|\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$)/g,\n (match) => {\n latexExpressions.push(match);\n return `<<LATEX_${latexExpressions.length - 1}>>`;\n },\n );\n\n // Step 3: Escape dollar signs that are likely currency indicators\n content = content.replace(/\\$(?=\\d)/g, \"\\\\$\");\n\n // Step 4: Restore LaTeX expressions\n content = content.replace(\n /<<LATEX_(\\d+)>>/g,\n (_, index) => latexExpressions[parseInt(index, 10)],\n );\n\n // Step 5: Restore code blocks\n content = content.replace(\n /<<CODE_BLOCK_(\\d+)>>/g,\n (_, index) => codeBlocks[parseInt(index, 10)],\n );\n\n // Step 6: Apply additional escaping functions\n content = escapeBrackets(content);\n content = escapeMhchem(content);\n\n return content;\n}\n\nexport function escapeBrackets(text: string): string {\n const pattern = new RegExp(\n `(${CODE_SPAN.source})|` +\n /\\\\\\[((?:[\\s\\S]*?[^\\\\])?)\\\\]|\\\\\\((.*?)\\\\\\)/.source,\n \"g\",\n );\n return text.replace(\n pattern,\n (\n match: string,\n codeBlock: string | undefined,\n squareBracket: string | undefined,\n roundBracket: string | undefined,\n ): string => {\n if (codeBlock != null) {\n return codeBlock;\n } else if (squareBracket != null) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket != null) {\n return `$${roundBracket}$`;\n }\n return match;\n },\n );\n}\n\nexport function escapeMhchem(text: string): string {\n return text.replaceAll(\"$\\\\ce{\", \"$\\\\\\\\ce{\").replaceAll(\"$\\\\pu{\", \"$\\\\\\\\pu{\");\n}\n","import { clsx } from \"clsx\";\nimport { useMemo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport ReactMarkdown, { type Components } from \"react-markdown\";\nimport rehypeKatex from \"rehype-katex\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\n\nimport { completePartialTokens } from \"./completePartialTokens\";\nimport { CopyButton } from \"./CopyButton\";\nimport { preprocessLaTeX } from \"./preprocess\";\nimport type {\n CodeHighlighter,\n LLMMessageClassNames,\n LLMMessageComponents,\n} from \"./types\";\n\nexport interface LLMMessageProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"content\"> {\n /** The LLM message content as a markdown string. */\n children?: string;\n /** Alias for `children`. */\n content?: string;\n /** Class applied to the root element (merged with the built-in class). */\n className?: string;\n /** Per-element class overrides (merged with the built-in classes). */\n classNames?: LLMMessageClassNames;\n /** Per-element component overrides for full markup control. */\n components?: LLMMessageComponents;\n /**\n * Repair partially-streamed markdown/LaTeX so unterminated tokens (e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2`) do not render as raw\n * delimiter junk while the response is still streaming. Defaults to `true`.\n */\n completePartialTokens?: boolean;\n /**\n * Progressively render unterminated *block* math (`\\[…`, `$$…`) while it\n * streams, instead of hiding it until the closing delimiter arrives. This is\n * nicer to watch (a long block reveals row by row) but costs a synchronous\n * KaTeX parse on every chunk that contains an open block. Set to `false` to\n * hide unfinished blocks and skip that work. Only relevant while\n * `completePartialTokens` is enabled. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n /**\n * Optional syntax highlighter for fenced code blocks. When omitted, code\n * blocks render as plain text (so no highlighter bundle is pulled in). Pass\n * `ShikiHighlighter` / `ShikiWebHighlighter`, or build your own with\n * `createShikiHighlighter`.\n */\n highlighter?: CodeHighlighter;\n}\n\nconst remarkPlugins = [remarkGfm, remarkMath];\nconst rehypePlugins = [rehypeKatex];\n\nfunction cx(...inputs: Array<string | undefined>): string | undefined {\n const result = clsx(inputs);\n return result === \"\" ? undefined : result;\n}\n\nfunction buildComponents(\n classNames: LLMMessageClassNames | undefined,\n overrides: LLMMessageComponents | undefined,\n highlighter: CodeHighlighter | undefined,\n): Components {\n const cn = classNames ?? {};\n const o = overrides ?? {};\n const Highlighter = highlighter;\n\n return {\n code({ node: _node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || \"\");\n const codeText = String(children).replace(/\\n$/, \"\");\n // A fenced block always spans its own lines (so its text contains a\n // newline) even when no language info string is present; inline code\n // never does. Relying on the `language-` class alone would misrender a\n // bare ``` fence as inline code.\n const isBlock = match != null || String(children).includes(\"\\n\");\n\n if (isBlock) {\n const language = match?.[1] ?? \"\";\n if (o.codeBlock) {\n const CodeBlock = o.codeBlock;\n return (\n <CodeBlock\n code={codeText}\n language={language}\n className={cn.codeBlock}\n />\n );\n }\n return (\n <div className={cx(\"llm-code-block\", cn.codeBlock)}>\n <div className={cx(\"llm-code-header\", cn.codeHeader)}>\n <span className={cx(\"llm-code-language\", cn.codeLanguage)}>\n {language}\n </span>\n {o.copyButton ? (\n <o.copyButton text={codeText} className={cn.copyButton} />\n ) : (\n <CopyButton\n text={codeText}\n className={cx(\"llm-copy-button\", cn.copyButton)}\n />\n )}\n </div>\n <div className=\"llm-code-body\">\n {Highlighter ? (\n <Highlighter code={codeText} language={language} />\n ) : (\n <code className=\"llm-code-plain\">{codeText}</code>\n )}\n </div>\n </div>\n );\n }\n\n if (o.code) {\n const InlineCode = o.code;\n return (\n <InlineCode className={cx(\"llm-code\", cn.code, className)}>\n {children}\n </InlineCode>\n );\n }\n\n return (\n <code className={cx(\"llm-code\", cn.code, className)} {...props}>\n {children}\n </code>\n );\n },\n pre({ children }) {\n if (o.pre) {\n return <o.pre>{children}</o.pre>;\n }\n // Let the code component handle fenced blocks.\n return <>{children}</>;\n },\n table({ children }) {\n if (o.table) {\n return <o.table className={cn.table}>{children}</o.table>;\n }\n return (\n <div className={cx(\"llm-table-wrapper\", cn.tableWrapper)}>\n <table className={cx(\"llm-table\", cn.table)}>{children}</table>\n </div>\n );\n },\n th({ children }) {\n if (o.th) {\n return <o.th className={cn.th}>{children}</o.th>;\n }\n return <th className={cx(\"llm-th\", cn.th)}>{children}</th>;\n },\n td({ children }) {\n if (o.td) {\n return <o.td className={cn.td}>{children}</o.td>;\n }\n return <td className={cx(\"llm-td\", cn.td)}>{children}</td>;\n },\n blockquote({ children }) {\n if (o.blockquote) {\n return <o.blockquote className={cn.blockquote}>{children}</o.blockquote>;\n }\n return (\n <blockquote className={cx(\"llm-blockquote\", cn.blockquote)}>\n {children}\n </blockquote>\n );\n },\n ul({ children }) {\n if (o.ul) {\n return <o.ul className={cn.ul}>{children}</o.ul>;\n }\n return <ul className={cx(\"llm-ul\", cn.ul)}>{children}</ul>;\n },\n ol({ children }) {\n if (o.ol) {\n return <o.ol className={cn.ol}>{children}</o.ol>;\n }\n return <ol className={cx(\"llm-ol\", cn.ol)}>{children}</ol>;\n },\n li({ children }) {\n if (o.li) {\n return <o.li className={cn.li}>{children}</o.li>;\n }\n return <li className={cx(\"llm-li\", cn.li)}>{children}</li>;\n },\n p({ children }) {\n if (o.p) {\n return <o.p className={cn.p}>{children}</o.p>;\n }\n return <p className={cx(\"llm-p\", cn.p)}>{children}</p>;\n },\n h1({ children }) {\n if (o.h1) {\n return <o.h1 className={cn.h1}>{children}</o.h1>;\n }\n return <h1 className={cx(\"llm-h1\", cn.h1)}>{children}</h1>;\n },\n h2({ children }) {\n if (o.h2) {\n return <o.h2 className={cn.h2}>{children}</o.h2>;\n }\n return <h2 className={cx(\"llm-h2\", cn.h2)}>{children}</h2>;\n },\n h3({ children }) {\n if (o.h3) {\n return <o.h3 className={cn.h3}>{children}</o.h3>;\n }\n return <h3 className={cx(\"llm-h3\", cn.h3)}>{children}</h3>;\n },\n h4({ children }) {\n if (o.h4) {\n return <o.h4 className={cn.h4}>{children}</o.h4>;\n }\n return <h4 className={cx(\"llm-h4\", cn.h4)}>{children}</h4>;\n },\n h5({ children }) {\n if (o.h5) {\n return <o.h5 className={cn.h5}>{children}</o.h5>;\n }\n return <h5 className={cx(\"llm-h5\", cn.h5)}>{children}</h5>;\n },\n h6({ children }) {\n if (o.h6) {\n return <o.h6 className={cn.h6}>{children}</o.h6>;\n }\n return <h6 className={cx(\"llm-h6\", cn.h6)}>{children}</h6>;\n },\n input({ node: _node, type, checked, disabled, ...props }) {\n if (type === \"checkbox\") {\n if (o.checkbox) {\n return (\n <o.checkbox checked={Boolean(checked)} className={cn.checkbox} />\n );\n }\n return (\n <input\n type=\"checkbox\"\n checked={Boolean(checked)}\n disabled\n aria-label={checked ? \"Completed task\" : \"Incomplete task\"}\n className={cx(\"llm-checkbox\", cn.checkbox)}\n readOnly\n />\n );\n }\n return (\n <input\n type={type}\n checked={checked}\n disabled={disabled}\n readOnly\n {...props}\n />\n );\n },\n a({ href, children }) {\n if (o.a) {\n return (\n <o.a href={href} className={cn.a}>\n {children}\n </o.a>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cx(\"llm-a\", cn.a)}\n >\n {children}\n </a>\n );\n },\n img({ node: _node, src, alt, title, className: _className, ...props }) {\n if (o.img) {\n const Image = o.img;\n return (\n <Image\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cn.img}\n />\n );\n }\n return (\n <img\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cx(\"llm-img\", cn.img)}\n {...props}\n />\n );\n },\n hr() {\n if (o.hr) {\n return <o.hr className={cn.hr} />;\n }\n return <hr className={cx(\"llm-hr\", cn.hr)} />;\n },\n strong({ children }) {\n if (o.strong) {\n return <o.strong className={cn.strong}>{children}</o.strong>;\n }\n return <strong className={cx(\"llm-strong\", cn.strong)}>{children}</strong>;\n },\n em({ children }) {\n if (o.em) {\n return <o.em className={cn.em}>{children}</o.em>;\n }\n return <em className={cx(\"llm-em\", cn.em)}>{children}</em>;\n },\n del({ children }) {\n if (o.del) {\n return <o.del className={cn.del}>{children}</o.del>;\n }\n return <del className={cx(\"llm-del\", cn.del)}>{children}</del>;\n },\n };\n}\n\nexport function LLMMessage({\n children,\n content,\n className,\n classNames,\n components,\n completePartialTokens: repairPartialTokens = true,\n showUnfinishedLatexBlocks = true,\n highlighter,\n ...rest\n}: LLMMessageProps) {\n const source = content ?? children ?? \"\";\n\n const markdownComponents = useMemo(\n () => buildComponents(classNames, components, highlighter),\n [classNames, components, highlighter],\n );\n\n const processed = useMemo(() => {\n const repaired = repairPartialTokens\n ? completePartialTokens(source, { showUnfinishedLatexBlocks })\n : source;\n return preprocessLaTeX(repaired);\n }, [source, repairPartialTokens, showUnfinishedLatexBlocks]);\n\n return (\n <div className={cx(\"llm-message\", classNames?.root, className)} {...rest}>\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={markdownComponents}\n >\n {processed}\n </ReactMarkdown>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\n\nimport type { CodeHighlighter, CodeToHtml } from \"./types\";\n\ninterface CreateShikiHighlighterOptions {\n /** Theme pair forwarded to `codeToHtml`. Defaults to GitHub light/dark. */\n themes?: { light: string; dark: string };\n}\n\nconst DEFAULT_THEMES = { light: \"github-light\", dark: \"github-dark\" };\n\n/**\n * Builds a {@link CodeHighlighter} from any `codeToHtml`-compatible function.\n *\n * This factory imports no Shiki bundle itself, so importing it never drags\n * highlighting code into your app. You decide which bundle to pay for by\n * passing the `codeToHtml` from `shiki` (full), `shiki/bundle/web` (web), or a\n * minimal `createHighlighterCore` instance.\n *\n * @example\n * import { codeToHtml } from \"shiki/bundle/web\";\n * const Highlighter = createShikiHighlighter(codeToHtml);\n * <LLMMessage highlighter={Highlighter}>{content}</LLMMessage>\n */\nexport function createShikiHighlighter(\n codeToHtml: CodeToHtml,\n options?: CreateShikiHighlighterOptions,\n): CodeHighlighter {\n const themes = options?.themes ?? DEFAULT_THEMES;\n\n return function ShikiHighlighter({ code, language, className }) {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n Promise.resolve(codeToHtml(code, { lang: language, themes }))\n .then((result) => {\n if (!cancelled) setHtml(result);\n })\n .catch(() => {\n // Fallback: if the language is unsupported, just show plain code.\n if (!cancelled) setHtml(null);\n });\n return () => {\n cancelled = true;\n };\n // `codeToHtml` and `themes` are fixed for the lifetime of a highlighter\n // instance (captured from the factory closure), so they are intentionally\n // not listed: they never change between renders of this component.\n }, [code, language]);\n\n if (html) {\n return (\n <div\n className={className ?? \"llm-shiki\"}\n // The HTML is generated by Shiki, which is safe.\n dangerouslySetInnerHTML={{ __html: html }}\n />\n );\n }\n\n return <code className=\"llm-code-plain\">{code}</code>;\n };\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -52,11 +52,12 @@ declare function escapeMhchem(text: string): string;
|
|
|
52
52
|
/** Options controlling how {@link completePartialTokens} repairs the stream. */
|
|
53
53
|
interface CompletePartialTokensOptions {
|
|
54
54
|
/**
|
|
55
|
-
* Progressively render unterminated
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
55
|
+
* Progressively render unterminated math by closing the open constructs and
|
|
56
|
+
* keeping the largest prefix KaTeX accepts. This applies to both *block* math
|
|
57
|
+
* (`\[…`, `$$…`, revealed row by row) and *inline* math (`$…`, `\(…`, closed
|
|
58
|
+
* in place). It is convenient but costs a synchronous KaTeX parse on every
|
|
59
|
+
* chunk while the math streams. Set to `false` to instead hide the
|
|
60
|
+
* unterminated math entirely until its closing delimiter arrives, skipping the
|
|
60
61
|
* KaTeX work. Defaults to `true`.
|
|
61
62
|
*/
|
|
62
63
|
showUnfinishedLatexBlocks?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -52,11 +52,12 @@ declare function escapeMhchem(text: string): string;
|
|
|
52
52
|
/** Options controlling how {@link completePartialTokens} repairs the stream. */
|
|
53
53
|
interface CompletePartialTokensOptions {
|
|
54
54
|
/**
|
|
55
|
-
* Progressively render unterminated
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
55
|
+
* Progressively render unterminated math by closing the open constructs and
|
|
56
|
+
* keeping the largest prefix KaTeX accepts. This applies to both *block* math
|
|
57
|
+
* (`\[…`, `$$…`, revealed row by row) and *inline* math (`$…`, `\(…`, closed
|
|
58
|
+
* in place). It is convenient but costs a synchronous KaTeX parse on every
|
|
59
|
+
* chunk while the math streams. Set to `false` to instead hide the
|
|
60
|
+
* unterminated math entirely until its closing delimiter arrives, skipping the
|
|
60
61
|
* KaTeX work. Defaults to `true`.
|
|
61
62
|
*/
|
|
62
63
|
showUnfinishedLatexBlocks?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -122,7 +122,7 @@ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
|
|
|
122
122
|
opens.push({
|
|
123
123
|
index: text.lastIndexOf("\\("),
|
|
124
124
|
open: "\\(",
|
|
125
|
-
close: "",
|
|
125
|
+
close: "\\)",
|
|
126
126
|
block: false,
|
|
127
127
|
display: false
|
|
128
128
|
});
|
|
@@ -145,16 +145,12 @@ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
|
|
|
145
145
|
/(?<!\\)\$(?!\$)\d[\d\s.,+\-*/=]*\$/g,
|
|
146
146
|
(m) => " ".repeat(m.length)
|
|
147
147
|
);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
lastDollar = match.index;
|
|
151
|
-
}
|
|
152
|
-
const singles = masked.match(/(?<!\\)\$(?!\d)/g) ?? [];
|
|
153
|
-
if (singles.length % 2 === 1 && lastDollar !== -1) {
|
|
148
|
+
const dollars = inlineMathDollarIndices(masked);
|
|
149
|
+
if (dollars.length % 2 === 1) {
|
|
154
150
|
opens.push({
|
|
155
|
-
index:
|
|
151
|
+
index: dollars[dollars.length - 1],
|
|
156
152
|
open: "$",
|
|
157
|
-
close: "",
|
|
153
|
+
close: "$",
|
|
158
154
|
block: false,
|
|
159
155
|
display: false
|
|
160
156
|
});
|
|
@@ -164,14 +160,11 @@ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
|
|
|
164
160
|
if (valid.length === 0) return text;
|
|
165
161
|
const open = valid.reduce((a, b) => b.index < a.index ? b : a);
|
|
166
162
|
const before = text.slice(0, open.index);
|
|
167
|
-
if (!open.block) {
|
|
168
|
-
return before;
|
|
169
|
-
}
|
|
170
163
|
if (!showUnfinishedLatexBlocks) {
|
|
171
164
|
return before;
|
|
172
165
|
}
|
|
173
166
|
const inner = text.slice(open.index + open.open.length);
|
|
174
|
-
const body = bestRenderableMathBody(inner, open.display);
|
|
167
|
+
const body = bestRenderableMathBody(inner, open.display, open.block);
|
|
175
168
|
if (body == null) return before;
|
|
176
169
|
const blockLayout = /^[ \t]*\r?\n/.test(inner);
|
|
177
170
|
if (!blockLayout) {
|
|
@@ -182,14 +175,51 @@ ${open.open}`;
|
|
|
182
175
|
return `${before}${opener}${body.replace(/\s+$/, "")}
|
|
183
176
|
${open.close}`;
|
|
184
177
|
}
|
|
185
|
-
function
|
|
178
|
+
function inlineMathDollarIndices(masked) {
|
|
179
|
+
const indices = [];
|
|
180
|
+
const pattern = /(?<!\\)\$/g;
|
|
181
|
+
let match;
|
|
182
|
+
while ((match = pattern.exec(masked)) != null) {
|
|
183
|
+
const index = match.index;
|
|
184
|
+
if (/\d/.test(masked[index + 1] ?? "")) {
|
|
185
|
+
const rest = masked.slice(index + 1);
|
|
186
|
+
const end = rest.search(/(?<!\\)\$|\n/);
|
|
187
|
+
const span = end === -1 ? rest : rest.slice(0, end);
|
|
188
|
+
if (!/\\[a-zA-Z]/.test(span)) continue;
|
|
189
|
+
}
|
|
190
|
+
indices.push(index);
|
|
191
|
+
}
|
|
192
|
+
return indices;
|
|
193
|
+
}
|
|
194
|
+
function bestRenderableMathBody(inner, display, block) {
|
|
186
195
|
const candidates = unclosedEnvironments(inner).length > 0 ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))] : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];
|
|
196
|
+
if (!block) {
|
|
197
|
+
candidates.unshift(
|
|
198
|
+
closeOpenMathConstructs(
|
|
199
|
+
trimIncompleteMathTail(dropIncompleteBraceGroup(inner))
|
|
200
|
+
)
|
|
201
|
+
);
|
|
202
|
+
}
|
|
187
203
|
for (const candidate of candidates) {
|
|
188
204
|
if (!hasRenderableMathContent(candidate)) continue;
|
|
189
205
|
if (isRenderableMath(candidate, display)) return candidate;
|
|
190
206
|
}
|
|
191
207
|
return null;
|
|
192
208
|
}
|
|
209
|
+
function dropIncompleteBraceGroup(text) {
|
|
210
|
+
const stack = [];
|
|
211
|
+
for (let i = 0; i < text.length; i++) {
|
|
212
|
+
const char = text[i];
|
|
213
|
+
if (char === "\\") {
|
|
214
|
+
i++;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (char === "{") stack.push(i);
|
|
218
|
+
else if (char === "}" && stack.length > 0) stack.pop();
|
|
219
|
+
}
|
|
220
|
+
if (stack.length === 0) return text;
|
|
221
|
+
return text.slice(0, stack[0]);
|
|
222
|
+
}
|
|
193
223
|
function hasRenderableMathContent(body) {
|
|
194
224
|
const stripped = body.replace(/\\(?:begin|end)\s*\{[^}]*\}/g, "").replace(/[\s{}]/g, "");
|
|
195
225
|
return stripped.length > 0;
|
|
@@ -299,9 +329,13 @@ function closeDoubleUnderscore(text) {
|
|
|
299
329
|
if (!opensAtWordBoundary(text, lastIndex)) return text;
|
|
300
330
|
return insertBeforeTrailingWhitespace(text, "__");
|
|
301
331
|
}
|
|
332
|
+
function maskBlockAsterisks(text) {
|
|
333
|
+
return text.replace(/^[ \t]*\*(?:[ \t]*\*){2,}[ \t]*$/gm, (m) => " ".repeat(m.length)).replace(/^[ \t]*\*(?=[ \t])/gm, (m) => " ".repeat(m.length));
|
|
334
|
+
}
|
|
302
335
|
function closeRunMarker(text, marker) {
|
|
303
336
|
const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
304
|
-
const
|
|
337
|
+
const countSource = marker.includes("*") ? maskBlockAsterisks(text) : text;
|
|
338
|
+
const count = (countSource.match(new RegExp(escaped, "g")) ?? []).length;
|
|
305
339
|
if (count % 2 === 0) return text;
|
|
306
340
|
const lastIndex = text.lastIndexOf(marker);
|
|
307
341
|
const after = text.slice(lastIndex + marker.length);
|
|
@@ -309,7 +343,7 @@ function closeRunMarker(text, marker) {
|
|
|
309
343
|
return insertBeforeTrailingWhitespace(text, marker);
|
|
310
344
|
}
|
|
311
345
|
function closeSingleAsterisk(text) {
|
|
312
|
-
const masked = text.replace(/\*\*/g, "");
|
|
346
|
+
const masked = maskBlockAsterisks(text).replace(/\*\*/g, "");
|
|
313
347
|
const count = (masked.match(/\*/g) ?? []).length;
|
|
314
348
|
if (count % 2 === 0) return text;
|
|
315
349
|
const lastIndex = text.lastIndexOf("*");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/completePartialTokens.ts","../src/CopyButton.tsx","../src/preprocess.ts","../src/LLMMessage.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import katex from \"katex\";\n\n/** Options controlling how {@link completePartialTokens} repairs the stream. */\nexport interface CompletePartialTokensOptions {\n /**\n * Progressively render unterminated *block* math (`\\[…`, `$$…`) by closing\n * the open constructs and keeping the largest prefix KaTeX accepts. This is\n * convenient (a long block reveals row by row) but costs a synchronous KaTeX\n * parse on every chunk while the block streams. Set to `false` to instead\n * hide the block entirely until its closing delimiter arrives, skipping the\n * KaTeX work. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n}\n\n/**\n * Repairs partially-streamed markdown / LaTeX so that incomplete syntax does\n * not leak raw delimiter characters into the rendered output.\n *\n * While an LLM streams a response, the text often ends mid-token, e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2` or `\\(a + b`. Rendered\n * as-is, those dangling delimiters show up as literal junk (`**`, `` ` ``, `[`,\n * `$`, `\\(`). This function detects the unterminated constructs at the tail of\n * the string and:\n * - closes safe inline formatting so it renders as intended (`**bold` →\n * `**bold**`, `` `code `` → `` `code` ``);\n * - hides fragments that cannot be completed yet, namely incomplete links and\n * incomplete inline math (`$…`, `\\(…`);\n * - progressively renders incomplete *block* math (`\\[…`, `$$…`): instead of\n * hiding the whole block until it finishes streaming, it closes the open\n * environments/braces and renders the largest prefix KaTeX accepts, so a\n * long aligned block reveals row by row instead of popping in at the end.\n *\n * It is a no-op for already-complete text, so it is safe to run on every chunk.\n *\n * @param text The (possibly mid-stream) markdown string.\n * @returns The string with trailing incomplete tokens repaired.\n */\nexport function completePartialTokens(\n text: string,\n options?: CompletePartialTokensOptions,\n): string {\n if (!text) return text;\n\n const showUnfinishedLatexBlocks = options?.showUnfinishedLatexBlocks ?? true;\n\n // An unterminated fenced code block is fine on its own: remark renders it to\n // the end of the document and the partial content reads correctly as code,\n // so we must not touch any of the (markdown-looking) characters inside it.\n if (hasUnclosedCodeFence(text)) {\n return text;\n }\n\n const protectedSpans: string[] = [];\n const protect = (value: string): string =>\n `\\u0000llmph${protectedSpans.push(value) - 1}\\u0000`;\n\n // Protect complete fenced code blocks and complete inline code spans so their\n // contents are never mistaken for markdown/LaTeX markers. Double-backtick\n // spans are protected before single-backtick ones so a span that itself\n // contains a backtick (`` a`b ``) is not mangled by the single-backtick pass.\n let working = text.replace(/```[\\s\\S]*?```/g, (match) => protect(match));\n working = working.replace(/``[\\s\\S]*?``/g, (match) => protect(match));\n working = working.replace(/`[^`\\n]+`/g, (match) => protect(match));\n\n // A leftover single backtick starts an unterminated inline code span. Protect\n // the rest of the line and close it so the in-progress code renders cleanly.\n const lastBacktick = working.lastIndexOf(\"`\");\n if (lastBacktick !== -1) {\n // Bound the in-progress span to its own line so trailing markdown on later\n // lines is not swallowed into the protected code.\n const newline = working.indexOf(\"\\n\", lastBacktick);\n const end = newline === -1 ? working.length : newline;\n const span = working.slice(lastBacktick, end);\n working =\n working.slice(0, lastBacktick) +\n protect(`${span}\\``) +\n working.slice(end);\n }\n\n working = repairIncompleteMath(working, showUnfinishedLatexBlocks);\n working = hideIncompleteLink(working);\n working = completePartialTable(working);\n working = hideDanglingListMarker(working);\n working = closeUnbalancedEmphasis(working);\n\n return working.replace(\n /\\u0000llmph(\\d+)\\u0000/g,\n (_match, index: string) => protectedSpans[Number(index)] ?? \"\",\n );\n}\n\n/**\n * Completes a partially-streamed GFM table delimiter row.\n *\n * A table needs a full delimiter row (`| --- | --- |`) to be recognised, so\n * while it streams the buffer ends with a header row followed by a fragment like\n * `| ---`. Without a valid delimiter remark-gfm collapses both lines into a\n * paragraph (\"| Feature | Works | | ---\"). Once a delimiter fragment appears we\n * already know the column count from the header, so we expand the fragment to a\n * complete delimiter, preserving any alignment colons that have streamed in.\n */\nfunction completePartialTable(text: string): string {\n const lines = text.split(\"\\n\");\n if (lines.length < 2) return text;\n\n const last = lines[lines.length - 1];\n // The candidate delimiter must contain only delimiter characters and at least\n // one dash; anything else (letters, etc.) means it is a header or body row.\n if (!/-/.test(last) || !/^[\\s|:-]*$/.test(last)) return text;\n\n const header = lines[lines.length - 2];\n if (!header.includes(\"|\")) return text;\n\n // If the table already has a delimiter row at or above the candidate, then\n // the candidate is just a body row that happens to contain only dashes/pipes\n // (not a streaming delimiter), so the table is complete and must be left\n // untouched. Walk up the contiguous block of pipe rows to detect that.\n for (let i = lines.length - 2; i >= 0; i--) {\n const line = lines[i];\n if (!line.includes(\"|\")) break;\n if (/-/.test(line) && /^[\\s|:-]*$/.test(line)) return text;\n }\n\n const columns = countTableColumns(header);\n lines[lines.length - 1] = buildDelimiterRow(last, columns);\n return lines.join(\"\\n\");\n}\n\n/** Counts the cells in a GFM table row, ignoring the outer pipes. */\nfunction countTableColumns(row: string): number {\n let inner = row.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n return inner.split(\"|\").length;\n}\n\n/**\n * Builds a delimiter row with `columns` cells, reusing any alignment colons\n * already present in the streamed fragment.\n */\nfunction buildDelimiterRow(fragment: string, columns: number): string {\n let inner = fragment.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n const existing = inner.split(\"|\").map((cell) => cell.trim());\n\n const cells = Array.from({ length: columns }, (_unused, index) => {\n const spec = existing[index] ?? \"\";\n const left = spec.startsWith(\":\");\n const right = spec.endsWith(\":\");\n if (left && right) return \":---:\";\n if (right) return \"---:\";\n if (left) return \":---\";\n return \"---\";\n });\n\n return `| ${cells.join(\" | \")} |`;\n}\n\n/**\n * Hides a trailing line that would be parsed as a setext heading underline.\n *\n * Mid-stream a bullet list arrives a character at a time, so the buffer briefly\n * ends with `paragraph\\n-` before the item text follows. In CommonMark a lone\n * run of dashes directly beneath a non-blank line is a setext H2 underline, so\n * a line like \"Unordered list:\" would flash as a heading until \"- Item\" streams\n * in. We drop the dangling marker until it gains content. A blank line above the\n * dashes makes them a thematic break instead, which is left untouched.\n */\nfunction hideDanglingListMarker(text: string): string {\n const match = text.match(/\\n[ \\t]{0,3}-+[ \\t]*$/);\n if (match?.index == null) return text;\n\n const before = text.slice(0, match.index);\n const prevLine = before.slice(before.lastIndexOf(\"\\n\") + 1);\n if (prevLine.trim() === \"\") return text;\n\n return before;\n}\n\n/**\n * True when a code fence is left open. Backtick (```) and tilde (~~~) fences are\n * counted separately so that a complete block of one kind that happens to\n * contain a line of the other kind is not mistaken for an unbalanced fence.\n */\nfunction hasUnclosedCodeFence(text: string): boolean {\n const backticks = (text.match(/^[ \\t]{0,3}```/gm) ?? []).length;\n const tildes = (text.match(/^[ \\t]{0,3}~~~/gm) ?? []).length;\n return backticks % 2 === 1 || tildes % 2 === 1;\n}\n\n/**\n * Drops a trailing, still-incomplete link or image, e.g. `[label`, `: string {\n // Find the last \"[\" that is not an escaped LaTeX delimiter (\"\\[\").\n let open = -1;\n for (let i = text.length - 1; i >= 0; i--) {\n if (text[i] === \"[\" && text[i - 1] !== \"\\\\\") {\n open = i;\n break;\n }\n }\n if (open === -1) return text;\n\n const start = open > 0 && text[open - 1] === \"!\" ? open - 1 : open;\n const rest = text.slice(open);\n\n // Label is still open: \"[lab\" / \"![al\".\n if (!rest.includes(\"]\")) {\n return text.slice(0, start);\n }\n // Label closed, destination opened but not yet closed: \"[lab](http\".\n if (/^\\[[^\\]]*\\]\\([^)]*$/.test(rest)) {\n return text.slice(0, start);\n }\n return text;\n}\n\n/** A math delimiter that has been opened but not yet closed in the stream. */\ninterface OpenMath {\n /** Index of the opening delimiter in the source string. */\n index: number;\n /** The opening delimiter itself, e.g. `\"\\\\[\"` or `\"$$\"`. */\n open: string;\n /** The closing delimiter to append once repaired, empty for inline math. */\n close: string;\n /** Whether the math is block (display) math we try to render progressively. */\n block: boolean;\n /** Whether to render in KaTeX display mode when validating a candidate. */\n display: boolean;\n}\n\n/**\n * Repairs an unterminated LaTeX region at the tail of the stream.\n *\n * Inline math (`$…`, `\\(…`) is short, so it is simply hidden until it finishes\n * streaming. Block math (`\\[…`, `$$…`) is instead rendered progressively: we\n * close any open environments/braces and keep the largest leading slice that\n * KaTeX can parse, so a multi-line block reveals itself as it streams instead\n * of staying blank until the closing delimiter finally arrives.\n */\nfunction repairIncompleteMath(\n text: string,\n showUnfinishedLatexBlocks: boolean,\n): string {\n const countOf = (pattern: RegExp): number =>\n (text.match(pattern) ?? []).length;\n\n const opens: OpenMath[] = [];\n\n // Display math: \\[ ... \\]\n if (countOf(/\\\\\\[/g) > countOf(/\\\\\\]/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\[\"),\n open: \"\\\\[\",\n close: \"\\\\]\",\n block: true,\n display: true,\n });\n }\n\n // Inline math: \\( ... \\)\n if (countOf(/\\\\\\(/g) > countOf(/\\\\\\)/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\(\"),\n open: \"\\\\(\",\n close: \"\",\n block: false,\n display: false,\n });\n }\n\n if (countOf(/\\$\\$/g) % 2 === 1) {\n // Display math: $$ ... $$\n opens.push({\n index: text.lastIndexOf(\"$$\"),\n open: \"$$\",\n close: \"$$\",\n block: true,\n display: true,\n });\n } else {\n // Inline math: $ ... $. Mask complete \"$$\" pairs (keeping indices stable),\n // then ignore escaped \"\\$\" and currency like \"$5\" to avoid false positives.\n let masked = text.replace(/\\$\\$/g, \" \");\n // Also mask complete single-line \"$…$\" spans that contain a LaTeX command\n // (so they are real math, not \"$5\" currency). Their opening \"$\" may be\n // followed by a digit (e.g. \"$15 \\text{ г}$\"), which the currency guard\n // below would otherwise drop from the count while still counting the\n // closing \"$\", flipping the parity and hiding trailing content by mistake.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$/g,\n (m) => \" \".repeat(m.length),\n );\n // Same parity hazard for command-free numeric spans (e.g. \"$0$\", \"$15$\"):\n // the opening \"$\" is dropped by the currency guard below while the closing\n // \"$\" is still counted. Mask these balanced numeric spans too so neither\n // delimiter is counted. Plain currency (\"$5 and $10\") has prose between the\n // dollars, so it matches neither this nor the command mask and is left for\n // the currency guard to handle.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$/g,\n (m) => \" \".repeat(m.length),\n );\n let lastDollar = -1;\n for (const match of masked.matchAll(/(?<!\\\\)\\$(?!\\d)/g)) {\n lastDollar = match.index;\n }\n const singles = masked.match(/(?<!\\\\)\\$(?!\\d)/g) ?? [];\n if (singles.length % 2 === 1 && lastDollar !== -1) {\n opens.push({\n index: lastDollar,\n open: \"$\",\n close: \"\",\n block: false,\n display: false,\n });\n }\n }\n\n const valid = opens.filter((entry) => entry.index >= 0);\n if (valid.length === 0) return text;\n\n // The earliest opener marks where the incomplete math region begins; anything\n // after it is part of the unterminated construct.\n const open = valid.reduce((a, b) => (b.index < a.index ? b : a));\n const before = text.slice(0, open.index);\n\n if (!open.block) {\n // Inline math is hidden until it finishes streaming.\n return before;\n }\n\n // When progressive block rendering is disabled, hide the unterminated block\n // until its closing delimiter arrives, skipping the KaTeX validation cost.\n if (!showUnfinishedLatexBlocks) {\n return before;\n }\n\n const inner = text.slice(open.index + open.open.length);\n const body = bestRenderableMathBody(inner, open.display);\n if (body == null) return before;\n\n // Reproduce the original fenced layout so the markdown math parser can detect\n // the closing delimiter. When the block opens on its own line (`\\[\\n…`), the\n // closing delimiter must also sit on its own line; otherwise micromark treats\n // the run as inline math, never finds the closing fence, and KaTeX renders a\n // parse error that swallows the trailing delimiter.\n const blockLayout = /^[ \\t]*\\r?\\n/.test(inner);\n if (!blockLayout) {\n return before + open.open + body + open.close;\n }\n const opener =\n before === \"\" || before.endsWith(\"\\n\") ? open.open : `\\n${open.open}`;\n return `${before}${opener}${body.replace(/\\s+$/, \"\")}\\n${open.close}`;\n}\n\n/**\n * Returns the largest leading slice of incomplete block-math content that KaTeX\n * can render, with its open environments and braces closed, or `null` when no\n * usable prefix exists yet (in which case the caller hides the fragment).\n *\n * When an environment is still open (e.g. `\\begin{aligned}` mid-stream) we\n * prefer revealing only the complete rows so each equation appears fully formed,\n * falling back to a token-level repair so single-line blocks still stream in.\n */\nfunction bestRenderableMathBody(\n inner: string,\n display: boolean,\n): string | null {\n const candidates = unclosedEnvironments(inner).length > 0\n ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))]\n : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];\n\n for (const candidate of candidates) {\n if (!hasRenderableMathContent(candidate)) continue;\n if (isRenderableMath(candidate, display)) return candidate;\n }\n return null;\n}\n\n/** True when a math body contains something other than empty environment scaffolding. */\nfunction hasRenderableMathContent(body: string): boolean {\n const stripped = body\n .replace(/\\\\(?:begin|end)\\s*\\{[^}]*\\}/g, \"\")\n .replace(/[\\s{}]/g, \"\");\n return stripped.length > 0;\n}\n\n/**\n * True when KaTeX can render the math body without raising a parse error.\n *\n * Uses the public, stable `renderToString` entry point (with `throwOnError`)\n * rather than any internal parse-only API, so it keeps working across KaTeX\n * upgrades. We only care whether it throws; the produced string is discarded.\n */\nfunction isRenderableMath(body: string, display: boolean): boolean {\n try {\n katex.renderToString(body, {\n displayMode: display,\n throwOnError: true,\n strict: false,\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Keeps only the complete rows of a multi-line environment by cutting back to\n * the last row separator (`\\\\`), dropping the partially-streamed current row.\n * Returns an empty string when no full row has streamed yet.\n */\nfunction truncateToLastRow(inner: string): string {\n const lastRow = inner.lastIndexOf(\"\\\\\\\\\");\n if (lastRow === -1) return \"\";\n return inner.slice(0, lastRow + 2);\n}\n\n/**\n * Drops trailing tokens that cannot render on their own yet: surrounding\n * whitespace, a dangling backslash, an in-progress control word (`\\frac` may\n * still be `\\fra`), and a subscript/superscript with no argument. A complete\n * `\\\\` row separator is preserved.\n */\nfunction trimIncompleteMathTail(inner: string): string {\n let result = inner;\n let previous: string;\n do {\n previous = result;\n result = result.replace(/\\s+$/, \"\");\n // A trailing odd run of backslashes ends in a lone \"\\\" (an incomplete \"\\\\\"\n // or the start of a command); drop it. An even run is complete \"\\\\\".\n const backslashes = result.match(/\\\\+$/);\n if (backslashes != null && backslashes[0].length % 2 === 1) {\n result = result.slice(0, -1);\n }\n // A trailing control word is ambiguous mid-stream; drop it so it cannot be\n // an unknown (and therefore error-rendered) command.\n result = result.replace(/\\\\[a-zA-Z]+\\*?$/, \"\");\n // A subscript/superscript needs an argument that has not arrived yet.\n result = result.replace(/[_^]$/, \"\");\n } while (result !== previous);\n return result;\n}\n\n/**\n * Closes the constructs left open in a math fragment so KaTeX can parse it:\n * unmatched `\\left`, unbalanced `{` groups, and unclosed environments. Order is\n * a best effort; the caller validates the result with KaTeX regardless.\n */\nfunction closeOpenMathConstructs(inner: string): string {\n let result = inner;\n\n const lefts = (result.match(/\\\\left(?![a-zA-Z])/g) ?? []).length;\n const rights = (result.match(/\\\\right(?![a-zA-Z])/g) ?? []).length;\n result += \"\\\\right.\".repeat(Math.max(0, lefts - rights));\n\n result += \"}\".repeat(openBraceDepth(result));\n\n const environments = unclosedEnvironments(result);\n for (let i = environments.length - 1; i >= 0; i--) {\n result += `\\\\end{${environments[i]}}`;\n }\n return result;\n}\n\n/** Counts unclosed `{` groups, ignoring escaped braces (`\\{`, `\\}`). */\nfunction openBraceDepth(text: string): number {\n let depth = 0;\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === \"\\\\\") {\n i++;\n continue;\n }\n if (char === \"{\") depth++;\n else if (char === \"}\" && depth > 0) depth--;\n }\n return depth;\n}\n\n/**\n * Returns the names of environments opened with `\\begin{…}` but not yet closed\n * with a matching `\\end{…}`, outermost first.\n */\nfunction unclosedEnvironments(text: string): string[] {\n const stack: string[] = [];\n const pattern = /\\\\(begin|end)\\s*\\{([^}]*)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) != null) {\n const name = match[2];\n if (match[1] === \"begin\") {\n stack.push(name);\n } else {\n const index = stack.lastIndexOf(name);\n if (index !== -1) stack.splice(index, 1);\n else stack.pop();\n }\n }\n return stack;\n}\n\n/**\n * Closes unterminated emphasis runs: ~~strike~~, **bold**, *italic*, __bold__\n * and _italic_.\n */\nfunction closeUnbalancedEmphasis(text: string): string {\n let result = text;\n result = closeRunMarker(result, \"~~\");\n // Close a single \"*\" first so a \"***\" opener becomes \"*\" + \"**\" and both\n // halves get closed, yielding a balanced \"***…***\".\n result = closeSingleAsterisk(result);\n result = closeRunMarker(result, \"**\");\n result = closeSingleUnderscore(result);\n result = closeDoubleUnderscore(result);\n return result;\n}\n\n/**\n * True when the marker at `index` begins a delimiter run that could open\n * emphasis: it sits at the start of the string or directly after a non-word\n * character (whitespace or punctuation). Underscores require this so intra-word\n * usage (`snake_case`, `__init__`) is never treated as a dangling emphasis\n * opener.\n */\nfunction opensAtWordBoundary(text: string, index: number): boolean {\n if (index <= 0) return true;\n // Whitespace or punctuation before the marker counts as a boundary; an\n // alphanumeric character (or another underscore) does not, so intra-word\n // usage (`snake_case`, `__init__`) is never treated as a dangling opener\n // while a leading-punctuation case like `(_italic` still closes.\n return !/[\\p{L}\\p{N}_]/u.test(text[index - 1]);\n}\n\n/**\n * Closes a single `_` italic marker. `__` pairs are masked out first, and the\n * marker is only closed when it both opens at a word boundary and sits directly\n * before a non-space character, so `snake_case` is left alone.\n */\nfunction closeSingleUnderscore(text: string): string {\n const masked = text.replace(/__/g, \"\");\n const count = (masked.match(/_/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"_\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s_]/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"_\");\n}\n\n/**\n * Closes a `__` bold marker when it is unbalanced, opens at a word boundary,\n * and is directly followed by a non-space character (so `a__b` and `__init__`\n * are left untouched).\n */\nfunction closeDoubleUnderscore(text: string): string {\n const count = (text.match(/__/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"__\");\n const after = text.slice(lastIndex + 2);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"__\");\n}\n\n/**\n * Closes a two-character emphasis marker (`**` or `~~`) when it is unbalanced\n * and the final marker looks like an opener (immediately followed by a\n * non-space character), which avoids touching list markers or operators.\n */\nfunction closeRunMarker(text: string, marker: string): string {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const count = (text.match(new RegExp(escaped, \"g\")) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(marker);\n const after = text.slice(lastIndex + marker.length);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, marker);\n}\n\n/**\n * Closes a single `*` italic marker. `**` pairs are masked out first, and the\n * marker is only closed when it sits directly before a non-space character so\n * bullet markers (`* item`) and multiplication (`2 * 3`) are left alone.\n */\nfunction closeSingleAsterisk(text: string): string {\n const masked = text.replace(/\\*\\*/g, \"\");\n const count = (masked.match(/\\*/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"*\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s*]/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"*\");\n}\n\n/**\n * Appends a closing emphasis marker, but places it before any trailing\n * whitespace. A closer such as `**` is only valid when it directly follows a\n * non-space character, so `**bold ` must become `**bold** ` rather than the\n * un-renderable `**bold **`.\n */\nfunction insertBeforeTrailingWhitespace(text: string, marker: string): string {\n const trailing = text.match(/\\s+$/)?.[0] ?? \"\";\n const core = text.slice(0, text.length - trailing.length);\n return core + marker + trailing;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nimport type { CopyButtonProps } from \"./types\";\n\nfunction CopyIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport function CopyButton({ text, className }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const copy = () => {\n const clipboard = navigator.clipboard;\n if (!clipboard) return;\n // Only show the \"copied\" confirmation once the write actually succeeds.\n void clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n // Clipboard write failed; keep the idle state.\n });\n };\n\n return (\n <button\n type=\"button\"\n onClick={copy}\n className={className}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n data-copied={copied ? \"\" : undefined}\n >\n {copied ? <CheckIcon /> : <CopyIcon />}\n </button>\n );\n}\n","/**\n * Matches a fenced code block or an inline code span. Shared by\n * {@link preprocessLaTeX} and {@link escapeBrackets} so both functions treat\n * code identically; composed into the larger patterns below via `.source`.\n */\nconst CODE_SPAN = /```[\\s\\S]*?```|`[^`\\n]+`/;\n\n/**\n * Preprocesses LaTeX content by replacing delimiters and escaping certain characters.\n *\n * @param content The input string containing LaTeX expressions.\n * @returns The processed string with replaced delimiters and escaped characters.\n */\nexport function preprocessLaTeX(content: string): string {\n // Step 1: Protect code blocks\n const codeBlocks: string[] = [];\n content = content.replace(\n new RegExp(`(${CODE_SPAN.source})`, \"g\"),\n (_match, code) => {\n codeBlocks.push(code);\n return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;\n },\n );\n\n // Step 2: Protect existing LaTeX expressions. This is what makes the currency\n // escaping in Step 3 safe: by pulling complete `$$…$$` / `\\[…\\]` / `\\(…\\)`\n // regions out of the string first, the `\\$(?=\\d)` pass below cannot corrupt a\n // `$` that legitimately belongs to a math expression (e.g. `$$x = $5$$`).\n //\n // Single-dollar inline math whose content begins with a digit (e.g.\n // `$15 \\text{ г}$`) is protected too: without this its opening `$` would be\n // escaped as currency in Step 3, unbalancing the delimiters so remark-math\n // swallows the rest of the paragraph as one math region. Two shapes qualify:\n // 1. spans containing a LaTeX command (`\\…`), e.g. `$15 \\text{ г}$`;\n // 2. balanced spans whose content is purely numeric/math (digits, spaces\n // and basic operators, no prose letters), e.g. `$0$` or `$1288 / 3$`.\n // Both leave plain currency prose like `$5 and $10` for Step 3, because that\n // text contains letters between the dollars and so matches neither shape.\n const latexExpressions: string[] = [];\n content = content.replace(\n /(\\$\\$[\\s\\S]*?\\$\\$|\\\\\\[[\\s\\S]*?\\\\\\]|\\\\\\(.*?\\\\\\)|\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$|\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$)/g,\n (match) => {\n latexExpressions.push(match);\n return `<<LATEX_${latexExpressions.length - 1}>>`;\n },\n );\n\n // Step 3: Escape dollar signs that are likely currency indicators\n content = content.replace(/\\$(?=\\d)/g, \"\\\\$\");\n\n // Step 4: Restore LaTeX expressions\n content = content.replace(\n /<<LATEX_(\\d+)>>/g,\n (_, index) => latexExpressions[parseInt(index, 10)],\n );\n\n // Step 5: Restore code blocks\n content = content.replace(\n /<<CODE_BLOCK_(\\d+)>>/g,\n (_, index) => codeBlocks[parseInt(index, 10)],\n );\n\n // Step 6: Apply additional escaping functions\n content = escapeBrackets(content);\n content = escapeMhchem(content);\n\n return content;\n}\n\nexport function escapeBrackets(text: string): string {\n const pattern = new RegExp(\n `(${CODE_SPAN.source})|` +\n /\\\\\\[((?:[\\s\\S]*?[^\\\\])?)\\\\]|\\\\\\((.*?)\\\\\\)/.source,\n \"g\",\n );\n return text.replace(\n pattern,\n (\n match: string,\n codeBlock: string | undefined,\n squareBracket: string | undefined,\n roundBracket: string | undefined,\n ): string => {\n if (codeBlock != null) {\n return codeBlock;\n } else if (squareBracket != null) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket != null) {\n return `$${roundBracket}$`;\n }\n return match;\n },\n );\n}\n\nexport function escapeMhchem(text: string): string {\n return text.replaceAll(\"$\\\\ce{\", \"$\\\\\\\\ce{\").replaceAll(\"$\\\\pu{\", \"$\\\\\\\\pu{\");\n}\n","import { clsx } from \"clsx\";\nimport { useMemo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport ReactMarkdown, { type Components } from \"react-markdown\";\nimport rehypeKatex from \"rehype-katex\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\n\nimport { completePartialTokens } from \"./completePartialTokens\";\nimport { CopyButton } from \"./CopyButton\";\nimport { preprocessLaTeX } from \"./preprocess\";\nimport type {\n CodeHighlighter,\n LLMMessageClassNames,\n LLMMessageComponents,\n} from \"./types\";\n\nexport interface LLMMessageProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"content\"> {\n /** The LLM message content as a markdown string. */\n children?: string;\n /** Alias for `children`. */\n content?: string;\n /** Class applied to the root element (merged with the built-in class). */\n className?: string;\n /** Per-element class overrides (merged with the built-in classes). */\n classNames?: LLMMessageClassNames;\n /** Per-element component overrides for full markup control. */\n components?: LLMMessageComponents;\n /**\n * Repair partially-streamed markdown/LaTeX so unterminated tokens (e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2`) do not render as raw\n * delimiter junk while the response is still streaming. Defaults to `true`.\n */\n completePartialTokens?: boolean;\n /**\n * Progressively render unterminated *block* math (`\\[…`, `$$…`) while it\n * streams, instead of hiding it until the closing delimiter arrives. This is\n * nicer to watch (a long block reveals row by row) but costs a synchronous\n * KaTeX parse on every chunk that contains an open block. Set to `false` to\n * hide unfinished blocks and skip that work. Only relevant while\n * `completePartialTokens` is enabled. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n /**\n * Optional syntax highlighter for fenced code blocks. When omitted, code\n * blocks render as plain text (so no highlighter bundle is pulled in). Pass\n * `ShikiHighlighter` / `ShikiWebHighlighter`, or build your own with\n * `createShikiHighlighter`.\n */\n highlighter?: CodeHighlighter;\n}\n\nconst remarkPlugins = [remarkGfm, remarkMath];\nconst rehypePlugins = [rehypeKatex];\n\nfunction cx(...inputs: Array<string | undefined>): string | undefined {\n const result = clsx(inputs);\n return result === \"\" ? undefined : result;\n}\n\nfunction buildComponents(\n classNames: LLMMessageClassNames | undefined,\n overrides: LLMMessageComponents | undefined,\n highlighter: CodeHighlighter | undefined,\n): Components {\n const cn = classNames ?? {};\n const o = overrides ?? {};\n const Highlighter = highlighter;\n\n return {\n code({ node: _node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || \"\");\n const codeText = String(children).replace(/\\n$/, \"\");\n // A fenced block always spans its own lines (so its text contains a\n // newline) even when no language info string is present; inline code\n // never does. Relying on the `language-` class alone would misrender a\n // bare ``` fence as inline code.\n const isBlock = match != null || String(children).includes(\"\\n\");\n\n if (isBlock) {\n const language = match?.[1] ?? \"\";\n if (o.codeBlock) {\n const CodeBlock = o.codeBlock;\n return (\n <CodeBlock\n code={codeText}\n language={language}\n className={cn.codeBlock}\n />\n );\n }\n return (\n <div className={cx(\"llm-code-block\", cn.codeBlock)}>\n <div className={cx(\"llm-code-header\", cn.codeHeader)}>\n <span className={cx(\"llm-code-language\", cn.codeLanguage)}>\n {language}\n </span>\n {o.copyButton ? (\n <o.copyButton text={codeText} className={cn.copyButton} />\n ) : (\n <CopyButton\n text={codeText}\n className={cx(\"llm-copy-button\", cn.copyButton)}\n />\n )}\n </div>\n <div className=\"llm-code-body\">\n {Highlighter ? (\n <Highlighter code={codeText} language={language} />\n ) : (\n <code className=\"llm-code-plain\">{codeText}</code>\n )}\n </div>\n </div>\n );\n }\n\n if (o.code) {\n const InlineCode = o.code;\n return (\n <InlineCode className={cx(\"llm-code\", cn.code, className)}>\n {children}\n </InlineCode>\n );\n }\n\n return (\n <code className={cx(\"llm-code\", cn.code, className)} {...props}>\n {children}\n </code>\n );\n },\n pre({ children }) {\n if (o.pre) {\n return <o.pre>{children}</o.pre>;\n }\n // Let the code component handle fenced blocks.\n return <>{children}</>;\n },\n table({ children }) {\n if (o.table) {\n return <o.table className={cn.table}>{children}</o.table>;\n }\n return (\n <div className={cx(\"llm-table-wrapper\", cn.tableWrapper)}>\n <table className={cx(\"llm-table\", cn.table)}>{children}</table>\n </div>\n );\n },\n th({ children }) {\n if (o.th) {\n return <o.th className={cn.th}>{children}</o.th>;\n }\n return <th className={cx(\"llm-th\", cn.th)}>{children}</th>;\n },\n td({ children }) {\n if (o.td) {\n return <o.td className={cn.td}>{children}</o.td>;\n }\n return <td className={cx(\"llm-td\", cn.td)}>{children}</td>;\n },\n blockquote({ children }) {\n if (o.blockquote) {\n return <o.blockquote className={cn.blockquote}>{children}</o.blockquote>;\n }\n return (\n <blockquote className={cx(\"llm-blockquote\", cn.blockquote)}>\n {children}\n </blockquote>\n );\n },\n ul({ children }) {\n if (o.ul) {\n return <o.ul className={cn.ul}>{children}</o.ul>;\n }\n return <ul className={cx(\"llm-ul\", cn.ul)}>{children}</ul>;\n },\n ol({ children }) {\n if (o.ol) {\n return <o.ol className={cn.ol}>{children}</o.ol>;\n }\n return <ol className={cx(\"llm-ol\", cn.ol)}>{children}</ol>;\n },\n li({ children }) {\n if (o.li) {\n return <o.li className={cn.li}>{children}</o.li>;\n }\n return <li className={cx(\"llm-li\", cn.li)}>{children}</li>;\n },\n p({ children }) {\n if (o.p) {\n return <o.p className={cn.p}>{children}</o.p>;\n }\n return <p className={cx(\"llm-p\", cn.p)}>{children}</p>;\n },\n h1({ children }) {\n if (o.h1) {\n return <o.h1 className={cn.h1}>{children}</o.h1>;\n }\n return <h1 className={cx(\"llm-h1\", cn.h1)}>{children}</h1>;\n },\n h2({ children }) {\n if (o.h2) {\n return <o.h2 className={cn.h2}>{children}</o.h2>;\n }\n return <h2 className={cx(\"llm-h2\", cn.h2)}>{children}</h2>;\n },\n h3({ children }) {\n if (o.h3) {\n return <o.h3 className={cn.h3}>{children}</o.h3>;\n }\n return <h3 className={cx(\"llm-h3\", cn.h3)}>{children}</h3>;\n },\n h4({ children }) {\n if (o.h4) {\n return <o.h4 className={cn.h4}>{children}</o.h4>;\n }\n return <h4 className={cx(\"llm-h4\", cn.h4)}>{children}</h4>;\n },\n h5({ children }) {\n if (o.h5) {\n return <o.h5 className={cn.h5}>{children}</o.h5>;\n }\n return <h5 className={cx(\"llm-h5\", cn.h5)}>{children}</h5>;\n },\n h6({ children }) {\n if (o.h6) {\n return <o.h6 className={cn.h6}>{children}</o.h6>;\n }\n return <h6 className={cx(\"llm-h6\", cn.h6)}>{children}</h6>;\n },\n input({ node: _node, type, checked, disabled, ...props }) {\n if (type === \"checkbox\") {\n if (o.checkbox) {\n return (\n <o.checkbox checked={Boolean(checked)} className={cn.checkbox} />\n );\n }\n return (\n <input\n type=\"checkbox\"\n checked={Boolean(checked)}\n disabled\n aria-label={checked ? \"Completed task\" : \"Incomplete task\"}\n className={cx(\"llm-checkbox\", cn.checkbox)}\n readOnly\n />\n );\n }\n return (\n <input\n type={type}\n checked={checked}\n disabled={disabled}\n readOnly\n {...props}\n />\n );\n },\n a({ href, children }) {\n if (o.a) {\n return (\n <o.a href={href} className={cn.a}>\n {children}\n </o.a>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cx(\"llm-a\", cn.a)}\n >\n {children}\n </a>\n );\n },\n img({ node: _node, src, alt, title, className: _className, ...props }) {\n if (o.img) {\n const Image = o.img;\n return (\n <Image\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cn.img}\n />\n );\n }\n return (\n <img\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cx(\"llm-img\", cn.img)}\n {...props}\n />\n );\n },\n hr() {\n if (o.hr) {\n return <o.hr className={cn.hr} />;\n }\n return <hr className={cx(\"llm-hr\", cn.hr)} />;\n },\n strong({ children }) {\n if (o.strong) {\n return <o.strong className={cn.strong}>{children}</o.strong>;\n }\n return <strong className={cx(\"llm-strong\", cn.strong)}>{children}</strong>;\n },\n em({ children }) {\n if (o.em) {\n return <o.em className={cn.em}>{children}</o.em>;\n }\n return <em className={cx(\"llm-em\", cn.em)}>{children}</em>;\n },\n del({ children }) {\n if (o.del) {\n return <o.del className={cn.del}>{children}</o.del>;\n }\n return <del className={cx(\"llm-del\", cn.del)}>{children}</del>;\n },\n };\n}\n\nexport function LLMMessage({\n children,\n content,\n className,\n classNames,\n components,\n completePartialTokens: repairPartialTokens = true,\n showUnfinishedLatexBlocks = true,\n highlighter,\n ...rest\n}: LLMMessageProps) {\n const source = content ?? children ?? \"\";\n\n const markdownComponents = useMemo(\n () => buildComponents(classNames, components, highlighter),\n [classNames, components, highlighter],\n );\n\n const processed = useMemo(() => {\n const repaired = repairPartialTokens\n ? completePartialTokens(source, { showUnfinishedLatexBlocks })\n : source;\n return preprocessLaTeX(repaired);\n }, [source, repairPartialTokens, showUnfinishedLatexBlocks]);\n\n return (\n <div className={cx(\"llm-message\", classNames?.root, className)} {...rest}>\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={markdownComponents}\n >\n {processed}\n </ReactMarkdown>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/completePartialTokens.ts","../src/CopyButton.tsx","../src/preprocess.ts","../src/LLMMessage.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import katex from \"katex\";\n\n/** Options controlling how {@link completePartialTokens} repairs the stream. */\nexport interface CompletePartialTokensOptions {\n /**\n * Progressively render unterminated math by closing the open constructs and\n * keeping the largest prefix KaTeX accepts. This applies to both *block* math\n * (`\\[…`, `$$…`, revealed row by row) and *inline* math (`$…`, `\\(…`, closed\n * in place). It is convenient but costs a synchronous KaTeX parse on every\n * chunk while the math streams. Set to `false` to instead hide the\n * unterminated math entirely until its closing delimiter arrives, skipping the\n * KaTeX work. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n}\n\n/**\n * Repairs partially-streamed markdown / LaTeX so that incomplete syntax does\n * not leak raw delimiter characters into the rendered output.\n *\n * While an LLM streams a response, the text often ends mid-token, e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2` or `\\(a + b`. Rendered\n * as-is, those dangling delimiters show up as literal junk (`**`, `` ` ``, `[`,\n * `$`, `\\(`). This function detects the unterminated constructs at the tail of\n * the string and:\n * - closes safe inline formatting so it renders as intended (`**bold` →\n * `**bold**`, `` `code `` → `` `code` ``);\n * - hides fragments that cannot be completed yet, namely incomplete links and\n * incomplete inline math (`$…`, `\\(…`);\n * - progressively renders incomplete *block* math (`\\[…`, `$$…`): instead of\n * hiding the whole block until it finishes streaming, it closes the open\n * environments/braces and renders the largest prefix KaTeX accepts, so a\n * long aligned block reveals row by row instead of popping in at the end.\n *\n * It is a no-op for already-complete text, so it is safe to run on every chunk.\n *\n * @param text The (possibly mid-stream) markdown string.\n * @returns The string with trailing incomplete tokens repaired.\n */\nexport function completePartialTokens(\n text: string,\n options?: CompletePartialTokensOptions,\n): string {\n if (!text) return text;\n\n const showUnfinishedLatexBlocks = options?.showUnfinishedLatexBlocks ?? true;\n\n // An unterminated fenced code block is fine on its own: remark renders it to\n // the end of the document and the partial content reads correctly as code,\n // so we must not touch any of the (markdown-looking) characters inside it.\n if (hasUnclosedCodeFence(text)) {\n return text;\n }\n\n const protectedSpans: string[] = [];\n const protect = (value: string): string =>\n `\\u0000llmph${protectedSpans.push(value) - 1}\\u0000`;\n\n // Protect complete fenced code blocks and complete inline code spans so their\n // contents are never mistaken for markdown/LaTeX markers. Double-backtick\n // spans are protected before single-backtick ones so a span that itself\n // contains a backtick (`` a`b ``) is not mangled by the single-backtick pass.\n let working = text.replace(/```[\\s\\S]*?```/g, (match) => protect(match));\n working = working.replace(/``[\\s\\S]*?``/g, (match) => protect(match));\n working = working.replace(/`[^`\\n]+`/g, (match) => protect(match));\n\n // A leftover single backtick starts an unterminated inline code span. Protect\n // the rest of the line and close it so the in-progress code renders cleanly.\n const lastBacktick = working.lastIndexOf(\"`\");\n if (lastBacktick !== -1) {\n // Bound the in-progress span to its own line so trailing markdown on later\n // lines is not swallowed into the protected code.\n const newline = working.indexOf(\"\\n\", lastBacktick);\n const end = newline === -1 ? working.length : newline;\n const span = working.slice(lastBacktick, end);\n working =\n working.slice(0, lastBacktick) +\n protect(`${span}\\``) +\n working.slice(end);\n }\n\n working = repairIncompleteMath(working, showUnfinishedLatexBlocks);\n working = hideIncompleteLink(working);\n working = completePartialTable(working);\n working = hideDanglingListMarker(working);\n working = closeUnbalancedEmphasis(working);\n\n return working.replace(\n /\\u0000llmph(\\d+)\\u0000/g,\n (_match, index: string) => protectedSpans[Number(index)] ?? \"\",\n );\n}\n\n/**\n * Completes a partially-streamed GFM table delimiter row.\n *\n * A table needs a full delimiter row (`| --- | --- |`) to be recognised, so\n * while it streams the buffer ends with a header row followed by a fragment like\n * `| ---`. Without a valid delimiter remark-gfm collapses both lines into a\n * paragraph (\"| Feature | Works | | ---\"). Once a delimiter fragment appears we\n * already know the column count from the header, so we expand the fragment to a\n * complete delimiter, preserving any alignment colons that have streamed in.\n */\nfunction completePartialTable(text: string): string {\n const lines = text.split(\"\\n\");\n if (lines.length < 2) return text;\n\n const last = lines[lines.length - 1];\n // The candidate delimiter must contain only delimiter characters and at least\n // one dash; anything else (letters, etc.) means it is a header or body row.\n if (!/-/.test(last) || !/^[\\s|:-]*$/.test(last)) return text;\n\n const header = lines[lines.length - 2];\n if (!header.includes(\"|\")) return text;\n\n // If the table already has a delimiter row at or above the candidate, then\n // the candidate is just a body row that happens to contain only dashes/pipes\n // (not a streaming delimiter), so the table is complete and must be left\n // untouched. Walk up the contiguous block of pipe rows to detect that.\n for (let i = lines.length - 2; i >= 0; i--) {\n const line = lines[i];\n if (!line.includes(\"|\")) break;\n if (/-/.test(line) && /^[\\s|:-]*$/.test(line)) return text;\n }\n\n const columns = countTableColumns(header);\n lines[lines.length - 1] = buildDelimiterRow(last, columns);\n return lines.join(\"\\n\");\n}\n\n/** Counts the cells in a GFM table row, ignoring the outer pipes. */\nfunction countTableColumns(row: string): number {\n let inner = row.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n return inner.split(\"|\").length;\n}\n\n/**\n * Builds a delimiter row with `columns` cells, reusing any alignment colons\n * already present in the streamed fragment.\n */\nfunction buildDelimiterRow(fragment: string, columns: number): string {\n let inner = fragment.trim();\n if (inner.startsWith(\"|\")) inner = inner.slice(1);\n if (inner.endsWith(\"|\")) inner = inner.slice(0, -1);\n const existing = inner.split(\"|\").map((cell) => cell.trim());\n\n const cells = Array.from({ length: columns }, (_unused, index) => {\n const spec = existing[index] ?? \"\";\n const left = spec.startsWith(\":\");\n const right = spec.endsWith(\":\");\n if (left && right) return \":---:\";\n if (right) return \"---:\";\n if (left) return \":---\";\n return \"---\";\n });\n\n return `| ${cells.join(\" | \")} |`;\n}\n\n/**\n * Hides a trailing line that would be parsed as a setext heading underline.\n *\n * Mid-stream a bullet list arrives a character at a time, so the buffer briefly\n * ends with `paragraph\\n-` before the item text follows. In CommonMark a lone\n * run of dashes directly beneath a non-blank line is a setext H2 underline, so\n * a line like \"Unordered list:\" would flash as a heading until \"- Item\" streams\n * in. We drop the dangling marker until it gains content. A blank line above the\n * dashes makes them a thematic break instead, which is left untouched.\n */\nfunction hideDanglingListMarker(text: string): string {\n const match = text.match(/\\n[ \\t]{0,3}-+[ \\t]*$/);\n if (match?.index == null) return text;\n\n const before = text.slice(0, match.index);\n const prevLine = before.slice(before.lastIndexOf(\"\\n\") + 1);\n if (prevLine.trim() === \"\") return text;\n\n return before;\n}\n\n/**\n * True when a code fence is left open. Backtick (```) and tilde (~~~) fences are\n * counted separately so that a complete block of one kind that happens to\n * contain a line of the other kind is not mistaken for an unbalanced fence.\n */\nfunction hasUnclosedCodeFence(text: string): boolean {\n const backticks = (text.match(/^[ \\t]{0,3}```/gm) ?? []).length;\n const tildes = (text.match(/^[ \\t]{0,3}~~~/gm) ?? []).length;\n return backticks % 2 === 1 || tildes % 2 === 1;\n}\n\n/**\n * Drops a trailing, still-incomplete link or image, e.g. `[label`, `: string {\n // Find the last \"[\" that is not an escaped LaTeX delimiter (\"\\[\").\n let open = -1;\n for (let i = text.length - 1; i >= 0; i--) {\n if (text[i] === \"[\" && text[i - 1] !== \"\\\\\") {\n open = i;\n break;\n }\n }\n if (open === -1) return text;\n\n const start = open > 0 && text[open - 1] === \"!\" ? open - 1 : open;\n const rest = text.slice(open);\n\n // Label is still open: \"[lab\" / \"![al\".\n if (!rest.includes(\"]\")) {\n return text.slice(0, start);\n }\n // Label closed, destination opened but not yet closed: \"[lab](http\".\n if (/^\\[[^\\]]*\\]\\([^)]*$/.test(rest)) {\n return text.slice(0, start);\n }\n return text;\n}\n\n/** A math delimiter that has been opened but not yet closed in the stream. */\ninterface OpenMath {\n /** Index of the opening delimiter in the source string. */\n index: number;\n /** The opening delimiter itself, e.g. `\"\\\\[\"` or `\"$$\"`. */\n open: string;\n /** The closing delimiter to append once repaired, empty for inline math. */\n close: string;\n /** Whether the math is block (display) math we try to render progressively. */\n block: boolean;\n /** Whether to render in KaTeX display mode when validating a candidate. */\n display: boolean;\n}\n\n/**\n * Repairs an unterminated LaTeX region at the tail of the stream.\n *\n * Both inline math (`$…`, `\\(…`) and block math (`\\[…`, `$$…`) are rendered\n * progressively: we close any open environments/braces and keep the largest\n * leading slice that KaTeX can parse, so the math reveals itself as it streams\n * instead of staying blank until the closing delimiter finally arrives. Inline\n * math additionally drops an incomplete trailing brace group (e.g. `\\text{ kc`)\n * rather than auto-closing it, so a half-streamed word does not flash in the\n * middle of running text. Set `showUnfinishedLatexBlocks` to `false` to instead\n * hide the unterminated math entirely until its closing delimiter arrives.\n */\nfunction repairIncompleteMath(\n text: string,\n showUnfinishedLatexBlocks: boolean,\n): string {\n const countOf = (pattern: RegExp): number =>\n (text.match(pattern) ?? []).length;\n\n const opens: OpenMath[] = [];\n\n // Display math: \\[ ... \\]\n if (countOf(/\\\\\\[/g) > countOf(/\\\\\\]/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\[\"),\n open: \"\\\\[\",\n close: \"\\\\]\",\n block: true,\n display: true,\n });\n }\n\n // Inline math: \\( ... \\)\n if (countOf(/\\\\\\(/g) > countOf(/\\\\\\)/g)) {\n opens.push({\n index: text.lastIndexOf(\"\\\\(\"),\n open: \"\\\\(\",\n close: \"\\\\)\",\n block: false,\n display: false,\n });\n }\n\n if (countOf(/\\$\\$/g) % 2 === 1) {\n // Display math: $$ ... $$\n opens.push({\n index: text.lastIndexOf(\"$$\"),\n open: \"$$\",\n close: \"$$\",\n block: true,\n display: true,\n });\n } else {\n // Inline math: $ ... $. Mask complete \"$$\" pairs (keeping indices stable),\n // then ignore escaped \"\\$\" and currency like \"$5\" to avoid false positives.\n let masked = text.replace(/\\$\\$/g, \" \");\n // Also mask complete single-line \"$…$\" spans that contain a LaTeX command\n // (so they are real math, not \"$5\" currency). Their opening \"$\" may be\n // followed by a digit (e.g. \"$15 \\text{ g}$\"), which the currency guard\n // below would otherwise drop from the count while still counting the\n // closing \"$\", flipping the parity and hiding trailing content by mistake.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$/g,\n (m) => \" \".repeat(m.length),\n );\n // Same parity hazard for command-free numeric spans (e.g. \"$0$\", \"$15$\"):\n // the opening \"$\" is dropped by the currency guard below while the closing\n // \"$\" is still counted. Mask these balanced numeric spans too so neither\n // delimiter is counted. Plain currency (\"$5 and $10\") has prose between the\n // dollars, so it matches neither this nor the command mask and is left for\n // the currency guard to handle.\n masked = masked.replace(\n /(?<!\\\\)\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$/g,\n (m) => \" \".repeat(m.length),\n );\n const dollars = inlineMathDollarIndices(masked);\n if (dollars.length % 2 === 1) {\n opens.push({\n index: dollars[dollars.length - 1],\n open: \"$\",\n close: \"$\",\n block: false,\n display: false,\n });\n }\n }\n\n const valid = opens.filter((entry) => entry.index >= 0);\n if (valid.length === 0) return text;\n\n // The earliest opener marks where the incomplete math region begins; anything\n // after it is part of the unterminated construct.\n const open = valid.reduce((a, b) => (b.index < a.index ? b : a));\n const before = text.slice(0, open.index);\n\n // When progressive rendering is disabled, hide the unterminated math (inline\n // or block) until its closing delimiter arrives, skipping the KaTeX cost.\n if (!showUnfinishedLatexBlocks) {\n return before;\n }\n\n const inner = text.slice(open.index + open.open.length);\n const body = bestRenderableMathBody(inner, open.display, open.block);\n if (body == null) return before;\n\n // Reproduce the original fenced layout so the markdown math parser can detect\n // the closing delimiter. When the block opens on its own line (`\\[\\n…`), the\n // closing delimiter must also sit on its own line; otherwise micromark treats\n // the run as inline math, never finds the closing fence, and KaTeX renders a\n // parse error that swallows the trailing delimiter.\n const blockLayout = /^[ \\t]*\\r?\\n/.test(inner);\n if (!blockLayout) {\n return before + open.open + body + open.close;\n }\n const opener =\n before === \"\" || before.endsWith(\"\\n\") ? open.open : `\\n${open.open}`;\n return `${before}${opener}${body.replace(/\\s+$/, \"\")}\\n${open.close}`;\n}\n\n/**\n * Returns the indices of the unescaped single `$` characters that act as inline\n * math delimiters in `masked` (complete `$$`/`$…$` spans are expected to have\n * been blanked out by the caller already).\n *\n * A `$` directly followed by a digit is normally currency (`$5`) and ignored.\n * The exception is a span whose body merely *starts* with a number but contains\n * a LaTeX command, e.g. `$1288 \\text{ kcal}`: the `\\text` proves it is real\n * math, so the opening `$` must count as a delimiter instead of being mistaken\n * for `$1288` currency. The span is scanned only up to the next unescaped `$`,\n * a newline, or the end of the string, since inline math stays on one line.\n */\nfunction inlineMathDollarIndices(masked: string): number[] {\n const indices: number[] = [];\n const pattern = /(?<!\\\\)\\$/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(masked)) != null) {\n const index = match.index;\n if (/\\d/.test(masked[index + 1] ?? \"\")) {\n const rest = masked.slice(index + 1);\n const end = rest.search(/(?<!\\\\)\\$|\\n/);\n const span = end === -1 ? rest : rest.slice(0, end);\n if (!/\\\\[a-zA-Z]/.test(span)) continue;\n }\n indices.push(index);\n }\n return indices;\n}\n\n/**\n * Returns the largest leading slice of incomplete block-math content that KaTeX\n * can render, with its open environments and braces closed, or `null` when no\n * usable prefix exists yet (in which case the caller hides the fragment).\n *\n * When an environment is still open (e.g. `\\begin{aligned}` mid-stream) we\n * prefer revealing only the complete rows so each equation appears fully formed,\n * falling back to a token-level repair so single-line blocks still stream in.\n */\nfunction bestRenderableMathBody(\n inner: string,\n display: boolean,\n block: boolean,\n): string | null {\n const candidates = unclosedEnvironments(inner).length > 0\n ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))]\n : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];\n\n // Inline math is short and sits in running text, so a half-streamed brace\n // group (e.g. `\\text{ kc`) would flash a partial word that then changes. For\n // inline math we therefore prefer dropping the incomplete trailing group and\n // keeping the largest stable prefix, only falling back to the brace-closing\n // candidates above when that prefix cannot render on its own.\n if (!block) {\n candidates.unshift(\n closeOpenMathConstructs(\n trimIncompleteMathTail(dropIncompleteBraceGroup(inner)),\n ),\n );\n }\n\n for (const candidate of candidates) {\n if (!hasRenderableMathContent(candidate)) continue;\n if (isRenderableMath(candidate, display)) return candidate;\n }\n return null;\n}\n\n/**\n * Cuts a math fragment back to just before its first still-open `{`, dropping\n * the entire incomplete brace group. Escaped braces (`\\{`, `\\}`) are ignored.\n * Returns the input unchanged when every group is already balanced.\n */\nfunction dropIncompleteBraceGroup(text: string): string {\n const stack: number[] = [];\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === \"\\\\\") {\n i++;\n continue;\n }\n if (char === \"{\") stack.push(i);\n else if (char === \"}\" && stack.length > 0) stack.pop();\n }\n if (stack.length === 0) return text;\n return text.slice(0, stack[0]);\n}\n\n/** True when a math body contains something other than empty environment scaffolding. */\nfunction hasRenderableMathContent(body: string): boolean {\n const stripped = body\n .replace(/\\\\(?:begin|end)\\s*\\{[^}]*\\}/g, \"\")\n .replace(/[\\s{}]/g, \"\");\n return stripped.length > 0;\n}\n\n/**\n * True when KaTeX can render the math body without raising a parse error.\n *\n * Uses the public, stable `renderToString` entry point (with `throwOnError`)\n * rather than any internal parse-only API, so it keeps working across KaTeX\n * upgrades. We only care whether it throws; the produced string is discarded.\n */\nfunction isRenderableMath(body: string, display: boolean): boolean {\n try {\n katex.renderToString(body, {\n displayMode: display,\n throwOnError: true,\n strict: false,\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Keeps only the complete rows of a multi-line environment by cutting back to\n * the last row separator (`\\\\`), dropping the partially-streamed current row.\n * Returns an empty string when no full row has streamed yet.\n */\nfunction truncateToLastRow(inner: string): string {\n const lastRow = inner.lastIndexOf(\"\\\\\\\\\");\n if (lastRow === -1) return \"\";\n return inner.slice(0, lastRow + 2);\n}\n\n/**\n * Drops trailing tokens that cannot render on their own yet: surrounding\n * whitespace, a dangling backslash, an in-progress control word (`\\frac` may\n * still be `\\fra`), and a subscript/superscript with no argument. A complete\n * `\\\\` row separator is preserved.\n */\nfunction trimIncompleteMathTail(inner: string): string {\n let result = inner;\n let previous: string;\n do {\n previous = result;\n result = result.replace(/\\s+$/, \"\");\n // A trailing odd run of backslashes ends in a lone \"\\\" (an incomplete \"\\\\\"\n // or the start of a command); drop it. An even run is complete \"\\\\\".\n const backslashes = result.match(/\\\\+$/);\n if (backslashes != null && backslashes[0].length % 2 === 1) {\n result = result.slice(0, -1);\n }\n // A trailing control word is ambiguous mid-stream; drop it so it cannot be\n // an unknown (and therefore error-rendered) command.\n result = result.replace(/\\\\[a-zA-Z]+\\*?$/, \"\");\n // A subscript/superscript needs an argument that has not arrived yet.\n result = result.replace(/[_^]$/, \"\");\n } while (result !== previous);\n return result;\n}\n\n/**\n * Closes the constructs left open in a math fragment so KaTeX can parse it:\n * unmatched `\\left`, unbalanced `{` groups, and unclosed environments. Order is\n * a best effort; the caller validates the result with KaTeX regardless.\n */\nfunction closeOpenMathConstructs(inner: string): string {\n let result = inner;\n\n const lefts = (result.match(/\\\\left(?![a-zA-Z])/g) ?? []).length;\n const rights = (result.match(/\\\\right(?![a-zA-Z])/g) ?? []).length;\n result += \"\\\\right.\".repeat(Math.max(0, lefts - rights));\n\n result += \"}\".repeat(openBraceDepth(result));\n\n const environments = unclosedEnvironments(result);\n for (let i = environments.length - 1; i >= 0; i--) {\n result += `\\\\end{${environments[i]}}`;\n }\n return result;\n}\n\n/** Counts unclosed `{` groups, ignoring escaped braces (`\\{`, `\\}`). */\nfunction openBraceDepth(text: string): number {\n let depth = 0;\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === \"\\\\\") {\n i++;\n continue;\n }\n if (char === \"{\") depth++;\n else if (char === \"}\" && depth > 0) depth--;\n }\n return depth;\n}\n\n/**\n * Returns the names of environments opened with `\\begin{…}` but not yet closed\n * with a matching `\\end{…}`, outermost first.\n */\nfunction unclosedEnvironments(text: string): string[] {\n const stack: string[] = [];\n const pattern = /\\\\(begin|end)\\s*\\{([^}]*)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) != null) {\n const name = match[2];\n if (match[1] === \"begin\") {\n stack.push(name);\n } else {\n const index = stack.lastIndexOf(name);\n if (index !== -1) stack.splice(index, 1);\n else stack.pop();\n }\n }\n return stack;\n}\n\n/**\n * Closes unterminated emphasis runs: ~~strike~~, **bold**, *italic*, __bold__\n * and _italic_.\n */\nfunction closeUnbalancedEmphasis(text: string): string {\n let result = text;\n result = closeRunMarker(result, \"~~\");\n // Close a single \"*\" first so a \"***\" opener becomes \"*\" + \"**\" and both\n // halves get closed, yielding a balanced \"***…***\".\n result = closeSingleAsterisk(result);\n result = closeRunMarker(result, \"**\");\n result = closeSingleUnderscore(result);\n result = closeDoubleUnderscore(result);\n return result;\n}\n\n/**\n * True when the marker at `index` begins a delimiter run that could open\n * emphasis: it sits at the start of the string or directly after a non-word\n * character (whitespace or punctuation). Underscores require this so intra-word\n * usage (`snake_case`, `__init__`) is never treated as a dangling emphasis\n * opener.\n */\nfunction opensAtWordBoundary(text: string, index: number): boolean {\n if (index <= 0) return true;\n // Whitespace or punctuation before the marker counts as a boundary; an\n // alphanumeric character (or another underscore) does not, so intra-word\n // usage (`snake_case`, `__init__`) is never treated as a dangling opener\n // while a leading-punctuation case like `(_italic` still closes.\n return !/[\\p{L}\\p{N}_]/u.test(text[index - 1]);\n}\n\n/**\n * Closes a single `_` italic marker. `__` pairs are masked out first, and the\n * marker is only closed when it both opens at a word boundary and sits directly\n * before a non-space character, so `snake_case` is left alone.\n */\nfunction closeSingleUnderscore(text: string): string {\n const masked = text.replace(/__/g, \"\");\n const count = (masked.match(/_/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"_\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s_]/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"_\");\n}\n\n/**\n * Closes a `__` bold marker when it is unbalanced, opens at a word boundary,\n * and is directly followed by a non-space character (so `a__b` and `__init__`\n * are left untouched).\n */\nfunction closeDoubleUnderscore(text: string): string {\n const count = (text.match(/__/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"__\");\n const after = text.slice(lastIndex + 2);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n if (!opensAtWordBoundary(text, lastIndex)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"__\");\n}\n\n/**\n * Blanks out asterisks that belong to *block* constructs rather than inline\n * emphasis so they never skew the emphasis parity count: thematic breaks\n * (`***`, `* * *`) and line-leading list bullets (`* item`) at any\n * indentation. Each match is replaced with spaces of equal length so string\n * indices stay stable for the callers that still use the original text.\n */\nfunction maskBlockAsterisks(text: string): string {\n return text\n .replace(/^[ \\t]*\\*(?:[ \\t]*\\*){2,}[ \\t]*$/gm, (m) => \" \".repeat(m.length))\n .replace(/^[ \\t]*\\*(?=[ \\t])/gm, (m) => \" \".repeat(m.length));\n}\n\n/**\n * Closes a two-character emphasis marker (`**` or `~~`) when it is unbalanced\n * and the final marker looks like an opener (immediately followed by a\n * non-space character), which avoids touching list markers or operators.\n */\nfunction closeRunMarker(text: string, marker: string): string {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n // Asterisk runs share their character with bullets and thematic breaks, so\n // count them on a text whose block asterisks have been masked away.\n const countSource = marker.includes(\"*\") ? maskBlockAsterisks(text) : text;\n const count = (countSource.match(new RegExp(escaped, \"g\")) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(marker);\n const after = text.slice(lastIndex + marker.length);\n if (after.length === 0 || /^\\s/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, marker);\n}\n\n/**\n * Closes a single `*` italic marker. `**` pairs are masked out first, and the\n * marker is only closed when it sits directly before a non-space character so\n * bullet markers (`* item`) and multiplication (`2 * 3`) are left alone.\n */\nfunction closeSingleAsterisk(text: string): string {\n // Mask block-level asterisks (bullets, thematic breaks) and \"**\" pairs so the\n // marker is not miscounted as a dangling italic opener. Masking only affects\n // the parity count; `lastIndexOf` still operates on the original text.\n const masked = maskBlockAsterisks(text).replace(/\\*\\*/g, \"\");\n const count = (masked.match(/\\*/g) ?? []).length;\n if (count % 2 === 0) return text;\n\n const lastIndex = text.lastIndexOf(\"*\");\n const after = text.slice(lastIndex + 1);\n if (after.length === 0 || /^[\\s*]/.test(after)) return text;\n\n return insertBeforeTrailingWhitespace(text, \"*\");\n}\n\n/**\n * Appends a closing emphasis marker, but places it before any trailing\n * whitespace. A closer such as `**` is only valid when it directly follows a\n * non-space character, so `**bold ` must become `**bold** ` rather than the\n * un-renderable `**bold **`.\n */\nfunction insertBeforeTrailingWhitespace(text: string, marker: string): string {\n const trailing = text.match(/\\s+$/)?.[0] ?? \"\";\n const core = text.slice(0, text.length - trailing.length);\n return core + marker + trailing;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nimport type { CopyButtonProps } from \"./types\";\n\nfunction CopyIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"1em\"\n height=\"1em\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport function CopyButton({ text, className }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const copy = () => {\n const clipboard = navigator.clipboard;\n if (!clipboard) return;\n // Only show the \"copied\" confirmation once the write actually succeeds.\n void clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n if (timeoutRef.current != null) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n // Clipboard write failed; keep the idle state.\n });\n };\n\n return (\n <button\n type=\"button\"\n onClick={copy}\n className={className}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n data-copied={copied ? \"\" : undefined}\n >\n {copied ? <CheckIcon /> : <CopyIcon />}\n </button>\n );\n}\n","/**\n * Matches a fenced code block or an inline code span. Shared by\n * {@link preprocessLaTeX} and {@link escapeBrackets} so both functions treat\n * code identically; composed into the larger patterns below via `.source`.\n */\nconst CODE_SPAN = /```[\\s\\S]*?```|`[^`\\n]+`/;\n\n/**\n * Preprocesses LaTeX content by replacing delimiters and escaping certain characters.\n *\n * @param content The input string containing LaTeX expressions.\n * @returns The processed string with replaced delimiters and escaped characters.\n */\nexport function preprocessLaTeX(content: string): string {\n // Step 1: Protect code blocks\n const codeBlocks: string[] = [];\n content = content.replace(\n new RegExp(`(${CODE_SPAN.source})`, \"g\"),\n (_match, code) => {\n codeBlocks.push(code);\n return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;\n },\n );\n\n // Step 2: Protect existing LaTeX expressions. This is what makes the currency\n // escaping in Step 3 safe: by pulling complete `$$…$$` / `\\[…\\]` / `\\(…\\)`\n // regions out of the string first, the `\\$(?=\\d)` pass below cannot corrupt a\n // `$` that legitimately belongs to a math expression (e.g. `$$x = $5$$`).\n //\n // Single-dollar inline math whose content begins with a digit (e.g.\n // `$15 \\text{ g}$`) is protected too: without this its opening `$` would be\n // escaped as currency in Step 3, unbalancing the delimiters so remark-math\n // swallows the rest of the paragraph as one math region. Two shapes qualify:\n // 1. spans containing a LaTeX command (`\\…`), e.g. `$15 \\text{ g}$`;\n // 2. balanced spans whose content is purely numeric/math (digits, spaces\n // and basic operators, no prose letters), e.g. `$0$` or `$1288 / 3$`.\n // Both leave plain currency prose like `$5 and $10` for Step 3, because that\n // text contains letters between the dollars and so matches neither shape.\n const latexExpressions: string[] = [];\n content = content.replace(\n /(\\$\\$[\\s\\S]*?\\$\\$|\\\\\\[[\\s\\S]*?\\\\\\]|\\\\\\(.*?\\\\\\)|\\$(?!\\$)[^$\\n]*?\\\\[a-zA-Z][^$\\n]*?\\$|\\$(?!\\$)\\d[\\d\\s.,+\\-*/=]*\\$)/g,\n (match) => {\n latexExpressions.push(match);\n return `<<LATEX_${latexExpressions.length - 1}>>`;\n },\n );\n\n // Step 3: Escape dollar signs that are likely currency indicators\n content = content.replace(/\\$(?=\\d)/g, \"\\\\$\");\n\n // Step 4: Restore LaTeX expressions\n content = content.replace(\n /<<LATEX_(\\d+)>>/g,\n (_, index) => latexExpressions[parseInt(index, 10)],\n );\n\n // Step 5: Restore code blocks\n content = content.replace(\n /<<CODE_BLOCK_(\\d+)>>/g,\n (_, index) => codeBlocks[parseInt(index, 10)],\n );\n\n // Step 6: Apply additional escaping functions\n content = escapeBrackets(content);\n content = escapeMhchem(content);\n\n return content;\n}\n\nexport function escapeBrackets(text: string): string {\n const pattern = new RegExp(\n `(${CODE_SPAN.source})|` +\n /\\\\\\[((?:[\\s\\S]*?[^\\\\])?)\\\\]|\\\\\\((.*?)\\\\\\)/.source,\n \"g\",\n );\n return text.replace(\n pattern,\n (\n match: string,\n codeBlock: string | undefined,\n squareBracket: string | undefined,\n roundBracket: string | undefined,\n ): string => {\n if (codeBlock != null) {\n return codeBlock;\n } else if (squareBracket != null) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket != null) {\n return `$${roundBracket}$`;\n }\n return match;\n },\n );\n}\n\nexport function escapeMhchem(text: string): string {\n return text.replaceAll(\"$\\\\ce{\", \"$\\\\\\\\ce{\").replaceAll(\"$\\\\pu{\", \"$\\\\\\\\pu{\");\n}\n","import { clsx } from \"clsx\";\nimport { useMemo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport ReactMarkdown, { type Components } from \"react-markdown\";\nimport rehypeKatex from \"rehype-katex\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\n\nimport { completePartialTokens } from \"./completePartialTokens\";\nimport { CopyButton } from \"./CopyButton\";\nimport { preprocessLaTeX } from \"./preprocess\";\nimport type {\n CodeHighlighter,\n LLMMessageClassNames,\n LLMMessageComponents,\n} from \"./types\";\n\nexport interface LLMMessageProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"content\"> {\n /** The LLM message content as a markdown string. */\n children?: string;\n /** Alias for `children`. */\n content?: string;\n /** Class applied to the root element (merged with the built-in class). */\n className?: string;\n /** Per-element class overrides (merged with the built-in classes). */\n classNames?: LLMMessageClassNames;\n /** Per-element component overrides for full markup control. */\n components?: LLMMessageComponents;\n /**\n * Repair partially-streamed markdown/LaTeX so unterminated tokens (e.g.\n * `**bold`, `` `code ``, `[label](http`, `$E = mc^2`) do not render as raw\n * delimiter junk while the response is still streaming. Defaults to `true`.\n */\n completePartialTokens?: boolean;\n /**\n * Progressively render unterminated *block* math (`\\[…`, `$$…`) while it\n * streams, instead of hiding it until the closing delimiter arrives. This is\n * nicer to watch (a long block reveals row by row) but costs a synchronous\n * KaTeX parse on every chunk that contains an open block. Set to `false` to\n * hide unfinished blocks and skip that work. Only relevant while\n * `completePartialTokens` is enabled. Defaults to `true`.\n */\n showUnfinishedLatexBlocks?: boolean;\n /**\n * Optional syntax highlighter for fenced code blocks. When omitted, code\n * blocks render as plain text (so no highlighter bundle is pulled in). Pass\n * `ShikiHighlighter` / `ShikiWebHighlighter`, or build your own with\n * `createShikiHighlighter`.\n */\n highlighter?: CodeHighlighter;\n}\n\nconst remarkPlugins = [remarkGfm, remarkMath];\nconst rehypePlugins = [rehypeKatex];\n\nfunction cx(...inputs: Array<string | undefined>): string | undefined {\n const result = clsx(inputs);\n return result === \"\" ? undefined : result;\n}\n\nfunction buildComponents(\n classNames: LLMMessageClassNames | undefined,\n overrides: LLMMessageComponents | undefined,\n highlighter: CodeHighlighter | undefined,\n): Components {\n const cn = classNames ?? {};\n const o = overrides ?? {};\n const Highlighter = highlighter;\n\n return {\n code({ node: _node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || \"\");\n const codeText = String(children).replace(/\\n$/, \"\");\n // A fenced block always spans its own lines (so its text contains a\n // newline) even when no language info string is present; inline code\n // never does. Relying on the `language-` class alone would misrender a\n // bare ``` fence as inline code.\n const isBlock = match != null || String(children).includes(\"\\n\");\n\n if (isBlock) {\n const language = match?.[1] ?? \"\";\n if (o.codeBlock) {\n const CodeBlock = o.codeBlock;\n return (\n <CodeBlock\n code={codeText}\n language={language}\n className={cn.codeBlock}\n />\n );\n }\n return (\n <div className={cx(\"llm-code-block\", cn.codeBlock)}>\n <div className={cx(\"llm-code-header\", cn.codeHeader)}>\n <span className={cx(\"llm-code-language\", cn.codeLanguage)}>\n {language}\n </span>\n {o.copyButton ? (\n <o.copyButton text={codeText} className={cn.copyButton} />\n ) : (\n <CopyButton\n text={codeText}\n className={cx(\"llm-copy-button\", cn.copyButton)}\n />\n )}\n </div>\n <div className=\"llm-code-body\">\n {Highlighter ? (\n <Highlighter code={codeText} language={language} />\n ) : (\n <code className=\"llm-code-plain\">{codeText}</code>\n )}\n </div>\n </div>\n );\n }\n\n if (o.code) {\n const InlineCode = o.code;\n return (\n <InlineCode className={cx(\"llm-code\", cn.code, className)}>\n {children}\n </InlineCode>\n );\n }\n\n return (\n <code className={cx(\"llm-code\", cn.code, className)} {...props}>\n {children}\n </code>\n );\n },\n pre({ children }) {\n if (o.pre) {\n return <o.pre>{children}</o.pre>;\n }\n // Let the code component handle fenced blocks.\n return <>{children}</>;\n },\n table({ children }) {\n if (o.table) {\n return <o.table className={cn.table}>{children}</o.table>;\n }\n return (\n <div className={cx(\"llm-table-wrapper\", cn.tableWrapper)}>\n <table className={cx(\"llm-table\", cn.table)}>{children}</table>\n </div>\n );\n },\n th({ children }) {\n if (o.th) {\n return <o.th className={cn.th}>{children}</o.th>;\n }\n return <th className={cx(\"llm-th\", cn.th)}>{children}</th>;\n },\n td({ children }) {\n if (o.td) {\n return <o.td className={cn.td}>{children}</o.td>;\n }\n return <td className={cx(\"llm-td\", cn.td)}>{children}</td>;\n },\n blockquote({ children }) {\n if (o.blockquote) {\n return <o.blockquote className={cn.blockquote}>{children}</o.blockquote>;\n }\n return (\n <blockquote className={cx(\"llm-blockquote\", cn.blockquote)}>\n {children}\n </blockquote>\n );\n },\n ul({ children }) {\n if (o.ul) {\n return <o.ul className={cn.ul}>{children}</o.ul>;\n }\n return <ul className={cx(\"llm-ul\", cn.ul)}>{children}</ul>;\n },\n ol({ children }) {\n if (o.ol) {\n return <o.ol className={cn.ol}>{children}</o.ol>;\n }\n return <ol className={cx(\"llm-ol\", cn.ol)}>{children}</ol>;\n },\n li({ children }) {\n if (o.li) {\n return <o.li className={cn.li}>{children}</o.li>;\n }\n return <li className={cx(\"llm-li\", cn.li)}>{children}</li>;\n },\n p({ children }) {\n if (o.p) {\n return <o.p className={cn.p}>{children}</o.p>;\n }\n return <p className={cx(\"llm-p\", cn.p)}>{children}</p>;\n },\n h1({ children }) {\n if (o.h1) {\n return <o.h1 className={cn.h1}>{children}</o.h1>;\n }\n return <h1 className={cx(\"llm-h1\", cn.h1)}>{children}</h1>;\n },\n h2({ children }) {\n if (o.h2) {\n return <o.h2 className={cn.h2}>{children}</o.h2>;\n }\n return <h2 className={cx(\"llm-h2\", cn.h2)}>{children}</h2>;\n },\n h3({ children }) {\n if (o.h3) {\n return <o.h3 className={cn.h3}>{children}</o.h3>;\n }\n return <h3 className={cx(\"llm-h3\", cn.h3)}>{children}</h3>;\n },\n h4({ children }) {\n if (o.h4) {\n return <o.h4 className={cn.h4}>{children}</o.h4>;\n }\n return <h4 className={cx(\"llm-h4\", cn.h4)}>{children}</h4>;\n },\n h5({ children }) {\n if (o.h5) {\n return <o.h5 className={cn.h5}>{children}</o.h5>;\n }\n return <h5 className={cx(\"llm-h5\", cn.h5)}>{children}</h5>;\n },\n h6({ children }) {\n if (o.h6) {\n return <o.h6 className={cn.h6}>{children}</o.h6>;\n }\n return <h6 className={cx(\"llm-h6\", cn.h6)}>{children}</h6>;\n },\n input({ node: _node, type, checked, disabled, ...props }) {\n if (type === \"checkbox\") {\n if (o.checkbox) {\n return (\n <o.checkbox checked={Boolean(checked)} className={cn.checkbox} />\n );\n }\n return (\n <input\n type=\"checkbox\"\n checked={Boolean(checked)}\n disabled\n aria-label={checked ? \"Completed task\" : \"Incomplete task\"}\n className={cx(\"llm-checkbox\", cn.checkbox)}\n readOnly\n />\n );\n }\n return (\n <input\n type={type}\n checked={checked}\n disabled={disabled}\n readOnly\n {...props}\n />\n );\n },\n a({ href, children }) {\n if (o.a) {\n return (\n <o.a href={href} className={cn.a}>\n {children}\n </o.a>\n );\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cx(\"llm-a\", cn.a)}\n >\n {children}\n </a>\n );\n },\n img({ node: _node, src, alt, title, className: _className, ...props }) {\n if (o.img) {\n const Image = o.img;\n return (\n <Image\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cn.img}\n />\n );\n }\n return (\n <img\n src={typeof src === \"string\" ? src : undefined}\n alt={alt}\n title={title}\n className={cx(\"llm-img\", cn.img)}\n {...props}\n />\n );\n },\n hr() {\n if (o.hr) {\n return <o.hr className={cn.hr} />;\n }\n return <hr className={cx(\"llm-hr\", cn.hr)} />;\n },\n strong({ children }) {\n if (o.strong) {\n return <o.strong className={cn.strong}>{children}</o.strong>;\n }\n return <strong className={cx(\"llm-strong\", cn.strong)}>{children}</strong>;\n },\n em({ children }) {\n if (o.em) {\n return <o.em className={cn.em}>{children}</o.em>;\n }\n return <em className={cx(\"llm-em\", cn.em)}>{children}</em>;\n },\n del({ children }) {\n if (o.del) {\n return <o.del className={cn.del}>{children}</o.del>;\n }\n return <del className={cx(\"llm-del\", cn.del)}>{children}</del>;\n },\n };\n}\n\nexport function LLMMessage({\n children,\n content,\n className,\n classNames,\n components,\n completePartialTokens: repairPartialTokens = true,\n showUnfinishedLatexBlocks = true,\n highlighter,\n ...rest\n}: LLMMessageProps) {\n const source = content ?? children ?? \"\";\n\n const markdownComponents = useMemo(\n () => buildComponents(classNames, components, highlighter),\n [classNames, components, highlighter],\n );\n\n const processed = useMemo(() => {\n const repaired = repairPartialTokens\n ? completePartialTokens(source, { showUnfinishedLatexBlocks })\n : source;\n return preprocessLaTeX(repaired);\n }, [source, repairPartialTokens, showUnfinishedLatexBlocks]);\n\n return (\n <div className={cx(\"llm-message\", classNames?.root, className)} {...rest}>\n <ReactMarkdown\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n components={markdownComponents}\n >\n {processed}\n </ReactMarkdown>\n </div>\n );\n}\n"]}
|
package/dist/styles.css
CHANGED
|
@@ -246,12 +246,16 @@
|
|
|
246
246
|
padding: 0.625rem 0.75rem;
|
|
247
247
|
font-weight: 500;
|
|
248
248
|
color: color-mix(in oklch, var(--llm-foreground) 90%, transparent);
|
|
249
|
+
overflow-wrap: normal;
|
|
250
|
+
word-break: normal;
|
|
249
251
|
}
|
|
250
252
|
.llm-td {
|
|
251
253
|
border-bottom: 1px solid
|
|
252
254
|
color-mix(in oklch, var(--llm-border) 50%, transparent);
|
|
253
255
|
padding: 0.625rem 0.75rem;
|
|
254
256
|
vertical-align: top;
|
|
257
|
+
overflow-wrap: normal;
|
|
258
|
+
word-break: normal;
|
|
255
259
|
}
|
|
256
260
|
|
|
257
261
|
/* Links */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-message-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "React component for rendering streaming LLM markdown, repairing incomplete tokens mid-stream, with GFM, KaTeX math and Shiki code highlighting.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|