@artooi/ag-ui-web-component 0.39.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +208 -1
  2. package/README.md +116 -36
  3. package/dist/ag-ui-web-component.bundle.js +255 -101
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/constants.d.ts +3 -2
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/core/ag_ui_chat.d.ts +7 -3
  8. package/dist/core/ag_ui_chat.d.ts.map +1 -1
  9. package/dist/core/agui_client.d.ts +29 -8
  10. package/dist/core/agui_client.d.ts.map +1 -1
  11. package/dist/core/attachment.d.ts +11 -4
  12. package/dist/core/attachment.d.ts.map +1 -1
  13. package/dist/core/client_seed.d.ts +14 -2
  14. package/dist/core/client_seed.d.ts.map +1 -1
  15. package/dist/core/tool_outcome.d.ts +4 -3
  16. package/dist/core/tool_outcome.d.ts.map +1 -1
  17. package/dist/core/utils.d.ts +19 -0
  18. package/dist/core/utils.d.ts.map +1 -1
  19. package/dist/index.js +1078 -664
  20. package/dist/index.js.map +4 -4
  21. package/dist/tools/tool_catalog.d.ts.map +1 -1
  22. package/dist/ui/composer/composer_attachments.d.ts +6 -1
  23. package/dist/ui/composer/composer_attachments.d.ts.map +1 -1
  24. package/dist/ui/composer/composer_voice.d.ts +3 -0
  25. package/dist/ui/composer/composer_voice.d.ts.map +1 -1
  26. package/dist/ui/excerpts/transcript_quote_offer.d.ts +7 -2
  27. package/dist/ui/excerpts/transcript_quote_offer.d.ts.map +1 -1
  28. package/dist/ui/history/conversation_history.d.ts +30 -4
  29. package/dist/ui/history/conversation_history.d.ts.map +1 -1
  30. package/dist/ui/placement/launcher_drag.d.ts +6 -0
  31. package/dist/ui/placement/launcher_drag.d.ts.map +1 -1
  32. package/dist/ui/placement/panel_placement.d.ts +1 -1
  33. package/dist/ui/placement/panel_placement.d.ts.map +1 -1
  34. package/dist/ui/styles.d.ts +1 -1
  35. package/dist/ui/styles.d.ts.map +1 -1
  36. package/dist/ui/transcript/transcript.d.ts +3 -2
  37. package/dist/ui/transcript/transcript.d.ts.map +1 -1
  38. package/dist/ui/ui_strings.d.ts +2 -0
  39. package/dist/ui/ui_strings.d.ts.map +1 -1
  40. package/package.json +3 -3
  41. package/src/constants.ts +3 -2
  42. package/src/core/ag_ui_chat.ts +217 -64
  43. package/src/core/agui_client.ts +155 -125
  44. package/src/core/attachment.ts +13 -5
  45. package/src/core/client_seed.ts +14 -2
  46. package/src/core/tool_outcome.ts +4 -3
  47. package/src/core/utils.ts +23 -0
  48. package/src/tools/tool_catalog.ts +63 -12
  49. package/src/ui/composer/composer_attachments.ts +64 -41
  50. package/src/ui/composer/composer_voice.ts +5 -0
  51. package/src/ui/excerpts/transcript_quote_offer.ts +26 -13
  52. package/src/ui/history/conversation_history.ts +149 -38
  53. package/src/ui/placement/launcher_drag.ts +104 -89
  54. package/src/ui/placement/panel_placement.ts +27 -3
  55. package/src/ui/styles.ts +137 -14
  56. package/src/ui/transcript/transcript.ts +10 -5
  57. package/src/ui/ui_strings.ts +3 -0
  58. package/src/version.ts +1 -1
package/dist/index.js CHANGED
@@ -929,6 +929,10 @@ function answerUnansweredCalls(messages, answer, except = /* @__PURE__ */ new Se
929
929
  function toolCallIds(value) {
930
930
  return Array.isArray(value) ? value.map((call) => Object(call).id).filter((id) => typeof id === "string") : [];
931
931
  }
932
+ function metadataOrTopLevel(message, key) {
933
+ const metadata = Object(message.metadata);
934
+ return metadata[key] ?? message[key];
935
+ }
932
936
 
933
937
  // src/ui/ui_strings.ts
934
938
  var DEFAULT_UI_STRINGS = {
@@ -982,6 +986,7 @@ var DEFAULT_UI_STRINGS = {
982
986
  attachmentsStillUploading: "{n} file still uploading \u2014 it was not sent with this message and is still attached.",
983
987
  notConnected: "This chat isn\u2019t connected to an agent, so the message wasn\u2019t sent.",
984
988
  continueNeedsTurn: "Type the next turn in the composer first, then pick a run to continue.",
989
+ continueWhileRunning: "Wait for the current answer or stop it, then pick a run to continue.",
985
990
  skillNeeds: "\u201C{title}\u201D needs {fields} \u2014 fill it in below, then send.",
986
991
  message: "Message",
987
992
  inputPlaceholder: "Ask anything\u2026",
@@ -1418,12 +1423,12 @@ var ToolCatalog = class {
1418
1423
  },
1419
1424
  required: ["question"]
1420
1425
  },
1421
- handler: (args) => this.#askUser(args)
1426
+ handler: (args, callId) => this.#askUser(args, callId)
1422
1427
  }
1423
1428
  ];
1424
1429
  }
1425
1430
  /** Render the `ask_user` question card and resolve with the user's answer. */
1426
- async #askUser(args) {
1431
+ async #askUser(args, callId) {
1427
1432
  const question = typeof args["question"] === "string" ? args["question"] : "";
1428
1433
  const request = { question };
1429
1434
  const rawOptions = args["options"];
@@ -1435,19 +1440,59 @@ var ToolCatalog = class {
1435
1440
  }
1436
1441
  const signal = this.#host.decision.open();
1437
1442
  this.#host.hidePending();
1438
- const renderer = this.#host.askUserRenderer();
1439
- const answer = renderer !== null ? (
1440
- // Called on the element, as `this.askUserRenderer(...)` always was.
1441
- await renderer.call(this.#host.element, request, { signal })
1442
- ) : await requestQuestion(this.#host.ensureGroup(), request, {
1443
+ const builtIn = () => requestQuestion(this.#host.ensureGroup(), request, {
1443
1444
  signal,
1444
1445
  strings: this.#host.strings()
1445
1446
  });
1447
+ const renderer = this.#host.askUserRenderer();
1448
+ let answer;
1449
+ if (renderer === null) {
1450
+ answer = await builtIn();
1451
+ } else {
1452
+ try {
1453
+ answer = await renderer.call(this.#host.element, request, { signal });
1454
+ } catch (error) {
1455
+ answer = await this.#afterRendererFailed(error, signal, callId, builtIn);
1456
+ }
1457
+ }
1446
1458
  this.#host.decision.close();
1447
1459
  this.#host.updateEmptyState();
1448
1460
  this.#host.follow();
1449
1461
  return answer;
1450
1462
  }
1463
+ /**
1464
+ * Answer an `ask_user` call whose host renderer threw or rejected instead of
1465
+ * answering: put the question to the built-in card.
1466
+ *
1467
+ * The same answer `approvalRenderer` gets for the same failure, and for the
1468
+ * same reason: a renderer is presentation, not a policy. It decides how the
1469
+ * question looks, never whether the agent's question is put to the user.
1470
+ * Uncaught, the throw escaped the handler, so the call's card settled as an
1471
+ * error quoting the host's message, that message went on to the agent as the
1472
+ * tool result -- a detail of the host's page, never written for the model --
1473
+ * and the pending decision was never closed, so the next Stop, in whatever
1474
+ * round, aborted the signal of a wait that had already ended rather than
1475
+ * finding nothing open. The built-in card still asks,
1476
+ * and the run carries on as if no renderer had been set. Reported the way a
1477
+ * failed `render` is, and for the same reason: survived is not the same as
1478
+ * findable.
1479
+ *
1480
+ * Except when the wait was already abandoned. A renderer honouring its signal
1481
+ * rejects once a Stop fires it, which is the signal working rather than the
1482
+ * renderer failing, and a card drawn then would ask about a run the user just
1483
+ * ended. So it resolves with the empty answer the built-in card resolves with
1484
+ * on the same abort, and says nothing.
1485
+ */
1486
+ #afterRendererFailed(error, signal, callId, builtIn) {
1487
+ if (signal.aborted) {
1488
+ return Promise.resolve("");
1489
+ }
1490
+ console.warn(
1491
+ `ag-ui-chat: askUserRenderer failed for tool call ${callId}, so the built-in question card asks instead`,
1492
+ error
1493
+ );
1494
+ return builtIn();
1495
+ }
1451
1496
  };
1452
1497
 
1453
1498
  // src/skills/skill_name_from.ts
