@michengai/dsh-btw 0.1.23 → 1.0.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.
package/lib/client.js CHANGED
@@ -519,6 +519,7 @@ var zh = {
519
519
  "error.attachments": "\u65C1\u95EE\u53EA\u63A5\u53D7\u6587\u5B57\uFF0C\u56FE\u7247\u548C\u6587\u4EF6\u4ECD\u4FDD\u7559\u5728\u8F93\u5165\u6846\u4E2D\u3002",
520
520
  "error.removeAttachments": "\u65C1\u95EE\u53EA\u63A5\u53D7\u6587\u5B57\uFF0C\u8BF7\u5148\u79FB\u9664\u56FE\u7247\u548C\u6587\u4EF6\u3002",
521
521
  "error.backend": "BTW \u540E\u7AEF\u5C1A\u672A\u542F\u7528\uFF0C\u8BF7\u68C0\u67E5\u63D2\u4EF6\u914D\u7F6E\u3002",
522
+ "error.subagent": "\u5B50\u4EE3\u7406\u4F1A\u8BDD\u6682\u4E0D\u652F\u6301\u65C1\u95EE\uFF0C\u8BF7\u8FD4\u56DE\u4E3B\u4F1A\u8BDD\u4F7F\u7528 /btw\u3002",
522
523
  "error.empty": "\u8BF7\u8F93\u5165\u65C1\u95EE\u5185\u5BB9\u3002",
523
524
  "error.length": `\u65C1\u95EE\u6700\u591A\u652F\u6301 ${MAX_QUESTION_LENGTH} \u4E2A\u5B57\u7B26\u3002`,
524
525
  "error.capacity": "\u6B63\u5728\u5904\u7406\u7684\u65C1\u95EE\u8F83\u591A\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
@@ -572,6 +573,7 @@ var en = {
572
573
  "error.attachments": "Side questions accept text only. Your images and files remain in the input.",
573
574
  "error.removeAttachments": "Side questions accept text only. Remove the images and files first.",
574
575
  "error.backend": "The BTW backend is unavailable. Check the plugin configuration.",
576
+ "error.subagent": "Side questions are not supported in subagent sessions. Use /btw in the main session.",
575
577
  "error.empty": "Enter a side question.",
576
578
  "error.length": `Side questions are limited to ${MAX_QUESTION_LENGTH.toLocaleString("en-US")} characters.`,
577
579
  "error.capacity": "Too many side questions are running. Try again shortly.",
@@ -604,6 +606,8 @@ var CLOSE_COMMAND = "btw-close";
604
606
 
605
607
  // src/client/bubbles.ts
606
608
  var MAX_BUBBLES_PER_SESSION = 20;
609
+ var SideRequestNotStartedError = class extends Error {
610
+ };
607
611
  var BubbleStore = class {
608
612
  constructor(transport, t = translate()) {
609
613
  this.transport = transport;
@@ -613,6 +617,9 @@ var BubbleStore = class {
613
617
  listeners = /* @__PURE__ */ new Set();
614
618
  active = /* @__PURE__ */ new Map();
615
619
  closing = /* @__PURE__ */ new Map();
620
+ notStarted = /* @__PURE__ */ new Set();
621
+ runEnd = /* @__PURE__ */ new Map();
622
+ closeFenced = /* @__PURE__ */ new Set();
616
623
  admitting = /* @__PURE__ */ new Set();
617
624
  disposed = false;
618
625
  getSnapshot = () => this.snapshot;
@@ -649,12 +656,43 @@ var BubbleStore = class {
649
656
  const id = crypto.randomUUID();
650
657
  const controller = new AbortController();
651
658
  this.active.set(id, controller);
659
+ this.runEnd.set(id, "pending");
652
660
  this.publish([...this.snapshot, { id, sessionId, question, ...reference === void 0 ? {} : { reference }, answer: "", phase: "answering" }]);
653
661
  void Promise.resolve().then(() => reference === void 0 ? this.transport.run(sessionId, id, question, controller.signal) : this.transport.run(sessionId, id, question, controller.signal, reference)).then((result) => {
654
- if (controller.signal.aborted || this.closing.has(id)) return;
655
- this.update(id, { phase: result.kind === "success" ? "done" : "error", answer: result.kind === "success" ? result.text : "", error: result.kind === "error" ? result.text : void 0 });
662
+ if (result.kind === "success") {
663
+ this.runEnd.set(id, "success");
664
+ if (!this.snapshot.some((item) => item.id === id)) return;
665
+ const failedClose = this.closeFenced.has(id) || Boolean(this.snapshot.find((item) => item.id === id)?.closeFailed);
666
+ this.update(id, { phase: failedClose ? "error" : this.closing.has(id) ? "closing" : "done", answer: result.text, ...failedClose ? {} : { error: void 0 } });
667
+ return;
668
+ }
669
+ if (controller.signal.aborted) {
670
+ if (this.runEnd.get(id) === "pending") this.runEnd.set(id, "aborted");
671
+ this.dropIfCloseCannotFinish(id);
672
+ return;
673
+ }
674
+ this.runEnd.set(id, "failed");
675
+ if (!this.closing.has(id)) this.update(id, { phase: "error", answer: "", error: result.text });
656
676
  }).catch((error) => {
657
- if (!controller.signal.aborted && !this.closing.has(id)) this.update(id, { phase: "error", error: String(error) });
677
+ if (this.runEnd.get(id) === "success") return;
678
+ const message = error instanceof Error ? error.message : String(error);
679
+ if (error instanceof SideRequestNotStartedError && this.snapshot.some((item) => item.id === id)) {
680
+ this.runEnd.set(id, "not-started");
681
+ this.notStarted.add(id);
682
+ if (this.closeFenced.has(id) || this.closing.has(id)) {
683
+ this.remove(id);
684
+ return;
685
+ }
686
+ this.update(id, { phase: "error", error: message });
687
+ return;
688
+ }
689
+ if (controller.signal.aborted) {
690
+ if (this.runEnd.get(id) === "pending") this.runEnd.set(id, "aborted");
691
+ this.dropIfCloseCannotFinish(id);
692
+ return;
693
+ }
694
+ this.runEnd.set(id, "failed");
695
+ if (!this.closing.has(id)) this.update(id, { phase: "error", error: message });
658
696
  }).finally(() => {
659
697
  this.active.delete(id);
660
698
  });
@@ -665,12 +703,28 @@ var BubbleStore = class {
665
703
  if (existing) return existing;
666
704
  const item = this.snapshot.find((bubble) => bubble.id === id);
667
705
  if (!item) return Promise.resolve();
706
+ if (this.notStarted.has(id)) {
707
+ this.remove(id);
708
+ return Promise.resolve();
709
+ }
668
710
  this.update(id, { phase: "closing", error: void 0, closeFailed: false });
669
711
  this.active.get(id)?.abort();
670
712
  const operation = Promise.resolve().then(() => this.transport.close(item.sessionId, id)).then((result) => {
671
713
  if (result.kind === "error") throw new Error(result.text);
672
- this.publish(this.snapshot.filter((bubble) => bubble.id !== id));
714
+ this.remove(id);
673
715
  }).catch((error) => {
716
+ if (this.notStarted.has(id) || this.runEnd.get(id) === "not-started") {
717
+ this.remove(id);
718
+ return;
719
+ }
720
+ if (error instanceof SideRequestNotStartedError) {
721
+ this.closeFenced.add(id);
722
+ const end = this.runEnd.get(id);
723
+ if (end === "aborted" || end === "not-started") {
724
+ this.remove(id);
725
+ return;
726
+ }
727
+ }
674
728
  this.update(id, { phase: "error", closeFailed: true, error: error instanceof Error ? error.message : String(error) });
675
729
  }).finally(() => {
676
730
  this.closing.delete(id);
@@ -683,6 +737,17 @@ var BubbleStore = class {
683
737
  this.disposed = true;
684
738
  await Promise.all(this.snapshot.map((item) => this.close(item.id)));
685
739
  }
740
+ dropIfCloseCannotFinish(id) {
741
+ if (!this.closeFenced.has(id)) return;
742
+ const end = this.runEnd.get(id);
743
+ if (end === "not-started" || end === "aborted") this.remove(id);
744
+ }
745
+ remove(id) {
746
+ this.notStarted.delete(id);
747
+ this.runEnd.delete(id);
748
+ this.closeFenced.delete(id);
749
+ this.publish(this.snapshot.filter((item) => item.id !== id));
750
+ }
686
751
  update(id, patch2) {
687
752
  this.publish(this.snapshot.map((item) => item.id === id ? { ...item, ...patch2 } : item));
688
753
  }
@@ -2804,7 +2869,7 @@ function normalizeUri(value) {
2804
2869
 
2805
2870
  // node_modules/micromark-factory-space/index.js
2806
2871
  function factorySpace(effects, ok3, type, max) {
2807
- const limit = max ? max - 1 : Number.POSITIVE_INFINITY;
2872
+ const limit = max ? max - 1 : Infinity;
2808
2873
  let size = 0;
2809
2874
  return start2;
2810
2875
  function start2(code4) {
@@ -2823,6 +2888,29 @@ function factorySpace(effects, ok3, type, max) {
2823
2888
  return ok3(code4);
2824
2889
  }
2825
2890
  }
2891
+ function factorySpaceMinMax(effects, ok3, nok, type, min, max) {
2892
+ let size = 0;
2893
+ return start2;
2894
+ function start2(code4) {
2895
+ if (max > 0 && markdownSpace(code4)) {
2896
+ effects.enter(type);
2897
+ return prefix(code4);
2898
+ }
2899
+ return after(code4);
2900
+ }
2901
+ function prefix(code4) {
2902
+ if (markdownSpace(code4) && size < max) {
2903
+ effects.consume(code4);
2904
+ size++;
2905
+ return prefix;
2906
+ }
2907
+ effects.exit(type);
2908
+ return after(code4);
2909
+ }
2910
+ function after(code4) {
2911
+ return size >= min ? ok3(code4) : nok(code4);
2912
+ }
2913
+ }
2826
2914
 
2827
2915
  // node_modules/micromark/lib/initialize/content.js
2828
2916
  var content = {
@@ -2874,6 +2962,104 @@ function initializeContent(effects) {
2874
2962
  }
2875
2963
  }
2876
2964
 
2965
+ // node_modules/micromark-util-edit-map/index.js
2966
+ var EditMap = class {
2967
+ /**
2968
+ * Create a new edit map.
2969
+ *
2970
+ * @returns
2971
+ * New instance.
2972
+ */
2973
+ constructor() {
2974
+ this.index = /* @__PURE__ */ new Map();
2975
+ this.map = [];
2976
+ }
2977
+ /**
2978
+ * Create an edit: a remove and/or add at a certain place.
2979
+ *
2980
+ * @param {number} index
2981
+ * Index at which to apply the edit.
2982
+ * @param {number} remove
2983
+ * Count of items to remove at the index.
2984
+ * @param {Array<Event>} add
2985
+ * Items to add at the index.
2986
+ * @returns {undefined}
2987
+ * Nothing.
2988
+ */
2989
+ add(index2, remove, add) {
2990
+ addImplementation(this, index2, remove, add, false);
2991
+ }
2992
+ /**
2993
+ * Create an edit: but insert `add` before existing additions, instead of
2994
+ * after them.
2995
+ *
2996
+ * @param {number} index
2997
+ * Index at which to apply the edit.
2998
+ * @param {number} remove
2999
+ * Count of items to remove at the index.
3000
+ * @param {Array<Event>} add
3001
+ * Items to add at the index.
3002
+ * @returns {undefined}
3003
+ * Nothing.
3004
+ */
3005
+ addBefore(index2, remove, add) {
3006
+ addImplementation(this, index2, remove, add, true);
3007
+ }
3008
+ /**
3009
+ * Done, change the events.
3010
+ *
3011
+ * @param {Array<Event>} events
3012
+ * List of events to apply the edits to.
3013
+ * @returns {undefined}
3014
+ * Nothing.
3015
+ */
3016
+ consume(events) {
3017
+ this.map.sort(function(a, b) {
3018
+ return a[0] - b[0];
3019
+ });
3020
+ if (this.map.length === 0) {
3021
+ return;
3022
+ }
3023
+ let index2 = this.map.length;
3024
+ const vecs = [];
3025
+ while (index2 > 0) {
3026
+ index2 -= 1;
3027
+ vecs.push(events.slice(this.map[index2][0] + this.map[index2][1]), this.map[index2][2]);
3028
+ events.length = this.map[index2][0];
3029
+ }
3030
+ vecs.push(events.slice());
3031
+ events.length = 0;
3032
+ let slice = vecs.pop();
3033
+ while (slice) {
3034
+ for (const element3 of slice) {
3035
+ events.push(element3);
3036
+ }
3037
+ slice = vecs.pop();
3038
+ }
3039
+ this.map.length = 0;
3040
+ this.index.clear();
3041
+ }
3042
+ };
3043
+ function addImplementation(editMap, at, remove, add, before) {
3044
+ if (remove === 0 && add.length === 0) {
3045
+ return;
3046
+ }
3047
+ const existing = editMap.index.get(at);
3048
+ if (existing) {
3049
+ existing[1] += remove;
3050
+ if (before) {
3051
+ add.push(...existing[2]);
3052
+ existing[2] = add;
3053
+ } else {
3054
+ existing[2].push(...add);
3055
+ }
3056
+ return;
3057
+ }
3058
+ const change = [at, remove, add];
3059
+ editMap.map.push(change);
3060
+ editMap.index.set(at, change);
3061
+ }
3062
+
2877
3063
  // node_modules/micromark/lib/initialize/document.js
2878
3064
  var document2 = {
2879
3065
  tokenize: initializeDocument
@@ -2921,8 +3107,10 @@ function initializeDocument(effects) {
2921
3107
  };
2922
3108
  index2++;
2923
3109
  }
2924
- splice(self2.events, indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
2925
- self2.events.length = index2;
3110
+ const editMap = new EditMap();
3111
+ editMap.add(indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
3112
+ editMap.add(indexBeforeExits, index2 - indexBeforeExits, []);
3113
+ editMap.consume(self2.events);
2926
3114
  return checkNewContainers(code4);
2927
3115
  }
2928
3116
  return start2(code4);
@@ -2941,7 +3129,9 @@ function initializeDocument(effects) {
2941
3129
  return effects.check(containerConstruct, thereIsANewContainer, thereIsNoNewContainer)(code4);
2942
3130
  }
2943
3131
  function thereIsANewContainer(code4) {
2944
- if (childFlow) closeFlow();
3132
+ if (childFlow) {
3133
+ closeFlow();
3134
+ }
2945
3135
  exitContainers(continued);
2946
3136
  return documentContinued(code4);
2947
3137
  }
@@ -2961,7 +3151,9 @@ function initializeDocument(effects) {
2961
3151
  }
2962
3152
  function flowStart(code4) {
2963
3153
  if (code4 === null) {
2964
- if (childFlow) closeFlow();
3154
+ if (childFlow) {
3155
+ closeFlow();
3156
+ }
2965
3157
  exitContainers(0);
2966
3158
  effects.consume(code4);
2967
3159
  return;
@@ -2993,9 +3185,13 @@ function initializeDocument(effects) {
2993
3185
  }
2994
3186
  function writeToChild(token, endOfFile) {
2995
3187
  const stream = self2.sliceStream(token);
2996
- if (endOfFile) stream.push(null);
3188
+ if (endOfFile) {
3189
+ stream.push(null);
3190
+ }
2997
3191
  token.previous = childToken;
2998
- if (childToken) childToken.next = token;
3192
+ if (childToken) {
3193
+ childToken.next = token;
3194
+ }
2999
3195
  childToken = token;
3000
3196
  childFlow.defineSkip(token.start);
3001
3197
  childFlow.write(stream);
@@ -3032,8 +3228,10 @@ function initializeDocument(effects) {
3032
3228
  };
3033
3229
  index2++;
3034
3230
  }
3035
- splice(self2.events, indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
3036
- self2.events.length = index2;
3231
+ const editMap = new EditMap();
3232
+ editMap.add(indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));
3233
+ editMap.add(indexBeforeExits, index2 - indexBeforeExits, []);
3234
+ editMap.consume(self2.events);
3037
3235
  }
3038
3236
  }
3039
3237
  function exitContainers(size) {
@@ -3088,24 +3286,17 @@ var attention = {
3088
3286
  };
3089
3287
  function resolveAllAttention(events, context) {
3090
3288
  let index2 = -1;
3091
- let open;
3092
- let group;
3093
- let text7;
3094
- let openingSequence;
3095
- let closingSequence;
3096
- let use;
3097
3289
  let nextEvents;
3098
- let offset;
3099
3290
  while (++index2 < events.length) {
3100
3291
  if (events[index2][0] === "enter" && events[index2][1].type === "attentionSequence" && events[index2][1]._close) {
3101
- open = index2;
3292
+ let open = index2;
3102
3293
  while (open--) {
3103
3294
  if (events[open][0] === "exit" && events[open][1].type === "attentionSequence" && events[open][1]._open && // If the markers are the same:
3104
3295
  context.sliceSerialize(events[open][1]).charCodeAt(0) === context.sliceSerialize(events[index2][1]).charCodeAt(0)) {
3105
3296
  if ((events[open][1]._close || events[index2][1]._open) && (events[index2][1].end.offset - events[index2][1].start.offset) % 3 && !((events[open][1].end.offset - events[open][1].start.offset + events[index2][1].end.offset - events[index2][1].start.offset) % 3)) {
3106
3297
  continue;
3107
3298
  }
3108
- use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index2][1].end.offset - events[index2][1].start.offset > 1 ? 2 : 1;
3299
+ const use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index2][1].end.offset - events[index2][1].start.offset > 1 ? 2 : 1;
3109
3300
  const start2 = {
3110
3301
  ...events[open][1].end
3111
3302
  };
@@ -3114,21 +3305,21 @@ function resolveAllAttention(events, context) {
3114
3305
  };
3115
3306
  movePoint(start2, -use);
3116
3307
  movePoint(end, use);
3117
- openingSequence = {
3308
+ const openingSequence = {
3118
3309
  type: use > 1 ? "strongSequence" : "emphasisSequence",
3119
3310
  start: start2,
3120
3311
  end: {
3121
3312
  ...events[open][1].end
3122
3313
  }
3123
3314
  };
3124
- closingSequence = {
3315
+ const closingSequence = {
3125
3316
  type: use > 1 ? "strongSequence" : "emphasisSequence",
3126
3317
  start: {
3127
3318
  ...events[index2][1].start
3128
3319
  },
3129
3320
  end
3130
3321
  };
3131
- text7 = {
3322
+ const text7 = {
3132
3323
  type: use > 1 ? "strongText" : "emphasisText",
3133
3324
  start: {
3134
3325
  ...events[open][1].end
@@ -3137,7 +3328,7 @@ function resolveAllAttention(events, context) {
3137
3328
  ...events[index2][1].start
3138
3329
  }
3139
3330
  };
3140
- group = {
3331
+ const group = {
3141
3332
  type: use > 1 ? "strong" : "emphasis",
3142
3333
  start: {
3143
3334
  ...openingSequence.start
@@ -3159,11 +3350,10 @@ function resolveAllAttention(events, context) {
3159
3350
  nextEvents = push(nextEvents, [["enter", group, context], ["enter", openingSequence, context], ["exit", openingSequence, context], ["enter", text7, context]]);
3160
3351
  nextEvents = push(nextEvents, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + 1, index2), context));
3161
3352
  nextEvents = push(nextEvents, [["exit", text7, context], ["enter", closingSequence, context], ["exit", closingSequence, context], ["exit", group, context]]);
3353
+ let offset = 0;
3162
3354
  if (events[index2][1].end.offset - events[index2][1].start.offset) {
3163
3355
  offset = 2;
3164
3356
  nextEvents = push(nextEvents, [["enter", events[index2][1], context], ["exit", events[index2][1], context]]);
3165
- } else {
3166
- offset = 0;
3167
3357
  }
3168
3358
  splice(events, open - 1, index2 - open + 3, nextEvents);
3169
3359
  index2 = open + nextEvents.length - offset - 2;
@@ -3198,8 +3388,8 @@ function tokenizeAttention(effects, ok3) {
3198
3388
  }
3199
3389
  const token = effects.exit("attentionSequence");
3200
3390
  const after = classifyCharacter(code4);
3201
- const open = !after || after === 2 && before || attentionMarkers2.includes(code4);
3202
- const close = !before || before === 2 && after || attentionMarkers2.includes(previous3);
3391
+ const open = !after || after === 2 && before || attentionMarkers2.includes(code4) && code4 !== 42 && code4 !== 95;
3392
+ const close = !before || before === 2 && after || attentionMarkers2.includes(previous3) && previous3 !== 42 && previous3 !== 95;
3203
3393
  token._open = Boolean(marker === 42 ? open : open && (before || !close));
3204
3394
  token._close = Boolean(marker === 42 ? close : close && (after || !open));
3205
3395
  return ok3(code4);
@@ -3476,11 +3666,29 @@ function tokenizeCharacterReference(effects, ok3, nok) {
3476
3666
  }
3477
3667
  }
3478
3668
 
3479
- // node_modules/micromark-core-commonmark/lib/code-fenced.js
3669
+ // node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.js
3480
3670
  var nonLazyContinuation = {
3481
3671
  partial: true,
3482
3672
  tokenize: tokenizeNonLazyContinuation
3483
3673
  };
3674
+ function tokenizeNonLazyContinuation(effects, ok3, nok) {
3675
+ const self2 = this;
3676
+ return start2;
3677
+ function start2(code4) {
3678
+ if (code4 === null) {
3679
+ return nok(code4);
3680
+ }
3681
+ effects.enter("lineEnding");
3682
+ effects.consume(code4);
3683
+ effects.exit("lineEnding");
3684
+ return after;
3685
+ }
3686
+ function after(code4) {
3687
+ return self2.parser.lazy[self2.now().line] ? nok(code4) : ok3(code4);
3688
+ }
3689
+ }
3690
+
3691
+ // node_modules/micromark-core-commonmark/lib/code-fenced.js
3484
3692
  var codeFenced = {
3485
3693
  concrete: true,
3486
3694
  name: "codeFenced",
@@ -3642,22 +3850,6 @@ function tokenizeCodeFenced(effects, ok3, nok) {
3642
3850
  }
3643
3851
  }
3644
3852
  }
3645
- function tokenizeNonLazyContinuation(effects, ok3, nok) {
3646
- const self2 = this;
3647
- return start2;
3648
- function start2(code4) {
3649
- if (code4 === null) {
3650
- return nok(code4);
3651
- }
3652
- effects.enter("lineEnding");
3653
- effects.consume(code4);
3654
- effects.exit("lineEnding");
3655
- return lineStart;
3656
- }
3657
- function lineStart(code4) {
3658
- return self2.parser.lazy[self2.now().line] ? nok(code4) : ok3(code4);
3659
- }
3660
- }
3661
3853
 
3662
3854
  // node_modules/micromark-core-commonmark/lib/code-indented.js
3663
3855
  var codeIndented = {
@@ -3669,15 +3861,10 @@ var furtherStart = {
3669
3861
  tokenize: tokenizeFurtherStart
3670
3862
  };
3671
3863
  function tokenizeCodeIndented(effects, ok3, nok) {
3672
- const self2 = this;
3673
3864
  return start2;
3674
3865
  function start2(code4) {
3675
3866
  effects.enter("codeIndented");
3676
- return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code4);
3677
- }
3678
- function afterPrefix(code4) {
3679
- const tail = self2.events[self2.events.length - 1];
3680
- return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? atBreak(code4) : nok(code4);
3867
+ return factorySpaceMinMax(effects, atBreak, nok, "linePrefix", 4, 4)(code4);
3681
3868
  }
3682
3869
  function atBreak(code4) {
3683
3870
  if (code4 === null) {
@@ -3715,11 +3902,10 @@ function tokenizeFurtherStart(effects, ok3, nok) {
3715
3902
  effects.exit("lineEnding");
3716
3903
  return furtherStart2;
3717
3904
  }
3718
- return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code4);
3905
+ return factorySpaceMinMax(effects, ok3, onNotEnoughPrefix, "linePrefix", 4, 4)(code4);
3719
3906
  }
3720
- function afterPrefix(code4) {
3721
- const tail = self2.events[self2.events.length - 1];
3722
- return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok3(code4) : markdownLineEnding(code4) ? furtherStart2(code4) : nok(code4);
3907
+ function onNotEnoughPrefix(code4) {
3908
+ return markdownLineEnding(code4) ? furtherStart2(code4) : nok(code4);
3723
3909
  }
3724
3910
  }
3725
3911
 
@@ -4605,8 +4791,6 @@ var headingAtx = {
4605
4791
  function resolveHeadingAtx(events, context) {
4606
4792
  let contentEnd = events.length - 2;
4607
4793
  let contentStart = 3;
4608
- let content3;
4609
- let text7;
4610
4794
  if (events[contentStart][1].type === "whitespace") {
4611
4795
  contentStart += 2;
4612
4796
  }
@@ -4617,12 +4801,12 @@ function resolveHeadingAtx(events, context) {
4617
4801
  contentEnd -= contentStart + 1 === contentEnd ? 2 : 4;
4618
4802
  }
4619
4803
  if (contentEnd > contentStart) {
4620
- content3 = {
4804
+ const content3 = {
4621
4805
  type: "atxHeadingText",
4622
4806
  start: events[contentStart][1].start,
4623
4807
  end: events[contentEnd][1].end
4624
4808
  };
4625
- text7 = {
4809
+ const text7 = {
4626
4810
  type: "chunkText",
4627
4811
  start: events[contentStart][1].start,
4628
4812
  end: events[contentEnd][1].end,
@@ -4765,10 +4949,6 @@ var blankLineBefore = {
4765
4949
  partial: true,
4766
4950
  tokenize: tokenizeBlankLineBefore
4767
4951
  };
4768
- var nonLazyContinuationStart = {
4769
- partial: true,
4770
- tokenize: tokenizeNonLazyContinuationStart
4771
- };
4772
4952
  function resolveToHtmlFlow(events) {
4773
4953
  let index2 = events.length;
4774
4954
  while (index2--) {
@@ -5030,7 +5210,7 @@ function tokenizeHtmlFlow(effects, ok3, nok) {
5030
5210
  return continuation;
5031
5211
  }
5032
5212
  function continuationStart(code4) {
5033
- return effects.check(nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code4);
5213
+ return effects.check(nonLazyContinuation, continuationStartNonLazy, continuationAfter)(code4);
5034
5214
  }
5035
5215
  function continuationStartNonLazy(code4) {
5036
5216
  effects.enter("lineEnding");
@@ -5107,22 +5287,6 @@ function tokenizeHtmlFlow(effects, ok3, nok) {
5107
5287
  return ok3(code4);
5108
5288
  }
5109
5289
  }
5110
- function tokenizeNonLazyContinuationStart(effects, ok3, nok) {
5111
- const self2 = this;
5112
- return start2;
5113
- function start2(code4) {
5114
- if (markdownLineEnding(code4)) {
5115
- effects.enter("lineEnding");
5116
- effects.consume(code4);
5117
- effects.exit("lineEnding");
5118
- return after;
5119
- }
5120
- return nok(code4);
5121
- }
5122
- function after(code4) {
5123
- return self2.parser.lazy[self2.now().line] ? nok(code4) : ok3(code4);
5124
- }
5125
- }
5126
5290
  function tokenizeBlankLineBefore(effects, ok3, nok) {
5127
5291
  return start2;
5128
5292
  function start2(code4) {
@@ -5475,12 +5639,11 @@ function resolveAllLabelEnd(events) {
5475
5639
  function resolveToLabelEnd(events, context) {
5476
5640
  let index2 = events.length;
5477
5641
  let offset = 0;
5478
- let token;
5479
5642
  let open;
5480
5643
  let close;
5481
5644
  let media;
5482
5645
  while (index2--) {
5483
- token = events[index2][1];
5646
+ const token = events[index2][1];
5484
5647
  if (open) {
5485
5648
  if (token.type === "link" || token.type === "labelLink" && token._inactive) {
5486
5649
  break;
@@ -5539,14 +5702,14 @@ function resolveToLabelEnd(events, context) {
5539
5702
  }
5540
5703
  function tokenizeLabelEnd(effects, ok3, nok) {
5541
5704
  const self2 = this;
5542
- let index2 = self2.events.length;
5705
+ const labelStarts = self2._labelStarts;
5543
5706
  let labelStart;
5544
5707
  let defined;
5545
- while (index2--) {
5546
- if ((self2.events[index2][1].type === "labelImage" || self2.events[index2][1].type === "labelLink") && !self2.events[index2][1]._balanced) {
5547
- labelStart = self2.events[index2][1];
5548
- break;
5708
+ if (labelStarts) {
5709
+ while (labelStarts.length > 0 && labelStarts[labelStarts.length - 1]._balanced) {
5710
+ labelStarts.pop();
5549
5711
  }
5712
+ labelStart = labelStarts[labelStarts.length - 1];
5550
5713
  }
5551
5714
  return start2;
5552
5715
  function start2(code4) {
@@ -5580,6 +5743,7 @@ function tokenizeLabelEnd(effects, ok3, nok) {
5580
5743
  return effects.attempt(referenceCollapsedConstruct, labelEndOk, labelEndNok)(code4);
5581
5744
  }
5582
5745
  function labelEndOk(code4) {
5746
+ labelStarts.pop();
5583
5747
  return ok3(code4);
5584
5748
  }
5585
5749
  function labelEndNok(code4) {
@@ -5673,6 +5837,7 @@ var labelStartImage = {
5673
5837
  };
5674
5838
  function tokenizeLabelStartImage(effects, ok3, nok) {
5675
5839
  const self2 = this;
5840
+ let labelImage;
5676
5841
  return start2;
5677
5842
  function start2(code4) {
5678
5843
  effects.enter("labelImage");
@@ -5686,13 +5851,18 @@ function tokenizeLabelStartImage(effects, ok3, nok) {
5686
5851
  effects.enter("labelMarker");
5687
5852
  effects.consume(code4);
5688
5853
  effects.exit("labelMarker");
5689
- effects.exit("labelImage");
5854
+ labelImage = effects.exit("labelImage");
5690
5855
  return after;
5691
5856
  }
5692
5857
  return nok(code4);
5693
5858
  }
5694
5859
  function after(code4) {
5695
- return code4 === 94 && "_hiddenFootnoteSupport" in self2.parser.constructs ? nok(code4) : ok3(code4);
5860
+ if (code4 === 94 && "_hiddenFootnoteSupport" in self2.parser.constructs) {
5861
+ return nok(code4);
5862
+ }
5863
+ self2._labelStarts = self2._labelStarts || [];
5864
+ self2._labelStarts.push(labelImage);
5865
+ return ok3(code4);
5696
5866
  }
5697
5867
  }
5698
5868
 
@@ -5704,17 +5874,23 @@ var labelStartLink = {
5704
5874
  };
5705
5875
  function tokenizeLabelStartLink(effects, ok3, nok) {
5706
5876
  const self2 = this;
5877
+ let labelLink;
5707
5878
  return start2;
5708
5879
  function start2(code4) {
5709
5880
  effects.enter("labelLink");
5710
5881
  effects.enter("labelMarker");
5711
5882
  effects.consume(code4);
5712
5883
  effects.exit("labelMarker");
5713
- effects.exit("labelLink");
5884
+ labelLink = effects.exit("labelLink");
5714
5885
  return after;
5715
5886
  }
5716
5887
  function after(code4) {
5717
- return code4 === 94 && "_hiddenFootnoteSupport" in self2.parser.constructs ? nok(code4) : ok3(code4);
5888
+ if (code4 === 94 && "_hiddenFootnoteSupport" in self2.parser.constructs) {
5889
+ return nok(code4);
5890
+ }
5891
+ self2._labelStarts = self2._labelStarts || [];
5892
+ self2._labelStarts.push(labelLink);
5893
+ return ok3(code4);
5718
5894
  }
5719
5895
  }
5720
5896
 
@@ -5909,6 +6085,7 @@ var setextUnderline = {
5909
6085
  tokenize: tokenizeSetextUnderline
5910
6086
  };
5911
6087
  function resolveToSetextUnderline(events, context) {
6088
+ const editMap = new EditMap();
5912
6089
  let index2 = events.length;
5913
6090
  let content3;
5914
6091
  let text7;
@@ -5924,7 +6101,7 @@ function resolveToSetextUnderline(events, context) {
5924
6101
  }
5925
6102
  } else {
5926
6103
  if (events[index2][1].type === "content") {
5927
- events.splice(index2, 1);
6104
+ editMap.add(index2, 1, []);
5928
6105
  }
5929
6106
  if (!definition3 && events[index2][1].type === "definition") {
5930
6107
  definition3 = index2;
@@ -5942,15 +6119,16 @@ function resolveToSetextUnderline(events, context) {
5942
6119
  };
5943
6120
  events[text7][1].type = "setextHeadingText";
5944
6121
  if (definition3) {
5945
- events.splice(text7, 0, ["enter", heading3, context]);
5946
- events.splice(definition3 + 1, 0, ["exit", events[content3][1], context]);
6122
+ editMap.add(text7, 0, [["enter", heading3, context]]);
6123
+ editMap.add(definition3 + 1, 0, [["exit", events[content3][1], context]]);
5947
6124
  events[content3][1].end = {
5948
6125
  ...events[definition3][1].end
5949
6126
  };
5950
6127
  } else {
5951
6128
  events[content3][1] = heading3;
5952
6129
  }
5953
- events.push(["exit", heading3, context]);
6130
+ editMap.add(events.length, 0, [["exit", heading3, context]]);
6131
+ editMap.consume(events);
5954
6132
  return events;
5955
6133
  }
5956
6134
  function tokenizeSetextUnderline(effects, ok3, nok) {
@@ -6110,6 +6288,7 @@ function createResolver(extraResolver) {
6110
6288
  }
6111
6289
  }
6112
6290
  function resolveAllLineSuffixes(events, context) {
6291
+ const editMap = new EditMap();
6113
6292
  let eventIndex = 0;
6114
6293
  while (++eventIndex <= events.length) {
6115
6294
  if ((eventIndex === events.length || events[eventIndex][1].type === "lineEnding") && events[eventIndex - 1][1].type === "data") {
@@ -6127,7 +6306,9 @@ function resolveAllLineSuffixes(events, context) {
6127
6306
  size++;
6128
6307
  bufferIndex--;
6129
6308
  }
6130
- if (bufferIndex) break;
6309
+ if (bufferIndex) {
6310
+ break;
6311
+ }
6131
6312
  bufferIndex = -1;
6132
6313
  } else if (chunk === -2) {
6133
6314
  tabs = true;
@@ -6161,13 +6342,13 @@ function resolveAllLineSuffixes(events, context) {
6161
6342
  if (data.start.offset === data.end.offset) {
6162
6343
  Object.assign(data, token);
6163
6344
  } else {
6164
- events.splice(eventIndex, 0, ["enter", token, context], ["exit", token, context]);
6165
- eventIndex += 2;
6345
+ editMap.add(eventIndex, 0, [["enter", token, context], ["exit", token, context]]);
6166
6346
  }
6167
6347
  }
6168
6348
  eventIndex++;
6169
6349
  }
6170
6350
  }
6351
+ editMap.consume(events);
6171
6352
  return events;
6172
6353
  }
6173
6354
 
@@ -6325,11 +6506,10 @@ function createTokenizer(parser, initialize, from) {
6325
6506
  accountForPotentialSkip();
6326
6507
  }
6327
6508
  function main() {
6328
- let chunkIndex;
6329
6509
  while (point4._index < chunks.length) {
6330
6510
  const chunk = chunks[point4._index];
6331
6511
  if (typeof chunk === "string") {
6332
- chunkIndex = point4._index;
6512
+ const chunkIndex = point4._index;
6333
6513
  if (point4._bufferIndex < 0) {
6334
6514
  point4._bufferIndex = 0;
6335
6515
  }
@@ -6537,30 +6717,34 @@ function serializeChunks(chunks, expandTabs) {
6537
6717
  let value;
6538
6718
  if (typeof chunk === "string") {
6539
6719
  value = chunk;
6540
- } else switch (chunk) {
6541
- case -5: {
6542
- value = "\r";
6543
- break;
6544
- }
6545
- case -4: {
6546
- value = "\n";
6547
- break;
6548
- }
6549
- case -3: {
6550
- value = "\r\n";
6551
- break;
6552
- }
6553
- case -2: {
6554
- value = expandTabs ? " " : " ";
6555
- break;
6556
- }
6557
- case -1: {
6558
- if (!expandTabs && atTab) continue;
6559
- value = " ";
6560
- break;
6561
- }
6562
- default: {
6563
- value = String.fromCharCode(chunk);
6720
+ } else {
6721
+ switch (chunk) {
6722
+ case -5: {
6723
+ value = "\r";
6724
+ break;
6725
+ }
6726
+ case -4: {
6727
+ value = "\n";
6728
+ break;
6729
+ }
6730
+ case -3: {
6731
+ value = "\r\n";
6732
+ break;
6733
+ }
6734
+ case -2: {
6735
+ value = expandTabs ? " " : " ";
6736
+ break;
6737
+ }
6738
+ case -1: {
6739
+ if (!expandTabs && atTab) {
6740
+ continue;
6741
+ }
6742
+ value = " ";
6743
+ break;
6744
+ }
6745
+ default: {
6746
+ value = String.fromCharCode(chunk);
6747
+ }
6564
6748
  }
6565
6749
  }
6566
6750
  atTab = chunk === -2;
@@ -6611,14 +6795,9 @@ function preprocess() {
6611
6795
  let atCarriageReturn;
6612
6796
  return preprocessor;
6613
6797
  function preprocessor(value, encoding, end) {
6614
- const chunks = [];
6615
- let match;
6616
- let next;
6617
- let startPosition;
6618
- let endPosition;
6619
- let code4;
6620
6798
  value = buffer + (typeof value === "string" ? value.toString() : new TextDecoder(encoding || void 0).decode(value));
6621
- startPosition = 0;
6799
+ const chunks = [];
6800
+ let startPosition = 0;
6622
6801
  buffer = "";
6623
6802
  if (start2) {
6624
6803
  if (value.charCodeAt(0) === 65279) {
@@ -6628,9 +6807,9 @@ function preprocess() {
6628
6807
  }
6629
6808
  while (startPosition < value.length) {
6630
6809
  search.lastIndex = startPosition;
6631
- match = search.exec(value);
6632
- endPosition = match && match.index !== void 0 ? match.index : value.length;
6633
- code4 = value.charCodeAt(endPosition);
6810
+ const match = search.exec(value);
6811
+ const endPosition = match && match.index !== void 0 ? match.index : value.length;
6812
+ const code4 = value.charCodeAt(endPosition);
6634
6813
  if (!match) {
6635
6814
  buffer = value.slice(startPosition);
6636
6815
  break;
@@ -6654,9 +6833,11 @@ function preprocess() {
6654
6833
  break;
6655
6834
  }
6656
6835
  case 9: {
6657
- next = Math.ceil(column / 4) * 4;
6836
+ const next = Math.ceil(column / 4) * 4;
6658
6837
  chunks.push(-2);
6659
- while (column++ < next) chunks.push(-1);
6838
+ while (column++ < next) {
6839
+ chunks.push(-1);
6840
+ }
6660
6841
  break;
6661
6842
  }
6662
6843
  case 10: {
@@ -6673,8 +6854,12 @@ function preprocess() {
6673
6854
  startPosition = endPosition + 1;
6674
6855
  }
6675
6856
  if (end) {
6676
- if (atCarriageReturn) chunks.push(-5);
6677
- if (buffer) chunks.push(buffer);
6857
+ if (atCarriageReturn) {
6858
+ chunks.push(-5);
6859
+ }
6860
+ if (buffer) {
6861
+ chunks.push(buffer);
6862
+ }
6678
6863
  chunks.push(null);
6679
6864
  }
6680
6865
  return chunks;
@@ -6710,6 +6895,8 @@ function fromMarkdown(value, encoding, options) {
6710
6895
  }
6711
6896
  function compiler(options) {
6712
6897
  const config = {
6898
+ afterExit: [],
6899
+ beforeEnter: [],
6713
6900
  transforms: [],
6714
6901
  canContainEols: ["emphasis", "fragment", "heading", "paragraph", "strong"],
6715
6902
  enter: {
@@ -6813,7 +7000,8 @@ function compiler(options) {
6813
7000
  function compile(events) {
6814
7001
  let tree = {
6815
7002
  type: "root",
6816
- children: []
7003
+ children: [],
7004
+ position: void 0
6817
7005
  };
6818
7006
  const context = {
6819
7007
  stack: [tree],
@@ -6826,24 +7014,40 @@ function compiler(options) {
6826
7014
  data
6827
7015
  };
6828
7016
  const listStack = [];
7017
+ const prepared = [];
6829
7018
  let index2 = -1;
6830
7019
  while (++index2 < events.length) {
7020
+ prepared.push(events[index2]);
6831
7021
  if (events[index2][1].type === "listOrdered" || events[index2][1].type === "listUnordered") {
6832
7022
  if (events[index2][0] === "enter") {
6833
- listStack.push(index2);
7023
+ listStack.push(prepared.length - 1);
6834
7024
  } else {
6835
7025
  const tail = listStack.pop();
6836
- index2 = prepareList(events, tail, index2);
7026
+ prepareList(prepared, tail);
6837
7027
  }
6838
7028
  }
6839
7029
  }
7030
+ events = prepared;
6840
7031
  index2 = -1;
6841
7032
  while (++index2 < events.length) {
6842
7033
  const handler = config[events[index2][0]];
7034
+ if (events[index2][0] === "enter" && config.beforeEnter.length > 0) {
7035
+ callListeners(config.beforeEnter, {
7036
+ ...context,
7037
+ sliceSerialize: events[index2][2].sliceSerialize
7038
+ }, events[index2][1]);
7039
+ }
6843
7040
  if (own2.call(handler, events[index2][1].type)) {
6844
- handler[events[index2][1].type].call(Object.assign({
7041
+ handler[events[index2][1].type].call({
7042
+ ...context,
6845
7043
  sliceSerialize: events[index2][2].sliceSerialize
6846
- }, context), events[index2][1]);
7044
+ }, events[index2][1]);
7045
+ }
7046
+ if (events[index2][0] === "exit" && config.afterExit.length > 0) {
7047
+ callListeners(config.afterExit, {
7048
+ ...context,
7049
+ sliceSerialize: events[index2][2].sliceSerialize
7050
+ }, events[index2][1]);
6847
7051
  }
6848
7052
  }
6849
7053
  if (context.tokenStack.length > 0) {
@@ -6869,7 +7073,14 @@ function compiler(options) {
6869
7073
  }
6870
7074
  return tree;
6871
7075
  }
6872
- function prepareList(events, start2, length) {
7076
+ function callListeners(listeners, context, token) {
7077
+ let index2 = -1;
7078
+ while (++index2 < listeners.length) {
7079
+ listeners[index2].call(context, token);
7080
+ }
7081
+ }
7082
+ function prepareList(events, start2) {
7083
+ const end = events.length - 1;
6873
7084
  let index2 = start2 - 1;
6874
7085
  let containerBalance = -1;
6875
7086
  let listSpread = false;
@@ -6877,7 +7088,8 @@ function compiler(options) {
6877
7088
  let lineIndex;
6878
7089
  let firstBlankLineIndex;
6879
7090
  let atMarker;
6880
- while (++index2 <= length) {
7091
+ const insertions = [];
7092
+ while (++index2 <= end) {
6881
7093
  const event = events[index2];
6882
7094
  switch (event[1].type) {
6883
7095
  case "listUnordered":
@@ -6934,9 +7146,10 @@ function compiler(options) {
6934
7146
  listItem4._spread = true;
6935
7147
  }
6936
7148
  listItem4.end = Object.assign({}, lineIndex ? events[lineIndex][1].start : event[1].end);
6937
- events.splice(lineIndex || index2, 0, ["exit", listItem4, event[2]]);
6938
- index2++;
6939
- length++;
7149
+ insertions.push({
7150
+ at: lineIndex || index2,
7151
+ event: ["exit", listItem4, event[2]]
7152
+ });
6940
7153
  }
6941
7154
  if (event[1].type === "listItemPrefix") {
6942
7155
  const item = {
@@ -6947,16 +7160,25 @@ function compiler(options) {
6947
7160
  end: void 0
6948
7161
  };
6949
7162
  listItem4 = item;
6950
- events.splice(index2, 0, ["enter", item, event[2]]);
6951
- index2++;
6952
- length++;
7163
+ insertions.push({
7164
+ at: index2,
7165
+ event: ["enter", item, event[2]]
7166
+ });
6953
7167
  firstBlankLineIndex = void 0;
6954
7168
  atMarker = true;
6955
7169
  }
6956
7170
  }
6957
7171
  }
7172
+ const listEvents = events.splice(start2);
7173
+ let insertion = 0;
7174
+ index2 = -1;
7175
+ while (++index2 < listEvents.length) {
7176
+ while (insertion < insertions.length && insertions[insertion].at === start2 + index2) {
7177
+ events.push(insertions[insertion++].event);
7178
+ }
7179
+ events.push(listEvents[index2]);
7180
+ }
6958
7181
  events[start2][1]._spread = listSpread;
6959
- return length;
6960
7182
  }
6961
7183
  function opener(create2, and) {
6962
7184
  return open;
@@ -6998,7 +7220,8 @@ function compiler(options) {
6998
7220
  start: token.start,
6999
7221
  end: token.end
7000
7222
  }) + "): it\u2019s not open");
7001
- } else if (open[0].type !== token.type) {
7223
+ }
7224
+ if (open[0].type !== token.type) {
7002
7225
  if (onExitError) {
7003
7226
  onExitError.call(this, token, open[0]);
7004
7227
  } else {
@@ -7234,7 +7457,8 @@ function compiler(options) {
7234
7457
  function blockQuote2() {
7235
7458
  return {
7236
7459
  type: "blockquote",
7237
- children: []
7460
+ children: [],
7461
+ position: void 0
7238
7462
  };
7239
7463
  }
7240
7464
  function codeFlow() {
@@ -7242,13 +7466,15 @@ function compiler(options) {
7242
7466
  type: "code",
7243
7467
  lang: null,
7244
7468
  meta: null,
7245
- value: ""
7469
+ value: "",
7470
+ position: void 0
7246
7471
  };
7247
7472
  }
7248
7473
  function codeText2() {
7249
7474
  return {
7250
7475
  type: "inlineCode",
7251
- value: ""
7476
+ value: "",
7477
+ position: void 0
7252
7478
  };
7253
7479
  }
7254
7480
  function definition3() {
@@ -7257,13 +7483,15 @@ function compiler(options) {
7257
7483
  identifier: "",
7258
7484
  label: null,
7259
7485
  title: null,
7260
- url: ""
7486
+ url: "",
7487
+ position: void 0
7261
7488
  };
7262
7489
  }
7263
7490
  function emphasis3() {
7264
7491
  return {
7265
7492
  type: "emphasis",
7266
- children: []
7493
+ children: [],
7494
+ position: void 0
7267
7495
  };
7268
7496
  }
7269
7497
  function heading3() {
@@ -7271,18 +7499,21 @@ function compiler(options) {
7271
7499
  type: "heading",
7272
7500
  // @ts-expect-error `depth` will be set later.
7273
7501
  depth: 0,
7274
- children: []
7502
+ children: [],
7503
+ position: void 0
7275
7504
  };
7276
7505
  }
7277
7506
  function hardBreak3() {
7278
7507
  return {
7279
- type: "break"
7508
+ type: "break",
7509
+ position: void 0
7280
7510
  };
7281
7511
  }
7282
7512
  function html5() {
7283
7513
  return {
7284
7514
  type: "html",
7285
- value: ""
7515
+ value: "",
7516
+ position: void 0
7286
7517
  };
7287
7518
  }
7288
7519
  function image3() {
@@ -7290,7 +7521,8 @@ function compiler(options) {
7290
7521
  type: "image",
7291
7522
  title: null,
7292
7523
  url: "",
7293
- alt: null
7524
+ alt: null,
7525
+ position: void 0
7294
7526
  };
7295
7527
  }
7296
7528
  function link3() {
@@ -7298,7 +7530,8 @@ function compiler(options) {
7298
7530
  type: "link",
7299
7531
  title: null,
7300
7532
  url: "",
7301
- children: []
7533
+ children: [],
7534
+ position: void 0
7302
7535
  };
7303
7536
  }
7304
7537
  function list4(token) {
@@ -7307,7 +7540,8 @@ function compiler(options) {
7307
7540
  ordered: token.type === "listOrdered",
7308
7541
  start: null,
7309
7542
  spread: token._spread,
7310
- children: []
7543
+ children: [],
7544
+ position: void 0
7311
7545
  };
7312
7546
  }
7313
7547
  function listItem3(token) {
@@ -7315,30 +7549,35 @@ function compiler(options) {
7315
7549
  type: "listItem",
7316
7550
  spread: token._spread,
7317
7551
  checked: null,
7318
- children: []
7552
+ children: [],
7553
+ position: void 0
7319
7554
  };
7320
7555
  }
7321
7556
  function paragraph3() {
7322
7557
  return {
7323
7558
  type: "paragraph",
7324
- children: []
7559
+ children: [],
7560
+ position: void 0
7325
7561
  };
7326
7562
  }
7327
7563
  function strong3() {
7328
7564
  return {
7329
7565
  type: "strong",
7330
- children: []
7566
+ children: [],
7567
+ position: void 0
7331
7568
  };
7332
7569
  }
7333
7570
  function text7() {
7334
7571
  return {
7335
7572
  type: "text",
7336
- value: ""
7573
+ value: "",
7574
+ position: void 0
7337
7575
  };
7338
7576
  }
7339
7577
  function thematicBreak4() {
7340
7578
  return {
7341
- type: "thematicBreak"
7579
+ type: "thematicBreak",
7580
+ position: void 0
7342
7581
  };
7343
7582
  }
7344
7583
  }
@@ -7379,6 +7618,14 @@ function extension(combined, extension2) {
7379
7618
  }
7380
7619
  break;
7381
7620
  }
7621
+ case "afterExit":
7622
+ case "beforeEnter": {
7623
+ const right = extension2[key];
7624
+ if (right) {
7625
+ combined[key].push(right);
7626
+ }
7627
+ break;
7628
+ }
7382
7629
  case "enter":
7383
7630
  case "exit": {
7384
7631
  const right = extension2[key];
@@ -7400,12 +7647,11 @@ function defaultOnError(left, right) {
7400
7647
  start: right.start,
7401
7648
  end: right.end
7402
7649
  }) + ") is open");
7403
- } else {
7404
- throw new Error("Cannot close document, a token (`" + right.type + "`, " + stringifyPosition({
7405
- start: right.start,
7406
- end: right.end
7407
- }) + ") is still open");
7408
7650
  }
7651
+ throw new Error("Cannot close document, a token (`" + right.type + "`, " + stringifyPosition({
7652
+ start: right.start,
7653
+ end: right.end
7654
+ }) + ") is still open");
7409
7655
  }
7410
7656
 
7411
7657
  // node_modules/remark-parse/lib/index.js
@@ -10410,15 +10656,12 @@ function findAndReplace(tree, list4, options) {
10410
10656
  find2.lastIndex = position3 + 1;
10411
10657
  } else {
10412
10658
  if (start2 !== position3) {
10413
- nodes.push({
10414
- type: "text",
10415
- value: node2.value.slice(start2, position3)
10416
- });
10659
+ add({ type: "text", value: node2.value.slice(start2, position3) });
10417
10660
  }
10418
10661
  if (Array.isArray(value)) {
10419
- nodes.push(...value);
10662
+ for (const child of value) add(child);
10420
10663
  } else if (value) {
10421
- nodes.push(value);
10664
+ add(value);
10422
10665
  }
10423
10666
  start2 = position3 + match[0].length;
10424
10667
  change = true;
@@ -10430,20 +10673,28 @@ function findAndReplace(tree, list4, options) {
10430
10673
  }
10431
10674
  if (change) {
10432
10675
  if (start2 < node2.value.length) {
10433
- nodes.push({ type: "text", value: node2.value.slice(start2) });
10676
+ add({ type: "text", value: node2.value.slice(start2) });
10434
10677
  }
10435
10678
  parent.children.splice(index2, 1, ...nodes);
10436
10679
  } else {
10437
10680
  nodes = [node2];
10438
10681
  }
10439
10682
  return index2 + nodes.length;
10683
+ function add(child) {
10684
+ const previous3 = nodes[nodes.length - 1];
10685
+ if (previous3 && previous3.type === "text" && child.type === "text") {
10686
+ previous3.value += child.value;
10687
+ } else {
10688
+ nodes.push(child);
10689
+ }
10690
+ }
10440
10691
  }
10441
10692
  }
10442
10693
  function toPairs(tupleOrList) {
10443
- const result = [];
10444
10694
  if (!Array.isArray(tupleOrList)) {
10445
10695
  throw new TypeError("Expected find and replace tuple or list of tuples");
10446
10696
  }
10697
+ const result = [];
10447
10698
  const list4 = !tupleOrList[0] || Array.isArray(tupleOrList[0]) ? tupleOrList : [tupleOrList];
10448
10699
  let index2 = -1;
10449
10700
  while (++index2 < list4.length) {
@@ -10733,6 +10984,7 @@ var constructsWithoutStrikethrough = [
10733
10984
  "titleQuote",
10734
10985
  "titleApostrophe"
10735
10986
  ];
10987
+ handleDelete.attention = attentionDelete;
10736
10988
  handleDelete.peek = peekDelete;
10737
10989
  function gfmStrikethroughFromMarkdown() {
10738
10990
  return {
@@ -10743,35 +10995,39 @@ function gfmStrikethroughFromMarkdown() {
10743
10995
  }
10744
10996
  function gfmStrikethroughToMarkdown() {
10745
10997
  return {
10998
+ handlers: { delete: handleDelete },
10746
10999
  unsafe: [
10747
11000
  {
10748
11001
  character: "~",
10749
11002
  inConstruct: "phrasing",
10750
11003
  notInConstruct: constructsWithoutStrikethrough
10751
11004
  }
10752
- ],
10753
- handlers: { delete: handleDelete }
11005
+ ]
10754
11006
  };
10755
11007
  }
10756
11008
  function enterStrikethrough(token) {
10757
- this.enter({ type: "delete", children: [] }, token);
11009
+ this.enter({ type: "delete", children: [], position: void 0 }, token);
10758
11010
  }
10759
11011
  function exitStrikethrough(token) {
10760
11012
  this.exit(token);
10761
11013
  }
10762
11014
  function handleDelete(node2, _, state, info) {
10763
11015
  const tracker = state.createTracker(info);
11016
+ const sequence = state.stack.includes("strikethrough") ? "~" : "~~";
10764
11017
  const exit3 = state.enter("strikethrough");
10765
- let value = tracker.move("~~");
11018
+ let value = tracker.move(sequence);
10766
11019
  value += state.containerPhrasing(node2, {
10767
11020
  ...tracker.current(),
10768
11021
  before: value,
10769
11022
  after: "~"
10770
11023
  });
10771
- value += tracker.move("~~");
11024
+ value += tracker.move(sequence);
10772
11025
  exit3();
10773
11026
  return value;
10774
11027
  }
11028
+ function attentionDelete() {
11029
+ return { construct: "strikethrough", markers: ["~"], sizes: [2, 1] };
11030
+ }
10775
11031
  function peekDelete() {
10776
11032
  return "~";
10777
11033
  }
@@ -10917,6 +11173,34 @@ function toAlignment(value) {
10917
11173
  return code4 === 67 || code4 === 99 ? 99 : code4 === 76 || code4 === 108 ? 108 : code4 === 82 || code4 === 114 ? 114 : 0;
10918
11174
  }
10919
11175
 
11176
+ // node_modules/mdast-util-phrasing/lib/index.js
11177
+ var phrasing = (
11178
+ /** @type {(node?: unknown) => node is Exclude<PhrasingContent, Html>} */
11179
+ convert([
11180
+ "break",
11181
+ "delete",
11182
+ "emphasis",
11183
+ // To do: next major: removed since footnotes were added to GFM.
11184
+ "footnote",
11185
+ "footnoteReference",
11186
+ "image",
11187
+ "imageReference",
11188
+ "inlineCode",
11189
+ // Enabled by `mdast-util-math`:
11190
+ "inlineMath",
11191
+ "link",
11192
+ "linkReference",
11193
+ // Enabled by `mdast-util-mdx`:
11194
+ "mdxJsxTextElement",
11195
+ // Enabled by `mdast-util-mdx`:
11196
+ "mdxTextExpression",
11197
+ "strong",
11198
+ "text",
11199
+ // Enabled by `mdast-util-directive`:
11200
+ "textDirective"
11201
+ ])
11202
+ );
11203
+
10920
11204
  // node_modules/mdast-util-to-markdown/lib/handle/blockquote.js
10921
11205
  function blockquote2(node2, _, state, info) {
10922
11206
  const exit3 = state.enter("blockquote");
@@ -10958,8 +11242,9 @@ function listInScope(stack, list4, none) {
10958
11242
  function hardBreak2(_, _1, state, info) {
10959
11243
  let index2 = -1;
10960
11244
  while (++index2 < state.unsafe.length) {
10961
- if (state.unsafe[index2].character === "\n" && patternInScope(state.stack, state.unsafe[index2])) {
10962
- return /[ \t]/.test(info.before) ? "" : " ";
11245
+ const pattern = state.unsafe[index2];
11246
+ if (pattern.character === "\n" && !pattern.before && !pattern.after && patternInScope(state.stack, pattern)) {
11247
+ return /[\t ]/.test(info.before) ? "" : " ";
10963
11248
  }
10964
11249
  }
10965
11250
  return "\\\n";
@@ -10994,8 +11279,8 @@ function formatCodeAsIndented(node2, state) {
10994
11279
  return Boolean(
10995
11280
  state.options.fences === false && node2.value && // If there’s no info…
10996
11281
  !node2.lang && // And there’s a non-whitespace character…
10997
- /[^ \r\n]/.test(node2.value) && // And the value doesn’t start or end in a blank…
10998
- !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node2.value)
11282
+ /[^\n\r ]/.test(node2.value) && // And the value doesn’t start or end in a blank…
11283
+ !/^[\t ]*(?:[\n\r]|$)|(?:^|[\n\r])[\t ]*$/.test(node2.value)
10999
11284
  );
11000
11285
  }
11001
11286
 
@@ -11014,7 +11299,6 @@ function checkFence(state) {
11014
11299
  function code2(node2, _, state, info) {
11015
11300
  const marker = checkFence(state);
11016
11301
  const raw = node2.value || "";
11017
- const suffix = marker === "`" ? "GraveAccent" : "Tilde";
11018
11302
  if (formatCodeAsIndented(node2, state)) {
11019
11303
  const exit4 = state.enter("codeIndented");
11020
11304
  const value2 = state.indentLines(raw, map2);
@@ -11024,6 +11308,7 @@ function code2(node2, _, state, info) {
11024
11308
  const tracker = state.createTracker(info);
11025
11309
  const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3));
11026
11310
  const exit3 = state.enter("codeFenced");
11311
+ const suffix = marker === "`" ? "GraveAccent" : "Tilde";
11027
11312
  let value = tracker.move(sequence);
11028
11313
  if (node2.lang) {
11029
11314
  const subexit = state.enter(`codeFencedLang${suffix}`);
@@ -11140,93 +11425,32 @@ function checkEmphasis(state) {
11140
11425
  return marker;
11141
11426
  }
11142
11427
 
11143
- // node_modules/mdast-util-to-markdown/lib/util/encode-character-reference.js
11144
- function encodeCharacterReference(code4) {
11145
- return "&#x" + code4.toString(16).toUpperCase() + ";";
11146
- }
11147
-
11148
- // node_modules/mdast-util-to-markdown/lib/util/encode-info.js
11149
- function encodeInfo(outside, inside, marker) {
11150
- const outsideKind = classifyCharacter(outside);
11151
- const insideKind = classifyCharacter(inside);
11152
- if (outsideKind === void 0) {
11153
- return insideKind === void 0 ? (
11154
- // Letter inside:
11155
- // we have to encode *both* letters for `_` as it is looser.
11156
- // it already forms for `*` (and GFMs `~`).
11157
- marker === "_" ? { inside: true, outside: true } : { inside: false, outside: false }
11158
- ) : insideKind === 1 ? (
11159
- // Whitespace inside: encode both (letter, whitespace).
11160
- { inside: true, outside: true }
11161
- ) : (
11162
- // Punctuation inside: encode outer (letter)
11163
- { inside: false, outside: true }
11164
- );
11165
- }
11166
- if (outsideKind === 1) {
11167
- return insideKind === void 0 ? (
11168
- // Letter inside: already forms.
11169
- { inside: false, outside: false }
11170
- ) : insideKind === 1 ? (
11171
- // Whitespace inside: encode both (whitespace).
11172
- { inside: true, outside: true }
11173
- ) : (
11174
- // Punctuation inside: already forms.
11175
- { inside: false, outside: false }
11176
- );
11177
- }
11178
- return insideKind === void 0 ? (
11179
- // Letter inside: already forms.
11180
- { inside: false, outside: false }
11181
- ) : insideKind === 1 ? (
11182
- // Whitespace inside: encode inner (whitespace).
11183
- { inside: true, outside: false }
11184
- ) : (
11185
- // Punctuation inside: already forms.
11186
- { inside: false, outside: false }
11187
- );
11188
- }
11189
-
11190
11428
  // node_modules/mdast-util-to-markdown/lib/handle/emphasis.js
11191
- emphasis2.peek = emphasisPeek;
11429
+ emphasis2.attention = attention2;
11430
+ emphasis2.peek = peek;
11192
11431
  function emphasis2(node2, _, state, info) {
11193
- const marker = checkEmphasis(state);
11194
- const exit3 = state.enter("emphasis");
11195
- const tracker = state.createTracker(info);
11196
- const before = tracker.move(marker);
11197
- let between = tracker.move(
11198
- state.containerPhrasing(node2, {
11199
- after: marker,
11200
- before,
11201
- ...tracker.current()
11202
- })
11203
- );
11204
- const betweenHead = between.charCodeAt(0);
11205
- const open = encodeInfo(
11206
- info.before.charCodeAt(info.before.length - 1),
11207
- betweenHead,
11208
- marker
11209
- );
11210
- if (open.inside) {
11211
- between = encodeCharacterReference(betweenHead) + between.slice(1);
11212
- }
11213
- const betweenTail = between.charCodeAt(between.length - 1);
11214
- const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);
11215
- if (close.inside) {
11216
- between = between.slice(0, -1) + encodeCharacterReference(betweenTail);
11217
- }
11218
- const after = tracker.move(marker);
11432
+ const exit3 = state.enter("phrasing");
11433
+ const value = state.containerPhrasing({ type: "root", children: [node2] }, info);
11219
11434
  exit3();
11220
- state.attentionEncodeSurroundingInfo = {
11221
- after: close.outside,
11222
- before: open.outside
11435
+ return value;
11436
+ }
11437
+ function attention2(_, state) {
11438
+ const marker = checkEmphasis(state);
11439
+ return {
11440
+ construct: "emphasis",
11441
+ markers: marker === "*" ? ["*", "_"] : ["_", "*"],
11442
+ sizes: [1]
11223
11443
  };
11224
- return before + between + after;
11225
11444
  }
11226
- function emphasisPeek(_, _1, state) {
11445
+ function peek(_, _1, state) {
11227
11446
  return state.options.emphasis || "*";
11228
11447
  }
11229
11448
 
11449
+ // node_modules/mdast-util-to-markdown/lib/util/encode-character-reference.js
11450
+ function encodeCharacterReference(code4) {
11451
+ return "&#x" + code4.toString(16).toUpperCase() + ";";
11452
+ }
11453
+
11230
11454
  // node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.js
11231
11455
  function formatHeadingAsSetext(node2, state) {
11232
11456
  let literalWithBreak = false;
@@ -11271,8 +11495,9 @@ function heading2(node2, _, state, info) {
11271
11495
  after: "\n",
11272
11496
  ...tracker.current()
11273
11497
  });
11274
- if (/^[\t ]/.test(value)) {
11275
- value = encodeCharacterReference(value.charCodeAt(0)) + value.slice(1);
11498
+ const head = value.charCodeAt(0);
11499
+ if (head === 9 || head === 32) {
11500
+ value = encodeCharacterReference(head) + value.slice(1);
11276
11501
  }
11277
11502
  value = value ? sequence + " " + value : sequence;
11278
11503
  if (state.options.closeAtx) {
@@ -11365,7 +11590,9 @@ function imageReference2(node2, _, state, info) {
11365
11590
  value += tracker.move(alt + "][");
11366
11591
  subexit();
11367
11592
  const stack = state.stack;
11368
- state.stack = [];
11593
+ state.stack = stack.filter(function(d) {
11594
+ return d !== "phrasing";
11595
+ });
11369
11596
  subexit = state.enter("reference");
11370
11597
  const reference = state.safe(state.associationId(node2), {
11371
11598
  before: value,
@@ -11397,14 +11624,14 @@ function inlineCode2(node2, _, state) {
11397
11624
  while (new RegExp("(^|[^`])" + sequence + "([^`]|$)").test(value)) {
11398
11625
  sequence += "`";
11399
11626
  }
11400
- if (/[^ \r\n]/.test(value) && (/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value) || /^`|`$/.test(value))) {
11627
+ if (/[^\n\r ]/.test(value) && (/^[\n\r ]/.test(value) && /[\n\r ]$/.test(value) || /^`|`$/.test(value))) {
11401
11628
  value = " " + value + " ";
11402
11629
  }
11403
11630
  while (++index2 < state.unsafe.length) {
11404
11631
  const pattern = state.unsafe[index2];
11405
11632
  const expression = state.compilePattern(pattern);
11406
- let match;
11407
11633
  if (!pattern.atBreak) continue;
11634
+ let match;
11408
11635
  while (match = expression.exec(value)) {
11409
11636
  let position3 = match.index;
11410
11637
  if (value.charCodeAt(position3) === 10 && value.charCodeAt(position3 - 1) === 13) {
@@ -11424,11 +11651,11 @@ function formatLinkAsAutolink(node2, state) {
11424
11651
  const raw = toString(node2);
11425
11652
  return Boolean(
11426
11653
  !state.options.resourceLink && // If there’s a url…
11427
- node2.url && // And there’s a no title…
11654
+ node2.url && // And there’s no title…
11428
11655
  !node2.title && // And the content of `node` is a single text node…
11429
11656
  node2.children && node2.children.length === 1 && node2.children[0].type === "text" && // And if the url is the same as the content…
11430
11657
  (raw === node2.url || "mailto:" + raw === node2.url) && // And that starts w/ a protocol…
11431
- /^[a-z][a-z+.-]+:/i.test(node2.url) && // And that doesn’t contain ASCII control codes (character escapes and
11658
+ /^[a-z][+\-.a-z]+:/i.test(node2.url) && // And that doesn’t contain ASCII control codes (character escapes and
11432
11659
  // references don’t work), space, or angle brackets…
11433
11660
  !/[\0- <>\u007F]/.test(node2.url)
11434
11661
  );
@@ -11440,12 +11667,12 @@ function link2(node2, _, state, info) {
11440
11667
  const quote = checkQuote(state);
11441
11668
  const suffix = quote === '"' ? "Quote" : "Apostrophe";
11442
11669
  const tracker = state.createTracker(info);
11443
- let exit3;
11444
- let subexit;
11445
11670
  if (formatLinkAsAutolink(node2, state)) {
11446
11671
  const stack = state.stack;
11447
- state.stack = [];
11448
- exit3 = state.enter("autolink");
11672
+ state.stack = stack.filter(function(d) {
11673
+ return d !== "phrasing";
11674
+ });
11675
+ const exit4 = state.enter("autolink");
11449
11676
  let value2 = tracker.move("<");
11450
11677
  value2 += tracker.move(
11451
11678
  state.containerPhrasing(node2, {
@@ -11455,12 +11682,12 @@ function link2(node2, _, state, info) {
11455
11682
  })
11456
11683
  );
11457
11684
  value2 += tracker.move(">");
11458
- exit3();
11685
+ exit4();
11459
11686
  state.stack = stack;
11460
11687
  return value2;
11461
11688
  }
11462
- exit3 = state.enter("link");
11463
- subexit = state.enter("label");
11689
+ const exit3 = state.enter("link");
11690
+ let subexit = state.enter("label");
11464
11691
  let value = tracker.move("[");
11465
11692
  value += tracker.move(
11466
11693
  state.containerPhrasing(node2, {
@@ -11530,7 +11757,9 @@ function linkReference2(node2, _, state, info) {
11530
11757
  value += tracker.move(text7 + "][");
11531
11758
  subexit();
11532
11759
  const stack = state.stack;
11533
- state.stack = [];
11760
+ state.stack = stack.filter(function(d) {
11761
+ return d !== "phrasing";
11762
+ });
11534
11763
  subexit = state.enter("reference");
11535
11764
  const reference = state.safe(state.associationId(node2), {
11536
11765
  before: value,
@@ -11696,41 +11925,16 @@ function paragraph2(node2, _, state, info) {
11696
11925
  return value;
11697
11926
  }
11698
11927
 
11699
- // node_modules/mdast-util-phrasing/lib/index.js
11700
- var phrasing = (
11701
- /** @type {(node?: unknown) => node is Exclude<PhrasingContent, Html>} */
11702
- convert([
11703
- "break",
11704
- "delete",
11705
- "emphasis",
11706
- // To do: next major: removed since footnotes were added to GFM.
11707
- "footnote",
11708
- "footnoteReference",
11709
- "image",
11710
- "imageReference",
11711
- "inlineCode",
11712
- // Enabled by `mdast-util-math`:
11713
- "inlineMath",
11714
- "link",
11715
- "linkReference",
11716
- // Enabled by `mdast-util-mdx`:
11717
- "mdxJsxTextElement",
11718
- // Enabled by `mdast-util-mdx`:
11719
- "mdxTextExpression",
11720
- "strong",
11721
- "text",
11722
- // Enabled by `mdast-util-directive`:
11723
- "textDirective"
11724
- ])
11725
- );
11726
-
11727
11928
  // node_modules/mdast-util-to-markdown/lib/handle/root.js
11728
11929
  function root3(node2, _, state, info) {
11729
11930
  const hasPhrasing = node2.children.some(function(d) {
11730
11931
  return phrasing(d);
11731
11932
  });
11732
- const container = hasPhrasing ? state.containerPhrasing : state.containerFlow;
11733
- return container.call(state, node2, info);
11933
+ if (!hasPhrasing) return state.containerFlow(node2, info);
11934
+ const exit3 = state.enter("phrasing");
11935
+ const value = state.containerPhrasing(node2, info);
11936
+ exit3();
11937
+ return value;
11734
11938
  }
11735
11939
 
11736
11940
  // node_modules/mdast-util-to-markdown/lib/util/check-strong.js
@@ -11745,48 +11949,35 @@ function checkStrong(state) {
11745
11949
  }
11746
11950
 
11747
11951
  // node_modules/mdast-util-to-markdown/lib/handle/strong.js
11748
- strong2.peek = strongPeek;
11952
+ strong2.attention = attention3;
11953
+ strong2.peek = peek2;
11749
11954
  function strong2(node2, _, state, info) {
11750
- const marker = checkStrong(state);
11751
- const exit3 = state.enter("strong");
11752
- const tracker = state.createTracker(info);
11753
- const before = tracker.move(marker + marker);
11754
- let between = tracker.move(
11755
- state.containerPhrasing(node2, {
11756
- after: marker,
11757
- before,
11758
- ...tracker.current()
11759
- })
11760
- );
11761
- const betweenHead = between.charCodeAt(0);
11762
- const open = encodeInfo(
11763
- info.before.charCodeAt(info.before.length - 1),
11764
- betweenHead,
11765
- marker
11766
- );
11767
- if (open.inside) {
11768
- between = encodeCharacterReference(betweenHead) + between.slice(1);
11769
- }
11770
- const betweenTail = between.charCodeAt(between.length - 1);
11771
- const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);
11772
- if (close.inside) {
11773
- between = between.slice(0, -1) + encodeCharacterReference(betweenTail);
11774
- }
11775
- const after = tracker.move(marker + marker);
11955
+ const exit3 = state.enter("phrasing");
11956
+ const value = state.containerPhrasing({ type: "root", children: [node2] }, info);
11776
11957
  exit3();
11777
- state.attentionEncodeSurroundingInfo = {
11778
- after: close.outside,
11779
- before: open.outside
11958
+ return value;
11959
+ }
11960
+ function attention3(_, state) {
11961
+ const marker = checkStrong(state);
11962
+ return {
11963
+ construct: "strong",
11964
+ markers: marker === "*" ? ["*", "_"] : ["_", "*"],
11965
+ sizes: [2]
11780
11966
  };
11781
- return before + between + after;
11782
11967
  }
11783
- function strongPeek(_, _1, state) {
11968
+ function peek2(_, _1, state) {
11784
11969
  return state.options.strong || "*";
11785
11970
  }
11786
11971
 
11787
11972
  // node_modules/mdast-util-to-markdown/lib/handle/text.js
11788
- function text5(node2, _, state, info) {
11789
- return state.safe(node2.value, info);
11973
+ function text5(node2, parent, state, info) {
11974
+ const siblings = parent ? parent.children : [];
11975
+ const index2 = siblings.indexOf(node2);
11976
+ return state.safe(node2.value, {
11977
+ ...info,
11978
+ afterNode: siblings[index2 + 1],
11979
+ beforeNode: siblings[index2 - 1]
11980
+ });
11790
11981
  }
11791
11982
 
11792
11983
  // node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.js
@@ -12790,23 +12981,28 @@ function gfmStrikethrough(options) {
12790
12981
  }
12791
12982
 
12792
12983
  // node_modules/micromark-extension-gfm-table/lib/edit-map.js
12793
- var EditMap = class {
12984
+ var EditMap2 = class {
12794
12985
  /**
12795
12986
  * Create a new edit map.
12796
12987
  */
12797
12988
  constructor() {
12798
12989
  this.map = [];
12990
+ this.index = /* @__PURE__ */ new Map();
12799
12991
  }
12800
12992
  /**
12801
12993
  * Create an edit: a remove and/or add at a certain place.
12802
12994
  *
12803
12995
  * @param {number} index
12996
+ * Index at which to apply the edit.
12804
12997
  * @param {number} remove
12998
+ * Count of items to remove at the index.
12805
12999
  * @param {Array<Event>} add
13000
+ * Items to add at the index.
12806
13001
  * @returns {undefined}
13002
+ * Nothing.
12807
13003
  */
12808
13004
  add(index2, remove, add) {
12809
- addImplementation(this, index2, remove, add);
13005
+ addImplementation2(this, index2, remove, add);
12810
13006
  }
12811
13007
  // To do: add this when moving to `micromark`.
12812
13008
  // /**
@@ -12824,7 +13020,9 @@ var EditMap = class {
12824
13020
  * Done, change the events.
12825
13021
  *
12826
13022
  * @param {Array<Event>} events
13023
+ * List of events to apply the edits to.
12827
13024
  * @returns {undefined}
13025
+ * Nothing.
12828
13026
  */
12829
13027
  consume(events) {
12830
13028
  this.map.sort(function(a, b) {
@@ -12850,22 +13048,22 @@ var EditMap = class {
12850
13048
  slice = vecs.pop();
12851
13049
  }
12852
13050
  this.map.length = 0;
13051
+ this.index.clear();
12853
13052
  }
12854
13053
  };
12855
- function addImplementation(editMap, at, remove, add) {
12856
- let index2 = 0;
13054
+ function addImplementation2(editMap, at, remove, add) {
12857
13055
  if (remove === 0 && add.length === 0) {
12858
13056
  return;
12859
13057
  }
12860
- while (index2 < editMap.map.length) {
12861
- if (editMap.map[index2][0] === at) {
12862
- editMap.map[index2][1] += remove;
12863
- editMap.map[index2][2].push(...add);
12864
- return;
12865
- }
12866
- index2 += 1;
13058
+ const existing = editMap.index.get(at);
13059
+ if (existing) {
13060
+ existing[1] += remove;
13061
+ existing[2].push(...add);
13062
+ return;
12867
13063
  }
12868
- editMap.map.push([at, remove, add]);
13064
+ const change = [at, remove, add];
13065
+ editMap.map.push(change);
13066
+ editMap.index.set(at, change);
12869
13067
  }
12870
13068
 
12871
13069
  // node_modules/micromark-extension-gfm-table/lib/infer.js
@@ -12916,10 +13114,15 @@ function tokenizeTable(effects, ok3, nok) {
12916
13114
  function start2(code4) {
12917
13115
  let index2 = self2.events.length - 1;
12918
13116
  while (index2 > -1) {
12919
- const type = self2.events[index2][1].type;
13117
+ const {
13118
+ type
13119
+ } = self2.events[index2][1];
12920
13120
  if (type === "lineEnding" || // Note: markdown-rs uses `whitespace` instead of `linePrefix`
12921
- type === "linePrefix") index2--;
12922
- else break;
13121
+ type === "linePrefix") {
13122
+ index2--;
13123
+ } else {
13124
+ break;
13125
+ }
12923
13126
  }
12924
13127
  const tail = index2 > -1 ? self2.events[index2][1].type : null;
12925
13128
  const next = tail === "tableHead" || tail === "tableRow" ? bodyRowStart : headRowBefore;
@@ -13133,7 +13336,7 @@ function resolveTable(events, context) {
13133
13336
  let currentTable;
13134
13337
  let currentBody;
13135
13338
  let currentCell;
13136
- const map3 = new EditMap();
13339
+ const map3 = new EditMap2();
13137
13340
  while (++index2 < events.length) {
13138
13341
  const event = events[index2];
13139
13342
  const token = event[1];
@@ -13793,7 +13996,7 @@ function sessionIdOf(session) {
13793
13996
  if (session && typeof session === "object" && "sessionId" in session) return String(session.sessionId);
13794
13997
  return String(session);
13795
13998
  }
13796
- function attachOfficialBtw(commandUi, claim, t) {
13999
+ function attachOfficialBtw(commandUi, claim, t, isSubagent) {
13797
14000
  const live = commandUi;
13798
14001
  if (!live) return () => {
13799
14002
  };
@@ -13803,7 +14006,7 @@ function attachOfficialBtw(commandUi, claim, t) {
13803
14006
  live.candidates = async (...args) => {
13804
14007
  const rows = await original.apply(live, args);
13805
14008
  if (!Array.isArray(rows)) return rows;
13806
- return rows.map((row) => {
14009
+ return rows.filter((row) => !(isSubagent(sessionIdOf(args[0])) && row && typeof row === "object" && "name" in row && row.name === "btw")).map((row) => {
13807
14010
  if (!row || typeof row !== "object" || !("name" in row) || row.name !== "btw") return row;
13808
14011
  const item = row;
13809
14012
  return {
@@ -13821,14 +14024,14 @@ function attachOfficialBtw(commandUi, claim, t) {
13821
14024
  }
13822
14025
  if (typeof live.dispatch === "function") {
13823
14026
  const original = live.dispatch.bind(live);
13824
- live.dispatch = (pick) => pick.candidate?.name === "btw" ? claim(sessionIdOf(pick.session)) : original(pick);
14027
+ live.dispatch = (pick) => pick.candidate?.name === "btw" ? isSubagent(sessionIdOf(pick.session)) ? void 0 : claim(sessionIdOf(pick.session)) : original(pick);
13825
14028
  restore.push(() => {
13826
14029
  live.dispatch = original;
13827
14030
  });
13828
14031
  }
13829
14032
  if (typeof live.matchSpace === "function") {
13830
14033
  const original = live.matchSpace.bind(live);
13831
- live.matchSpace = (session, token) => token === "/btw" ? claim(sessionIdOf(session)) : original(session, token);
14034
+ live.matchSpace = (session, token) => token === "/btw" ? isSubagent(sessionIdOf(session)) ? void 0 : claim(sessionIdOf(session)) : original(session, token);
13832
14035
  restore.push(() => {
13833
14036
  live.matchSpace = original;
13834
14037
  });
@@ -13837,6 +14040,7 @@ function attachOfficialBtw(commandUi, claim, t) {
13837
14040
  const original = live.matchEnter.bind(live);
13838
14041
  live.matchEnter = async (session, line, signal, envelope) => {
13839
14042
  if (!/^\/btw(?:\s|$)/.test(line.trim())) return original(session, line, signal, envelope);
14043
+ if (isSubagent(sessionIdOf(session))) throw new Error(t("error.subagent"));
13840
14044
  if (envelope?.attachments || envelope?.images) throw new Error(t("error.removeAttachments"));
13841
14045
  return claim(sessionIdOf(session));
13842
14046
  };
@@ -13848,6 +14052,7 @@ function attachOfficialBtw(commandUi, claim, t) {
13848
14052
  const original = live.execute.bind(live);
13849
14053
  live.execute = async (session, line, attachments) => {
13850
14054
  if (!/^\/btw(?:\s|$)/.test(line)) return original(session, line, attachments);
14055
+ if (isSubagent(sessionIdOf(session))) return { kind: "error", text: t("error.subagent") };
13851
14056
  if (Array.isArray(attachments) && attachments.length) return { kind: "error", text: t("error.attachments") };
13852
14057
  const outcome = claim(sessionIdOf(session));
13853
14058
  if (!outcome || typeof outcome !== "object" || !("claim" in outcome)) return { kind: "error", text: t("error.backend") };
@@ -13868,9 +14073,19 @@ function apply(ctx) {
13868
14073
  const t = ctx.locale.bind(NS);
13869
14074
  const slots = ctx.get("slots");
13870
14075
  const remote = ctx.get("remote");
14076
+ const sessions = ctx.get("sessions");
14077
+ const isSubagent = (id) => Boolean(sessions.subagentAddress?.(id)) || sessions.list?.getSnapshot().byId[id]?.origin === "subagent";
13871
14078
  const execute = async (session, line, signal) => {
13872
14079
  const response = await remote.commands.execute(session, line, [], signal);
13873
- if (!response.ok) throw new Error(response.error.message);
14080
+ if (!response.ok) {
14081
+ const failure = response.error;
14082
+ const code4 = failure.code;
14083
+ const details = failure.details;
14084
+ const reason = details && typeof details === "object" && "reason" in details && typeof details.reason === "string" ? details.reason : void 0;
14085
+ const ownedBySubagent = (code4 === "agent-busy" || code4 === "session/agent-busy") && (reason === "use subagent delivery for this child session" || failure.message === `session "${session}" is owned by subagent routing`);
14086
+ if (ownedBySubagent) throw new SideRequestNotStartedError(t("error.subagent"));
14087
+ throw new Error(failure.message);
14088
+ }
13874
14089
  if (!response.value) throw new Error(t("error.backend"));
13875
14090
  return { kind: response.value.result.kind, text: response.value.result.text ?? "" };
13876
14091
  };
@@ -13880,11 +14095,12 @@ function apply(ctx) {
13880
14095
  }, t);
13881
14096
  const claim = (sessionId) => ({ claim: {
13882
14097
  name: "btw",
13883
- token: "/btw",
14098
+ token: "/btw ",
13884
14099
  get hint() {
13885
14100
  return t("command.hint");
13886
14101
  },
13887
14102
  submit: async (args, _actx, attachments) => {
14103
+ if (isSubagent(sessionId)) return { kind: "error", text: t("error.subagent") };
13888
14104
  if (attachments.length) return { kind: "error", text: t("error.attachments") };
13889
14105
  try {
13890
14106
  await store.ask(sessionId, args.trim());
@@ -13894,8 +14110,8 @@ function apply(ctx) {
13894
14110
  }
13895
14111
  }
13896
14112
  } });
13897
- if (typeof ctx.inject === "function") ctx.inject(["commandUi"], (scope) => attachOfficialBtw(scope.get("commandUi"), (sessionId) => claim(sessionId), t));
13898
- else ctx.effect(() => attachOfficialBtw(ctx.get("commandUi"), (sessionId) => claim(sessionId), t));
14113
+ if (typeof ctx.inject === "function") ctx.inject(["commandUi"], (scope) => attachOfficialBtw(scope.get("commandUi"), (sessionId) => claim(sessionId), t, isSubagent));
14114
+ else ctx.effect(() => attachOfficialBtw(ctx.get("commandUi"), (sessionId) => claim(sessionId), t, isSubagent));
13899
14115
  ctx.effect(() => {
13900
14116
  const style = document.createElement("style");
13901
14117
  style.dataset.plugin = "@michengai/dsh-btw";
@@ -13907,7 +14123,7 @@ function apply(ctx) {
13907
14123
  });
13908
14124
  ctx.effect(() => () => store.dispose());
13909
14125
  function Dock(props) {
13910
- return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(SelectionAsk, { key: props.session.sessionId, store, sessionId: props.session.sessionId, t: props.t, addToConversation: (reference) => {
14126
+ return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, !props.session.subagent && !isSubagent(props.session.sessionId) && /* @__PURE__ */ import_react7.default.createElement(SelectionAsk, { key: props.session.sessionId, store, sessionId: props.session.sessionId, t: props.t, addToConversation: (reference) => {
13911
14127
  const session = ctx.get("sessions").scope(props.session.sessionId);
13912
14128
  if (!session) throw new Error(props.t("error.backend"));
13913
14129
  addQuoteToComposer(ctx.conversation.input.for(session), reference, props.t);