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 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
- let lastDollar = -1;
159
- for (const match of masked.matchAll(/(?<!\\)\$(?!\d)/g)) {
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: lastDollar,
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 bestRenderableMathBody(inner, display) {
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 count = (text.match(new RegExp(escaped, "g")) ?? []).length;
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("*");
@@ -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`, `![alt` or\n * `[label](http`. Closed bracket fragments such as `arr[i]` or `[label]` are\n * left untouched to avoid hiding legitimate text.\n */\nfunction hideIncompleteLink(text: string): 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`, `![alt` or\n * `[label](http`. Closed bracket fragments such as `arr[i]` or `[label]` are\n * left untouched to avoid hiding legitimate text.\n */\nfunction hideIncompleteLink(text: string): 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 *block* math (`\[…`, `$$…`) by closing
56
- * the open constructs and keeping the largest prefix KaTeX accepts. This is
57
- * convenient (a long block reveals row by row) but costs a synchronous KaTeX
58
- * parse on every chunk while the block streams. Set to `false` to instead
59
- * hide the block entirely until its closing delimiter arrives, skipping the
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 *block* math (`\[…`, `$$…`) by closing
56
- * the open constructs and keeping the largest prefix KaTeX accepts. This is
57
- * convenient (a long block reveals row by row) but costs a synchronous KaTeX
58
- * parse on every chunk while the block streams. Set to `false` to instead
59
- * hide the block entirely until its closing delimiter arrives, skipping the
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
- let lastDollar = -1;
149
- for (const match of masked.matchAll(/(?<!\\)\$(?!\d)/g)) {
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: lastDollar,
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 bestRenderableMathBody(inner, display) {
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 count = (text.match(new RegExp(escaped, "g")) ?? []).length;
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`, `![alt` or\n * `[label](http`. Closed bracket fragments such as `arr[i]` or `[label]` are\n * left untouched to avoid hiding legitimate text.\n */\nfunction hideIncompleteLink(text: string): 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`, `![alt` or\n * `[label](http`. Closed bracket fragments such as `arr[i]` or `[label]` are\n * left untouched to avoid hiding legitimate text.\n */\nfunction hideIncompleteLink(text: string): 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.2",
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",