@@ -2711,8 +2756,15 @@ var ComposerAttachments = class {
2711
2756
  * built-in multipart endpoint: reveal the 📎 button, wire the hidden file
2712
2757
  * input + drag-and-drop, and mount the tray. With neither, the affordance
2713
2758
  * stays hidden and the chat degrades to text-only.
2759
+ *
2760
+ * Called on every connect, so it starts by taking down the tray the last
2761
+ * connection mounted: that one was disposed when the element left, and the
2762
+ * attributes that decide whether there is a tray at all may have changed
2763
+ * since. The shell outlives a connection, so its listeners go under `signal`.
2714
2764
  */
2715
- wire() {
2765
+ wire(signal) {
2766
+ this.#tray?.element.remove();
2767
+ this.#tray = null;
2716
2768
  const url = this.#host.element.getAttribute("data-attachments-url");
2717
2769
  const upload = this.#host.uploadHandler() ?? this.#defaultUploadHandler(url);
2718
2770
  if (upload === null) {
@@ -2734,8 +2786,8 @@ var ComposerAttachments = class {
2734
2786
  this.#host.slot.appendChild(this.#tray.element);
2735
2787
  this.#host.fileInput.accept = accept;
2736
2788
  this.#host.button.hidden = false;
2737
- this.#enableDragAndDrop();
2738
- this.#enablePaste(tray);
2789
+ this.#enableDragAndDrop(signal);
2790
+ this.#enablePaste(tray, signal);
2739
2791
  }
2740
2792
  /** The queueing behind `AgUiChat.attachFile`, whose doc is the contract. */
2741
2793
  attach(file) {
@@ -2779,25 +2831,37 @@ var ComposerAttachments = class {
2779
2831
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_ATTACHMENT_MAX_BYTES;
2780
2832
  }
2781
2833
  /** Accept files dropped anywhere on the chat shell into the tray. */
2782
- #enableDragAndDrop() {
2834
+ #enableDragAndDrop(signal) {
2783
2835
  const chat = this.#host.chat;
2784
- chat.addEventListener("dragover", (event) => {
2785
- event.preventDefault();
2786
- chat.classList.add("chat--dragover");
2787
- });
2788
- chat.addEventListener("dragleave", () => {
2789
- chat.classList.remove("chat--dragover");
2790
- });
2791
- chat.addEventListener("drop", (event) => {
2792
- event.preventDefault();
2793
- chat.classList.remove("chat--dragover");
2794
- const files = event.dataTransfer?.files;
2795
- if (files !== void 0) {
2796
- for (const file of Array.from(files)) {
2797
- this.#tray?.add(file);
2836
+ chat.addEventListener(
2837
+ "dragover",
2838
+ (event) => {
2839
+ event.preventDefault();
2840
+ chat.classList.add("chat--dragover");
2841
+ },
2842
+ { signal }
2843
+ );
2844
+ chat.addEventListener(
2845
+ "dragleave",
2846
+ () => {
2847
+ chat.classList.remove("chat--dragover");
2848
+ },
2849
+ { signal }
2850
+ );
2851
+ chat.addEventListener(
2852
+ "drop",
2853
+ (event) => {
2854
+ event.preventDefault();
2855
+ chat.classList.remove("chat--dragover");
2856
+ const files = event.dataTransfer?.files;
2857
+ if (files !== void 0) {
2858
+ for (const file of Array.from(files)) {
2859
+ this.#tray?.add(file);
2860
+ }
2798
2861
  }
2799
- }
2800
- });
2862
+ },
2863
+ { signal }
2864
+ );
2801
2865
  }
2802
2866
  /**
2803
2867
  * Turn a very long text paste into an attachment instead of a wall of text.
@@ -2867,24 +2931,28 @@ var ComposerAttachments = class {
2867
2931
  * clipboard, and swallowing the words someone meant to paste in order to
2868
2932
  * attach a picture they did not is the worse of the two failures.
2869
2933
  */
2870
- #enablePaste(tray) {
2871
- this.#host.chat.addEventListener("paste", (event) => {
2872
- const clipboard = event.clipboardData ?? null;
2873
- if (clipboard === null) {
2874
- return;
2875
- }
2876
- const files = Array.from(clipboard.files);
2877
- if (files.length === 0) {
2878
- this.#pasteLongTextAsFile(event, clipboard, tray);
2879
- return;
2880
- }
2881
- if (clipboard.getData("text/plain") === "") {
2882
- event.preventDefault();
2883
- }
2884
- for (const file of files) {
2885
- this.#tray?.add(named(file));
2886
- }
2887
- });
2934
+ #enablePaste(tray, signal) {
2935
+ this.#host.chat.addEventListener(
2936
+ "paste",
2937
+ (event) => {
2938
+ const clipboard = event.clipboardData ?? null;
2939
+ if (clipboard === null) {
2940
+ return;
2941
+ }
2942
+ const files = Array.from(clipboard.files);
2943
+ if (files.length === 0) {
2944
+ this.#pasteLongTextAsFile(event, clipboard, tray);
2945
+ return;
2946
+ }
2947
+ if (clipboard.getData("text/plain") === "") {
2948
+ event.preventDefault();
2949
+ }
2950
+ for (const file of files) {
2951
+ this.#tray?.add(named(file));
2952
+ }
2953
+ },
2954
+ { signal }
2955
+ );
2888
2956
  }
2889
2957
  /** Tell the host what the tray now holds — see {@link ATTACHMENT_EVENT}. */
2890
2958
  #dispatch(tray) {
@@ -3112,8 +3180,13 @@ var ComposerVoice = class {
3112
3180
  * built-in POST endpoint. The control records via `MediaRecorder` and drops
3113
3181
  * the transcript into the composer; with neither configured the mic stays
3114
3182
  * hidden and the chat is text-only.
3183
+ *
3184
+ * Called on every connect, so it starts by taking down the mic the last
3185
+ * connection mounted, which was released when the element left.
3115
3186
  */
3116
3187
  wire() {
3188
+ this.#voice?.element.remove();
3189
+ this.#voice = null;
3117
3190
  const url = this.#host.element.getAttribute("data-transcribe-url");
3118
3191
  const transcribe = this.#host.transcribeHandler() ?? this.#defaultTranscribeHandler(url);
3119
3192
  if (transcribe === null) {
@@ -3622,26 +3695,39 @@ ${quoted}`;
3622
3695
  this.#pageQuote?.detach();
3623
3696
  this.#pageQuote = null;
3624
3697
  }
3625
- /** Build the offer and listen for settled selections in the transcript. */
3626
- mount() {
3698
+ /**
3699
+ * Build the offer and listen for settled selections in the transcript.
3700
+ *
3701
+ * The button and the transcript outlive a connection, so the listeners go
3702
+ * under `signal`, which the element aborts when it leaves the document.
3703
+ */
3704
+ mount(signal) {
3627
3705
  const button2 = this.button;
3628
3706
  button2.className = "quote-selection";
3629
3707
  button2.type = "button";
3630
3708
  button2.setAttribute("part", "quote-selection");
3631
3709
  button2.textContent = this.#host.strings().quoteSelection;
3632
3710
  button2.hidden = true;
3633
- button2.addEventListener("mousedown", (event) => {
3634
- event.preventDefault();
3635
- });
3636
- button2.addEventListener("click", () => {
3637
- this.#host.quote(this.#quoting);
3638
- window.getSelection()?.removeAllRanges();
3639
- this.#hide();
3640
- });
3711
+ button2.addEventListener(
3712
+ "mousedown",
3713
+ (event) => {
3714
+ event.preventDefault();
3715
+ },
3716
+ { signal }
3717
+ );
3718
+ button2.addEventListener(
3719
+ "click",
3720
+ () => {
3721
+ this.#host.quote(this.#quoting);
3722
+ window.getSelection()?.removeAllRanges();
3723
+ this.#hide();
3724
+ },
3725
+ { signal }
3726
+ );
3641
3727
  const messages = this.#host.messages;
3642
- messages.addEventListener("mouseup", (event) => this.#onSelectionSettled(event));
3643
- messages.addEventListener("keyup", () => this.#onSelectionSettled());
3644
- messages.addEventListener("mousedown", () => this.#hide());
3728
+ messages.addEventListener("mouseup", (event) => this.#onSelectionSettled(event), { signal });
3729
+ messages.addEventListener("keyup", () => this.#onSelectionSettled(), { signal });
3730
+ messages.addEventListener("mousedown", () => this.#hide(), { signal });
3645
3731
  }
3646
3732
  /** Whether the transcript offers to quote what the user selects. */
3647
3733
  #enabled() {
@@ -3927,10 +4013,11 @@ var CheckpointMenu = class {
3927
4013
 
3928
4014
  // src/ui/history/conversation_history.ts
3929
4015
  import { randomUUID as randomUUID3 } from "@ag-ui/client";
4016
+ import { contentToText } from "@ag-ui/core";
3930
4017
 
3931
4018
  // src/core/attachment.ts
3932
4019
  function messageAttachments(message) {
3933
- const refs = message.attachments;
4020
+ const refs = metadataOrTopLevel(message, "attachments");
3934
4021
  return Array.isArray(refs) ? refs.filter(isAttachmentRef) : [];
3935
4022
  }
3936
4023
  function isAttachmentRef(value) {
@@ -4022,10 +4109,16 @@ var ConversationHistory = class {
4022
4109
  /** The active thread's id. Empty until the element connects. */
4023
4110
  #threadId = "";
4024
4111
  /**
4025
- * The messages the last restore replayed, which seed the next client the
4026
- * element builds. Emptied with the rest of the in-memory run.
4112
+ * The conversation as last written for the next client the element builds to
4113
+ * start from: what the last restore replayed, or what a checkpoint
4114
+ * continuation last saved after it. Emptied with the rest of the in-memory run.
4027
4115
  */
4028
4116
  #restored = [];
4117
+ /**
4118
+ * Counts the conversations cleared away, so a continuation can tell whether
4119
+ * the one it continued is still on screen when it saves.
4120
+ */
4121
+ #cleared = 0;
4029
4122
  // Bumped on every rehydrate; a replay whose generation is stale (a newer
4030
4123
  // thread switch started while it awaited a slow store) drops its result.
4031
4124
  #generation = 0;
@@ -4043,10 +4136,14 @@ var ConversationHistory = class {
4043
4136
  get threadId() {
4044
4137
  return this.#threadId;
4045
4138
  }
4046
- /** The messages the last restore replayed, for seeding the next client. */
4139
+ /** The conversation as last written, for seeding the next client. */
4047
4140
  get restored() {
4048
4141
  return this.#restored;
4049
4142
  }
4143
+ /** The checkpoint continuation in flight, or `null` when none is running. */
4144
+ get continuation() {
4145
+ return this.#continuation;
4146
+ }
4050
4147
  /** Point at the thread the store says is active. */
4051
4148
  adoptActiveThread() {
4052
4149
  this.#threadId = this.#host.conversationStore().threadId();
@@ -4071,6 +4168,7 @@ var ConversationHistory = class {
4071
4168
  /** Forget the messages the last restore seeded, with the rest of the run. */
4072
4169
  forgetRestored() {
4073
4170
  this.#restored = [];
4171
+ this.#cleared += 1;
4074
4172
  }
4075
4173
  /** Delete the active thread if nothing was ever sent in it. */
4076
4174
  reapUnsent() {
@@ -4156,43 +4254,76 @@ var ConversationHistory = class {
4156
4254
  * Uses a short-lived agent pointed at the resume / fork endpoint and seeded
4157
4255
  * with no history, because those endpoints supply the prior turns from the
4158
4256
  * snapshot and re-sending them would duplicate. A separate agent makes that
4159
- * structural — the main agent keeps its own history — and mints the fresh
4160
- * `run_id` the endpoints also require.
4257
+ * structural and mints the fresh `run_id` the endpoints also require.
4161
4258
  *
4162
4259
  * Built by the same construction as the conversation's own client, so the
4163
4260
  * continuation streams into the same transcript the user is looking at and
4164
4261
  * runs under the same state, tools and bounds. It is the run in flight while
4165
4262
  * it lasts: {@link stopContinuation} is how the element's Stop reaches it.
4263
+ *
4264
+ * What it adds joins the conversation. Its saves write the conversation on
4265
+ * screen ahead of its exchange, and each one hands that whole list to the
4266
+ * next client the element builds, so the next ordinary message is sent with
4267
+ * the exchange it follows. The conversation's own client never held it, and
4268
+ * was sending without it.
4166
4269
  */
4167
4270
  async continueRun(runId, verb) {
4168
4271
  const index = this.runs();
4169
4272
  if (index === null) {
4170
4273
  return;
4171
4274
  }
4275
+ if (this.#host.running() || this.#continuation !== null) {
4276
+ this.#refuse(this.#host.strings().continueWhileRunning);
4277
+ return;
4278
+ }
4172
4279
  const content = this.#host.input.value.trim();
4173
4280
  if (content === "") {
4174
- this.#host.hint.textContent = this.#host.strings().continueNeedsTurn;
4175
- this.#host.hint.hidden = false;
4176
- this.#host.input.focus();
4281
+ this.#refuse(this.#host.strings().continueNeedsTurn);
4177
4282
  return;
4178
4283
  }
4179
4284
  this.#host.input.value = "";
4180
4285
  this.#host.autoGrow();
4286
+ const cleared = this.#cleared;
4181
4287
  const client = this.#host.buildClient({
4182
4288
  endpoint: verb === "resume" ? index.resumeUrl(runId) : index.forkUrl(runId),
4183
4289
  // The seed the endpoints assume: nothing. The snapshot is the history.
4184
4290
  initialMessages: [],
4185
- // Nor does it write the store. Its agent holds only the new turn and its
4186
- // answer, and a store keeps one list per thread, so saving what this
4187
- // client has would replace the conversation with its last exchange.
4188
- persist: false
4291
+ // What its saves write ahead of the exchange: the conversation on screen,
4292
+ // in the form the store holds it. From the conversation's own client when
4293
+ // there is one, because that client keeps how each call ended beside its
4294
+ // messages rather than on them; otherwise what the last restore or
4295
+ // continuation wrote, which is already in that form.
4296
+ //
4297
+ // All of it, even where this forks an earlier run and the server's
4298
+ // snapshot stops there: what is saved is what the screen shows.
4299
+ follows: this.#host.client()?.messages ?? this.#restored,
4300
+ onSaved: (conversation) => {
4301
+ if (cleared !== this.#cleared) {
4302
+ return;
4303
+ }
4304
+ this.#restored = conversation;
4305
+ this.#host.releaseClient();
4306
+ }
4189
4307
  });
4190
4308
  this.#continuation = client;
4191
- await client.send(content);
4192
- if (this.#continuation === client) {
4193
- this.#continuation = null;
4309
+ try {
4310
+ await client.send(content);
4311
+ } finally {
4312
+ if (this.#continuation === client) {
4313
+ this.#continuation = null;
4314
+ this.#host.continuationEnded();
4315
+ }
4194
4316
  }
4195
4317
  }
4318
+ /**
4319
+ * Say at the composer why a picked run did not continue, and put the caret
4320
+ * there. The hint clears itself on the next keystroke.
4321
+ */
4322
+ #refuse(reason) {
4323
+ this.#host.hint.textContent = reason;
4324
+ this.#host.hint.hidden = false;
4325
+ this.#host.input.focus();
4326
+ }
4196
4327
  /**
4197
4328
  * Restore the conversation from the store on mount, then — if a navigating
4198
4329
  * tool reloaded the page mid-run — resume the loop by supplying that tool's
@@ -4244,14 +4375,13 @@ var ConversationHistory = class {
4244
4375
  const restored = answerUnansweredCalls(
4245
4376
  messages,
4246
4377
  // The shape the store holds for a call the client answered the same way:
4247
- // its tool message, with the outcome it annotates onto the stored copy.
4248
- // Cast at the AG-UI boundary, as the client's own annotation is.
4378
+ // its tool message, with the outcome in its metadata.
4249
4379
  (toolCallId) => ({
4250
4380
  id: randomUUID3(),
4251
4381
  role: "tool",
4252
4382
  content: unfinished,
4253
4383
  toolCallId,
4254
- outcome: TOOL_OUTCOME.INTERRUPTED
4384
+ metadata: { outcome: TOOL_OUTCOME.INTERRUPTED }
4255
4385
  }),
4256
4386
  new Set(checkpoint === null ? [] : [checkpoint.toolCallId])
4257
4387
  );
@@ -4343,8 +4473,10 @@ var ConversationHistory = class {
4343
4473
  const card = this.#host.transcript.card(message.toolCallId);
4344
4474
  if (card !== void 0) {
4345
4475
  card.settle(
4346
- toolStatusFromOutcome(message.outcome),
4347
- message.content
4476
+ toolStatusFromOutcome(metadataOrTopLevel(message, "outcome")),
4477
+ // Flattened exactly as the live path flattens it, so a reload shows
4478
+ // the card the user watched settle.
4479
+ contentToText(message.content)
4348
4480
  );
4349
4481
  }
4350
4482
  }
@@ -4784,6 +4916,7 @@ var STEP = 16;
4784
4916
  var COARSE_STEP = 64;
4785
4917
  function enableLauncherDrag(launcher, options) {
4786
4918
  let suppressClick = false;
4919
+ const { signal } = options;
4787
4920
  launcher.addEventListener(
4788
4921
  "click",
4789
4922
  (event) => {
@@ -4794,54 +4927,58 @@ function enableLauncherDrag(launcher, options) {
4794
4927
  event.stopPropagation();
4795
4928
  event.preventDefault();
4796
4929
  },
4797
- true
4930
+ { capture: true, signal }
4798
4931
  );
4799
- launcher.addEventListener("pointerdown", (event) => {
4800
- suppressClick = false;
4801
- if (!options.enabled()) {
4802
- return;
4803
- }
4804
- const start = options.rect();
4805
- const originX = event.clientX;
4806
- const originY = event.clientY;
4807
- let dragging = false;
4808
- const onMove = (move) => {
4809
- const dx = move.clientX - originX;
4810
- const dy = move.clientY - originY;
4811
- if (!dragging && Math.hypot(dx, dy) < DRAG_THRESHOLD) {
4812
- return;
4813
- }
4814
- dragging = true;
4815
- launcher.setAttribute("data-dragging", "true");
4816
- const next = clampLauncher(
4817
- { ...start, left: start.left + dx, top: start.top + dy },
4818
- options.viewport()
4819
- );
4820
- options.apply(next.left, next.top);
4821
- };
4822
- const onUp = (up) => {
4823
- window.removeEventListener("pointermove", onMove);
4824
- window.removeEventListener("pointerup", onUp);
4825
- window.removeEventListener("pointercancel", onUp);
4826
- if (!dragging) {
4932
+ launcher.addEventListener(
4933
+ "pointerdown",
4934
+ (event) => {
4935
+ suppressClick = false;
4936
+ if (!options.enabled()) {
4827
4937
  return;
4828
4938
  }
4829
- launcher.removeAttribute("data-dragging");
4830
- suppressClick = true;
4831
- const next = clampLauncher(
4832
- {
4833
- ...start,
4834
- left: start.left + (up.clientX - originX),
4835
- top: start.top + (up.clientY - originY)
4836
- },
4837
- options.viewport()
4838
- );
4839
- options.commit(next.left, next.top);
4840
- };
4841
- window.addEventListener("pointermove", onMove);
4842
- window.addEventListener("pointerup", onUp);
4843
- window.addEventListener("pointercancel", onUp);
4844
- });
4939
+ const start = options.rect();
4940
+ const originX = event.clientX;
4941
+ const originY = event.clientY;
4942
+ let dragging = false;
4943
+ const onMove = (move) => {
4944
+ const dx = move.clientX - originX;
4945
+ const dy = move.clientY - originY;
4946
+ if (!dragging && Math.hypot(dx, dy) < DRAG_THRESHOLD) {
4947
+ return;
4948
+ }
4949
+ dragging = true;
4950
+ launcher.setAttribute("data-dragging", "true");
4951
+ const next = clampLauncher(
4952
+ { ...start, left: start.left + dx, top: start.top + dy },
4953
+ options.viewport()
4954
+ );
4955
+ options.apply(next.left, next.top);
4956
+ };
4957
+ const onUp = (up) => {
4958
+ window.removeEventListener("pointermove", onMove);
4959
+ window.removeEventListener("pointerup", onUp);
4960
+ window.removeEventListener("pointercancel", onUp);
4961
+ if (!dragging) {
4962
+ return;
4963
+ }
4964
+ launcher.removeAttribute("data-dragging");
4965
+ suppressClick = true;
4966
+ const next = clampLauncher(
4967
+ {
4968
+ ...start,
4969
+ left: start.left + (up.clientX - originX),
4970
+ top: start.top + (up.clientY - originY)
4971
+ },
4972
+ options.viewport()
4973
+ );
4974
+ options.commit(next.left, next.top);
4975
+ };
4976
+ window.addEventListener("pointermove", onMove);
4977
+ window.addEventListener("pointerup", onUp);
4978
+ window.addEventListener("pointercancel", onUp);
4979
+ },
4980
+ { signal }
4981
+ );
4845
4982
  let pending = null;
4846
4983
  const settle = () => {
4847
4984
  if (pending === null) {
@@ -4851,32 +4988,36 @@ function enableLauncherDrag(launcher, options) {
4851
4988
  pending = null;
4852
4989
  options.commit(left, top);
4853
4990
  };
4854
- launcher.addEventListener("keydown", (event) => {
4855
- if (!options.enabled()) {
4856
- return;
4857
- }
4858
- const step = event.shiftKey ? COARSE_STEP : STEP;
4859
- const rect = options.rect();
4860
- let moved = null;
4861
- if (event.key === "ArrowLeft") {
4862
- moved = { left: rect.left - step, top: rect.top };
4863
- } else if (event.key === "ArrowRight") {
4864
- moved = { left: rect.left + step, top: rect.top };
4865
- } else if (event.key === "ArrowUp") {
4866
- moved = { left: rect.left, top: rect.top - step };
4867
- } else if (event.key === "ArrowDown") {
4868
- moved = { left: rect.left, top: rect.top + step };
4869
- }
4870
- if (moved === null) {
4871
- return;
4872
- }
4873
- event.preventDefault();
4874
- const next = clampLauncher({ ...rect, ...moved }, options.viewport());
4875
- options.apply(next.left, next.top);
4876
- pending = next;
4877
- });
4878
- launcher.addEventListener("keyup", settle);
4879
- launcher.addEventListener("blur", settle);
4991
+ launcher.addEventListener(
4992
+ "keydown",
4993
+ (event) => {
4994
+ if (!options.enabled()) {
4995
+ return;
4996
+ }
4997
+ const step = event.shiftKey ? COARSE_STEP : STEP;
4998
+ const rect = options.rect();
4999
+ let moved = null;
5000
+ if (event.key === "ArrowLeft") {
5001
+ moved = { left: rect.left - step, top: rect.top };
5002
+ } else if (event.key === "ArrowRight") {
5003
+ moved = { left: rect.left + step, top: rect.top };
5004
+ } else if (event.key === "ArrowUp") {
5005
+ moved = { left: rect.left, top: rect.top - step };
5006
+ } else if (event.key === "ArrowDown") {
5007
+ moved = { left: rect.left, top: rect.top + step };
5008
+ }
5009
+ if (moved === null) {
5010
+ return;
5011
+ }
5012
+ event.preventDefault();
5013
+ const next = clampLauncher({ ...rect, ...moved }, options.viewport());
5014
+ options.apply(next.left, next.top);
5015
+ pending = next;
5016
+ },
5017
+ { signal }
5018
+ );
5019
+ launcher.addEventListener("keyup", settle, { signal });
5020
+ launcher.addEventListener("blur", settle, { signal });
4880
5021
  }
4881
5022
 
4882
5023
  // src/ui/placement/place_widget.ts
@@ -5123,8 +5264,9 @@ var PanelPlacement = class {
5123
5264
  * away and unclickable behind the open panel, so a drag there would move
5124
5265
  * something nobody can see.
5125
5266
  */
5126
- enableLauncherDrag() {
5267
+ enableLauncherDrag(signal) {
5127
5268
  enableLauncherDrag(this.#host.launcher, {
5269
+ signal,
5128
5270
  enabled: () => this.#host.collapsed() && this.#launcherDraggable(),
5129
5271
  rect: () => this.#launcherBox(),
5130
5272
  viewport: () => this.#viewport(),
@@ -5509,20 +5651,26 @@ var PanelPlacement = class {
5509
5651
  if (visual === null || visual === void 0) {
5510
5652
  return;
5511
5653
  }
5512
- if (Math.abs(visual.height - window.innerHeight) < 1) {
5654
+ const layout = this.#screen().height;
5655
+ if (Math.abs(visual.height - layout) < 1) {
5513
5656
  this.#host.element.style.removeProperty("--ag-ui-visual-viewport-height");
5514
5657
  this.#host.element.style.removeProperty("--ag-ui-visual-viewport-inset-bottom");
5658
+ this.#host.element.style.removeProperty("--ag-ui-visual-viewport-inset-top");
5515
5659
  return;
5516
5660
  }
5517
5661
  this.#host.element.style.setProperty(
5518
5662
  "--ag-ui-visual-viewport-height",
5519
5663
  `${Math.round(visual.height)}px`
5520
5664
  );
5521
- const hidden = window.innerHeight - visual.height - visual.offsetTop;
5665
+ const hidden = layout - visual.height - visual.offsetTop;
5522
5666
  this.#host.element.style.setProperty(
5523
5667
  "--ag-ui-visual-viewport-inset-bottom",
5524
5668
  `${Math.max(0, Math.round(hidden))}px`
5525
5669
  );
5670
+ this.#host.element.style.setProperty(
5671
+ "--ag-ui-visual-viewport-inset-top",
5672
+ `${Math.max(0, Math.round(visual.offsetTop))}px`
5673
+ );
5526
5674
  }
5527
5675
  /**
5528
5676
  * The launcher's box in viewport coordinates, with its transform divided out.
@@ -6665,7 +6813,24 @@ var STYLES = `
6665
6813
  keyboard changes no viewport-percentage length -- not vh, not dvh, not svh
6666
6814
  -- so a full-bleed panel on a phone has to be told the height rather than
6667
6815
  deriving it. The value to publish there is the visual viewport's. */
6668
- --_viewport-height: var(--ag-ui-viewport-height, var(--_visual-viewport-height));
6816
+ --_viewport-height: var(
6817
+ --ag-ui-viewport-height,
6818
+ calc(
6819
+ min(var(--_visual-viewport-inset-top) + var(--_visual-viewport-height), 100dvh - var(--_viewport-inset-bottom)) -
6820
+ var(--_viewport-inset-top) - var(--_keyboard-inset-top)
6821
+ )
6822
+ );
6823
+ /* That default is the host's box cut to the part of the screen the user can
6824
+ see: from the top the panel starts at, the host's reserved top moved down
6825
+ by the keyboard inset below, to whichever is further up, the bottom of the
6826
+ visible area or the host's reserved bottom. Where nothing has measured, the
6827
+ visible area is the layout viewport with no pan, and this is the host's
6828
+ box exactly.
6829
+
6830
+ Cut rather than replaced. A measured height used as the whole answer kept
6831
+ a bar the host reserved at the top in the position and out of the height,
6832
+ so the panel ran that far past the bottom of the visible area, with its
6833
+ composer behind the keyboard. */
6669
6834
  /* The measured height of the part of the screen the user can actually see,
6670
6835
  written by the element from the visual viewport and falling back to the
6671
6836
  layout viewport where nothing has measured yet.
@@ -6678,11 +6843,15 @@ var STYLES = `
6678
6843
 
6679
6844
  Separate from the token above so a host that states the usable height
6680
6845
  outright still wins: the element writes this one inline, and an inline
6681
- value would otherwise outrank the host's own rule. */
6682
- --_visual-viewport-height: var(
6683
- --ag-ui-visual-viewport-height,
6684
- calc(100vh - var(--_viewport-inset-top) - var(--_viewport-inset-bottom))
6685
- );
6846
+ value would otherwise outrank the host's own rule.
6847
+
6848
+ The fallback is dvh rather than vh because the browser's own bars do move
6849
+ it, where a keyboard does not. iOS Safari resolves vh to the viewport with
6850
+ its bars collapsed, so on a page that does not scroll them away a panel
6851
+ sized from it ran under the address bar by the bars' height -- 40px on
6852
+ the phone measured -- with a docked composer underneath. dvh is the
6853
+ viewport with the bars as they are. */
6854
+ --_visual-viewport-height: var(--ag-ui-visual-viewport-height, 100dvh);
6686
6855
  /* How much of the layout viewport is hidden below the visible one, measured
6687
6856
  and written by the element alongside the height above.
6688
6857
 
@@ -6697,6 +6866,24 @@ var STYLES = `
6697
6866
  A host wanting no keyboard lift at all sets --ag-ui-keyboard-inset: 0px. */
6698
6867
  --_keyboard-inset: var(--ag-ui-keyboard-inset, var(--_visual-viewport-inset-bottom));
6699
6868
  --_visual-viewport-inset-bottom: var(--ag-ui-visual-viewport-inset-bottom, 0px);
6869
+ /* How far a panel anchored at the top moves down for a keyboard, below the
6870
+ top the host reserved. With the same two-token shape as the lift above;
6871
+ 0px keeps the panel at the host's top.
6872
+
6873
+ To show the field being typed into, a browser pans the visible area down
6874
+ the layout viewport, and a fixed element stays against the layout top, so
6875
+ a panel that did not move showed only its lower part, from the pan down,
6876
+ with its header off the screen and an empty band under it. It moves by
6877
+ what the pan goes past the host's reserved top, not by the whole pan: the
6878
+ pan scrolls a bar reserved there away with the rest of the page rather
6879
+ than pushing it down, and adding the two put the panel a whole bar below
6880
+ the visible area. A corner panel anchored at the bottom does not use this,
6881
+ because the band below already accounts for the pan. */
6882
+ --_keyboard-inset-top: var(--ag-ui-keyboard-inset-top, max(0px, var(--_visual-viewport-inset-top) - var(--_viewport-inset-top)));
6883
+ /* How much of the layout viewport is hidden above the visible one: how far
6884
+ the browser panned. Measured and written by the element with the two
6885
+ above. */
6886
+ --_visual-viewport-inset-top: var(--ag-ui-visual-viewport-inset-top, 0px);
6700
6887
  --_viewport-width: var(
6701
6888
  --ag-ui-viewport-width,
6702
6889
  calc(100vw - var(--_viewport-inset-left) - var(--_viewport-inset-right))
@@ -6833,7 +7020,7 @@ var STYLES = `
6833
7020
  }
6834
7021
 
6835
7022
  :host([placement="side"]) {
6836
- --_inset: var(--ag-ui-inset, var(--_viewport-inset-top) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
7023
+ --_inset: var(--ag-ui-inset, calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
6837
7024
  --_width: var(--ag-ui-width, 420px);
6838
7025
  --_height: var(--ag-ui-height, var(--_viewport-height));
6839
7026
  --_max-height: var(--ag-ui-max-height, var(--_viewport-height));
@@ -6843,7 +7030,8 @@ var STYLES = `
6843
7030
  :host([placement="full"]) {
6844
7031
  --_inset: var(
6845
7032
  --ag-ui-inset,
6846
- var(--_viewport-inset-top) var(--_viewport-inset-right) var(--_viewport-inset-bottom) var(--_viewport-inset-left)
7033
+ calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right)
7034
+ var(--_viewport-inset-bottom) var(--_viewport-inset-left)
6847
7035
  );
6848
7036
  --_width: var(--ag-ui-width, var(--_viewport-width));
6849
7037
  --_height: var(--ag-ui-height, var(--_viewport-height));
@@ -6860,7 +7048,8 @@ var STYLES = `
6860
7048
  :host([placement="page"]) {
6861
7049
  --_inset: var(
6862
7050
  --ag-ui-inset,
6863
- var(--_viewport-inset-top) var(--_viewport-inset-right) var(--_viewport-inset-bottom) var(--_viewport-inset-left)
7051
+ calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right)
7052
+ var(--_viewport-inset-bottom) var(--_viewport-inset-left)
6864
7053
  );
6865
7054
  --_width: var(--ag-ui-width, var(--_viewport-width));
6866
7055
  --_height: var(--ag-ui-height, var(--_viewport-height));
@@ -6926,7 +7115,7 @@ var STYLES = `
6926
7115
  :host([placement=""]:not([data-small-viewport="off"])) {
6927
7116
  --_inset: var(
6928
7117
  --ag-ui-inset,
6929
- var(--_viewport-inset-top) var(--_viewport-inset-right)
7118
+ calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right)
6930
7119
  calc(var(--_viewport-inset-bottom) + var(--_keyboard-inset))
6931
7120
  var(--_viewport-inset-left)
6932
7121
  );
@@ -6956,7 +7145,7 @@ var STYLES = `
6956
7145
  --ag-ui-position: static (and place this element in your own layout) for a
6957
7146
  host-managed push instead. */
6958
7147
  :host([placement="sidebar"]) {
6959
- --_inset: var(--ag-ui-inset, var(--_viewport-inset-top) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
7148
+ --_inset: var(--ag-ui-inset, calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
6960
7149
  --_width: var(--ag-ui-width, 420px);
6961
7150
  --_height: var(--ag-ui-height, var(--_viewport-height));
6962
7151
  --_max-height: var(--ag-ui-max-height, var(--_viewport-height));
@@ -6965,7 +7154,11 @@ var STYLES = `
6965
7154
  }
6966
7155
 
6967
7156
  :host([placement="sidebar"][data-side="left"]) {
6968
- --_inset: var(--ag-ui-inset, var(--_viewport-inset-top) auto var(--_viewport-inset-bottom) var(--_viewport-inset-left));
7157
+ --_inset: var(
7158
+ --ag-ui-inset,
7159
+ calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) auto var(--_viewport-inset-bottom)
7160
+ var(--_viewport-inset-left)
7161
+ );
6969
7162
  }
6970
7163
 
6971
7164
  /* The docked panel is pinned to the edge it docks against rather than filling
@@ -7722,6 +7915,64 @@ var STYLES = `
7722
7915
  border-block-start-color: transparent;
7723
7916
  }
7724
7917
 
7918
+ /* On a phone the composer stays at the foot and the greeting takes the room
7919
+ above it, which is the other way round from everything above.
7920
+
7921
+ Centring is a shape for a screen with room to spare: the composer reads as
7922
+ the one thing on the page, and whichever way the rows grow there is space
7923
+ left on both sides of them. A phone has no space to spare, and the keyboard
7924
+ is what takes it -- opening one leaves a 426px-tall visible area with the
7925
+ composer halfway up it and an empty band underneath, which is the half of
7926
+ the screen a thumb is already resting on. Docked, the field sits directly
7927
+ over the keyboard, where every chat on the platform puts it, and the
7928
+ greeting keeps the rest.
7929
+
7930
+ Both rules restate the selector they override, with the breakpoint's own
7931
+ opt-out added: this is part of the shape a host keeps its desktop layout
7932
+ instead of, so it goes the same way as the rest of that shape. Restating
7933
+ rather than adding conditions to the originals keeps each of those rules
7934
+ readable as one decision, and source order settles the pair. */
7935
+ @media (max-width: 600px) {
7936
+ :host([data-empty]:not([data-restoring]):not([data-small-viewport="off"])) .chat::after {
7937
+ flex-grow: 0;
7938
+ }
7939
+
7940
+ /* The empty region fills the transcript instead of being centred in it as a
7941
+ block, so the two things in it can go to different places: the prompts the
7942
+ host offers to the foot, against the composer, and the greeting to the
7943
+ middle of what they leave.
7944
+
7945
+ A prompt chip is a way into the conversation. Against the field it starts,
7946
+ it reads as one; under the greeting halfway up the panel, with the field
7947
+ at the foot, it reads as decoration next to something else. Nothing here
7948
+ moves them on a screen where the composer is still centred: there the
7949
+ whole region hangs at the foot of the upper half, directly over the
7950
+ composer, and the prompts are already against it.
7951
+
7952
+ Auto block margins on the greeting are what centre it, and they take the
7953
+ free space whether or not there are prompts below to leave any, so a host
7954
+ that offers none gets a greeting in the middle of the transcript rather
7955
+ than one clinging to the composer.
7956
+ The region declares a display here, which outranks the rule collapsing a
7957
+ hidden one, so it says it is not hidden itself. Nothing sets the two
7958
+ apart today -- the transcript writes the hidden property and the host's
7959
+ data-empty from one expression -- and that is exactly why: a rule holding
7960
+ because of how a method in another file happens to be written is a rule
7961
+ holding by luck. */
7962
+ :host([placement="page"][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .empty:not([hidden]),
7963
+ :host([placement="embedded"][data-greeting][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .empty:not([hidden]) {
7964
+ margin: 0;
7965
+ flex: 1;
7966
+ display: flex;
7967
+ flex-direction: column;
7968
+ }
7969
+
7970
+ :host([placement="page"][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .greeting,
7971
+ :host([placement="embedded"][data-greeting][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .greeting {
7972
+ margin-block: auto;
7973
+ }
7974
+ }
7975
+
7725
7976
  /* Nor does the greeting paint while a restore is in flight. Hidden rather than
7726
7977
  removed, so it keeps its place and nothing around it moves when it shows. */
7727
7978
  :host([data-restoring]) .greeting {
@@ -8205,6 +8456,17 @@ var STYLES = `
8205
8456
  gap: 3px;
8206
8457
  }
8207
8458
 
8459
+ /* A call with no arguments drops the region rather than framing an empty
8460
+ object, and a settled card drops the result region until it has one -- both
8461
+ by setting the hidden property, and an author display beats the user-agent
8462
+ rule for that attribute. Without this the region kept laying out: 42px of
8463
+ card holding the ARGUMENTS heading over nothing, on every call the agent
8464
+ made with no arguments, in the display mode that shows arguments by
8465
+ default. */
8466
+ .tool-call-section[hidden] {
8467
+ display: none;
8468
+ }
8469
+
8208
8470
  /* The heading that tells the two payloads apart. Without it the arguments and
8209
8471
  the result were one run of text and a reader had to guess the boundary. */
8210
8472
  .tool-call-section-label {
@@ -8875,8 +9137,8 @@ var STYLES = `
8875
9137
  display: none;
8876
9138
  }
8877
9139
 
8878
- /* The mic button's mount point; filled only once #wireVoice mounts the
8879
- control. */
9140
+ /* The mic button's mount point; filled only once ComposerVoice.wire mounts
9141
+ the control, which it skips unless transcription is configured. */
8880
9142
  .voice-slot {
8881
9143
  display: contents;
8882
9144
  }
@@ -9553,6 +9815,15 @@ var STYLES = `
9553
9815
  padding: 10px 12px;
9554
9816
  }
9555
9817
 
9818
+ /* The row is hidden whenever the host offers no skills, which is most elements
9819
+ most of the time, and an author display beats the user-agent rule for the
9820
+ hidden attribute. Without this it kept its padding: 20px of panel between
9821
+ the transcript and the composer, under every placement, reading as the gap
9822
+ under whatever the transcript ends with. */
9823
+ .skill-chips[hidden] {
9824
+ display: none;
9825
+ }
9826
+
9556
9827
  .skill-chip {
9557
9828
  border: 1px solid var(--_border);
9558
9829
  border-radius: 999px;
@@ -10505,7 +10776,7 @@ var AnswerActions = class {
10505
10776
  }
10506
10777
  };
10507
10778
 
10508
- // node_modules/.pnpm/dompurify@3.4.14/node_modules/dompurify/dist/purify.es.mjs
10779
+ // node_modules/.pnpm/dompurify@3.4.15/node_modules/dompurify/dist/purify.es.mjs
10509
10780
  function _arrayLikeToArray(r, a) {
10510
10781
  (null == a || a > r.length) && (a = r.length);
10511
10782
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
@@ -10514,18 +10785,18 @@ function _arrayLikeToArray(r, a) {
10514
10785
  function _arrayWithHoles(r) {
10515
10786
  if (Array.isArray(r)) return r;
10516
10787
  }
10517
- function _iterableToArrayLimit(r, l3) {
10788
+ function _iterableToArrayLimit(r, l) {
10518
10789
  var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
10519
10790
  if (null != t) {
10520
- var e, n, i, u, a = [], f2 = true, o = false;
10791
+ var e, n, i, u3, a = [], f2 = true, o = false;
10521
10792
  try {
10522
- if (i = (t = t.call(r)).next, 0 === l3) ;
10523
- else for (; !(f2 = (e = i.call(t)).done) && (a.push(e.value), a.length !== l3); f2 = true) ;
10793
+ if (i = (t = t.call(r)).next, 0 === l) ;
10794
+ else for (; !(f2 = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f2 = true) ;
10524
10795
  } catch (r2) {
10525
10796
  o = true, n = r2;
10526
10797
  } finally {
10527
10798
  try {
10528
- if (!f2 && null != t.return && (u = t.return(), Object(u) !== u)) return;
10799
+ if (!f2 && null != t.return && (u3 = t.return(), Object(u3) !== u3)) return;
10529
10800
  } finally {
10530
10801
  if (o) throw n;
10531
10802
  }
@@ -10630,14 +10901,14 @@ function addToSet(set, array) {
10630
10901
  if (!arrayIsArray(array)) {
10631
10902
  return set;
10632
10903
  }
10633
- let l3 = array.length;
10634
- while (l3--) {
10635
- let element = array[l3];
10904
+ let l = array.length;
10905
+ while (l--) {
10906
+ let element = array[l];
10636
10907
  if (typeof element === "string") {
10637
10908
  const lcElement = transformCaseFunc(element);
10638
10909
  if (lcElement !== element) {
10639
10910
  if (!isFrozen(array)) {
10640
- array[l3] = lcElement;
10911
+ array[l] = lcElement;
10641
10912
  }
10642
10913
  element = lcElement;
10643
10914
  }
@@ -10845,7 +11116,7 @@ var _resolveObjectOption = function _resolveObjectOption2(cfg, key, makeFallback
10845
11116
  function createDOMPurify() {
10846
11117
  let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
10847
11118
  const DOMPurify = (root) => createDOMPurify(root);
10848
- DOMPurify.version = "3.4.14";
11119
+ DOMPurify.version = "3.4.15";
10849
11120
  DOMPurify.removed = [];
10850
11121
  if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
10851
11122
  DOMPurify.isSupported = false;
@@ -10862,6 +11133,7 @@ function createDOMPurify() {
10862
11133
  const ElementPrototype = Element2.prototype;
10863
11134
  const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
10864
11135
  const remove = lookupGetter(ElementPrototype, "remove");
11136
+ const removeAttributeNode = lookupGetter(ElementPrototype, "removeAttributeNode");
10865
11137
  const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
10866
11138
  const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
10867
11139
  const getParentNode = lookupGetter(ElementPrototype, "parentNode");
@@ -11295,7 +11567,7 @@ function createDOMPurify() {
11295
11567
  };
11296
11568
  const _stripAttributeNode = function _stripAttributeNode2(element, attribute, name) {
11297
11569
  try {
11298
- element.removeAttributeNode(attribute);
11570
+ removeAttributeNode(element, attribute);
11299
11571
  } catch (_2) {
11300
11572
  try {
11301
11573
  element.removeAttribute(name);
@@ -11343,7 +11615,7 @@ function createDOMPurify() {
11343
11615
  });
11344
11616
  try {
11345
11617
  if (attr) {
11346
- element.removeAttributeNode(attr);
11618
+ removeAttributeNode(element, attr);
11347
11619
  } else {
11348
11620
  element.removeAttribute(name);
11349
11621
  }
@@ -11531,7 +11803,16 @@ function createDOMPurify() {
11531
11803
  // makes the direct read diverge from the cached read; a clean form
11532
11804
  // (same-realm OR foreign-realm) has both reads pointing at the same
11533
11805
  // canonical NamedNodeMap.
11534
- element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || // NodeType clobbering probe. Cached Node.prototype.nodeType getter
11806
+ element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || // A form descendant named "removeAttributeNode" or "getAttributeNode"
11807
+ // shadows these Attr-node methods via [LegacyOverrideBuiltIns].
11808
+ // _removeAttribute() / _stripAttributeNode() reach for
11809
+ // element.removeAttributeNode(attr) first; when it is shadowed the call
11810
+ // throws and the name-based fallback element.removeAttribute(name)
11811
+ // ASCII-lowercases its lookup key in an HTML document, silently missing
11812
+ // a case-preserved event-handler attribute (e.g. an ONANIMATIONSTART
11813
+ // that reached the sanitizer through an XML/XHTML parse). Flag the form
11814
+ // so it is removed wholesale, exactly as for the other shadowed methods.
11815
+ typeof element.removeAttributeNode !== "function" || typeof element.getAttributeNode !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || // NodeType clobbering probe. Cached Node.prototype.nodeType getter
11535
11816
  // returns the integer 1 for any Element regardless of realm; direct
11536
11817
  // read on a clobbered form (e.g. <input name="nodeType">) returns
11537
11818
  // the named child element. Cheap addition — nodeType is read from
@@ -11757,11 +12038,12 @@ function createDOMPurify() {
11757
12038
  }
11758
12039
  if (_isClobbered(currentNode)) {
11759
12040
  _forceRemove(currentNode);
11760
- } else {
11761
- arrayPop(DOMPurify.removed);
12041
+ return false;
11762
12042
  }
12043
+ return true;
11763
12044
  } catch (_2) {
11764
12045
  _removeAttribute(name, currentNode);
12046
+ return false;
11765
12047
  }
11766
12048
  };
11767
12049
  const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
@@ -11778,14 +12060,15 @@ function createDOMPurify() {
11778
12060
  allowedAttributes: ALLOWED_ATTR2,
11779
12061
  forceKeepAttr: void 0
11780
12062
  };
11781
- let l3 = attributes.length;
12063
+ let l = attributes.length;
11782
12064
  const lcTag = transformCaseFunc(currentNode.nodeName);
11783
- while (l3--) {
11784
- const attr = attributes[l3];
12065
+ while (l--) {
12066
+ const attr = attributes[l];
11785
12067
  const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
11786
12068
  const lcName = transformCaseFunc(name);
11787
12069
  const initValue = attrValue;
11788
12070
  let value = name === "value" ? initValue : stringTrim(initValue);
12071
+ let recreatedNamedProp = false;
11789
12072
  hookEvent.attrName = lcName;
11790
12073
  hookEvent.attrValue = value;
11791
12074
  hookEvent.keepAttr = true;
@@ -11795,6 +12078,7 @@ function createDOMPurify() {
11795
12078
  if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
11796
12079
  _removeAttribute(name, currentNode, attr);
11797
12080
  value = SANITIZE_NAMED_PROPS_PREFIX + value;
12081
+ recreatedNamedProp = true;
11798
12082
  }
11799
12083
  if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
11800
12084
  _removeAttribute(name, currentNode, attr);
@@ -11824,7 +12108,10 @@ function createDOMPurify() {
11824
12108
  }
11825
12109
  value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
11826
12110
  if (value !== initValue) {
11827
- _setAttributeValue(currentNode, name, namespaceURI, value);
12111
+ const cleanWrite = _setAttributeValue(currentNode, name, namespaceURI, value);
12112
+ if (cleanWrite && recreatedNamedProp) {
12113
+ arrayPop(DOMPurify.removed);
12114
+ }
11828
12115
  }
11829
12116
  }
11830
12117
  _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
@@ -11934,9 +12221,9 @@ function createDOMPurify() {
11934
12221
  const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
11935
12222
  if (inPlace) {
11936
12223
  _neutralizePatchLinkage(dirty);
11937
- const nn2 = _readNodeName(dirty);
11938
- if (typeof nn2 === "string") {
11939
- const tagName = transformCaseFunc(nn2);
12224
+ const nn = _readNodeName(dirty);
12225
+ if (typeof nn === "string") {
12226
+ const tagName = transformCaseFunc(nn);
11940
12227
  if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
11941
12228
  _neutralizeRoot(dirty);
11942
12229
  throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
@@ -11962,7 +12249,7 @@ function createDOMPurify() {
11962
12249
  } else {
11963
12250
  body.appendChild(importedNode);
11964
12251
  }
11965
- _sanitizeAttachedShadowRoots(importedNode);
12252
+ _sanitizeAttachedShadowRoots(body);
11966
12253
  } else {
11967
12254
  if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
11968
12255
  dirty.indexOf("<") === -1) {
@@ -12089,38 +12376,38 @@ function createDOMPurify() {
12089
12376
  }
12090
12377
  var purify = createDOMPurify();
12091
12378
 
12092
- // node_modules/.pnpm/marked@18.0.11/node_modules/marked/lib/marked.esm.js
12379
+ // node_modules/.pnpm/marked@18.0.12/node_modules/marked/lib/marked.esm.js
12093
12380
  function A() {
12094
12381
  return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
12095
12382
  }
12096
- var R = A();
12097
- function j(l3) {
12098
- R = l3;
12383
+ var T = A();
12384
+ function j(u3) {
12385
+ T = u3;
12099
12386
  }
12100
- var z = { exec: () => null };
12101
- function I(l3) {
12387
+ var E = { exec: () => null };
12388
+ function I(u3) {
12102
12389
  let e = [];
12103
12390
  return (t) => {
12104
12391
  let n = Math.max(0, Math.min(3, t - 1)), s = e[n];
12105
- return s || (s = l3(n), e[n] = s), s;
12392
+ return s || (s = u3(n), e[n] = s), s;
12106
12393
  };
12107
12394
  }
12108
- function k(l3, e = "") {
12109
- let t = typeof l3 == "string" ? l3 : l3.source, n = { replace: (s, r) => {
12110
- let i = typeof r == "string" ? r : r.source;
12111
- return i = i.replace(m.caret, "$1"), t = t.replace(s, i), n;
12395
+ function k(u3, e = "") {
12396
+ let t = typeof u3 == "string" ? u3 : u3.source, n = { replace: (s, r) => {
12397
+ let o = typeof r == "string" ? r : r.source;
12398
+ return o = o.replace(m.caret, "$1"), t = t.replace(s, o), n;
12112
12399
  }, getRegex: () => new RegExp(t, e) };
12113
12400
  return n;
12114
12401
  }
12115
- var Oe = ((l3 = "") => {
12402
+ var Te = ((u3 = "") => {
12116
12403
  try {
12117
- return !!new RegExp("(?<=1)(?<!1)" + l3);
12404
+ return !!new RegExp("(?<=1)(?<!1)" + u3);
12118
12405
  } catch {
12119
12406
  return false;
12120
12407
  }
12121
12408
  })();
12122
- var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (l3) => new RegExp(`^( {0,3}${l3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: I((l3) => new RegExp(`^ {0,${l3}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)), hrRegex: I((l3) => new RegExp(`^ {0,${l3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: I((l3) => new RegExp(`^ {0,${l3}}(?:\`\`\`|~~~)`)), headingBeginRegex: I((l3) => new RegExp(`^ {0,${l3}}#`)), htmlBeginRegex: I((l3) => new RegExp(`^ {0,${l3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: I((l3) => new RegExp(`^ {0,${l3}}>`)) };
12123
- var Te = /^(?:[ \t]*(?:\n|$))+/;
12409
+ var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, endingSpaceTabChar: /[ \t]$/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (u3) => new RegExp(`^( {0,3}${u3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: I((u3) => new RegExp(`^ {0,${u3}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)), hrRegex: I((u3) => new RegExp(`^ {0,${u3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}(?:\`\`\`|~~~)`)), headingBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}#`)), htmlBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}>`)) };
12410
+ var Oe = /^(?:[ \t]*(?:\n|$))+/;
12124
12411
  var we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
12125
12412
  var ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
12126
12413
  var q = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
@@ -12136,15 +12423,15 @@ var $e = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[
12136
12423
  var Le = k(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, U).getRegex();
12137
12424
  var Q = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
12138
12425
  var X = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
12139
- var Ee = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", X).replace("tag", Q).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
12140
- var le = (l3) => k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", l3).replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
12141
- var ze = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
12426
+ var ze = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][a-z0-9-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][a-z0-9-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", X).replace("tag", Q).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
12427
+ var le = (u3) => k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", u3).replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
12428
+ var Ee = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
12142
12429
  var Me = le(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/);
12143
12430
  var Ae = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Me).getRegex();
12144
- var J = { blockquote: Ae, code: we, def: $e, fences: ye, heading: Pe, hr: q, html: Ee, lheading: ae, list: Le, newline: Te, paragraph: ze, table: z, text: _e };
12431
+ var J = { blockquote: Ae, code: we, def: $e, fences: ye, heading: Pe, hr: q, html: ze, lheading: ae, list: Le, newline: Oe, paragraph: Ee, table: E, text: _e };
12145
12432
  var se = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
12146
12433
  var Ie = { ...J, lheading: Se, table: se, paragraph: k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex() };
12147
- var Ce = { ...J, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", X).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: z, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(K).replace("hr", q).replace("heading", ` *#{1,6} *[^
12434
+ var Ce = { ...J, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", X).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: E, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(K).replace("hr", q).replace("heading", ` *#{1,6} *[^
12148
12435
  ]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
12149
12436
  var Be = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
12150
12437
  var De = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
@@ -12158,7 +12445,7 @@ var He = /[\p{Pi}\p{Ps}"']/u;
12158
12445
  var pe = /(?!~)[\p{P}\p{S}]/u;
12159
12446
  var Ze = /(?!~)[\s\p{P}\p{S}]/u;
12160
12447
  var Ge = /(?:[^\s\p{P}\p{S}]|~)/u;
12161
- var Qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Oe ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
12448
+ var Qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
12162
12449
  var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
12163
12450
  var Ne = k(ce, "u").replace(/punct/g, _).getRegex();
12164
12451
  var je = k(ce, "u").replace(/punct/g, pe).getRegex();
@@ -12178,106 +12465,107 @@ var rt = k(nt, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).repl
12178
12465
  var st = k(/\\(punct)/, "gu").replace(/punct/g, _).getRegex();
12179
12466
  var it = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
12180
12467
  var ot = k(X).replace("(?:-->|$)", "-->").getRegex();
12181
- var at = k("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", ot).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
12182
- var G = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
12183
- var lt = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", G).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
12468
+ var at = k("^comment|^</[a-zA-Z][a-zA-Z0-9-]*\\s*>|^<[a-zA-Z][a-zA-Z0-9-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", ot).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
12469
+ var lt = /\[(?:\\[\s\S]|[^\[\]\\])*\]/;
12470
+ var G = k(/(?:\[(?:brackets|\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/).replace("brackets", lt).getRegex();
12471
+ var ut = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", G).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
12184
12472
  var ke = k(/^!?\[(label)\]\[(ref)\]/).replace("label", G).replace("ref", W).getRegex();
12185
12473
  var de = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", W).getRegex();
12186
- var ut = k("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
12474
+ var pt = k("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
12187
12475
  var ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
12188
- var V = { _backpedal: z, anyPunctuation: st, autolink: it, blockSkip: Qe, br: ue, code: De, del: z, delLDelim: z, delRDelim: z, emStrongLDelim: Ne, emStrongRDelimAst: Ke, emStrongRDelimUnd: Ve, escape: Be, link: lt, nolink: de, punctuation: ve, reflink: ke, reflinkSearch: ut, tag: at, text: qe, url: z };
12189
- var pt = { ...V, emStrongLDelim: Ue, emStrongRDelimAst: Je, emStrongRDelimUnd: et, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", G).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", G).getRegex() };
12190
- var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", ie).getRegex() };
12191
- var ct = { ...F, br: k(ue).replace("{2,}", "*").getRegex(), text: k(F.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
12476
+ var V = { _backpedal: E, anyPunctuation: st, autolink: it, blockSkip: Qe, br: ue, code: De, del: E, delLDelim: E, delRDelim: E, emStrongLDelim: Ne, emStrongRDelimAst: Ke, emStrongRDelimUnd: Ve, escape: Be, link: ut, nolink: de, punctuation: ve, reflink: ke, reflinkSearch: pt, tag: at, text: qe, url: E };
12477
+ var ct = { ...V, emStrongLDelim: Ue, emStrongRDelimAst: Je, emStrongRDelimUnd: et, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", G).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", G).getRegex() };
12478
+ var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![\w-])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", ie).getRegex() };
12479
+ var ht = { ...F, br: k(ue).replace("{2,}", "*").getRegex(), text: k(F.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
12192
12480
  var H = { normal: J, gfm: Ie, pedantic: Ce };
12193
- var B = { normal: V, gfm: F, breaks: ct, pedantic: pt };
12194
- var ht = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
12195
- var ge = (l3) => ht[l3];
12196
- function T(l3, e) {
12481
+ var B = { normal: V, gfm: F, breaks: ht, pedantic: ct };
12482
+ var kt = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
12483
+ var ge = (u3) => kt[u3];
12484
+ function R(u3, e) {
12197
12485
  if (e) {
12198
- if (m.escapeTest.test(l3)) return l3.replace(m.escapeReplace, ge);
12199
- } else if (m.escapeTestNoEncode.test(l3)) return l3.replace(m.escapeReplaceNoEncode, ge);
12200
- return l3;
12486
+ if (m.escapeTest.test(u3)) return u3.replace(m.escapeReplace, ge);
12487
+ } else if (m.escapeTestNoEncode.test(u3)) return u3.replace(m.escapeReplaceNoEncode, ge);
12488
+ return u3;
12201
12489
  }
12202
- function Y(l3) {
12490
+ function Y(u3) {
12203
12491
  try {
12204
- l3 = encodeURI(l3).replace(m.percentDecode, "%");
12492
+ u3 = encodeURI(u3).replace(m.percentDecode, "%");
12205
12493
  } catch {
12206
12494
  return null;
12207
12495
  }
12208
- return l3;
12496
+ return u3;
12209
12497
  }
12210
- function ee(l3, e) {
12211
- let t = l3.replace(m.findPipe, (r, i, o) => {
12212
- let u = false, a = i;
12213
- for (; --a >= 0 && o[a] === "\\"; ) u = !u;
12214
- return u ? "|" : " |";
12498
+ function ee(u3, e) {
12499
+ let t = u3.replace(m.findPipe, (r, o, i) => {
12500
+ let l = false, a = o;
12501
+ for (; --a >= 0 && i[a] === "\\"; ) l = !l;
12502
+ return l ? "|" : " |";
12215
12503
  }), n = t.split(m.splitPipe), s = 0;
12216
12504
  if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
12217
12505
  else for (; n.length < e; ) n.push("");
12218
12506
  for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|");
12219
12507
  return n;
12220
12508
  }
12221
- function $(l3, e, t) {
12222
- let n = l3.length;
12509
+ function $(u3, e, t) {
12510
+ let n = u3.length;
12223
12511
  if (n === 0) return "";
12224
12512
  let s = 0;
12225
12513
  for (; s < n; ) {
12226
- let r = l3.charAt(n - s - 1);
12514
+ let r = u3.charAt(n - s - 1);
12227
12515
  if (r === e && !t) s++;
12228
12516
  else if (r !== e && t) s++;
12229
12517
  else break;
12230
12518
  }
12231
- return l3.slice(0, n - s);
12519
+ return u3.slice(0, n - s);
12232
12520
  }
12233
- function te(l3) {
12234
- let e = l3.split(`
12521
+ function te(u3) {
12522
+ let e = u3.split(`
12235
12523
  `), t = e.length - 1;
12236
12524
  for (; t >= 0 && m.blankLine.test(e[t]); ) t--;
12237
- return e.length - t <= 2 ? l3 : e.slice(0, t + 1).join(`
12525
+ return e.length - t <= 2 ? u3 : e.slice(0, t + 1).join(`
12238
12526
  `);
12239
12527
  }
12240
- function fe(l3, e) {
12241
- if (l3.indexOf(e[1]) === -1) return -1;
12528
+ function fe(u3, e) {
12529
+ if (u3.indexOf(e[1]) === -1) return -1;
12242
12530
  let t = 0;
12243
- for (let n = 0; n < l3.length; n++) if (l3[n] === "\\") n++;
12244
- else if (l3[n] === e[0]) t++;
12245
- else if (l3[n] === e[1] && (t--, t < 0)) return n;
12531
+ for (let n = 0; n < u3.length; n++) if (u3[n] === "\\") n++;
12532
+ else if (u3[n] === e[0]) t++;
12533
+ else if (u3[n] === e[1] && (t--, t < 0)) return n;
12246
12534
  return t > 0 ? -2 : -1;
12247
12535
  }
12248
- function me(l3, e = 0) {
12536
+ function me(u3, e = 0) {
12249
12537
  let t = e, n = "";
12250
- for (let s of l3) if (s === " ") {
12538
+ for (let s of u3) if (s === " ") {
12251
12539
  let r = 4 - t % 4;
12252
12540
  n += " ".repeat(r), t += r;
12253
12541
  } else n += s, t++;
12254
12542
  return n;
12255
12543
  }
12256
- function xe(l3, e, t, n, s) {
12257
- let r = e.href, i = e.title || null, o = l3[1].replace(s.other.outputLinkReplace, "$1"), u = l3[0].charAt(0) === "!";
12544
+ function xe(u3, e, t, n, s) {
12545
+ let r = e.href, o = e.title || null, i = u3[1].replace(s.other.outputLinkReplace, "$1"), l = u3[0].charAt(0) === "!";
12258
12546
  n.state.inLink = true;
12259
12547
  let a = n.state.linkEmitted, p = n.state.inRawBlock;
12260
12548
  n.state.linkEmitted = false;
12261
- let c = n.inlineTokens(o), h = n.state.linkEmitted;
12262
- if (n.state.linkEmitted = a, n.state.inLink = false, !u) {
12549
+ let c = n.inlineTokens(i), h = n.state.linkEmitted;
12550
+ if (n.state.linkEmitted = a, n.state.inLink = false, !l) {
12263
12551
  if (h) {
12264
12552
  n.state.inRawBlock = p;
12265
12553
  return;
12266
12554
  }
12267
12555
  n.state.linkEmitted = true;
12268
12556
  }
12269
- return { type: u ? "image" : "link", raw: t, href: r, title: i, text: o, tokens: c };
12557
+ return { type: l ? "image" : "link", raw: t, href: r, title: o, text: i, tokens: c };
12270
12558
  }
12271
- function kt(l3, e, t) {
12272
- let n = l3.match(t.other.indentCodeCompensation);
12559
+ function dt(u3, e, t) {
12560
+ let n = u3.match(t.other.indentCodeCompensation);
12273
12561
  if (n === null) return e;
12274
12562
  let s = n[1];
12275
12563
  return e.split(`
12276
12564
  `).map((r) => {
12277
- let i = r.match(t.other.beginningSpace);
12278
- if (i === null) return r;
12279
- let [o] = i;
12280
- return o.length >= s.length ? r.slice(s.length) : r;
12565
+ let o = r.match(t.other.beginningSpace);
12566
+ if (o === null) return r;
12567
+ let [i] = o;
12568
+ return r.slice(Math.min(i.length, s.length));
12281
12569
  }).join(`
12282
12570
  `);
12283
12571
  }
@@ -12286,7 +12574,7 @@ var y = class {
12286
12574
  rules;
12287
12575
  lexer;
12288
12576
  constructor(e) {
12289
- this.options = e || R;
12577
+ this.options = e || T;
12290
12578
  }
12291
12579
  space(e) {
12292
12580
  let t = this.rules.block.newline.exec(e);
@@ -12302,7 +12590,7 @@ var y = class {
12302
12590
  fences(e) {
12303
12591
  let t = this.rules.block.fences.exec(e);
12304
12592
  if (t) {
12305
- let n = t[0], s = kt(n, t[3] || "", this.rules);
12593
+ let n = t[0], s = dt(n, t[3] || "", this.rules);
12306
12594
  return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s };
12307
12595
  }
12308
12596
  }
@@ -12312,7 +12600,7 @@ var y = class {
12312
12600
  let n = t[2].trim();
12313
12601
  if (this.rules.other.endingHash.test(n)) {
12314
12602
  let s = $(n, "#");
12315
- (this.options.pedantic || !s || this.rules.other.endingSpaceChar.test(s)) && (n = s.trim());
12603
+ (this.options.pedantic || !s || this.rules.other.endingSpaceTabChar.test(s)) && (n = s.trim());
12316
12604
  }
12317
12605
  return { type: "heading", raw: $(t[0], `
12318
12606
  `), depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
@@ -12328,40 +12616,40 @@ var y = class {
12328
12616
  if (t) {
12329
12617
  let n = $(t[0], `
12330
12618
  `).split(`
12331
- `), s = "", r = "", i = [];
12619
+ `), s = "", r = "", o = [];
12332
12620
  for (; n.length > 0; ) {
12333
- let o = false, u = [], a;
12334
- for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a])) u.push(n[a]), o = true;
12335
- else if (!o) u.push(n[a]);
12621
+ let i = false, l = [], a;
12622
+ for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a])) l.push(n[a]), i = true;
12623
+ else if (!i) l.push(n[a]);
12336
12624
  else break;
12337
12625
  n = n.slice(a);
12338
- let p = u.join(`
12626
+ let p = l.join(`
12339
12627
  `), c = p.replace(this.rules.other.blockquoteSetextReplace, `
12340
12628
  $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
12341
12629
  s = s ? `${s}
12342
12630
  ${p}` : p, r = r ? `${r}
12343
12631
  ${c}` : c;
12344
12632
  let h = this.lexer.state.top;
12345
- if (this.lexer.state.top = true, this.lexer.blockTokens(c, i, true), this.lexer.state.top = h, n.length === 0) break;
12346
- let d = i.at(-1);
12633
+ if (this.lexer.state.top = true, this.lexer.blockTokens(c, o, true), this.lexer.state.top = h, n.length === 0) break;
12634
+ let d = o.at(-1);
12347
12635
  if (d?.type === "code") break;
12348
12636
  if (d?.type === "blockquote") {
12349
12637
  let O = d, g = n.join(`
12350
12638
  `), w = O.raw + `
12351
- ` + g.replace(this.rules.other.blockquoteSetextReplace2, ""), E = this.blockquote(w);
12352
- i[i.length - 1] = E, s = `${s}
12353
- ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12639
+ ` + g.replace(this.rules.other.blockquoteSetextReplace2, ""), z = this.blockquote(w);
12640
+ o[o.length - 1] = z, s = `${s}
12641
+ ${g}`, r = r.substring(0, r.length - O.text.length) + z.text;
12354
12642
  break;
12355
12643
  } else if (d?.type === "list") {
12356
12644
  let O = d, g = O.raw + `
12357
12645
  ` + n.join(`
12358
12646
  `), w = this.list(g);
12359
- i[i.length - 1] = w, s = s.substring(0, s.length - d.raw.length) + w.raw, r = r.substring(0, r.length - O.raw.length) + w.raw, n = g.substring(i.at(-1).raw.length).split(`
12647
+ o[o.length - 1] = w, s = s.substring(0, s.length - d.raw.length) + w.raw, r = r.substring(0, r.length - O.raw.length) + w.raw, n = g.substring(o.at(-1).raw.length).split(`
12360
12648
  `);
12361
12649
  continue;
12362
12650
  }
12363
12651
  }
12364
- return { type: "blockquote", raw: s, tokens: i, text: r };
12652
+ return { type: "blockquote", raw: s, tokens: o, text: r };
12365
12653
  }
12366
12654
  }
12367
12655
  list(e) {
@@ -12369,25 +12657,25 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12369
12657
  if (t) {
12370
12658
  let n = t[1].trim(), s = n.length > 1, r = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] };
12371
12659
  n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
12372
- let i = this.rules.other.listItemRegex(n), o = false;
12660
+ let o = this.rules.other.listItemRegex(n), i = false;
12373
12661
  for (; e; ) {
12374
12662
  let a = false, p = "", c = "";
12375
- if (!(t = i.exec(e)) || this.rules.block.hr.test(e)) break;
12663
+ if (!(t = o.exec(e)) || this.rules.block.hr.test(e)) break;
12376
12664
  p = t[0], e = e.substring(p.length);
12377
12665
  let h = me(t[2].split(`
12378
12666
  `, 1)[0], t[1].length), d = e.split(`
12379
12667
  `, 1)[0], O = !h.trim(), g = 0;
12380
12668
  if (this.options.pedantic ? (g = 2, c = h.trimStart()) : O ? g = t[1].length + 1 : (g = h.search(this.rules.other.nonSpaceChar), g = g > 4 ? 1 : g, c = h.slice(g), g += t[1].length), O && this.rules.other.blankLine.test(d) && (p += d + `
12381
12669
  `, e = e.substring(d.length + 1), a = true), !a) {
12382
- let w = this.rules.other.nextBulletRegex(g), E = this.rules.other.hrRegex(g), ne = this.rules.other.fencesBeginRegex(g), re = this.rules.other.headingBeginRegex(g), be = this.rules.other.htmlBeginRegex(g), Re = this.rules.other.blockquoteBeginRegex(g);
12670
+ let w = this.rules.other.nextBulletRegex(g), z = this.rules.other.hrRegex(g), ne = this.rules.other.fencesBeginRegex(g), re = this.rules.other.headingBeginRegex(g), be = this.rules.other.htmlBeginRegex(g), Re = this.rules.other.blockquoteBeginRegex(g);
12383
12671
  for (; e; ) {
12384
12672
  let N = e.split(`
12385
12673
  `, 1)[0], D;
12386
- if (d = N, this.options.pedantic ? (d = d.replace(this.rules.other.listReplaceNesting, " "), D = d) : D = d.replace(this.rules.other.tabCharGlobal, " "), ne.test(d) || re.test(d) || be.test(d) || Re.test(d) || w.test(d) || E.test(d)) break;
12674
+ if (d = N, this.options.pedantic ? (d = d.replace(this.rules.other.listReplaceNesting, " "), D = d) : D = d.replace(this.rules.other.tabCharGlobal, " "), ne.test(d) || re.test(d) || be.test(d) || Re.test(d) || w.test(d) || z.test(d)) break;
12387
12675
  if (D.search(this.rules.other.nonSpaceChar) >= g || !d.trim()) c += `
12388
12676
  ` + D.slice(g);
12389
12677
  else {
12390
- if (O || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || E.test(h)) break;
12678
+ if (O || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || z.test(h)) break;
12391
12679
  c += `
12392
12680
  ` + d;
12393
12681
  }
@@ -12395,10 +12683,10 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12395
12683
  `, e = e.substring(N.length + 1), h = D.slice(g);
12396
12684
  }
12397
12685
  }
12398
- r.loose || (o ? r.loose = true : this.rules.other.doubleBlankLine.test(p) && (o = true)), r.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), r.raw += p;
12686
+ r.loose || (i ? r.loose = true : this.rules.other.doubleBlankLine.test(p) && (i = true)), r.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), r.raw += p;
12399
12687
  }
12400
- let u = r.items.at(-1);
12401
- if (u) u.raw = u.raw.trimEnd(), u.text = u.text.trimEnd();
12688
+ let l = r.items.at(-1);
12689
+ if (l) l.raw = l.raw.trimEnd(), l.text = l.text.trimEnd();
12402
12690
  else return;
12403
12691
  r.raw = r.raw.trimEnd();
12404
12692
  for (let a of r.items) if (this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []), !r.loose) {
@@ -12446,13 +12734,13 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12446
12734
  let t = this.rules.block.table.exec(e);
12447
12735
  if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
12448
12736
  let n = ee(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), r = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
12449
- `) : [], i = { type: "table", raw: $(t[0], `
12737
+ `) : [], o = { type: "table", raw: $(t[0], `
12450
12738
  `), header: [], align: [], rows: [] };
12451
12739
  if (n.length === s.length) {
12452
- for (let o of s) this.rules.other.tableAlignRight.test(o) ? i.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? i.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? i.align.push("left") : i.align.push(null);
12453
- for (let o = 0; o < n.length; o++) i.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: i.align[o] });
12454
- for (let o of r) i.rows.push(ee(o, i.header.length).map((u, a) => ({ text: u, tokens: this.lexer.inline(u), header: false, align: i.align[a] })));
12455
- return i;
12740
+ for (let i of s) this.rules.other.tableAlignRight.test(i) ? o.align.push("right") : this.rules.other.tableAlignCenter.test(i) ? o.align.push("center") : this.rules.other.tableAlignLeft.test(i) ? o.align.push("left") : o.align.push(null);
12741
+ for (let i = 0; i < n.length; i++) o.header.push({ text: n[i], tokens: this.lexer.inline(n[i]), header: true, align: o.align[i] });
12742
+ for (let i of r) o.rows.push(ee(i, o.header.length).map((l, a) => ({ text: l, tokens: this.lexer.inline(l), header: false, align: o.align[a] })));
12743
+ return o;
12456
12744
  }
12457
12745
  }
12458
12746
  lheading(e) {
@@ -12489,20 +12777,20 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12489
12777
  let n = t[2].trim();
12490
12778
  if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
12491
12779
  if (!this.rules.other.endAngleBracket.test(n)) return;
12492
- let i = $(n.slice(0, -1), "\\");
12493
- if ((n.length - i.length) % 2 === 0) return;
12780
+ let o = $(n.slice(0, -1), "\\");
12781
+ if ((n.length - o.length) % 2 === 0) return;
12494
12782
  } else {
12495
- let i = fe(t[2], "()");
12496
- if (i === -2) return;
12497
- if (i > -1) {
12498
- let u = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + i;
12499
- t[2] = t[2].substring(0, i), t[0] = t[0].substring(0, u).trim(), t[3] = "";
12783
+ let o = fe(t[2], "()");
12784
+ if (o === -2) return;
12785
+ if (o > -1) {
12786
+ let l = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + o;
12787
+ t[2] = t[2].substring(0, o), t[0] = t[0].substring(0, l).trim(), t[3] = "";
12500
12788
  }
12501
12789
  }
12502
12790
  let s = t[2], r = "";
12503
12791
  if (this.options.pedantic) {
12504
- let i = this.rules.other.pedanticHrefTitle.exec(s);
12505
- i && (s = i[1], r = i[3]);
12792
+ let o = this.rules.other.pedanticHrefTitle.exec(s);
12793
+ o && (s = o[1], r = o[3]);
12506
12794
  } else r = t[3] ? t[3].slice(1, -1) : "";
12507
12795
  return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), xe(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: r && r.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
12508
12796
  }
@@ -12512,8 +12800,8 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12512
12800
  if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
12513
12801
  let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), r = t[s.toLowerCase()];
12514
12802
  if (!r) {
12515
- let i = n[0].charAt(0);
12516
- return { type: "text", raw: i, text: i };
12803
+ let o = n[0].charAt(0);
12804
+ return { type: "text", raw: o, text: o };
12517
12805
  }
12518
12806
  return xe(n, r, n[0], this.lexer, this.rules);
12519
12807
  }
@@ -12522,25 +12810,25 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12522
12810
  let s = this.rules.inline.emStrongLDelim.exec(e);
12523
12811
  if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
12524
12812
  if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
12525
- let i = [...s[0]].length - 1, o, u, a = i, p = 0, c = s[0][0], h = n === c, d = c === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
12526
- for (d.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = d.exec(t)) !== null; ) {
12527
- if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue;
12528
- if (u = [...o].length, s[3] || s[4]) {
12529
- a += u;
12813
+ let o = [...s[0]].length - 1, i, l, a = o, p = 0, c = s[0][0], h = n === c, d = c === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
12814
+ for (d.lastIndex = 0, t = t.slice(-1 * e.length + o); (s = d.exec(t)) !== null; ) {
12815
+ if (i = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !i) continue;
12816
+ if (l = [...i].length, s[3] || s[4]) {
12817
+ a += l;
12530
12818
  continue;
12531
12819
  } else if (s[5] || s[6]) {
12532
- if (i % 3 && !((i + u) % 3)) {
12533
- p += u;
12820
+ if (o % 3 && !((o + l) % 3)) {
12821
+ p += l;
12534
12822
  continue;
12535
12823
  }
12536
12824
  if (h) break;
12537
12825
  }
12538
- if (a -= u, a > 0) continue;
12539
- u = Math.min(u, u + a + p);
12540
- let O = [...s[0]][0].length, g = e.slice(0, i + s.index + O + u);
12541
- if (Math.min(i, u) % 2) {
12542
- let E = g.slice(1, -1);
12543
- return { type: "em", raw: g, text: E, tokens: this.lexer.inlineTokens(E) };
12826
+ if (a -= l, a > 0) continue;
12827
+ l = Math.min(l, l + a + p);
12828
+ let O = [...s[0]][0].length, g = e.slice(0, o + s.index + O + l);
12829
+ if (Math.min(o, l) % 2) {
12830
+ let z = g.slice(1, -1);
12831
+ return { type: "em", raw: g, text: z, tokens: this.lexer.inlineTokens(z) };
12544
12832
  }
12545
12833
  let w = g.slice(2, -2);
12546
12834
  return { type: "strong", raw: g, text: w, tokens: this.lexer.inlineTokens(w) };
@@ -12562,16 +12850,16 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12562
12850
  let s = this.rules.inline.delLDelim.exec(e);
12563
12851
  if (!s) return;
12564
12852
  if (!(s[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
12565
- let i = [...s[0]].length - 1, o, u, a = i, p = this.rules.inline.delRDelim;
12566
- for (p.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = p.exec(t)) !== null; ) {
12567
- if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o || (u = [...o].length, u !== i)) continue;
12853
+ let o = [...s[0]].length - 1, i, l, a = o, p = this.rules.inline.delRDelim;
12854
+ for (p.lastIndex = 0, t = t.slice(-1 * e.length + o); (s = p.exec(t)) !== null; ) {
12855
+ if (i = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !i || (l = [...i].length, l !== o)) continue;
12568
12856
  if (s[3] || s[4]) {
12569
- a += u;
12857
+ a += l;
12570
12858
  continue;
12571
12859
  }
12572
- if (a -= u, a > 0) continue;
12573
- u = Math.min(u, u + a);
12574
- let c = [...s[0]][0].length, h = e.slice(0, i + s.index + c + u), d = h.slice(i, -i);
12860
+ if (a -= l, a > 0) continue;
12861
+ l = Math.min(l, l + a);
12862
+ let c = [...s[0]][0].length, h = e.slice(0, o + s.index + c + l), d = h.slice(o, -o);
12575
12863
  return { type: "del", raw: h, text: d, tokens: this.lexer.inlineTokens(d) };
12576
12864
  }
12577
12865
  }
@@ -12580,7 +12868,7 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12580
12868
  let t = this.rules.inline.autolink.exec(e);
12581
12869
  if (t) {
12582
12870
  let n, s;
12583
- return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
12871
+ return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, autolink: true, tokens: [{ type: "text", raw: n, text: n }] };
12584
12872
  }
12585
12873
  }
12586
12874
  url(e) {
@@ -12595,7 +12883,7 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12595
12883
  while (r !== t[0]);
12596
12884
  n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0];
12597
12885
  }
12598
- return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
12886
+ return { type: "link", raw: t[0], text: n, href: s, autolink: true, tokens: [{ type: "text", raw: n, text: n }] };
12599
12887
  }
12600
12888
  }
12601
12889
  inlineText(e) {
@@ -12606,14 +12894,14 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
12606
12894
  }
12607
12895
  }
12608
12896
  };
12609
- var x = class l {
12897
+ var x = class u {
12610
12898
  tokens;
12611
12899
  options;
12612
12900
  state;
12613
12901
  inlineQueue;
12614
12902
  tokenizer;
12615
12903
  constructor(e) {
12616
- this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || R, this.options.tokenizer = this.options.tokenizer || new y(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, linkEmitted: false, top: true };
12904
+ this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new y(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, linkEmitted: false, top: true };
12617
12905
  let t = { other: m, block: H.normal, inline: B.normal };
12618
12906
  this.options.pedantic ? (t.block = H.pedantic, t.inline = B.pedantic) : this.options.gfm && (t.block = H.gfm, this.options.breaks ? t.inline = B.breaks : t.inline = B.gfm), this.tokenizer.rules = t;
12619
12907
  }
@@ -12621,10 +12909,10 @@ var x = class l {
12621
12909
  return { block: H, inline: B };
12622
12910
  }
12623
12911
  static lex(e, t) {
12624
- return new l(t).lex(e);
12912
+ return new u(t).lex(e);
12625
12913
  }
12626
12914
  static lexInline(e, t) {
12627
- return new l(t).inlineTokens(e);
12915
+ return new u(t).inlineTokens(e);
12628
12916
  }
12629
12917
  lex(e) {
12630
12918
  e = e.replace(m.carriageReturn, `
@@ -12645,21 +12933,21 @@ var x = class l {
12645
12933
  break;
12646
12934
  }
12647
12935
  let r;
12648
- if (this.options.extensions?.block?.some((o) => (r = o.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
12936
+ if (this.options.extensions?.block?.some((i) => (r = i.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
12649
12937
  if (r = this.tokenizer.space(e)) {
12650
12938
  e = e.substring(r.raw.length);
12651
- let o = t.at(-1);
12652
- r.raw.length === 1 && o !== void 0 ? o.raw += `
12939
+ let i = t.at(-1);
12940
+ r.raw.length === 1 && i !== void 0 ? i.raw += `
12653
12941
  ` : t.push(r);
12654
12942
  continue;
12655
12943
  }
12656
12944
  if (r = this.tokenizer.code(e)) {
12657
12945
  e = e.substring(r.raw.length);
12658
- let o = t.at(-1);
12659
- o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(`
12946
+ let i = t.at(-1);
12947
+ i?.type === "paragraph" || i?.type === "text" ? (i.raw += (i.raw.endsWith(`
12660
12948
  `) ? "" : `
12661
- `) + r.raw, o.text += `
12662
- ` + r.text, this.inlineQueue.at(-1).src = o.text) : t.push(r);
12949
+ `) + r.raw, i.text += `
12950
+ ` + r.text, this.inlineQueue.at(-1).src = i.text) : t.push(r);
12663
12951
  continue;
12664
12952
  }
12665
12953
  if (r = this.tokenizer.fences(e)) {
@@ -12688,11 +12976,11 @@ var x = class l {
12688
12976
  }
12689
12977
  if (r = this.tokenizer.def(e)) {
12690
12978
  e = e.substring(r.raw.length);
12691
- let o = t.at(-1);
12692
- o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(`
12979
+ let i = t.at(-1);
12980
+ i?.type === "paragraph" || i?.type === "text" ? (i.raw += (i.raw.endsWith(`
12693
12981
  `) ? "" : `
12694
- `) + r.raw, o.text += `
12695
- ` + r.raw, this.inlineQueue.at(-1).src = o.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
12982
+ `) + r.raw, i.text += `
12983
+ ` + r.raw, this.inlineQueue.at(-1).src = i.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
12696
12984
  continue;
12697
12985
  }
12698
12986
  if (r = this.tokenizer.table(e)) {
@@ -12703,28 +12991,28 @@ var x = class l {
12703
12991
  e = e.substring(r.raw.length), t.push(r);
12704
12992
  continue;
12705
12993
  }
12706
- let i = e;
12994
+ let o = e;
12707
12995
  if (this.options.extensions?.startBlock) {
12708
- let o = 1 / 0, u = e.slice(1), a;
12996
+ let i = 1 / 0, l = e.slice(1), a;
12709
12997
  this.options.extensions.startBlock.forEach((p) => {
12710
- a = p.call({ lexer: this }, u), typeof a == "number" && a >= 0 && (o = Math.min(o, a));
12711
- }), o < 1 / 0 && o >= 0 && (i = e.substring(0, o + 1));
12998
+ a = p.call({ lexer: this }, l), typeof a == "number" && a >= 0 && (i = Math.min(i, a));
12999
+ }), i < 1 / 0 && i >= 0 && (o = e.substring(0, i + 1));
12712
13000
  }
12713
- if (this.state.top && (r = this.tokenizer.paragraph(i))) {
12714
- let o = t.at(-1);
12715
- n && o?.type === "paragraph" ? (o.raw += (o.raw.endsWith(`
13001
+ if (this.state.top && (r = this.tokenizer.paragraph(o))) {
13002
+ let i = t.at(-1);
13003
+ n && i?.type === "paragraph" ? (i.raw += (i.raw.endsWith(`
12716
13004
  `) ? "" : `
12717
- `) + r.raw, o.text += `
12718
- ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length);
13005
+ `) + r.raw, i.text += `
13006
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = i.text) : t.push(r), n = o.length !== e.length, e = e.substring(r.raw.length);
12719
13007
  continue;
12720
13008
  }
12721
13009
  if (r = this.tokenizer.text(e)) {
12722
13010
  e = e.substring(r.raw.length);
12723
- let o = t.at(-1);
12724
- o?.type === "text" ? (o.raw += (o.raw.endsWith(`
13011
+ let i = t.at(-1);
13012
+ i?.type === "text" ? (i.raw += (i.raw.endsWith(`
12725
13013
  `) ? "" : `
12726
- `) + r.raw, o.text += `
12727
- ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t.push(r);
13014
+ `) + r.raw, i.text += `
13015
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = i.text) : t.push(r);
12728
13016
  continue;
12729
13017
  }
12730
13018
  if (e) {
@@ -12751,84 +13039,84 @@ var x = class l {
12751
13039
  this.tokenizer.lexer = this;
12752
13040
  let n = e;
12753
13041
  if (this.tokens.links && e.includes("[")) {
12754
- let o = this.tokenizer.rules.inline.reflinkSearch, u = (a) => {
13042
+ let i = this.tokenizer.rules.inline.reflinkSearch, l = (a) => {
12755
13043
  let p = a.lastIndexOf("[");
12756
13044
  if (!Object.hasOwn(this.tokens.links, a.slice(p + 1, -1))) return a;
12757
13045
  if (p > 1 && a.charAt(0) !== "!") {
12758
13046
  let c = a.slice(1, p - 1);
12759
- if (this.linkInText(c)) return "[" + c.replace(o, u) + "][" + "a".repeat(a.length - p - 2) + "]";
13047
+ if (this.linkInText(c)) return "[" + c.replace(i, l) + "][" + "a".repeat(a.length - p - 2) + "]";
12760
13048
  }
12761
13049
  return "[" + "a".repeat(a.length - 2) + "]";
12762
13050
  };
12763
- n = n.replace(o, u);
13051
+ n = n.replace(i, l);
12764
13052
  }
12765
- n = n.replace(this.tokenizer.rules.inline.anyPunctuation, (o) => "+".repeat(o.length)), n = n.replace(this.tokenizer.rules.inline.blockSkip, (o, u, a) => {
13053
+ n = n.replace(this.tokenizer.rules.inline.anyPunctuation, (i) => "+".repeat(i.length)), n = n.replace(this.tokenizer.rules.inline.blockSkip, (i, l, a) => {
12766
13054
  let p = a ? a.length : 0;
12767
- return o.slice(0, p) + "[" + "a".repeat(o.length - p - 2) + "]";
13055
+ return i.slice(0, p) + "[" + "a".repeat(i.length - p - 2) + "]";
12768
13056
  }), n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
12769
- let s = false, r = "", i = 1 / 0;
13057
+ let s = false, r = "", o = 1 / 0;
12770
13058
  for (; e; ) {
12771
- if (e.length < i) i = e.length;
13059
+ if (e.length < o) o = e.length;
12772
13060
  else {
12773
13061
  this.infiniteLoopError(e.charCodeAt(0));
12774
13062
  break;
12775
13063
  }
12776
13064
  s || (r = ""), s = false;
12777
- let o;
12778
- if (this.options.extensions?.inline?.some((a) => (o = a.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
12779
- if (o = this.tokenizer.escape(e)) {
12780
- e = e.substring(o.raw.length), t.push(o);
13065
+ let i;
13066
+ if (this.options.extensions?.inline?.some((a) => (i = a.call({ lexer: this }, e, t)) ? (e = e.substring(i.raw.length), t.push(i), true) : false)) continue;
13067
+ if (i = this.tokenizer.escape(e)) {
13068
+ e = e.substring(i.raw.length), t.push(i);
12781
13069
  continue;
12782
13070
  }
12783
- if (o = this.tokenizer.tag(e)) {
12784
- e = e.substring(o.raw.length), t.push(o);
13071
+ if (i = this.tokenizer.tag(e)) {
13072
+ e = e.substring(i.raw.length), t.push(i);
12785
13073
  continue;
12786
13074
  }
12787
- if (o = this.tokenizer.link(e)) {
12788
- e = e.substring(o.raw.length), t.push(o);
13075
+ if (i = this.tokenizer.link(e)) {
13076
+ e = e.substring(i.raw.length), t.push(i);
12789
13077
  continue;
12790
13078
  }
12791
- if (o = this.tokenizer.reflink(e, this.tokens.links)) {
12792
- e = e.substring(o.raw.length);
13079
+ if (i = this.tokenizer.reflink(e, this.tokens.links)) {
13080
+ e = e.substring(i.raw.length);
12793
13081
  let a = t.at(-1);
12794
- o.type === "text" && a?.type === "text" ? (a.raw += o.raw, a.text += o.text) : t.push(o);
13082
+ i.type === "text" && a?.type === "text" ? (a.raw += i.raw, a.text += i.text) : t.push(i);
12795
13083
  continue;
12796
13084
  }
12797
- if (o = this.tokenizer.emStrong(e, n, r)) {
12798
- e = e.substring(o.raw.length), t.push(o);
13085
+ if (i = this.tokenizer.emStrong(e, n, r)) {
13086
+ e = e.substring(i.raw.length), t.push(i);
12799
13087
  continue;
12800
13088
  }
12801
- if (o = this.tokenizer.codespan(e)) {
12802
- e = e.substring(o.raw.length), t.push(o);
13089
+ if (i = this.tokenizer.codespan(e)) {
13090
+ e = e.substring(i.raw.length), t.push(i);
12803
13091
  continue;
12804
13092
  }
12805
- if (o = this.tokenizer.br(e)) {
12806
- e = e.substring(o.raw.length), t.push(o);
13093
+ if (i = this.tokenizer.br(e)) {
13094
+ e = e.substring(i.raw.length), t.push(i);
12807
13095
  continue;
12808
13096
  }
12809
- if (o = this.tokenizer.del(e, n, r)) {
12810
- e = e.substring(o.raw.length), t.push(o);
13097
+ if (i = this.tokenizer.del(e, n, r)) {
13098
+ e = e.substring(i.raw.length), t.push(i);
12811
13099
  continue;
12812
13100
  }
12813
- if (o = this.tokenizer.autolink(e)) {
12814
- e = e.substring(o.raw.length), t.push(o);
13101
+ if (i = this.tokenizer.autolink(e)) {
13102
+ e = e.substring(i.raw.length), t.push(i);
12815
13103
  continue;
12816
13104
  }
12817
- if (!this.state.inLink && (o = this.tokenizer.url(e))) {
12818
- e = e.substring(o.raw.length), t.push(o);
13105
+ if (!this.state.inLink && (i = this.tokenizer.url(e))) {
13106
+ e = e.substring(i.raw.length), t.push(i);
12819
13107
  continue;
12820
13108
  }
12821
- let u = e;
13109
+ let l = e;
12822
13110
  if (this.options.extensions?.startInline) {
12823
13111
  let a = 1 / 0, p = e.slice(1), c;
12824
13112
  this.options.extensions.startInline.forEach((h) => {
12825
13113
  c = h.call({ lexer: this }, p), typeof c == "number" && c >= 0 && (a = Math.min(a, c));
12826
- }), a < 1 / 0 && a >= 0 && (u = e.substring(0, a + 1));
13114
+ }), a < 1 / 0 && a >= 0 && (l = e.substring(0, a + 1));
12827
13115
  }
12828
- if (o = this.tokenizer.inlineText(u)) {
12829
- e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (r = o.raw.slice(-1)), s = true;
13116
+ if (i = this.tokenizer.inlineText(l)) {
13117
+ e = e.substring(i.raw.length), i.raw.slice(-1) !== "_" && (r = i.raw.slice(-1)), s = true;
12830
13118
  let a = t.at(-1);
12831
- a?.type === "text" ? (a.raw += o.raw, a.text += o.text) : t.push(o);
13119
+ a?.type === "text" ? (a.raw += i.raw, a.text += i.text) : t.push(i);
12832
13120
  continue;
12833
13121
  }
12834
13122
  if (e) {
@@ -12848,16 +13136,16 @@ var P = class {
12848
13136
  options;
12849
13137
  parser;
12850
13138
  constructor(e) {
12851
- this.options = e || R;
13139
+ this.options = e || T;
12852
13140
  }
12853
13141
  space(e) {
12854
13142
  return "";
12855
13143
  }
12856
13144
  code({ text: e, lang: t, escaped: n }) {
12857
- let s = (t || "").match(m.notSpaceStart)?.[0], r = e.replace(m.endingNewline, "") + `
12858
- `;
12859
- return s ? '<pre><code class="language-' + T(s) + '">' + (n ? r : T(r, true)) + `</code></pre>
12860
- ` : "<pre><code>" + (n ? r : T(r, true)) + `</code></pre>
13145
+ let s = (t || "").match(m.notSpaceStart)?.[0], r = e ? e.replace(m.endingNewline, "") + `
13146
+ ` : "";
13147
+ return s ? '<pre><code class="language-' + R(s) + '">' + (n ? r : R(r, true)) + `</code></pre>
13148
+ ` : "<pre><code>" + (n ? r : R(r, true)) + `</code></pre>
12861
13149
  `;
12862
13150
  }
12863
13151
  blockquote({ tokens: e }) {
@@ -12881,12 +13169,12 @@ ${this.parser.parse(e)}</blockquote>
12881
13169
  }
12882
13170
  list(e) {
12883
13171
  let t = e.ordered, n = e.start, s = "";
12884
- for (let o = 0; o < e.items.length; o++) {
12885
- let u = e.items[o];
12886
- s += this.listitem(u);
13172
+ for (let i = 0; i < e.items.length; i++) {
13173
+ let l = e.items[i];
13174
+ s += this.listitem(l);
12887
13175
  }
12888
- let r = t ? "ol" : "ul", i = t && n !== 1 ? ' start="' + n + '"' : "";
12889
- return "<" + r + i + `>
13176
+ let r = t ? "ol" : "ul", o = t && n !== 1 ? ' start="' + n + '"' : "";
13177
+ return "<" + r + o + `>
12890
13178
  ` + s + "</" + r + `>
12891
13179
  `;
12892
13180
  }
@@ -12907,9 +13195,9 @@ ${this.parser.parse(e)}</blockquote>
12907
13195
  t += this.tablerow({ text: n });
12908
13196
  let s = "";
12909
13197
  for (let r = 0; r < e.rows.length; r++) {
12910
- let i = e.rows[r];
13198
+ let o = e.rows[r];
12911
13199
  n = "";
12912
- for (let o = 0; o < i.length; o++) n += this.tablecell(i[o]);
13200
+ for (let i = 0; i < o.length; i++) n += this.tablecell(o[i]);
12913
13201
  s += this.tablerow({ text: n });
12914
13202
  }
12915
13203
  return s && (s = `<tbody>${s}</tbody>`), `<table>
@@ -12935,7 +13223,7 @@ ${e}</tr>
12935
13223
  return `<em>${this.parser.parseInline(e)}</em>`;
12936
13224
  }
12937
13225
  codespan({ text: e }) {
12938
- return `<code>${T(e, true)}</code>`;
13226
+ return `<code>${R(e, true)}</code>`;
12939
13227
  }
12940
13228
  br(e) {
12941
13229
  return "<br>";
@@ -12943,23 +13231,23 @@ ${e}</tr>
12943
13231
  del({ tokens: e }) {
12944
13232
  return `<del>${this.parser.parseInline(e)}</del>`;
12945
13233
  }
12946
- link({ href: e, title: t, tokens: n }) {
12947
- let s = this.parser.parseInline(n), r = Y(e);
12948
- if (r === null) return s;
12949
- e = r;
12950
- let i = '<a href="' + e + '"';
12951
- return t && (i += ' title="' + T(t) + '"'), i += ">" + s + "</a>", i;
13234
+ link({ href: e, title: t, text: n, tokens: s, autolink: r }) {
13235
+ let o = r ? R(n, true) : this.parser.parseInline(s), i = Y(e);
13236
+ if (i === null) return o;
13237
+ e = R(i, r);
13238
+ let l = '<a href="' + e + '"';
13239
+ return t && (l += ' title="' + R(t) + '"'), l += ">" + o + "</a>", l;
12952
13240
  }
12953
13241
  image({ href: e, title: t, text: n, tokens: s }) {
12954
13242
  s && (n = this.parser.parseInline(s, this.parser.textRenderer));
12955
13243
  let r = Y(e);
12956
- if (r === null) return T(n);
13244
+ if (r === null) return R(n);
12957
13245
  e = r;
12958
- let i = `<img src="${e}" alt="${T(n)}"`;
12959
- return t && (i += ` title="${T(t)}"`), i += ">", i;
13246
+ let o = `<img src="${R(e)}" alt="${R(n)}"`;
13247
+ return t && (o += ` title="${R(t)}"`), o += ">", o;
12960
13248
  }
12961
13249
  text(e) {
12962
- return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : T(e.text);
13250
+ return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : R(e.text);
12963
13251
  }
12964
13252
  };
12965
13253
  var L = class {
@@ -12994,18 +13282,18 @@ var L = class {
12994
13282
  return e;
12995
13283
  }
12996
13284
  };
12997
- var b = class l2 {
13285
+ var b = class u2 {
12998
13286
  options;
12999
13287
  renderer;
13000
13288
  textRenderer;
13001
13289
  constructor(e) {
13002
- this.options = e || R, this.options.renderer = this.options.renderer || new P(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new L();
13290
+ this.options = e || T, this.options.renderer = this.options.renderer || new P(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new L();
13003
13291
  }
13004
13292
  static parse(e, t) {
13005
- return new l2(t).parse(e);
13293
+ return new u2(t).parse(e);
13006
13294
  }
13007
13295
  static parseInline(e, t) {
13008
- return new l2(t).parseInline(e);
13296
+ return new u2(t).parseInline(e);
13009
13297
  }
13010
13298
  parse(e) {
13011
13299
  this.renderer.parser = this;
@@ -13013,9 +13301,9 @@ var b = class l2 {
13013
13301
  for (let n = 0; n < e.length; n++) {
13014
13302
  let s = e[n];
13015
13303
  if (this.options.extensions?.renderers?.[s.type]) {
13016
- let i = s, o = this.options.extensions.renderers[i.type].call({ parser: this }, i);
13017
- if (o !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "checkbox", "html", "def", "paragraph", "text"].includes(i.type)) {
13018
- t += o || "";
13304
+ let o = s, i = this.options.extensions.renderers[o.type].call({ parser: this }, o);
13305
+ if (i !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "checkbox", "html", "def", "paragraph", "text"].includes(o.type)) {
13306
+ t += i || "";
13019
13307
  continue;
13020
13308
  }
13021
13309
  }
@@ -13070,9 +13358,9 @@ var b = class l2 {
13070
13358
  break;
13071
13359
  }
13072
13360
  default: {
13073
- let i = 'Token with "' + r.type + '" type was not found.';
13074
- if (this.options.silent) return console.error(i), "";
13075
- throw new Error(i);
13361
+ let o = 'Token with "' + r.type + '" type was not found.';
13362
+ if (this.options.silent) return console.error(o), "";
13363
+ throw new Error(o);
13076
13364
  }
13077
13365
  }
13078
13366
  }
@@ -13084,62 +13372,62 @@ var b = class l2 {
13084
13372
  for (let s = 0; s < e.length; s++) {
13085
13373
  let r = e[s];
13086
13374
  if (this.options.extensions?.renderers?.[r.type]) {
13087
- let o = this.options.extensions.renderers[r.type].call({ parser: this }, r);
13088
- if (o !== false || !["escape", "html", "link", "image", "checkbox", "strong", "em", "codespan", "br", "del", "text"].includes(r.type)) {
13089
- n += o || "";
13375
+ let i = this.options.extensions.renderers[r.type].call({ parser: this }, r);
13376
+ if (i !== false || !["escape", "html", "link", "image", "checkbox", "strong", "em", "codespan", "br", "del", "text"].includes(r.type)) {
13377
+ n += i || "";
13090
13378
  continue;
13091
13379
  }
13092
13380
  }
13093
- let i = r;
13094
- switch (i.type) {
13381
+ let o = r;
13382
+ switch (o.type) {
13095
13383
  case "escape": {
13096
- n += t.text(i);
13384
+ n += t.text(o);
13097
13385
  break;
13098
13386
  }
13099
13387
  case "html": {
13100
- n += t.html(i);
13388
+ n += t.html(o);
13101
13389
  break;
13102
13390
  }
13103
13391
  case "link": {
13104
- n += t.link(i);
13392
+ n += t.link(o);
13105
13393
  break;
13106
13394
  }
13107
13395
  case "image": {
13108
- n += t.image(i);
13396
+ n += t.image(o);
13109
13397
  break;
13110
13398
  }
13111
13399
  case "checkbox": {
13112
- n += t.checkbox(i);
13400
+ n += t.checkbox(o);
13113
13401
  break;
13114
13402
  }
13115
13403
  case "strong": {
13116
- n += t.strong(i);
13404
+ n += t.strong(o);
13117
13405
  break;
13118
13406
  }
13119
13407
  case "em": {
13120
- n += t.em(i);
13408
+ n += t.em(o);
13121
13409
  break;
13122
13410
  }
13123
13411
  case "codespan": {
13124
- n += t.codespan(i);
13412
+ n += t.codespan(o);
13125
13413
  break;
13126
13414
  }
13127
13415
  case "br": {
13128
- n += t.br(i);
13416
+ n += t.br(o);
13129
13417
  break;
13130
13418
  }
13131
13419
  case "del": {
13132
- n += t.del(i);
13420
+ n += t.del(o);
13133
13421
  break;
13134
13422
  }
13135
13423
  case "text": {
13136
- n += t.text(i);
13424
+ n += t.text(o);
13137
13425
  break;
13138
13426
  }
13139
13427
  default: {
13140
- let o = 'Token with "' + i.type + '" type was not found.';
13141
- if (this.options.silent) return console.error(o), "";
13142
- throw new Error(o);
13428
+ let i = 'Token with "' + o.type + '" type was not found.';
13429
+ if (this.options.silent) return console.error(i), "";
13430
+ throw new Error(i);
13143
13431
  }
13144
13432
  }
13145
13433
  }
@@ -13150,7 +13438,7 @@ var S = class {
13150
13438
  options;
13151
13439
  block;
13152
13440
  constructor(e) {
13153
- this.options = e || R;
13441
+ this.options = e || T;
13154
13442
  }
13155
13443
  static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
13156
13444
  static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
@@ -13192,8 +13480,8 @@ var Z = class {
13192
13480
  for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) {
13193
13481
  case "table": {
13194
13482
  let r = s;
13195
- for (let i of r.header) n = n.concat(this.walkTokens(i.tokens, t));
13196
- for (let i of r.rows) for (let o of i) n = n.concat(this.walkTokens(o.tokens, t));
13483
+ for (let o of r.header) n = n.concat(this.walkTokens(o.tokens, t));
13484
+ for (let o of r.rows) for (let i of o) n = n.concat(this.walkTokens(i.tokens, t));
13197
13485
  break;
13198
13486
  }
13199
13487
  case "list": {
@@ -13203,9 +13491,9 @@ var Z = class {
13203
13491
  }
13204
13492
  default: {
13205
13493
  let r = s;
13206
- this.defaults.extensions?.childTokens?.[r.type] ? this.defaults.extensions.childTokens[r.type].forEach((i) => {
13207
- let o = r[i].flat(1 / 0);
13208
- n = n.concat(this.walkTokens(o, t));
13494
+ this.defaults.extensions?.childTokens?.[r.type] ? this.defaults.extensions.childTokens[r.type].forEach((o) => {
13495
+ let i = r[o].flat(1 / 0);
13496
+ n = n.concat(this.walkTokens(i, t));
13209
13497
  }) : r.tokens && (n = n.concat(this.walkTokens(r.tokens, t)));
13210
13498
  }
13211
13499
  }
@@ -13218,26 +13506,26 @@ var Z = class {
13218
13506
  if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((r) => {
13219
13507
  if (!r.name) throw new Error("extension name required");
13220
13508
  if ("renderer" in r) {
13221
- let i = t.renderers[r.name];
13222
- i ? t.renderers[r.name] = function(...o) {
13223
- let u = r.renderer.apply(this, o);
13224
- return u === false && (u = i.apply(this, o)), u;
13509
+ let o = t.renderers[r.name];
13510
+ o ? t.renderers[r.name] = function(...i) {
13511
+ let l = r.renderer.apply(this, i);
13512
+ return l === false && (l = o.apply(this, i)), l;
13225
13513
  } : t.renderers[r.name] = r.renderer;
13226
13514
  }
13227
13515
  if ("tokenizer" in r) {
13228
13516
  if (!r.level || r.level !== "block" && r.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
13229
- let i = t[r.level];
13230
- i ? i.unshift(r.tokenizer) : t[r.level] = [r.tokenizer], r.start && (r.level === "block" ? t.startBlock ? t.startBlock.push(r.start) : t.startBlock = [r.start] : r.level === "inline" && (t.startInline ? t.startInline.push(r.start) : t.startInline = [r.start]));
13517
+ let o = t[r.level];
13518
+ o ? o.unshift(r.tokenizer) : t[r.level] = [r.tokenizer], r.start && (r.level === "block" ? t.startBlock ? t.startBlock.push(r.start) : t.startBlock = [r.start] : r.level === "inline" && (t.startInline ? t.startInline.push(r.start) : t.startInline = [r.start]));
13231
13519
  }
13232
13520
  "childTokens" in r && r.childTokens && (t.childTokens[r.name] = r.childTokens);
13233
13521
  }), s.extensions = t), n.renderer) {
13234
13522
  let r = this.defaults.renderer || new P(this.defaults);
13235
- for (let i in n.renderer) {
13236
- if (!(i in r)) throw new Error(`renderer '${i}' does not exist`);
13237
- if (["options", "parser"].includes(i)) continue;
13238
- let o = i, u = n.renderer[o], a = r[o];
13239
- r[o] = (...p) => {
13240
- let c = u.apply(r, p);
13523
+ for (let o in n.renderer) {
13524
+ if (!(o in r)) throw new Error(`renderer '${o}' does not exist`);
13525
+ if (["options", "parser"].includes(o)) continue;
13526
+ let i = o, l = n.renderer[i], a = r[i];
13527
+ r[i] = (...p) => {
13528
+ let c = l.apply(r, p);
13241
13529
  return c === false && (c = a.apply(r, p)), c || "";
13242
13530
  };
13243
13531
  }
@@ -13245,12 +13533,12 @@ var Z = class {
13245
13533
  }
13246
13534
  if (n.tokenizer) {
13247
13535
  let r = this.defaults.tokenizer || new y(this.defaults);
13248
- for (let i in n.tokenizer) {
13249
- if (!(i in r)) throw new Error(`tokenizer '${i}' does not exist`);
13250
- if (["options", "rules", "lexer"].includes(i)) continue;
13251
- let o = i, u = n.tokenizer[o], a = r[o];
13252
- r[o] = (...p) => {
13253
- let c = u.apply(r, p);
13536
+ for (let o in n.tokenizer) {
13537
+ if (!(o in r)) throw new Error(`tokenizer '${o}' does not exist`);
13538
+ if (["options", "rules", "lexer"].includes(o)) continue;
13539
+ let i = o, l = n.tokenizer[i], a = r[i];
13540
+ r[i] = (...p) => {
13541
+ let c = l.apply(r, p);
13254
13542
  return c === false && (c = a.apply(r, p)), c;
13255
13543
  };
13256
13544
  }
@@ -13258,33 +13546,33 @@ var Z = class {
13258
13546
  }
13259
13547
  if (n.hooks) {
13260
13548
  let r = this.defaults.hooks || new S();
13261
- for (let i in n.hooks) {
13262
- if (!(i in r)) throw new Error(`hook '${i}' does not exist`);
13263
- if (["options", "block"].includes(i)) continue;
13264
- let o = i, u = n.hooks[o], a = r[o];
13265
- S.passThroughHooks.has(i) ? r[o] = (p) => {
13266
- if (this.defaults.async && S.passThroughHooksRespectAsync.has(i)) return (async () => {
13267
- let h = await u.call(r, p);
13549
+ for (let o in n.hooks) {
13550
+ if (!(o in r)) throw new Error(`hook '${o}' does not exist`);
13551
+ if (["options", "block"].includes(o)) continue;
13552
+ let i = o, l = n.hooks[i], a = r[i];
13553
+ S.passThroughHooks.has(o) ? r[i] = (p) => {
13554
+ if (this.defaults.async && S.passThroughHooksRespectAsync.has(o)) return (async () => {
13555
+ let h = await l.call(r, p);
13268
13556
  return a.call(r, h);
13269
13557
  })();
13270
- let c = u.call(r, p);
13558
+ let c = l.call(r, p);
13271
13559
  return a.call(r, c);
13272
- } : r[o] = (...p) => {
13560
+ } : r[i] = (...p) => {
13273
13561
  if (this.defaults.async) return (async () => {
13274
- let h = await u.apply(r, p);
13562
+ let h = await l.apply(r, p);
13275
13563
  return h === false && (h = await a.apply(r, p)), h;
13276
13564
  })();
13277
- let c = u.apply(r, p);
13565
+ let c = l.apply(r, p);
13278
13566
  return c === false && (c = a.apply(r, p)), c;
13279
13567
  };
13280
13568
  }
13281
13569
  s.hooks = r;
13282
13570
  }
13283
13571
  if (n.walkTokens) {
13284
- let r = this.defaults.walkTokens, i = n.walkTokens;
13285
- s.walkTokens = function(o) {
13286
- let u = [];
13287
- return u.push(i.call(this, o)), r && (u = u.concat(r.call(this, o))), u;
13572
+ let r = this.defaults.walkTokens, o = n.walkTokens;
13573
+ s.walkTokens = function(i) {
13574
+ let l = [];
13575
+ return l.push(o.call(this, i)), r && (l = l.concat(r.call(this, i))), l;
13288
13576
  };
13289
13577
  }
13290
13578
  this.defaults = { ...this.defaults, ...s };
@@ -13301,24 +13589,24 @@ var Z = class {
13301
13589
  }
13302
13590
  parseMarkdown(e) {
13303
13591
  return (n, s) => {
13304
- let r = { ...s }, i = { ...this.defaults, ...r }, o = this.onError(!!i.silent, !!i.async);
13305
- if (this.defaults.async === true && r.async === false) return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
13306
- if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null"));
13307
- if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
13308
- if (i.hooks && (i.hooks.options = i, i.hooks.block = e), i.async) return (async () => {
13309
- let u = i.hooks ? await i.hooks.preprocess(n) : n, p = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(u, i), c = i.hooks ? await i.hooks.processAllTokens(p) : p;
13310
- i.walkTokens && await Promise.all(this.walkTokens(c, i.walkTokens));
13311
- let d = await (i.hooks ? await i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, i);
13312
- return i.hooks ? await i.hooks.postprocess(d) : d;
13313
- })().catch(o);
13592
+ let r = { ...s }, o = { ...this.defaults, ...r }, i = this.onError(!!o.silent, !!o.async);
13593
+ if (this.defaults.async === true && r.async === false) return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
13594
+ if (typeof n > "u" || n === null) return i(new Error("marked(): input parameter is undefined or null"));
13595
+ if (typeof n != "string") return i(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
13596
+ if (o.hooks && (o.hooks.options = o, o.hooks.block = e), o.async) return (async () => {
13597
+ let l = o.hooks ? await o.hooks.preprocess(n) : n, p = await (o.hooks ? await o.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(l, o), c = o.hooks ? await o.hooks.processAllTokens(p) : p;
13598
+ o.walkTokens && await Promise.all(this.walkTokens(c, o.walkTokens));
13599
+ let d = await (o.hooks ? await o.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, o);
13600
+ return o.hooks ? await o.hooks.postprocess(d) : d;
13601
+ })().catch(i);
13314
13602
  try {
13315
- i.hooks && (n = i.hooks.preprocess(n));
13316
- let a = (i.hooks ? i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, i);
13317
- i.hooks && (a = i.hooks.processAllTokens(a)), i.walkTokens && this.walkTokens(a, i.walkTokens);
13318
- let c = (i.hooks ? i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, i);
13319
- return i.hooks && (c = i.hooks.postprocess(c)), c;
13320
- } catch (u) {
13321
- return o(u);
13603
+ o.hooks && (n = o.hooks.preprocess(n));
13604
+ let a = (o.hooks ? o.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, o);
13605
+ o.hooks && (a = o.hooks.processAllTokens(a)), o.walkTokens && this.walkTokens(a, o.walkTokens);
13606
+ let c = (o.hooks ? o.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, o);
13607
+ return o.hooks && (c = o.hooks.postprocess(c)), c;
13608
+ } catch (l) {
13609
+ return i(l);
13322
13610
  }
13323
13611
  };
13324
13612
  }
@@ -13326,7 +13614,7 @@ var Z = class {
13326
13614
  return (n) => {
13327
13615
  if (n.message += `
13328
13616
  Please report this to https://github.com/markedjs/marked.`, e) {
13329
- let s = "<p>An error occurred:</p><pre>" + T(n.message + "", true) + "</pre>";
13617
+ let s = "<p>An error occurred:</p><pre>" + R(n.message + "", true) + "</pre>";
13330
13618
  return t ? Promise.resolve(s) : s;
13331
13619
  }
13332
13620
  if (t) return Promise.reject(n);
@@ -13335,20 +13623,20 @@ Please report this to https://github.com/markedjs/marked.`, e) {
13335
13623
  }
13336
13624
  };
13337
13625
  var M = new Z();
13338
- function f(l3, e) {
13339
- return M.parse(l3, e);
13626
+ function f(u3, e) {
13627
+ return M.parse(u3, e);
13340
13628
  }
13341
- f.options = f.setOptions = function(l3) {
13342
- return M.setOptions(l3), f.defaults = M.defaults, j(f.defaults), f;
13629
+ f.options = f.setOptions = function(u3) {
13630
+ return M.setOptions(u3), f.defaults = M.defaults, j(f.defaults), f;
13343
13631
  };
13344
13632
  f.getDefaults = A;
13345
- f.defaults = R;
13346
- function dt(...l3) {
13347
- return M.use(...l3), f.defaults = M.defaults, j(f.defaults), f;
13633
+ f.defaults = T;
13634
+ function gt(...u3) {
13635
+ return M.use(...u3), f.defaults = M.defaults, j(f.defaults), f;
13348
13636
  }
13349
- f.use = dt;
13350
- f.walkTokens = function(l3, e) {
13351
- return M.walkTokens(l3, e);
13637
+ f.use = gt;
13638
+ f.walkTokens = function(u3, e) {
13639
+ return M.walkTokens(u3, e);
13352
13640
  };
13353
13641
  f.parseInline = M.parseInline;
13354
13642
  f.Parser = b;
@@ -13360,12 +13648,12 @@ f.lexer = x.lex;
13360
13648
  f.Tokenizer = y;
13361
13649
  f.Hooks = S;
13362
13650
  f.parse = f;
13363
- var nn = f.options;
13364
- var rn = f.setOptions;
13365
- var sn = f.walkTokens;
13366
- var on = f.parseInline;
13367
- var ln = b.parse;
13368
- var un = x.lex;
13651
+ var rn = f.options;
13652
+ var sn = f.setOptions;
13653
+ var on = f.walkTokens;
13654
+ var an = f.parseInline;
13655
+ var un = b.parse;
13656
+ var pn = x.lex;
13369
13657
 
13370
13658
  // src/ui/transcript/render_markdown.ts
13371
13659
  var parser = new Z({ gfm: true, breaks: true });
@@ -13846,12 +14134,17 @@ var Transcript = class {
13846
14134
  /**
13847
14135
  * Start following the foot of the list, and wire the jump button to it.
13848
14136
  * Called while rendering rather than at construction: the viewport has to
13849
- * exist and the observer has to have something to observe.
14137
+ * exist and the observer has to have something to observe. The button
14138
+ * outlives a connection, so its listener goes under `signal`.
13850
14139
  */
13851
- mountScroller(jumpButton) {
13852
- jumpButton.addEventListener("click", () => {
13853
- this.jump();
13854
- });
14140
+ mountScroller(jumpButton, signal) {
14141
+ jumpButton.addEventListener(
14142
+ "click",
14143
+ () => {
14144
+ this.jump();
14145
+ },
14146
+ { signal }
14147
+ );
13855
14148
  this.#scroller = createStickToBottom({
13856
14149
  viewport: this.#host.messages,
13857
14150
  onMissedContent: (missed) => {
@@ -14238,6 +14531,9 @@ import {
14238
14531
  buildResumeArray,
14239
14532
  randomUUID as randomUUID4
14240
14533
  } from "@ag-ui/client";
14534
+ import {
14535
+ contentToText as contentToText2
14536
+ } from "@ag-ui/core";
14241
14537
  var ConnectionLostError = class extends Error {
14242
14538
  constructor(message) {
14243
14539
  super(message);
@@ -14258,29 +14554,6 @@ var AgUiClient = class {
14258
14554
  * set would miss entirely.
14259
14555
  */
14260
14556
  #closedMessageIds = /* @__PURE__ */ new Set();
14261
- /**
14262
- * How each tool call ended, keyed by call id, for the transcript this client
14263
- * persists.
14264
- *
14265
- * A side table rather than a field written onto the message, because neither
14266
- * producer of a tool message will carry it. `@ag-ui/client` builds the
14267
- * server-side one by destructuring five named fields off the event, so an
14268
- * `outcome` beside them is dropped before the message exists; and writing it
14269
- * back onto that message afterwards would put it in `agent.messages`, which is
14270
- * what the *next* request sends to the server. This keeps the annotation on
14271
- * the copy handed to the store and off the wire.
14272
- *
14273
- * Per client, not per run: `saveMessages` rewrites the whole transcript on
14274
- * every persist, so an outcome recorded in round one has to still be here in
14275
- * round five or the earlier card silently reverts to a green one. Bounded by
14276
- * the number of tool calls in the conversation, which the transcript beside it
14277
- * already is.
14278
- *
14279
- * Values are `unknown` because a restored seed fills it too (see
14280
- * {@link #adoptSeededOutcomes}), and a store is not trusted to hold only the
14281
- * words this class writes: whatever it held is written back as it was.
14282
- */
14283
- #outcomes = /* @__PURE__ */ new Map();
14284
14557
  #connectionLostMessage;
14285
14558
  #unfinishedMessage;
14286
14559
  #declinedMessage;
@@ -14302,7 +14575,7 @@ var AgUiClient = class {
14302
14575
  this.#declinedMessage = config.declinedMessage ?? "User declined the action.";
14303
14576
  const rounds = config.maxToolRounds ?? MAX_TOOL_ROUNDS;
14304
14577
  this.#maxToolRounds = rounds >= 1 ? Math.floor(rounds) : MAX_TOOL_ROUNDS;
14305
- this.#adoptSeededOutcomes();
14578
+ this.#moveSeededKeysIntoMetadata();
14306
14579
  const onStateChanged = config.onStateChanged;
14307
14580
  if (onStateChanged !== void 0) {
14308
14581
  this.#agent.subscribe({
@@ -14336,15 +14609,18 @@ var AgUiClient = class {
14336
14609
  * tools (bounded by {@link AgUiClientConfig.maxToolRounds}, which defaults to
14337
14610
  * {@link MAX_TOOL_ROUNDS}).
14338
14611
  *
14339
- * `attachments` ride on the user message as a non-standard field so the
14340
- * default store round-trips them for history replay; see
14612
+ * `attachments` ride in the user message's `metadata`, under
14613
+ * `attachments`, which is how the server learns which files the agent can
14614
+ * read and how the default store round-trips them for history replay; see
14341
14615
  * {@link messageAttachments}.
14342
14616
  */
14343
14617
  async send(content, attachments = []) {
14344
- const message = { id: randomUUID4(), role: "user", content };
14345
- if (attachments.length > 0) {
14346
- message.attachments = attachments;
14347
- }
14618
+ const message = {
14619
+ id: randomUUID4(),
14620
+ role: "user",
14621
+ content,
14622
+ ...attachments.length > 0 ? { metadata: { attachments } } : {}
14623
+ };
14348
14624
  this.#agent.addMessage(message);
14349
14625
  this.#persist();
14350
14626
  await this.#run();
@@ -14430,36 +14706,31 @@ var AgUiClient = class {
14430
14706
  this.#handlers.onCancelled();
14431
14707
  }
14432
14708
  /**
14433
- * Move the outcome annotations a restored history carries off the agent's
14434
- * messages and into {@link #outcomes}.
14709
+ * Move the keys a history stored by an earlier release carries at the top
14710
+ * level of its messages into their `metadata`, where this release writes them.
14435
14711
  *
14436
- * A restore seeds the agent from the stored copy, and the stored copy is the
14437
- * annotated one {@link #persist} wrote. Left on `agent.messages`, the
14438
- * annotation went out on the very next request -- the one place it was
14439
- * promised never to go. Moved rather than dropped: the store keeps the whole
14440
- * transcript as one list, so the next save has to write each annotation back
14441
- * or a declined card turns green on the reload after.
14712
+ * Earlier releases wrote a tool message's `outcome` and a user message's
14713
+ * `attachments` beside the protocol's own fields. `@ag-ui/client` 1.0 strips
14714
+ * every undeclared key from the input it sends, so a restored conversation
14715
+ * sent as it was stored would lose both on its first request: the server
14716
+ * would no longer be told about any file attached before the upgrade, and
14717
+ * each strip would print a warning. Moved rather than dropped, so the next
14718
+ * save writes the conversation in the shape this release reads first and a
14719
+ * reload after it still replays a declined card as declined.
14442
14720
  *
14443
- * `ag_ui_chat_restored_outcome_wire.test.ts` holds the move, off the body of a
14444
- * real request. The early return only spares the copy for a seed with nothing
14445
- * to move, and the role check is held by the type checker: only a tool message
14446
- * has the `toolCallId` the annotation is keyed by.
14721
+ * Merged into the metadata a message already has, with a key already there
14722
+ * winning: a message carrying both was last written by the newer writer.
14723
+ * `ag_ui_chat_restored_outcome_wire.test.ts` reads the result off the body of
14724
+ * a real request. The check before `setMessages` only spares a copy when
14725
+ * nothing moves, which is every restore of a store this release wrote;
14726
+ * nothing observable depends on it.
14447
14727
  */
14448
- #adoptSeededOutcomes() {
14728
+ #moveSeededKeysIntoMetadata() {
14449
14729
  const seeded = this.#agent.messages;
14450
- if (!seeded.some((message) => "outcome" in message)) {
14451
- return;
14730
+ const moved = seeded.map(withTopLevelKeysInMetadata);
14731
+ if (moved.some((message, index) => message !== seeded[index])) {
14732
+ this.#agent.setMessages(moved);
14452
14733
  }
14453
- this.#agent.setMessages(
14454
- seeded.map((message) => {
14455
- if (message.role !== "tool") {
14456
- return message;
14457
- }
14458
- const { outcome, ...wire } = message;
14459
- this.#outcomes.set(message.toolCallId, outcome);
14460
- return wire;
14461
- })
14462
- );
14463
14734
  }
14464
14735
  /**
14465
14736
  * Give every tool call in history a result, before a request carries it.
@@ -14476,17 +14747,21 @@ var AgUiClient = class {
14476
14747
  * approval runs or denies them server-side, and a result here would answer
14477
14748
  * them twice.
14478
14749
  *
14479
- * The labels go to {@link #outcomes}, never onto the messages, because these
14480
- * messages are the request.
14750
+ * The outcome rides in the result's `metadata`, where the client folds a
14751
+ * server's own, so the next request carries it and a reload replays it. A
14752
+ * server that does not read it ignores it: `metadata` is a declared field.
14481
14753
  */
14482
14754
  #answerUnansweredCalls(resuming) {
14483
14755
  const messages = this.#agent.messages;
14484
14756
  const answered = answerUnansweredCalls(
14485
14757
  messages,
14486
- (toolCallId) => {
14487
- this.#outcomes.set(toolCallId, TOOL_OUTCOME.INTERRUPTED);
14488
- return { id: randomUUID4(), role: "tool", content: this.#unfinishedMessage, toolCallId };
14489
- },
14758
+ (toolCallId) => ({
14759
+ id: randomUUID4(),
14760
+ role: "tool",
14761
+ content: this.#unfinishedMessage,
14762
+ toolCallId,
14763
+ metadata: { outcome: TOOL_OUTCOME.INTERRUPTED }
14764
+ }),
14490
14765
  resuming
14491
14766
  );
14492
14767
  if (answered !== messages) {
@@ -14513,40 +14788,43 @@ var AgUiClient = class {
14513
14788
  for (const interrupt of interrupts) {
14514
14789
  const toolCallId = interrupt.toolCallId;
14515
14790
  if (toolCallId !== void 0 && responses[interrupt.id]?.status === "cancelled") {
14516
- this.#outcomes.set(toolCallId, TOOL_OUTCOME.DENIED);
14517
14791
  this.#agent.addMessage({
14518
14792
  id: randomUUID4(),
14519
14793
  role: "tool",
14520
14794
  content: this.#declinedMessage,
14521
- toolCallId
14795
+ toolCallId,
14796
+ metadata: { outcome: TOOL_OUTCOME.DENIED }
14522
14797
  });
14523
14798
  }
14524
14799
  }
14525
14800
  this.#persist();
14526
14801
  }
14527
14802
  /**
14528
- * Hand the transcript to the host's store, annotated with what {@link #outcomes}
14529
- * knows about how each tool call ended.
14803
+ * Hand the transcript to the host's store.
14530
14804
  *
14531
- * Every persist in this class goes through here, because the store keeps only
14532
- * the most recent list: annotating one call site would mean the next
14533
- * unannotated save quietly threw the annotations away.
14805
+ * The list as the agent holds it, with nothing added: how each tool call
14806
+ * ended rides in its result's `metadata`, which the client folds in from a
14807
+ * server's `TOOL_CALL_RESULT` and this class writes for the results it makes
14808
+ * itself, so the store sees exactly what the next request sends.
14534
14809
  */
14535
14810
  #persist() {
14536
- const messages = this.#agent.messages;
14537
- if (this.#outcomes.size === 0) {
14538
- this.#onPersist(messages);
14539
- return;
14540
- }
14541
- this.#onPersist(
14542
- messages.map((message) => {
14543
- if (message.role !== "tool") {
14544
- return message;
14545
- }
14546
- const outcome = this.#outcomes.get(message.toolCallId);
14547
- return outcome === void 0 ? message : { ...message, outcome };
14548
- })
14549
- );
14811
+ this.#onPersist(this.#agent.messages);
14812
+ }
14813
+ /**
14814
+ * The history in the form a save writes it, which is now {@link messages}
14815
+ * itself.
14816
+ *
14817
+ * It differed while this client kept how each tool call ended in a side table
14818
+ * and annotated a copy for the store, because `@ag-ui/client` 0.x kept nothing
14819
+ * but five named fields of a result. 1.0 folds a result's `metadata` onto the
14820
+ * message it appends, so the outcome is on the message and there is no copy
14821
+ * left to make.
14822
+ *
14823
+ * @deprecated Read {@link messages}. Kept so a caller written against the
14824
+ * getter keeps compiling and gets the same list.
14825
+ */
14826
+ get annotatedMessages() {
14827
+ return this.messages;
14550
14828
  }
14551
14829
  async #runLoop() {
14552
14830
  let resume;
@@ -14606,14 +14884,12 @@ var AgUiClient = class {
14606
14884
  if (result.halt === true) {
14607
14885
  return;
14608
14886
  }
14609
- if (result.outcome !== void 0) {
14610
- this.#outcomes.set(call.id, result.outcome);
14611
- }
14612
14887
  this.#agent.addMessage({
14613
14888
  id: randomUUID4(),
14614
14889
  role: "tool",
14615
14890
  content: result.content,
14616
- toolCallId: call.id
14891
+ toolCallId: call.id,
14892
+ ...result.outcome === void 0 ? {} : { metadata: { outcome: result.outcome } }
14617
14893
  });
14618
14894
  this.#persist();
14619
14895
  executed = true;
@@ -14626,7 +14902,6 @@ var AgUiClient = class {
14626
14902
  #buildSubscriber(pending, runState) {
14627
14903
  const h = this.#handlers;
14628
14904
  const closed = this.#closedMessageIds;
14629
- const outcomes = this.#outcomes;
14630
14905
  const cancelled = () => this.#cancelled;
14631
14906
  const pendingDeltas = /* @__PURE__ */ new Set();
14632
14907
  return {
@@ -14657,11 +14932,8 @@ var AgUiClient = class {
14657
14932
  h.onToolCall(call);
14658
14933
  },
14659
14934
  onToolCallResultEvent({ event }) {
14660
- const outcome = event["outcome"];
14661
- if (typeof outcome === "string") {
14662
- outcomes.set(event.toolCallId, outcome);
14663
- }
14664
- h.onToolResult(event.toolCallId, event.content, outcome);
14935
+ const outcome = event.metadata?.["outcome"];
14936
+ h.onToolResult(event.toolCallId, contentToText2(event.content), outcome);
14665
14937
  },
14666
14938
  onActivitySnapshotEvent({ event, messages }) {
14667
14939
  const known = messages.some(
@@ -14719,9 +14991,11 @@ var AgUiClient = class {
14719
14991
  }
14720
14992
  pendingDeltas.clear();
14721
14993
  },
14722
- // `@ag-ui/client` maps the deprecated THINKING_* events onto these
14723
- // REASONING_* callbacks, so the reasoning family alone covers both
14724
- // protocol versions.
14994
+ // THINKING_* left the protocol in its 1.0, but `@ag-ui/client` still
14995
+ // converts a server's THINKING_* events onto these REASONING_* callbacks,
14996
+ // with a console warning, for a deprecation window it sets. Nothing in the
14997
+ // family emits THINKING_*: pydantic-ai has sent REASONING_* at every
14998
+ // protocol version django-ag-ui admits.
14725
14999
  onReasoningStartEvent() {
14726
15000
  h.onReasoningStart();
14727
15001
  },
@@ -14768,6 +15042,22 @@ function isAbortError(error) {
14768
15042
  }
14769
15043
  return error.name === "AbortError" || error instanceof TypeError && /abort/i.test(error.message);
14770
15044
  }
15045
+ function withTopLevelKeysInMetadata(message) {
15046
+ const { outcome, attachments, ...wire } = message;
15047
+ if (outcome === void 0 && attachments === void 0) {
15048
+ return message;
15049
+ }
15050
+ const existing = wire.metadata;
15051
+ return {
15052
+ ...wire,
15053
+ metadata: {
15054
+ ...outcome === void 0 ? {} : { outcome },
15055
+ ...attachments === void 0 ? {} : { attachments },
15056
+ // `null` passes the check and spreads as nothing, which is what it means.
15057
+ ...typeof existing === "object" ? existing : {}
15058
+ }
15059
+ };
15060
+ }
14771
15061
 
14772
15062
  // src/core/conversation_store.ts
14773
15063
  import { randomUUID as randomUUID5 } from "@ag-ui/client";
@@ -15771,6 +16061,8 @@ var AgUiChat = class extends HTMLElement {
15771
16061
  * Optional full replacement for the `ask_user` question UI, resolving with
15772
16062
  * the answer; the same seam as {@link approvalRenderer}, styled via `strings`
15773
16063
  * and the `question*` `::part()`s when left unset. Requires {@link askUser}.
16064
+ * A renderer that throws or rejects hands the question to the built-in card,
16065
+ * as a failing {@link approvalRenderer} does, unless Stop already fired.
15774
16066
  */
15775
16067
  askUserRenderer = null;
15776
16068
  /**
@@ -16075,10 +16367,37 @@ var AgUiChat = class extends HTMLElement {
16075
16367
  #voice;
16076
16368
  /** Whether the element is currently in the DOM; gates the connect-time warning. */
16077
16369
  #connected = false;
16370
+ /**
16371
+ * Aborted when the element leaves the document, and replaced when it comes
16372
+ * back.
16373
+ *
16374
+ * Every listener connecting adds to an element that outlives the connection
16375
+ * -- the composer, Send, the launcher, the shell -- is added under this
16376
+ * signal. Connecting runs again on every insertion, so a listener added
16377
+ * without it is a second listener the next time: one click on Stop stopped
16378
+ * the run three times, and one press of the built-in theme toggle flipped it
16379
+ * twice, back to where it started.
16380
+ */
16381
+ #connection = new AbortController();
16382
+ /**
16383
+ * Whether the element has connected before, which makes this connection a
16384
+ * re-insertion: there is a transcript on screen from last time, and the
16385
+ * history replay would draw the conversation a second time beneath it.
16386
+ */
16387
+ #connectedBefore = false;
16388
+ /**
16389
+ * The remote store `data-threads-url` wrapped around the conversation store,
16390
+ * and the store inside it, so connecting again can wrap that store rather
16391
+ * than the wrapper.
16392
+ */
16393
+ #threadStore = null;
16078
16394
  #client = null;
16079
16395
  // Seed for the next client. Once one exists it owns the live value (the
16080
16396
  // agent applies STATE_SNAPSHOT / STATE_DELTA into it), so this is only the
16081
- // starting point — `sharedState` reads through to the client when present.
16397
+ // starting point — `sharedState` reads through to the client when present,
16398
+ // and to a running checkpoint continuation before that. Every client mirrors
16399
+ // its changes here, which is what the client built after a continuation is
16400
+ // seeded from.
16082
16401
  #sharedState = {};
16083
16402
  // Whether an interaction is in flight (first onRunStart → onSettled). Drives
16084
16403
  // the Send⇄Stop button: `agent.isRunning` is false between frontend-tool
@@ -16285,7 +16604,9 @@ var AgUiChat = class extends HTMLElement {
16285
16604
  }
16286
16605
  });
16287
16606
  this.#checkpoints = new CheckpointMenu((runId, verb) => {
16288
- void this.#history.continueRun(runId, verb);
16607
+ void this.#history.continueRun(runId, verb).catch((error) => {
16608
+ console.warn("<ag-ui-chat>: continuing a run failed", error);
16609
+ });
16289
16610
  });
16290
16611
  this.#history = new ConversationHistory({
16291
16612
  element: this,
@@ -16305,8 +16626,14 @@ var AgUiChat = class extends HTMLElement {
16305
16626
  requestCredentials: () => this.#requestCredentials(),
16306
16627
  appendMessage: (role, content) => this.appendMessage(role, content),
16307
16628
  autoGrow: () => autoGrow(this.#input),
16629
+ continuationEnded: () => this.#flushQueued(),
16630
+ client: () => this.#client,
16308
16631
  ensureClient: () => this.#ensureClient(),
16309
16632
  buildClient: (seed) => this.#buildClient(seed),
16633
+ releaseClient: () => {
16634
+ this.#client = null;
16635
+ },
16636
+ running: () => this.#running,
16310
16637
  cancelRun: () => this.#cancelRun(),
16311
16638
  resetState: () => this.#resetState(),
16312
16639
  setRunning: (running) => this.#setRunning(running)
@@ -16388,11 +16715,32 @@ var AgUiChat = class extends HTMLElement {
16388
16715
  * from {@link registerPageState}, which exposes host state as ordinary tools.
16389
16716
  */
16390
16717
  get sharedState() {
16391
- return this.#client?.state ?? this.#sharedState;
16718
+ return this.#liveClient()?.state ?? this.#sharedState;
16392
16719
  }
16393
16720
  set sharedState(state) {
16394
16721
  this.#sharedState = { ...state };
16395
- this.#client?.setState(this.#sharedState);
16722
+ this.#liveClient()?.setState(this.#sharedState);
16723
+ }
16724
+ /**
16725
+ * The client holding the conversation's live shared state: a checkpoint
16726
+ * continuation while one runs, otherwise the conversation's own client, and
16727
+ * `null` before either exists.
16728
+ *
16729
+ * The continuation first, because the state it streams is applied to its own
16730
+ * agent. Reading the conversation's client alone returned what the state was
16731
+ * before the continuation began, for as long as that client lived.
16732
+ *
16733
+ * It now lives no longer than the continuation's first save, which hands the
16734
+ * conversation to the next client built, seeded from the mirror every client
16735
+ * writes -- so the next run sends what the continuation left. That release
16736
+ * alone makes the getter's fallback give the same answer, and no test can
16737
+ * tell the two apart; reading the continuation keeps the getter right
16738
+ * without depending on when the other client is let go. The setter has no
16739
+ * such fallback, and is held by "reads the shared state it changed while it
16740
+ * runs, not the conversation's" in `ag_ui_chat_checkpoints.test.ts`.
16741
+ */
16742
+ #liveClient() {
16743
+ return this.#history.continuation ?? this.#client;
16396
16744
  }
16397
16745
  /** Bind a piece of host page state to `read_<name>` / `set_<name>` tools. */
16398
16746
  registerPageState(binding) {
@@ -16569,6 +16917,11 @@ var AgUiChat = class extends HTMLElement {
16569
16917
  this.setAttribute("data-tool-display", value);
16570
16918
  }
16571
16919
  connectedCallback() {
16920
+ this.#connection = new AbortController();
16921
+ if (this.#connectedBefore) {
16922
+ this.#resetConversation();
16923
+ }
16924
+ this.#connectedBefore = true;
16572
16925
  this.#storage.claim();
16573
16926
  this.#placement.restoreSize();
16574
16927
  requestAnimationFrame(() => {
@@ -16590,13 +16943,13 @@ var AgUiChat = class extends HTMLElement {
16590
16943
  }
16591
16944
  this.#syncLauncher();
16592
16945
  this.#skills.init();
16593
- this.conversationStore = this.#storage.scopeStore(this.conversationStore, this.userKey);
16946
+ this.conversationStore = this.#storage.scopeStore(this.#unwrappedStore(), this.userKey);
16594
16947
  window.addEventListener("resize", this.#onViewportResize);
16595
16948
  window.visualViewport?.addEventListener("resize", this.#onViewportResize);
16596
16949
  window.visualViewport?.addEventListener("scroll", this.#onViewportResize);
16597
16950
  this.#placement.publishVisualViewport();
16598
16951
  this.#wireThreadStore();
16599
- this.#attachments.wire();
16952
+ this.#attachments.wire(this.#connection.signal);
16600
16953
  this.#voice.wire();
16601
16954
  this.#history.adoptActiveThread();
16602
16955
  queueMicrotask(() => this.#startup());
@@ -16661,6 +17014,7 @@ var AgUiChat = class extends HTMLElement {
16661
17014
  */
16662
17015
  disconnectedCallback() {
16663
17016
  this.#connected = false;
17017
+ this.#connection.abort();
16664
17018
  window.removeEventListener("resize", this.#onViewportResize);
16665
17019
  window.visualViewport?.removeEventListener("resize", this.#onViewportResize);
16666
17020
  window.visualViewport?.removeEventListener("scroll", this.#onViewportResize);
@@ -16768,17 +17122,34 @@ var AgUiChat = class extends HTMLElement {
16768
17122
  * thread id, the navigation checkpoint) keep their local store either way.
16769
17123
  */
16770
17124
  #wireThreadStore() {
17125
+ this.#threadStore = null;
16771
17126
  const url = this.getAttribute("data-threads-url");
16772
17127
  if (url !== null) {
16773
- this.conversationStore = new RemoteConversationStore(
17128
+ const inner = this.conversationStore;
17129
+ const remote = new RemoteConversationStore(
16774
17130
  url,
16775
17131
  () => this.#headersFor(url),
16776
- this.conversationStore,
17132
+ inner,
16777
17133
  () => this.#requestCredentials(),
16778
17134
  this.getAttribute("data-threads-cache") !== "false"
16779
17135
  );
17136
+ this.#threadStore = { remote, inner };
17137
+ this.conversationStore = remote;
16780
17138
  }
16781
17139
  }
17140
+ /**
17141
+ * The conversation store without the remote this element wrapped it in.
17142
+ *
17143
+ * An element removed and inserted again connects again, and wrapping the
17144
+ * wrapper stacked a second remote on the first, so every rename and delete
17145
+ * reached the server twice. Unwrapping first also lets a `data-threads-url`
17146
+ * removed while detached take the remote away. A store the host assigned
17147
+ * since is theirs, and comes back as it is.
17148
+ */
17149
+ #unwrappedStore() {
17150
+ const wrapped = this.#threadStore;
17151
+ return wrapped !== null && this.conversationStore === wrapped.remote ? wrapped.inner : this.conversationStore;
17152
+ }
16782
17153
  /**
16783
17154
  * Replace the host-supplied (client) skill catalog. Merged after the embedded
16784
17155
  * and fetched skills (so a client skill overrides a same-named server one).
@@ -17020,12 +17391,22 @@ var AgUiChat = class extends HTMLElement {
17020
17391
  }
17021
17392
  /** Drop the in-memory run + transcript, leaving the thread id untouched. */
17022
17393
  #resetState() {
17394
+ this.#resetConversation();
17395
+ this.#sentDrafts.length = 0;
17396
+ this.#recallIndex = null;
17397
+ }
17398
+ /**
17399
+ * Drop the in-memory run and transcript, and nothing the user typed.
17400
+ *
17401
+ * Split from {@link #resetState} for re-insertion, which rebuilds the
17402
+ * conversation from history but is not a new one, so the composer's recall
17403
+ * history stays.
17404
+ */
17405
+ #resetConversation() {
17023
17406
  this.#client = null;
17024
17407
  this.#runHandlers.detach();
17025
17408
  this.#clearTranscript();
17026
17409
  this.#history.forgetRestored();
17027
- this.#sentDrafts.length = 0;
17028
- this.#recallIndex = null;
17029
17410
  }
17030
17411
  /**
17031
17412
  * Wipe the rendered transcript and everything that indexes into it.
@@ -17091,7 +17472,19 @@ var AgUiChat = class extends HTMLElement {
17091
17472
  appendMessage(role, content) {
17092
17473
  return this.#transcript.append(role, content);
17093
17474
  }
17475
+ /**
17476
+ * Build the chrome, from the attributes as they stand.
17477
+ *
17478
+ * Runs on every connect, not once, because removing and re-inserting the
17479
+ * element is the documented way to apply a connect-time attribute written
17480
+ * late. So it has to build the same element the second time as the first:
17481
+ * the elements made here are new each time, the long-lived ones it fills
17482
+ * are filled with `replaceChildren` rather than appended to, and every
17483
+ * listener on a long-lived one goes under the connection's signal. Appending
17484
+ * gave a re-inserted element two headers and two composers.
17485
+ */
17094
17486
  #render() {
17487
+ const { signal } = this.#connection;
17095
17488
  this.#chat.className = "chat";
17096
17489
  this.#chat.setAttribute("part", "panel");
17097
17490
  const header = document.createElement("div");
@@ -17128,7 +17521,7 @@ var AgUiChat = class extends HTMLElement {
17128
17521
  this.#themeToggle.setAttribute("part", "header-button theme-toggle");
17129
17522
  this.#themeToggle.title = this.#strings.toggleTheme;
17130
17523
  this.#themeToggle.setAttribute("aria-label", this.#strings.toggleTheme);
17131
- this.#themeToggle.addEventListener("click", () => this.toggleTheme());
17524
+ this.#themeToggle.addEventListener("click", () => this.toggleTheme(), { signal });
17132
17525
  this.#syncThemeGlyph();
17133
17526
  controls.append(this.#themeToggle);
17134
17527
  }
@@ -17144,8 +17537,8 @@ var AgUiChat = class extends HTMLElement {
17144
17537
  this.#jumpButton.type = "button";
17145
17538
  this.#jumpButton.setAttribute("part", "jump-latest");
17146
17539
  this.#jumpButton.textContent = this.#strings.jumpToLatest;
17147
- this.#excerpts.mount();
17148
- this.#transcript.mountScroller(this.#jumpButton);
17540
+ this.#excerpts.mount(signal);
17541
+ this.#transcript.mountScroller(this.#jumpButton, signal);
17149
17542
  this.#announcer.mount();
17150
17543
  this.#emptyWrap.className = "empty";
17151
17544
  this.#emptyWrap.setAttribute("part", "empty");
@@ -17157,7 +17550,6 @@ var AgUiChat = class extends HTMLElement {
17157
17550
  greetingSlot.append(this.#greetingText);
17158
17551
  greeting.append(greetingSlot);
17159
17552
  this.#syncGreeting();
17160
- this.#emptyWrap.append(greeting);
17161
17553
  const emptySlot = document.createElement("slot");
17162
17554
  emptySlot.name = "empty";
17163
17555
  const starters = renderStarterChips(this, this.#strings, (prompt) => {
@@ -17166,7 +17558,7 @@ var AgUiChat = class extends HTMLElement {
17166
17558
  if (starters !== null) {
17167
17559
  emptySlot.append(starters);
17168
17560
  }
17169
- this.#emptyWrap.append(emptySlot);
17561
+ this.#emptyWrap.replaceChildren(greeting, emptySlot);
17170
17562
  this.#queuedRow.className = "queued";
17171
17563
  this.#queuedRow.setAttribute("part", "queued");
17172
17564
  this.#queuedRow.setAttribute("role", "group");
@@ -17188,41 +17580,47 @@ var AgUiChat = class extends HTMLElement {
17188
17580
  this.#input.setAttribute("aria-label", this.#strings.message);
17189
17581
  this.#input.rows = 1;
17190
17582
  this.#input.placeholder = this.#strings.inputPlaceholder;
17191
- this.#input.addEventListener("keydown", (event) => this.#onKeydown(event));
17192
- this.#input.addEventListener("input", () => this.#onInput());
17583
+ this.#input.addEventListener("keydown", (event) => this.#onKeydown(event), { signal });
17584
+ this.#input.addEventListener("input", () => this.#onInput(), { signal });
17193
17585
  this.#send.className = "send";
17194
17586
  this.#send.type = "button";
17195
17587
  this.#send.setAttribute("part", "send");
17196
- this.#send.append(
17588
+ this.#send.replaceChildren(
17197
17589
  glyphSlot("icon-send", "send-send", ICON_SEND),
17198
17590
  glyphSlot("icon-stop", "send-stop", ICON_STOP)
17199
17591
  );
17200
17592
  this.#send.title = this.#strings.send;
17201
17593
  this.#send.setAttribute("aria-label", this.#strings.send);
17202
17594
  this.#send.dataset["state"] = "idle";
17203
- this.#send.addEventListener("click", () => {
17204
- if (this.#running) {
17205
- this.#cancelRun();
17206
- return;
17207
- }
17208
- void this.#submit();
17209
- });
17595
+ this.#send.addEventListener(
17596
+ "click",
17597
+ () => {
17598
+ if (this.#running) {
17599
+ this.#cancelRun();
17600
+ return;
17601
+ }
17602
+ void this.#submit();
17603
+ },
17604
+ { signal }
17605
+ );
17210
17606
  this.#composerHint.className = "skill-hint";
17211
17607
  this.#composerHint.setAttribute("part", "skill-hint");
17212
17608
  this.#composerHint.hidden = true;
17213
17609
  this.#attachButton.className = "attach-btn";
17214
17610
  this.#attachButton.type = "button";
17215
17611
  this.#attachButton.setAttribute("part", "attach-button");
17216
- this.#attachButton.append(glyphSlot("icon-attach", "attach-glyph", ICON_ATTACH));
17612
+ this.#attachButton.replaceChildren(glyphSlot("icon-attach", "attach-glyph", ICON_ATTACH));
17217
17613
  this.#attachButton.title = this.#strings.attachFiles;
17218
17614
  this.#attachButton.setAttribute("aria-label", this.#strings.attachFiles);
17219
17615
  this.#attachButton.hidden = true;
17220
- this.#attachButton.addEventListener("click", () => this.#fileInput.click());
17616
+ this.#attachButton.addEventListener("click", () => this.#fileInput.click(), { signal });
17221
17617
  this.#fileInput.className = "attach-input";
17222
17618
  this.#fileInput.type = "file";
17223
17619
  this.#fileInput.multiple = true;
17224
17620
  this.#fileInput.hidden = true;
17225
- this.#fileInput.addEventListener("change", () => this.#attachments.onFilesPicked());
17621
+ this.#fileInput.addEventListener("change", () => this.#attachments.onFilesPicked(), {
17622
+ signal
17623
+ });
17226
17624
  this.#attachSlot.className = "attachment-slot";
17227
17625
  this.#voiceSlot.className = "voice-slot";
17228
17626
  const footer = document.createElement("slot");
@@ -17231,8 +17629,8 @@ var AgUiChat = class extends HTMLElement {
17231
17629
  composer.append(this.#input, tools);
17232
17630
  inputRow.append(composer, this.#fileInput);
17233
17631
  this.#messagesWrap.className = "messages-wrap";
17234
- this.#messagesWrap.append(this.#messages, this.#jumpButton, this.#excerpts.button);
17235
- this.#chat.append(
17632
+ this.#messagesWrap.replaceChildren(this.#messages, this.#jumpButton, this.#excerpts.button);
17633
+ this.#chat.replaceChildren(
17236
17634
  header,
17237
17635
  this.#messagesWrap,
17238
17636
  this.#skillsMenu.palette,
@@ -17245,16 +17643,20 @@ var AgUiChat = class extends HTMLElement {
17245
17643
  this.#drawer.element,
17246
17644
  this.#checkpoints.element
17247
17645
  );
17248
- this.#chat.addEventListener("pointerdown", (event) => {
17249
- if (!this.#checkpoints.open_) {
17250
- return;
17251
- }
17252
- const path = event.composedPath();
17253
- if (path.includes(this.#checkpoints.element) || path.includes(checkpoints)) {
17254
- return;
17255
- }
17256
- this.#checkpoints.close();
17257
- });
17646
+ this.#chat.addEventListener(
17647
+ "pointerdown",
17648
+ (event) => {
17649
+ if (!this.#checkpoints.open_) {
17650
+ return;
17651
+ }
17652
+ const path = event.composedPath();
17653
+ if (path.includes(this.#checkpoints.element) || path.includes(checkpoints)) {
17654
+ return;
17655
+ }
17656
+ this.#checkpoints.close();
17657
+ },
17658
+ { signal }
17659
+ );
17258
17660
  this.#launcher.className = "launcher";
17259
17661
  this.#launcher.type = "button";
17260
17662
  this.#launcher.setAttribute("part", "launcher");
@@ -17267,19 +17669,19 @@ var AgUiChat = class extends HTMLElement {
17267
17669
  this.#railLabel.setAttribute("part", "rail-label");
17268
17670
  this.#railLabel.setAttribute("aria-hidden", "true");
17269
17671
  this.#railLabel.textContent = this.getAttribute("title-text") ?? this.#strings.title;
17270
- this.#launcher.append(
17672
+ this.#launcher.replaceChildren(
17271
17673
  iconElement("launcher", "launcher-icon", ICON_LAUNCHER, readLauncherIconUrl(this)),
17272
17674
  this.#railLabel,
17273
17675
  this.#badge
17274
17676
  );
17275
- this.#launcher.addEventListener("click", () => this.setCollapsed(false));
17276
- this.#placement.enableLauncherDrag();
17677
+ this.#launcher.addEventListener("click", () => this.setCollapsed(false), { signal });
17678
+ this.#placement.enableLauncherDrag(signal);
17277
17679
  this.#placement.mountResizeGrips(this.#chat);
17278
17680
  adoptStyles(this.#root);
17279
17681
  const probe = this.#placement.probe;
17280
17682
  probe.className = "viewport-probe";
17281
17683
  probe.setAttribute("aria-hidden", "true");
17282
- this.#root.append(probe, this.#announcer.region, this.#chat, this.#launcher);
17684
+ this.#root.replaceChildren(probe, this.#announcer.region, this.#chat, this.#launcher);
17283
17685
  }
17284
17686
  /**
17285
17687
  * Reflect the collapsed state and the unread count on the launcher.
@@ -17434,6 +17836,9 @@ var AgUiChat = class extends HTMLElement {
17434
17836
  * other shape would be a second sender racing the guard above.
17435
17837
  */
17436
17838
  #flushQueued() {
17839
+ if (this.#running || this.#history.continuation !== null) {
17840
+ return;
17841
+ }
17437
17842
  const next = this.#queued.shift();
17438
17843
  this.#renderQueued();
17439
17844
  if (next !== void 0) {
@@ -17471,7 +17876,7 @@ var AgUiChat = class extends HTMLElement {
17471
17876
  if (content === "" && attachments.length === 0) {
17472
17877
  return;
17473
17878
  }
17474
- if (this.#running) {
17879
+ if (this.#running || this.#history.continuation !== null) {
17475
17880
  if (content !== "") {
17476
17881
  this.#queued.push(content);
17477
17882
  this.#renderQueued();
@@ -17509,12 +17914,14 @@ var AgUiChat = class extends HTMLElement {
17509
17914
  * `attachments` are durable {@link AttachmentRef}s — what {@link attachFile}
17510
17915
  * resolves to and what {@link ATTACHMENT_EVENT} reports.
17511
17916
  *
17512
- * No-ops on an empty message, and while a run is in flight, since a second
17513
- * concurrent run would orphan the first. Unlike the built-in Send it does not
17514
- * consult the tray: what you pass is what is sent.
17917
+ * No-ops on an empty message, and while a run or a picked checkpoint's
17918
+ * continuation is in flight, since a second concurrent run would orphan the
17919
+ * first. Unlike the built-in Send it does not queue: it returns, and the
17920
+ * caller keeps what it tried to send. Nor does it consult the tray -- what
17921
+ * you pass is what is sent.
17515
17922
  */
17516
17923
  async sendMessage(content, attachments = []) {
17517
- if (this.#running || content === "" && attachments.length === 0) {
17924
+ if (this.#running || this.#history.continuation !== null || content === "" && attachments.length === 0) {
17518
17925
  return;
17519
17926
  }
17520
17927
  if (this.#transcript.isEmpty()) {
@@ -17587,7 +17994,8 @@ var AgUiChat = class extends HTMLElement {
17587
17994
  this.#client = this.#buildClient({
17588
17995
  endpoint: this.endpoint,
17589
17996
  initialMessages: this.#history.restored,
17590
- persist: true
17997
+ // Its history is the whole conversation, so nothing goes ahead of it.
17998
+ follows: []
17591
17999
  });
17592
18000
  }
17593
18001
  return this.#client;
@@ -17624,9 +18032,15 @@ var AgUiChat = class extends HTMLElement {
17624
18032
  getContext: () => this.#dispatch.buildContext(),
17625
18033
  executeTool: (call) => this.#dispatch.execute(call),
17626
18034
  resolveInterrupts: (interrupts) => this.#dispatch.resolveInterrupts(interrupts),
17627
- ...seed.persist ? {
17628
- onPersist: (messages) => this.conversationStore.saveMessages(threadId, messages)
17629
- } : {},
18035
+ // Every client saves the whole conversation, because a store keeps one
18036
+ // list per thread. For the conversation's own client that is its
18037
+ // history; a continuation holds only what it adds, and writes the
18038
+ // conversation it continues ahead of that.
18039
+ onPersist: (messages) => {
18040
+ const conversation = [...seed.follows, ...messages];
18041
+ this.conversationStore.saveMessages(threadId, conversation);
18042
+ seed.onSaved?.(conversation);
18043
+ },
17630
18044
  onStateChanged: (state) => this.#onSharedStateChanged(state),
17631
18045
  connectionLostMessage: this.#strings.connectionLost,
17632
18046
  unfinishedMessage: this.#strings.callNotFinished,
@@ -17789,7 +18203,7 @@ function setControlValue(el2, value) {
17789
18203
  }
17790
18204
 
17791
18205
  // src/version.ts
17792
- var VERSION = "0.39.0";
18206
+ var VERSION = "0.41.0";
17793
18207
  export {
17794
18208
  ATTACHMENT_EVENT,
17795
18209
  AgUiChat,
@@ -17887,6 +18301,6 @@ export {
17887
18301
  /*! Bundled license information:
17888
18302
 
17889
18303
  dompurify/dist/purify.es.mjs:
17890
- (*! @license DOMPurify 3.4.14 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.14/LICENSE *)
18304
+ (*! @license DOMPurify 3.4.15 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.15/LICENSE *)
17891
18305
  */
17892
18306
  //# sourceMappingURL=index.js.map