@synclineapi/editor 2.0.0 → 3.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.
@@ -1,14 +1,362 @@
1
- var De = Object.defineProperty;
2
- var He = (s, e, t) => e in s ? De(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var u = (s, e, t) => He(s, typeof e != "symbol" ? e + "" : e, t);
4
- const Re = {
1
+ var rt = Object.defineProperty;
2
+ var ot = (r, e, t) => e in r ? rt(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var p = (r, e, t) => ot(r, typeof e != "symbol" ? e + "" : e, t);
4
+ const Z = Object.freeze({ site: "\0root", clock: 0 });
5
+ function z(r) {
6
+ return `${r.site}@${r.clock}`;
7
+ }
8
+ function he(r, e) {
9
+ return r.site === e.site && r.clock === e.clock;
10
+ }
11
+ function pe(r) {
12
+ return Object.fromEntries(r);
13
+ }
14
+ function at(r) {
15
+ return new Map(Object.entries(r));
16
+ }
17
+ class de {
18
+ constructor(e) {
19
+ /** All nodes, keyed by their canonical string ID */
20
+ p(this, "_chars", /* @__PURE__ */ new Map());
21
+ /** The full ordered sequence of IDs (visible + tombstones) */
22
+ p(this, "_seq", []);
23
+ /** Reverse index: idStr → index in _seq (invalidated on splice, rebuilt lazily) */
24
+ p(this, "_idxDirty", !1);
25
+ p(this, "_idxMap", /* @__PURE__ */ new Map());
26
+ p(this, "siteId");
27
+ p(this, "_clock", 0);
28
+ p(this, "stateVector", /* @__PURE__ */ new Map());
29
+ /** Full operation log — used to answer sync-requests from peers */
30
+ p(this, "_opLog", []);
31
+ this.siteId = e;
32
+ const t = { id: Z, after: Z, char: "", deleted: !0 };
33
+ this._chars.set(z(Z), t), this._seq = [Z], this._rebuildIdx();
34
+ }
35
+ // ── Public accessors ──────────────────────────────────────
36
+ get clock() {
37
+ return this._clock;
38
+ }
39
+ /** Return the visible document text */
40
+ getText() {
41
+ let e = "";
42
+ for (const t of this._seq) {
43
+ const i = this._chars.get(z(t));
44
+ i.deleted || (e += i.char);
45
+ }
46
+ return e;
47
+ }
48
+ /** Number of visible characters */
49
+ get length() {
50
+ let e = 0;
51
+ for (const t of this._seq)
52
+ this._chars.get(z(t)).deleted || e++;
53
+ return e;
54
+ }
55
+ // ── Local editing (produces ops to send to peers) ─────────
56
+ /**
57
+ * Insert `text` at visible offset `offset`.
58
+ * Returns the generated ops (apply them locally AND send to peers).
59
+ */
60
+ localInsert(e, t) {
61
+ const i = [];
62
+ let s = this._visibleIdAt(e - 1);
63
+ for (const n of t) {
64
+ const o = this._genId(), a = { type: "insert", id: o, after: s, char: n };
65
+ this._applyInsert(
66
+ a,
67
+ !0
68
+ /* local */
69
+ ), this._opLog.push(a), i.push(a), s = o;
70
+ }
71
+ return i;
72
+ }
73
+ /**
74
+ * Delete `length` visible characters starting at `offset`.
75
+ * Returns the generated ops.
76
+ */
77
+ localDelete(e, t) {
78
+ const i = this._visibleIdsInRange(e, t), s = [];
79
+ for (const n of i) {
80
+ const o = { type: "delete", id: n };
81
+ this._applyDelete(o, !0), this._opLog.push(o), s.push(o);
82
+ }
83
+ return s;
84
+ }
85
+ // ── Remote op application ──────────────────────────────────
86
+ /**
87
+ * Apply an op from a remote peer.
88
+ * Returns true if the op was new (applied), false if already seen.
89
+ */
90
+ apply(e) {
91
+ const t = z(e.id);
92
+ if (e.type === "insert") {
93
+ if (this._chars.has(t)) return !1;
94
+ this._applyInsert(e, !1);
95
+ } else {
96
+ const i = this._chars.get(t);
97
+ if (!i || i.deleted) return !1;
98
+ this._applyDelete(e, !1);
99
+ }
100
+ return this._opLog.push(e), this._updateSV(e.id), !0;
101
+ }
102
+ // ── Sync helpers ───────────────────────────────────────────
103
+ /** Return all ops not yet seen by `sv` */
104
+ getOpsSince(e) {
105
+ return this._opLog.filter((t) => (e.get(t.id.site) ?? 0) < t.id.clock);
106
+ }
107
+ getStateVector() {
108
+ return new Map(this.stateVector);
109
+ }
110
+ // ── Serialisation ──────────────────────────────────────────
111
+ serialize() {
112
+ return { siteId: this.siteId, clock: this._clock, ops: [...this._opLog] };
113
+ }
114
+ static deserialize(e) {
115
+ const t = new de(e.siteId);
116
+ t._clock = e.clock;
117
+ for (const i of e.ops) t.apply(i);
118
+ return t;
119
+ }
120
+ // ── Internal helpers ───────────────────────────────────────
121
+ _genId() {
122
+ return { site: this.siteId, clock: ++this._clock };
123
+ }
124
+ _updateSV(e) {
125
+ const t = this.stateVector.get(e.site) ?? 0;
126
+ e.clock > t && this.stateVector.set(e.site, e.clock), e.clock >= this._clock && (this._clock = e.clock + 1);
127
+ }
128
+ _applyInsert(e, t) {
129
+ t && this._updateSV(e.id);
130
+ const i = { id: e.id, after: e.after, char: e.char, deleted: !1 };
131
+ this._chars.set(z(e.id), i);
132
+ const s = z(e.after);
133
+ this._idxDirty && this._rebuildIdx();
134
+ let n = (this._idxMap.get(s) ?? 0) + 1;
135
+ for (; n < this._seq.length; ) {
136
+ const o = this._seq[n], a = this._chars.get(z(o));
137
+ if (!he(a.after, e.after)) break;
138
+ if (this._cmp(o, e.id) > 0) {
139
+ n++;
140
+ continue;
141
+ }
142
+ break;
143
+ }
144
+ this._seq.splice(n, 0, e.id), this._idxDirty = !0;
145
+ }
146
+ _applyDelete(e, t) {
147
+ t && this._updateSV(e.id);
148
+ const i = this._chars.get(z(e.id));
149
+ i && (i.deleted = !0);
150
+ }
151
+ /**
152
+ * YATA comparison: returns >0 if `a` has priority (goes first / to the left).
153
+ * Higher clock wins; equal clock → lower siteId wins.
154
+ */
155
+ _cmp(e, t) {
156
+ return e.clock !== t.clock ? e.clock - t.clock : e.site < t.site ? 1 : e.site > t.site ? -1 : 0;
157
+ }
158
+ _rebuildIdx() {
159
+ this._idxMap.clear();
160
+ for (let e = 0; e < this._seq.length; e++)
161
+ this._idxMap.set(z(this._seq[e]), e);
162
+ this._idxDirty = !1;
163
+ }
164
+ /** Return the ID of the n-th visible character (0-indexed). Returns ROOT_ID for n<0. */
165
+ _visibleIdAt(e) {
166
+ if (e < 0) return Z;
167
+ let t = 0;
168
+ for (const s of this._seq)
169
+ if (!(this._chars.get(z(s)).deleted || he(s, Z))) {
170
+ if (t === e) return s;
171
+ t++;
172
+ }
173
+ let i = Z;
174
+ for (const s of this._seq)
175
+ this._chars.get(z(s)).deleted || (i = s);
176
+ return i;
177
+ }
178
+ /** Return IDs of `len` visible characters starting at `offset` */
179
+ _visibleIdsInRange(e, t) {
180
+ const i = [];
181
+ let s = 0;
182
+ for (const n of this._seq) {
183
+ if (i.length >= t) break;
184
+ this._chars.get(z(n)).deleted || he(n, Z) || (s >= e && i.push(n), s++);
185
+ }
186
+ return i;
187
+ }
188
+ }
189
+ function lt(r, e) {
190
+ if (r === e) return [];
191
+ if (r.length === 0) return [{ type: "insert", offset: 0, chars: e }];
192
+ if (e.length === 0) return [{ type: "delete", offset: 0, chars: r }];
193
+ let t = 0;
194
+ const i = Math.min(r.length, e.length);
195
+ for (; t < i && r[t] === e[t]; ) t++;
196
+ let s = 0;
197
+ for (; s < r.length - t && s < e.length - t && r[r.length - 1 - s] === e[e.length - 1 - s]; ) s++;
198
+ const n = r.slice(t, r.length - s), o = e.slice(t, e.length - s), a = [];
199
+ return n.length > 0 && a.push({ type: "delete", offset: t, chars: n }), o.length > 0 && a.push({ type: "insert", offset: t, chars: o }), a;
200
+ }
201
+ const Ae = 1e4, ct = 3e3, De = [
202
+ "#e06c75",
203
+ "#98c379",
204
+ "#e5c07b",
205
+ "#61afef",
206
+ "#c678dd",
207
+ "#56b6c2",
208
+ "#d19a66",
209
+ "#be5046"
210
+ ];
211
+ function dt(r) {
212
+ let e = 0;
213
+ for (let t = 0; t < r.length; t++) e = e * 31 + r.charCodeAt(t) >>> 0;
214
+ return De[e % De.length];
215
+ }
216
+ class ht {
217
+ constructor(e, t) {
218
+ p(this, "_local");
219
+ p(this, "_peers", /* @__PURE__ */ new Map());
220
+ p(this, "_transport");
221
+ p(this, "_unsub", null);
222
+ p(this, "_heartbeat", null);
223
+ p(this, "_gcTimer", null);
224
+ p(this, "_onChange", null);
225
+ this._transport = e, this._local = {
226
+ siteId: e.siteId,
227
+ name: t,
228
+ color: dt(e.siteId),
229
+ cursor: null,
230
+ selection: null,
231
+ updatedAt: Date.now()
232
+ }, this._unsub = e.onMessage((i) => {
233
+ var n;
234
+ if (i.type !== "awareness") return;
235
+ const s = i.state;
236
+ s.siteId !== e.siteId && (this._peers.set(s.siteId, s), (n = this._onChange) == null || n.call(this, this._peers));
237
+ }), this._heartbeat = setInterval(() => this._broadcast(), ct), this._gcTimer = setInterval(() => {
238
+ var n;
239
+ const i = Date.now();
240
+ let s = !1;
241
+ for (const [o, a] of this._peers)
242
+ i - a.updatedAt > Ae && (this._peers.delete(o), s = !0);
243
+ s && ((n = this._onChange) == null || n.call(this, this._peers));
244
+ }, Ae);
245
+ }
246
+ /** Called by the binding when the local cursor moves */
247
+ updateCursor(e, t) {
248
+ this._local = { ...this._local, cursor: { row: e, col: t }, updatedAt: Date.now() }, this._broadcast();
249
+ }
250
+ updateSelection(e, t) {
251
+ this._local = { ...this._local, selection: { from: e, to: t }, updatedAt: Date.now() }, this._broadcast();
252
+ }
253
+ clearSelection() {
254
+ this._local = { ...this._local, selection: null, updatedAt: Date.now() }, this._broadcast();
255
+ }
256
+ get localState() {
257
+ return this._local;
258
+ }
259
+ get peers() {
260
+ return this._peers;
261
+ }
262
+ onChange(e) {
263
+ this._onChange = e;
264
+ }
265
+ /** Expose broadcast for external use (e.g. initial announcement) */
266
+ broadcast() {
267
+ this._broadcast();
268
+ }
269
+ _broadcast() {
270
+ this._transport.send({ type: "awareness", state: { ...this._local, updatedAt: Date.now() } });
271
+ }
272
+ destroy() {
273
+ var e;
274
+ (e = this._unsub) == null || e.call(this), this._heartbeat && clearInterval(this._heartbeat), this._gcTimer && clearInterval(this._gcTimer);
275
+ }
276
+ }
277
+ class Qe {
278
+ // true while applying remote ops
279
+ constructor(e, t, i, s = {}) {
280
+ p(this, "doc");
281
+ p(this, "awareness");
282
+ p(this, "_editor");
283
+ p(this, "_transport");
284
+ p(this, "_unsub");
285
+ p(this, "_lastText");
286
+ p(this, "_suppress", !1);
287
+ if (this._editor = e, this.doc = t, this._transport = i, this._lastText = e.getValue(), this._lastText) {
288
+ const n = t.localInsert(0, this._lastText);
289
+ i.send({
290
+ type: "ops",
291
+ fromSite: i.siteId,
292
+ ops: n,
293
+ sv: pe(t.stateVector)
294
+ });
295
+ }
296
+ this.awareness = new ht(i, s.name ?? "Peer"), this.awareness.onChange((n) => {
297
+ var o;
298
+ return (o = s.onPeersChange) == null ? void 0 : o.call(s, n);
299
+ }), e.updateConfig({
300
+ onChange: (n) => this._onEditorChange(n)
301
+ }), this._unsub = i.onMessage((n) => this._onMessage(n)), i.send({
302
+ type: "sync-request",
303
+ fromSite: i.siteId,
304
+ sv: pe(t.stateVector)
305
+ }), this.awareness.broadcast();
306
+ }
307
+ // ── Editor → CRDT ──────────────────────────────────────────
308
+ _onEditorChange(e) {
309
+ if (this._suppress) return;
310
+ const t = this._lastText;
311
+ this._lastText = e;
312
+ const i = lt(t, e);
313
+ if (i.length === 0) return;
314
+ const s = [], n = i.filter((a) => a.type === "delete"), o = i.filter((a) => a.type === "insert");
315
+ for (const a of [...n].reverse())
316
+ s.push(...this.doc.localDelete(a.offset, a.chars.length));
317
+ for (const a of o)
318
+ s.push(...this.doc.localInsert(a.offset, a.chars));
319
+ s.length > 0 && this._transport.send({
320
+ type: "ops",
321
+ fromSite: this._transport.siteId,
322
+ ops: s,
323
+ sv: pe(this.doc.stateVector)
324
+ });
325
+ }
326
+ // ── Transport → CRDT → Editor ──────────────────────────────
327
+ _onMessage(e) {
328
+ if (e.type === "ops")
329
+ this._applyRemoteOps(e.ops);
330
+ else if (e.type === "sync-request") {
331
+ const t = at(e.sv), i = this.doc.getOpsSince(t);
332
+ i.length > 0 && this._transport.send({
333
+ type: "sync-reply",
334
+ fromSite: this._transport.siteId,
335
+ ops: i
336
+ });
337
+ } else e.type === "sync-reply" && this._applyRemoteOps(e.ops);
338
+ }
339
+ _applyRemoteOps(e) {
340
+ let t = !1;
341
+ for (const s of e)
342
+ this.doc.apply(s) && (t = !0);
343
+ if (!t) return;
344
+ const i = this.doc.getText();
345
+ i !== this._lastText && (this._suppress = !0, this._lastText = i, this._editor.setValue(i), this._suppress = !1);
346
+ }
347
+ // ── Lifecycle ──────────────────────────────────────────────
348
+ destroy() {
349
+ this._unsub(), this.awareness.destroy();
350
+ }
351
+ }
352
+ const pt = 22, je = 6, et = 300, ut = 60, se = 14, Pe = 20, Q = 7.82, ft = 13, gt = 2, bt = 80, q = 2, Y = 1.1, oe = 3, mt = 120, _t = 700, yt = 120, vt = {
5
353
  typescript: "//",
6
354
  javascript: "//",
7
355
  css: "//",
8
356
  json: "",
9
357
  markdown: "",
10
358
  text: ""
11
- }, se = /* @__PURE__ */ new Set([
359
+ }, we = /* @__PURE__ */ new Set([
12
360
  "function",
13
361
  "const",
14
362
  "let",
@@ -65,7 +413,7 @@ const Re = {
65
413
  "undefined",
66
414
  "require",
67
415
  "constructor"
68
- ]), Be = /* @__PURE__ */ new Set([
416
+ ]), wt = /* @__PURE__ */ new Set([
69
417
  "function",
70
418
  "const",
71
419
  "let",
@@ -110,7 +458,7 @@ const Re = {
110
458
  "require",
111
459
  "constructor",
112
460
  "static"
113
- ]), je = /* @__PURE__ */ new Set([
461
+ ]), kt = /* @__PURE__ */ new Set([
114
462
  // At-rules (without @)
115
463
  "media",
116
464
  "keyframes",
@@ -176,7 +524,7 @@ const Re = {
176
524
  "min",
177
525
  "max",
178
526
  "clamp"
179
- ]), Pe = /* @__PURE__ */ new Set(["null", "true", "false"]), he = /* @__PURE__ */ new Set(), ae = /* @__PURE__ */ new Set([
527
+ ]), xt = /* @__PURE__ */ new Set(["null", "true", "false"]), $e = /* @__PURE__ */ new Set(), ke = /* @__PURE__ */ new Set([
180
528
  "number",
181
529
  "string",
182
530
  "boolean",
@@ -203,7 +551,7 @@ const Re = {
203
551
  "Event",
204
552
  "MouseEvent",
205
553
  "CustomEvent"
206
- ]), $e = /* @__PURE__ */ new Set([
554
+ ]), Ct = /* @__PURE__ */ new Set([
207
555
  "number",
208
556
  "string",
209
557
  "boolean",
@@ -223,24 +571,24 @@ const Re = {
223
571
  "Event",
224
572
  "MouseEvent",
225
573
  "CustomEvent"
226
- ]), We = /* @__PURE__ */ new Set(), Ne = /* @__PURE__ */ new Set(), pe = /* @__PURE__ */ new Set(), Ee = {
227
- typescript: se,
228
- javascript: Be,
229
- css: je,
230
- json: Pe,
231
- markdown: he,
232
- text: he
233
- }, Se = {
234
- typescript: ae,
235
- javascript: $e,
236
- css: We,
237
- json: Ne,
238
- markdown: pe,
239
- text: pe
574
+ ]), St = /* @__PURE__ */ new Set(), Tt = /* @__PURE__ */ new Set(), He = /* @__PURE__ */ new Set(), tt = {
575
+ typescript: we,
576
+ javascript: wt,
577
+ css: kt,
578
+ json: xt,
579
+ markdown: $e,
580
+ text: $e
581
+ }, it = {
582
+ typescript: ke,
583
+ javascript: Ct,
584
+ css: St,
585
+ json: Tt,
586
+ markdown: He,
587
+ text: He
240
588
  };
241
- function ue(s, e) {
589
+ function We(r, e) {
242
590
  return {
243
- fileId: s,
591
+ fileId: r,
244
592
  doc: [...e],
245
593
  cur: { row: 0, col: 0 },
246
594
  sel: null,
@@ -250,208 +598,208 @@ function ue(s, e) {
250
598
  scrollTop: 0
251
599
  };
252
600
  }
253
- function E(s, e = 300) {
601
+ function A(r, e = et) {
254
602
  const t = {
255
- doc: [...s.doc],
256
- cur: { ...s.cur },
257
- sel: s.sel ? { ...s.sel } : null
603
+ doc: [...r.doc],
604
+ cur: { ...r.cur },
605
+ sel: r.sel ? { ...r.sel } : null
258
606
  };
259
- s.undoStack.push(t), s.undoStack.length > e && s.undoStack.shift(), s.redoStack = [], s.dirty = !0;
607
+ r.undoStack.push(t), r.undoStack.length > e && r.undoStack.shift(), r.redoStack = [], r.dirty = !0;
260
608
  }
261
- function Oe(s) {
262
- if (!s.undoStack.length) return !1;
609
+ function Mt(r) {
610
+ if (!r.undoStack.length) return !1;
263
611
  const e = {
264
- doc: [...s.doc],
265
- cur: { ...s.cur },
266
- sel: s.sel ? { ...s.sel } : null
612
+ doc: [...r.doc],
613
+ cur: { ...r.cur },
614
+ sel: r.sel ? { ...r.sel } : null
267
615
  };
268
- s.redoStack.push(e);
269
- const t = s.undoStack.pop();
270
- return s.doc = t.doc, s.cur = t.cur, s.sel = t.sel, !0;
616
+ r.redoStack.push(e);
617
+ const t = r.undoStack.pop();
618
+ return r.doc = t.doc, r.cur = t.cur, r.sel = t.sel, !0;
271
619
  }
272
- function Fe(s) {
273
- if (!s.redoStack.length) return !1;
620
+ function Et(r) {
621
+ if (!r.redoStack.length) return !1;
274
622
  const e = {
275
- doc: [...s.doc],
276
- cur: { ...s.cur },
277
- sel: s.sel ? { ...s.sel } : null
623
+ doc: [...r.doc],
624
+ cur: { ...r.cur },
625
+ sel: r.sel ? { ...r.sel } : null
278
626
  };
279
- s.undoStack.push(e);
280
- const t = s.redoStack.pop();
281
- return s.doc = t.doc, s.cur = t.cur, s.sel = t.sel, !0;
627
+ r.undoStack.push(e);
628
+ const t = r.redoStack.pop();
629
+ return r.doc = t.doc, r.cur = t.cur, r.sel = t.sel, !0;
282
630
  }
283
- function A(s) {
284
- const { doc: e, cur: t } = s;
631
+ function L(r) {
632
+ const { doc: e, cur: t } = r;
285
633
  t.row = Math.max(0, Math.min(e.length - 1, t.row)), t.col = Math.max(0, Math.min((e[t.row] ?? "").length, t.col));
286
634
  }
287
- function P(s) {
288
- const { ar: e, ac: t, fr: i, fc: r } = s;
289
- return e < i || e === i && t <= r ? s : { ar: i, ac: r, fr: e, fc: t };
635
+ function J(r) {
636
+ const { ar: e, ac: t, fr: i, fc: s } = r;
637
+ return e < i || e === i && t <= s ? r : { ar: i, ac: s, fr: e, fc: t };
290
638
  }
291
- function fe(s, e, t) {
292
- if (!s) return null;
293
- const i = P(s);
639
+ function Oe(r, e, t) {
640
+ if (!r) return null;
641
+ const i = J(r);
294
642
  return e < i.ar || e > i.fr ? null : {
295
643
  start: e === i.ar ? i.ac : 0,
296
644
  end: e === i.fr ? i.fc : t
297
645
  };
298
646
  }
299
- function Ue(s) {
300
- if (!s.sel) return 0;
301
- const e = P(s.sel);
647
+ function It(r) {
648
+ if (!r.sel) return 0;
649
+ const e = J(r.sel);
302
650
  let t = 0;
303
651
  for (let i = e.ar; i <= e.fr; i++) {
304
- const r = s.doc[i] ?? "", n = i === e.ar ? e.ac : 0, a = i === e.fr ? e.fc : r.length;
305
- t += a - n;
652
+ const s = r.doc[i] ?? "", n = i === e.ar ? e.ac : 0, o = i === e.fr ? e.fc : s.length;
653
+ t += o - n;
306
654
  }
307
655
  return t;
308
656
  }
309
- function ge(s) {
310
- if (!s.sel) return "";
311
- const e = P(s.sel), t = [];
657
+ function Ne(r) {
658
+ if (!r.sel) return "";
659
+ const e = J(r.sel), t = [];
312
660
  for (let i = e.ar; i <= e.fr; i++) {
313
- const r = s.doc[i] ?? "";
314
- t.push(r.slice(i === e.ar ? e.ac : 0, i === e.fr ? e.fc : r.length));
661
+ const s = r.doc[i] ?? "";
662
+ t.push(s.slice(i === e.ar ? e.ac : 0, i === e.fr ? e.fc : s.length));
315
663
  }
316
664
  return t.join(`
317
665
  `);
318
666
  }
319
- function O(s) {
320
- const e = s.sel;
321
- if (!e) return s.cur;
322
- const t = P(e), i = (s.doc[t.ar] ?? "").slice(0, t.ac), r = (s.doc[t.fr] ?? "").slice(t.fc);
323
- return s.doc.splice(t.ar, t.fr - t.ar + 1, i + r), s.sel = null, { row: t.ar, col: t.ac };
667
+ function re(r) {
668
+ const e = r.sel;
669
+ if (!e) return r.cur;
670
+ const t = J(e), i = (r.doc[t.ar] ?? "").slice(0, t.ac), s = (r.doc[t.fr] ?? "").slice(t.fc);
671
+ return r.doc.splice(t.ar, t.fr - t.ar + 1, i + s), r.sel = null, { row: t.ar, col: t.ac };
324
672
  }
325
- function ze(s, e, t) {
326
- if (!t || s.length <= e) return [s];
673
+ function Lt(r, e, t) {
674
+ if (!t || r.length <= e) return [r];
327
675
  const i = [];
328
- let r = 0;
329
- for (; r < s.length; ) {
330
- if (s.length - r <= e) {
331
- i.push(s.slice(r));
676
+ let s = 0;
677
+ for (; s < r.length; ) {
678
+ if (r.length - s <= e) {
679
+ i.push(r.slice(s));
332
680
  break;
333
681
  }
334
- const n = r + e;
335
- let a = -1;
336
- for (let l = n; l > r; l--)
337
- if (s[l - 1] === " ") {
338
- a = l;
682
+ const n = s + e;
683
+ let o = -1;
684
+ for (let a = n; a > s; a--)
685
+ if (r[a - 1] === " ") {
686
+ o = a;
339
687
  break;
340
688
  }
341
- a === -1 ? (i.push(s.slice(r, n)), r = n) : (i.push(s.slice(r, a)), r = a);
689
+ o === -1 ? (i.push(r.slice(s, n)), s = n) : (i.push(r.slice(s, o)), s = o);
342
690
  }
343
691
  return i;
344
692
  }
345
- function Ge(s, e, t, i) {
346
- const r = [], n = [], a = [];
347
- let l = -1;
348
- for (let o = 0; o < s.length; o++) {
349
- if (o > 0 && o <= l) {
350
- a.push(n.length), r.push([s[o] ?? ""]);
693
+ function Rt(r, e, t, i) {
694
+ const s = [], n = [], o = [];
695
+ let a = -1;
696
+ for (let l = 0; l < r.length; l++) {
697
+ if (l > 0 && l <= a) {
698
+ o.push(n.length), s.push([r[l] ?? ""]);
351
699
  continue;
352
700
  }
353
- a.push(n.length);
354
- const c = ze(s[o] ?? "", e, t);
355
- r.push(c), c.forEach((d, p) => n.push({ docLine: o, segIdx: p, text: d })), i.has(o) && (l = i.get(o));
701
+ o.push(n.length);
702
+ const c = Lt(r[l] ?? "", e, t);
703
+ s.push(c), c.forEach((d, u) => n.push({ docLine: l, segIdx: u, text: d })), i.has(l) && (a = i.get(l));
356
704
  }
357
- return { segments: r, visualRows: n, docToVisArr: a };
705
+ return { segments: s, visualRows: n, docToVisArr: o };
358
706
  }
359
- function F(s, e, t) {
360
- const i = s.segments[e] ?? [""];
361
- let r = t;
707
+ function ee(r, e, t) {
708
+ const i = r.segments[e] ?? [""];
709
+ let s = t;
362
710
  for (let n = 0; n < i.length; n++) {
363
- if (r <= i[n].length || n === i.length - 1)
711
+ if (s <= i[n].length || n === i.length - 1)
364
712
  return {
365
- visRow: s.docToVisArr[e] + n,
366
- colInSeg: Math.min(r, i[n].length)
713
+ visRow: r.docToVisArr[e] + n,
714
+ colInSeg: Math.min(s, i[n].length)
367
715
  };
368
- r -= i[n].length;
716
+ s -= i[n].length;
369
717
  }
370
- return { visRow: s.docToVisArr[e] ?? 0, colInSeg: 0 };
718
+ return { visRow: r.docToVisArr[e] ?? 0, colInSeg: 0 };
371
719
  }
372
- function Y(s, e, t) {
373
- var a;
374
- const i = s.visualRows[e];
720
+ function le(r, e, t) {
721
+ var o;
722
+ const i = r.visualRows[e];
375
723
  if (!i) return { row: 0, col: 0 };
376
- const r = s.segments[i.docLine] ?? [""];
377
- let n = Math.min(t, ((a = r[i.segIdx]) == null ? void 0 : a.length) ?? 0);
378
- for (let l = 0; l < i.segIdx; l++) n += r[l].length;
724
+ const s = r.segments[i.docLine] ?? [""];
725
+ let n = Math.min(t, ((o = s[i.segIdx]) == null ? void 0 : o.length) ?? 0);
726
+ for (let a = 0; a < i.segIdx; a++) n += s[a].length;
379
727
  return { row: i.docLine, col: n };
380
728
  }
381
- function oe(s, e = {}) {
382
- var d, p;
383
- const t = [], i = s.length;
384
- let r = 0;
385
- const n = (h, g, y) => {
386
- y > g && t.push({ cls: h, start: g, end: y });
387
- }, a = Ee[e.language ?? "typescript"] ?? se, l = Se[e.language ?? "typescript"] ?? ae, o = (d = e.extraKeywords) != null && d.size ? /* @__PURE__ */ new Set([...a, ...e.extraKeywords]) : a, c = (p = e.extraTypes) != null && p.size ? /* @__PURE__ */ new Set([...l, ...e.extraTypes]) : l;
388
- for (; r < i; ) {
389
- if (s[r] === "/" && s[r + 1] === "/") {
390
- n("cmt", r, i);
729
+ function xe(r, e = {}) {
730
+ var d, u;
731
+ const t = [], i = r.length;
732
+ let s = 0;
733
+ const n = (h, _, y) => {
734
+ y > _ && t.push({ cls: h, start: _, end: y });
735
+ }, o = tt[e.language ?? "typescript"] ?? we, a = it[e.language ?? "typescript"] ?? ke, l = (d = e.extraKeywords) != null && d.size ? /* @__PURE__ */ new Set([...o, ...e.extraKeywords]) : o, c = (u = e.extraTypes) != null && u.size ? /* @__PURE__ */ new Set([...a, ...e.extraTypes]) : a;
736
+ for (; s < i; ) {
737
+ if (r[s] === "/" && r[s + 1] === "/") {
738
+ n("cmt", s, i);
391
739
  break;
392
740
  }
393
- if (s[r] === "*" || s[r] === "/" && s[r + 1] === "*") {
394
- n("cmt", r, i);
741
+ if (r[s] === "*" || r[s] === "/" && r[s + 1] === "*") {
742
+ n("cmt", s, i);
395
743
  break;
396
744
  }
397
- if (s[r] === "@") {
398
- let h = r + 1;
399
- for (; h < i && /\w/.test(s[h]); ) h++;
400
- n("dec", r, h), r = h;
745
+ if (r[s] === "@") {
746
+ let h = s + 1;
747
+ for (; h < i && /\w/.test(r[h]); ) h++;
748
+ n("dec", s, h), s = h;
401
749
  continue;
402
750
  }
403
- if (s[r] === '"' || s[r] === "'" || s[r] === "`") {
404
- const h = s[r];
405
- let g = r + 1;
406
- for (; g < i; ) {
407
- if (s[g] === "\\") {
408
- g += 2;
751
+ if (r[s] === '"' || r[s] === "'" || r[s] === "`") {
752
+ const h = r[s];
753
+ let _ = s + 1;
754
+ for (; _ < i; ) {
755
+ if (r[_] === "\\") {
756
+ _ += 2;
409
757
  continue;
410
758
  }
411
- if (s[g] === h) {
412
- g++;
759
+ if (r[_] === h) {
760
+ _++;
413
761
  break;
414
762
  }
415
- g++;
763
+ _++;
416
764
  }
417
- n("str", r, g), r = g;
765
+ n("str", s, _), s = _;
418
766
  continue;
419
767
  }
420
- if (/\d/.test(s[r]) && (r === 0 || !/\w/.test(s[r - 1]))) {
421
- let h = r;
422
- for (; h < i && /[\d._xXa-fA-F]/.test(s[h]); ) h++;
423
- n("num", r, h), r = h;
768
+ if (/\d/.test(r[s]) && (s === 0 || !/\w/.test(r[s - 1]))) {
769
+ let h = s;
770
+ for (; h < i && /[\d._xXa-fA-F]/.test(r[h]); ) h++;
771
+ n("num", s, h), s = h;
424
772
  continue;
425
773
  }
426
- if (/[a-zA-Z_$]/.test(s[r])) {
427
- let h = r;
428
- for (; h < i && /[\w$]/.test(s[h]); ) h++;
429
- const g = s.slice(r, h);
430
- o.has(g) ? n("kw", r, h) : c.has(g) ? n("typ", r, h) : h < i && s[h] === "(" ? n("fn", r, h) : /^[A-Z]/.test(g) && n("cls", r, h), r = h;
774
+ if (/[a-zA-Z_$]/.test(r[s])) {
775
+ let h = s;
776
+ for (; h < i && /[\w$]/.test(r[h]); ) h++;
777
+ const _ = r.slice(s, h);
778
+ l.has(_) ? n("kw", s, h) : c.has(_) ? n("typ", s, h) : h < i && r[h] === "(" ? n("fn", s, h) : /^[A-Z]/.test(_) && n("cls", s, h), s = h;
431
779
  continue;
432
780
  }
433
- if (/[=<>!&|+\-*/%^~?:,;.[\]{}()]/.test(s[r])) {
434
- n("op", r, r + 1), r++;
781
+ if (/[=<>!&|+\-*/%^~?:,;.[\]{}()]/.test(r[s])) {
782
+ n("op", s, s + 1), s++;
435
783
  continue;
436
784
  }
437
- r++;
785
+ s++;
438
786
  }
439
787
  return t;
440
788
  }
441
- function Ie(s, e) {
442
- const t = new Array(s.length).fill("");
789
+ function st(r, e) {
790
+ const t = new Array(r.length).fill("");
443
791
  for (const i of e)
444
- for (let r = i.start; r < i.end; r++) t[r] = i.cls;
792
+ for (let s = i.start; s < i.end; s++) t[s] = i.cls;
445
793
  return t;
446
794
  }
447
- class Ke {
795
+ class Bt {
448
796
  constructor(e = 5e3) {
449
- u(this, "_cache", /* @__PURE__ */ new Map());
450
- u(this, "_maxSize");
797
+ p(this, "_cache", /* @__PURE__ */ new Map());
798
+ p(this, "_maxSize");
451
799
  // ── Performance counters ──────────────────────────────────
452
- u(this, "_hits", 0);
453
- u(this, "_misses", 0);
454
- u(this, "_evictions", 0);
800
+ p(this, "_hits", 0);
801
+ p(this, "_misses", 0);
802
+ p(this, "_evictions", 0);
455
803
  this._maxSize = e;
456
804
  }
457
805
  /** Live snapshot of cache performance. Useful for observability. */
@@ -483,7 +831,7 @@ class Ke {
483
831
  this._hits = 0, this._misses = 0, this._evictions = 0;
484
832
  }
485
833
  }
486
- const qe = {
834
+ const At = {
487
835
  id: "",
488
836
  name: "VR Dark",
489
837
  description: "Default deep dark theme",
@@ -544,7 +892,7 @@ const qe = {
544
892
  tokTyp: "#6ec9d4",
545
893
  tokDec: "#f28b82"
546
894
  }
547
- }, Ve = {
895
+ }, Dt = {
548
896
  id: "vscode-dark",
549
897
  name: "VSCode Dark+",
550
898
  description: "Visual Studio Code dark",
@@ -605,7 +953,7 @@ const qe = {
605
953
  tokTyp: "#4ec9b0",
606
954
  tokDec: "#9cdcfe"
607
955
  }
608
- }, Ye = {
956
+ }, jt = {
609
957
  id: "monokai",
610
958
  name: "Monokai",
611
959
  description: "Classic Sublime Text theme",
@@ -666,7 +1014,7 @@ const qe = {
666
1014
  tokTyp: "#66d9e8",
667
1015
  tokDec: "#fd971f"
668
1016
  }
669
- }, Je = {
1017
+ }, Pt = {
670
1018
  id: "dracula",
671
1019
  name: "Dracula",
672
1020
  description: "Purple-tinted dark theme",
@@ -727,7 +1075,7 @@ const qe = {
727
1075
  tokTyp: "#8be9fd",
728
1076
  tokDec: "#ffb86c"
729
1077
  }
730
- }, Xe = {
1078
+ }, $t = {
731
1079
  id: "github-light",
732
1080
  name: "GitHub Light",
733
1081
  description: "GitHub's clean light theme",
@@ -788,7 +1136,7 @@ const qe = {
788
1136
  tokTyp: "#0550ae",
789
1137
  tokDec: "#0969da"
790
1138
  }
791
- }, Ze = {
1139
+ }, Ht = {
792
1140
  id: "solarized-light",
793
1141
  name: "Solarized Light",
794
1142
  description: "Warm precision light theme",
@@ -849,7 +1197,7 @@ const qe = {
849
1197
  tokTyp: "#268bd2",
850
1198
  tokDec: "#cb4b16"
851
1199
  }
852
- }, Qe = {
1200
+ }, Wt = {
853
1201
  id: "mdx-dark",
854
1202
  name: "MDX Dark",
855
1203
  description: "Catppuccin Mocha — matches .smdx-dark MDX editor chrome, single-colour tokens",
@@ -911,7 +1259,7 @@ const qe = {
911
1259
  tokTyp: "#e2e8f0",
912
1260
  tokDec: "#e2e8f0"
913
1261
  }
914
- }, et = {
1262
+ }, Ot = {
915
1263
  id: "mdx-light",
916
1264
  name: "MDX Light",
917
1265
  description: "Clean light — matches default .smdx-editor MDX chrome, single-colour tokens",
@@ -973,16 +1321,16 @@ const qe = {
973
1321
  tokTyp: "#1e293b",
974
1322
  tokDec: "#1e293b"
975
1323
  }
976
- }, tt = [
977
- qe,
978
- Ve,
979
- Ye,
980
- Je,
981
- Xe,
982
- Ze,
983
- Qe,
984
- et
985
- ], it = {
1324
+ }, Nt = [
1325
+ At,
1326
+ Dt,
1327
+ jt,
1328
+ Pt,
1329
+ $t,
1330
+ Ht,
1331
+ Wt,
1332
+ Ot
1333
+ ], Ft = {
986
1334
  bg0: "--bg0",
987
1335
  bg1: "--bg1",
988
1336
  bg2: "--bg2",
@@ -1038,13 +1386,13 @@ const qe = {
1038
1386
  tokTyp: "--tok-typ",
1039
1387
  tokDec: "--tok-dec"
1040
1388
  };
1041
- class rt {
1389
+ class Ut {
1042
1390
  constructor(e) {
1043
- u(this, "_registry", /* @__PURE__ */ new Map());
1044
- u(this, "_activeId", "");
1045
- u(this, "_root");
1391
+ p(this, "_registry", /* @__PURE__ */ new Map());
1392
+ p(this, "_activeId", "");
1393
+ p(this, "_root");
1046
1394
  this._root = e;
1047
- for (const t of tt)
1395
+ for (const t of Nt)
1048
1396
  this._registry.set(t.id, t);
1049
1397
  }
1050
1398
  /** Register a custom or override theme. */
@@ -1070,11 +1418,11 @@ class rt {
1070
1418
  }
1071
1419
  _applyTokens(e) {
1072
1420
  const t = this._root.style;
1073
- for (const [i, r] of Object.entries(it))
1074
- t.setProperty(r, e[i]);
1421
+ for (const [i, s] of Object.entries(Ft))
1422
+ t.setProperty(s, e[i]);
1075
1423
  }
1076
1424
  }
1077
- const nt = `
1425
+ const zt = `
1078
1426
  /* ── Reset ── */
1079
1427
  *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
1080
1428
 
@@ -1143,7 +1491,11 @@ const nt = `
1143
1491
  .sl-editor::-webkit-scrollbar-track{background:transparent}
1144
1492
  .sl-editor::-webkit-scrollbar-thumb{background:var(--border3);border-radius:5px;border:2px solid var(--bg2)}
1145
1493
  .sl-spacer{position:absolute;left:0;top:0;width:1px;pointer-events:none}
1146
- .sl-vp{position:absolute;left:0;right:0;will-change:transform}
1494
+ /* overflow-x:clip clips horizontal overflow without creating a scroll container.
1495
+ * Unlike overflow-x:hidden, it does NOT force overflow-y from visible→auto,
1496
+ * so absolutely-positioned children (remote cursor name labels) that extend
1497
+ * above their row are never clipped on the Y axis. */
1498
+ .sl-vp{position:absolute;left:0;right:0;overflow-x:clip;overflow-y:visible;will-change:transform}
1147
1499
 
1148
1500
  /* ── Editor row ── */
1149
1501
  .sl-er{display:flex;align-items:stretch;position:relative}
@@ -1179,11 +1531,66 @@ const nt = `
1179
1531
  box-shadow:0 0 8px var(--cur-glow);
1180
1532
  animation:sl-blink 1.05s step-end infinite;pointer-events:none}
1181
1533
 
1534
+ /* ── Snippet tab-stop ghost markers ── */
1535
+ .sl-snip-stop{display:inline;width:0;height:0;position:relative}
1536
+ .sl-snip-stop::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
1537
+ background:var(--cur);border-radius:1px;opacity:0.28;pointer-events:none}
1538
+
1539
+ /* ── Remote peer cursors ── */
1540
+ /*
1541
+ * Architecture:
1542
+ * .sl-rc — zero-size inline anchor; creates relative-positioning context
1543
+ * .sl-rc::after — the 2 px tall vertical beam (full line height, like local cursor)
1544
+ * .sl-rc-label — name chip anchored at beam-top, translated up by its own height
1545
+ * so it always floats ABOVE the current row regardless of font/line-height.
1546
+ * .sl-rc-label::after — tiny downward triangle connecting label to beam
1547
+ */
1548
+ .sl-rc{display:inline;width:0;height:0;position:relative}
1549
+ /* Full-height coloured beam */
1550
+ .sl-rc::after{
1551
+ content:'';position:absolute;left:0;top:1px;
1552
+ width:2px;height:20px;
1553
+ background:var(--rc-color,#e06c75);border-radius:1px;
1554
+ pointer-events:none;z-index:3;
1555
+ box-shadow:0 0 6px color-mix(in srgb,var(--rc-color,#e06c75) 55%,transparent)}
1556
+ /* Name label — sits at beam-top then transforms up by its own height */
1557
+ .sl-rc-label{
1558
+ position:absolute;top:1px;left:2px;
1559
+ transform:translateY(-100%);
1560
+ background:var(--rc-color,#e06c75);color:#fff;
1561
+ font-size:10px;padding:1px 6px;
1562
+ border-radius:3px 3px 3px 0;white-space:nowrap;
1563
+ pointer-events:none;opacity:0.93;
1564
+ font-family:var(--mono);line-height:1.5;
1565
+ z-index:10;
1566
+ box-shadow:0 1px 5px rgba(0,0,0,.35);
1567
+ /* Small downward-pointing triangle connecting label to beam */
1568
+ }
1569
+ .sl-rc-label::after{
1570
+ content:'';position:absolute;bottom:-4px;left:0;
1571
+ width:0;height:0;
1572
+ border-left:4px solid transparent;
1573
+ border-right:4px solid transparent;
1574
+ border-top:4px solid var(--rc-color,#e06c75);
1575
+ }
1576
+ /* Flipped variant: label below the cursor beam (used on the first visible row
1577
+ so the label is never clipped by the scroll container's overflow). */
1578
+ .sl-rc-flip .sl-rc-label{
1579
+ top:auto;bottom:1px;
1580
+ transform:translateY(100%);
1581
+ border-radius:0 3px 3px 3px}
1582
+ .sl-rc-flip .sl-rc-label::after{
1583
+ bottom:auto;top:-4px;
1584
+ border-top:none;
1585
+ border-bottom:4px solid var(--rc-color,#e06c75)}
1586
+ /* Remote peer selection highlight — semi-transparent coloured fill */
1587
+ .sl-rs{border-radius:2px;background:var(--rs-color,rgba(224,108,117,0.28))}
1588
+
1182
1589
  /* ── Overlays ── */
1183
1590
  .sl-sh{background:var(--sel-bg);border-radius:2px}
1184
- .sl-fh{background:var(--find-bg);border:1px solid var(--find-border);border-radius:2px}
1185
- .sl-fh.sl-fh-cur{background:var(--find-cur-bg);border:1px solid var(--find-cur-border);color:var(--find-cur-text)}
1186
- .sl-wh{background:var(--word-hl-bg);border:1px solid var(--word-hl-border);border-radius:2px}
1591
+ .sl-fh{background:var(--find-bg);box-shadow:0 0 0 1px var(--find-border);border-radius:2px}
1592
+ .sl-fh.sl-fh-cur{background:var(--find-cur-bg);box-shadow:0 0 0 1px var(--find-cur-border);color:var(--find-cur-text)}
1593
+ .sl-wh{background:var(--word-hl-bg);box-shadow:0 0 0 1px var(--word-hl-border);border-radius:2px}
1187
1594
  .sl-bm{box-shadow:0 0 0 1px var(--bm-border);border-radius:2px}
1188
1595
  .sl-ig{position:absolute;top:0;bottom:0;width:1px;background:var(--indent-guide);pointer-events:none}
1189
1596
 
@@ -1219,6 +1626,24 @@ const nt = `
1219
1626
  .sl-sb-right{margin-left:auto;display:flex;align-items:center}
1220
1627
  .sl-sb-wrap.sl-on{font-weight:700}
1221
1628
 
1629
+ /* ── Placeholder ── */
1630
+ .sl-placeholder{position:absolute;top:0;right:0;pointer-events:none;user-select:none;
1631
+ color:var(--text3);white-space:pre;overflow:hidden;z-index:1}
1632
+
1633
+ /* ── Go to Line bar ── */
1634
+ .sl-gtl-bar{position:absolute;top:0;left:50%;z-index:50;background:var(--bg3);
1635
+ border:1px solid var(--border3);border-top:none;border-radius:0 0 10px 10px;
1636
+ display:flex;align-items:center;gap:8px;padding:8px 12px;
1637
+ transform:translateX(-50%) translateY(-100%);transition:transform .18s,box-shadow .18s;pointer-events:none}
1638
+ .sl-gtl-bar.sl-open{transform:translateX(-50%) translateY(0);pointer-events:all;box-shadow:0 8px 28px rgba(0,0,0,.4)}
1639
+ .sl-gtl-label{font-size:12px;color:var(--text2);white-space:nowrap}
1640
+ .sl-gtl-input{width:72px;background:var(--bg4);border:1px solid var(--border3);
1641
+ border-radius:5px;padding:4px 8px;font-size:12px;font-family:var(--mono);
1642
+ color:var(--text);outline:none;transition:border-color .15s;text-align:center}
1643
+ .sl-gtl-input:focus{border-color:var(--accent)}
1644
+ .sl-gtl-input.sl-gtl-err{border-color:#e05252}
1645
+ .sl-gtl-hint{font-size:11px;color:var(--text3);font-family:var(--mono);min-width:40px}
1646
+
1222
1647
  /* ── Find + Replace bar ── */
1223
1648
  .sl-find-bar{position:absolute;top:0;right:125px;z-index:50;background:var(--bg3);
1224
1649
  border:1px solid var(--border3);border-top:none;border-radius:0 0 10px 10px;
@@ -1337,57 +1762,57 @@ const nt = `
1337
1762
  .sl-empty{flex:1;display:flex;flex-direction:column;align-items:center;
1338
1763
  justify-content:center;gap:10px;color:var(--text3);font-size:13px}
1339
1764
  `;
1340
- function L(s, e, t) {
1341
- const i = document.createElement(s);
1765
+ function D(r, e, t) {
1766
+ const i = document.createElement(r);
1342
1767
  return e && (i.className = e), i;
1343
1768
  }
1344
- function q(s) {
1345
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1769
+ function ne(r) {
1770
+ return r.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1346
1771
  }
1347
- function X(s, e = document.documentElement) {
1348
- return getComputedStyle(e).getPropertyValue(s).trim();
1772
+ function ue(r, e = document.documentElement) {
1773
+ return getComputedStyle(e).getPropertyValue(r).trim();
1349
1774
  }
1350
- function be(s, e) {
1351
- const t = s.replace("#", ""), i = parseInt(t.slice(0, 2), 16), r = parseInt(t.slice(2, 4), 16), n = parseInt(t.slice(4, 6), 16);
1352
- return `rgba(${i},${r},${n},${e})`;
1775
+ function Fe(r, e) {
1776
+ const t = r.replace("#", ""), i = parseInt(t.slice(0, 2), 16), s = parseInt(t.slice(2, 4), 16), n = parseInt(t.slice(4, 6), 16);
1777
+ return `rgba(${i},${s},${n},${e})`;
1353
1778
  }
1354
- function me(s) {
1355
- return s.split(`
1779
+ function Ue(r) {
1780
+ return r.split(`
1356
1781
  `);
1357
1782
  }
1358
- function D(s) {
1359
- return s.join(`
1783
+ function P(r) {
1784
+ return r.join(`
1360
1785
  `);
1361
1786
  }
1362
- function _e(s) {
1363
- return (s.match(/^(\s*)/) ?? ["", ""])[1];
1787
+ function ze(r) {
1788
+ return (r.match(/^(\s*)/) ?? ["", ""])[1];
1364
1789
  }
1365
- function J(s) {
1366
- return " ".repeat(Math.max(0, s));
1790
+ function ce(r) {
1791
+ return " ".repeat(Math.max(0, r));
1367
1792
  }
1368
- function Ae(s) {
1369
- return /[\w$]/.test(s);
1793
+ function nt(r) {
1794
+ return /[\w$]/.test(r);
1370
1795
  }
1371
- function le(s, e, t = Ae) {
1796
+ function Ce(r, e, t = nt) {
1372
1797
  let i = e;
1373
- for (; i > 0 && t(s[i - 1]); ) i--;
1798
+ for (; i > 0 && t(r[i - 1]); ) i--;
1374
1799
  return i;
1375
1800
  }
1376
- function ce(s, e, t = Ae) {
1801
+ function Se(r, e, t = nt) {
1377
1802
  let i = e;
1378
- for (; i < s.length && t(s[i]); ) i++;
1803
+ for (; i < r.length && t(r[i]); ) i++;
1379
1804
  return i;
1380
1805
  }
1381
- function Z(s, e) {
1806
+ function fe(r, e) {
1382
1807
  let t = 0, i = null;
1383
- return (...r) => {
1384
- const n = Date.now(), a = e - (n - t);
1385
- a <= 0 ? (i !== null && (clearTimeout(i), i = null), t = n, s(...r)) : i === null && (i = setTimeout(() => {
1386
- t = Date.now(), i = null, s(...r);
1387
- }, a));
1808
+ return (...s) => {
1809
+ const n = Date.now(), o = e - (n - t);
1810
+ o <= 0 ? (i !== null && (clearTimeout(i), i = null), t = n, r(...s)) : i === null && (i = setTimeout(() => {
1811
+ t = Date.now(), i = null, r(...s);
1812
+ }, o));
1388
1813
  };
1389
1814
  }
1390
- const st = {
1815
+ const qt = {
1391
1816
  fontSize: [8, 72, 13],
1392
1817
  lineHeight: [14, 64, 22],
1393
1818
  tabSize: [1, 16, 2],
@@ -1400,80 +1825,80 @@ const st = {
1400
1825
  maxUndoHistory: [10, 5e3, 300],
1401
1826
  undoBatchMs: [0, 5e3, 700]
1402
1827
  };
1403
- function at(s, e, t, i) {
1404
- const r = Number(s);
1405
- return Number.isFinite(r) ? Math.max(e, Math.min(t, Math.round(r))) : i;
1828
+ function Gt(r, e, t, i) {
1829
+ const s = Number(r);
1830
+ return Number.isFinite(s) ? Math.max(e, Math.min(t, Math.round(s))) : i;
1406
1831
  }
1407
- function ye(s) {
1408
- const e = { ...s };
1409
- for (const [t, i] of Object.entries(st))
1410
- if (t in s && s[t] !== void 0) {
1411
- const [r, n, a] = i;
1412
- e[t] = at(s[t], r, n, a);
1832
+ function qe(r) {
1833
+ const e = { ...r };
1834
+ for (const [t, i] of Object.entries(qt))
1835
+ if (t in r && r[t] !== void 0) {
1836
+ const [s, n, o] = i;
1837
+ e[t] = Gt(r[t], s, n, o);
1413
1838
  }
1414
1839
  return e;
1415
1840
  }
1416
- const Q = { "(": ")", "{": "}", "[": "]" }, ee = { ")": "(", "}": "{", "]": "[" };
1417
- function ot(s, e) {
1418
- const { row: t, col: i } = e, r = s[t] ?? "";
1419
- let n = r[i], a = i;
1420
- if (!Q[n] && !ee[n] && (n = r[i - 1], a = i - 1), !n) return null;
1421
- if (Q[n]) {
1422
- const l = Q[n];
1423
- let o = 0;
1424
- for (let c = t; c < Math.min(s.length, t + 500); c++) {
1425
- const d = s[c] ?? "", p = c === t ? a : 0;
1426
- for (let h = p; h < d.length; h++)
1427
- if (d[h] === n) o++;
1428
- else if (d[h] === l && (o--, o === 0))
1841
+ const ge = { "(": ")", "{": "}", "[": "]" }, be = { ")": "(", "}": "{", "]": "[" };
1842
+ function Vt(r, e) {
1843
+ const { row: t, col: i } = e, s = r[t] ?? "";
1844
+ let n = s[i], o = i;
1845
+ if (!ge[n] && !be[n] && (n = s[i - 1], o = i - 1), !n) return null;
1846
+ if (ge[n]) {
1847
+ const a = ge[n];
1848
+ let l = 0;
1849
+ for (let c = t; c < Math.min(r.length, t + 500); c++) {
1850
+ const d = r[c] ?? "", u = c === t ? o : 0;
1851
+ for (let h = u; h < d.length; h++)
1852
+ if (d[h] === n) l++;
1853
+ else if (d[h] === a && (l--, l === 0))
1429
1854
  return {
1430
- open: { row: t, col: a },
1855
+ open: { row: t, col: o },
1431
1856
  close: { row: c, col: h }
1432
1857
  };
1433
1858
  }
1434
- } else if (ee[n]) {
1435
- const l = ee[n];
1436
- let o = 0;
1859
+ } else if (be[n]) {
1860
+ const a = be[n];
1861
+ let l = 0;
1437
1862
  for (let c = t; c >= Math.max(0, t - 500); c--) {
1438
- const d = s[c] ?? "", p = c === t ? a : d.length - 1;
1439
- for (let h = p; h >= 0; h--)
1440
- if (d[h] === n) o++;
1441
- else if (d[h] === l && (o--, o === 0))
1863
+ const d = r[c] ?? "", u = c === t ? o : d.length - 1;
1864
+ for (let h = u; h >= 0; h--)
1865
+ if (d[h] === n) l++;
1866
+ else if (d[h] === a && (l--, l === 0))
1442
1867
  return {
1443
1868
  open: { row: c, col: h },
1444
- close: { row: t, col: a }
1869
+ close: { row: t, col: o }
1445
1870
  };
1446
1871
  }
1447
1872
  }
1448
1873
  return null;
1449
1874
  }
1450
- function lt(s, e) {
1451
- const t = s[e] ?? "";
1875
+ function Kt(r, e) {
1876
+ const t = r[e] ?? "";
1452
1877
  let i = 0;
1453
- for (const r of t)
1454
- r === "{" ? i++ : r === "}" && i--;
1878
+ for (const s of t)
1879
+ s === "{" ? i++ : s === "}" && i--;
1455
1880
  return i > 0;
1456
1881
  }
1457
- function ct(s, e) {
1882
+ function Yt(r, e) {
1458
1883
  let t = 0;
1459
- for (let i = e; i < s.length; i++)
1460
- for (const r of s[i] ?? "")
1461
- if (r === "{") t++;
1462
- else if (r === "}" && (t--, t === 0))
1884
+ for (let i = e; i < r.length; i++)
1885
+ for (const s of r[i] ?? "")
1886
+ if (s === "{") t++;
1887
+ else if (s === "}" && (t--, t === 0))
1463
1888
  return i;
1464
1889
  return null;
1465
1890
  }
1466
- function dt(s, e, t) {
1467
- const i = new Map(s);
1891
+ function Jt(r, e, t) {
1892
+ const i = new Map(r);
1468
1893
  if (i.has(t))
1469
1894
  i.delete(t);
1470
1895
  else {
1471
- const r = ct(e, t);
1472
- r !== null && r > t && i.set(t, r);
1896
+ const s = Yt(e, t);
1897
+ s !== null && s > t && i.set(t, s);
1473
1898
  }
1474
1899
  return i;
1475
1900
  }
1476
- const ht = /* @__PURE__ */ new Set([
1901
+ const Xt = /* @__PURE__ */ new Set([
1477
1902
  "img",
1478
1903
  "input",
1479
1904
  "br",
@@ -1489,44 +1914,44 @@ const ht = /* @__PURE__ */ new Set([
1489
1914
  "track",
1490
1915
  "wbr"
1491
1916
  ]);
1492
- function ve(s) {
1493
- const e = s.trim();
1917
+ function Ge(r) {
1918
+ const e = r.trim();
1494
1919
  if (!e) return null;
1495
1920
  try {
1496
- const t = re(e);
1921
+ const t = ye(e);
1497
1922
  return t === e ? null : t;
1498
1923
  } catch {
1499
1924
  return null;
1500
1925
  }
1501
1926
  }
1502
- function re(s) {
1503
- if (s.includes(">")) {
1504
- const t = s.indexOf(">");
1505
- return te(s.slice(0, t), re(s.slice(t + 1)));
1927
+ function ye(r) {
1928
+ if (r.includes(">")) {
1929
+ const t = r.indexOf(">");
1930
+ return me(r.slice(0, t), ye(r.slice(t + 1)));
1506
1931
  }
1507
- if (s.includes("+"))
1508
- return s.split("+").map((t) => re(t.trim())).join(`
1932
+ if (r.includes("+"))
1933
+ return r.split("+").map((t) => ye(t.trim())).join(`
1509
1934
  `);
1510
- const e = s.match(/^(.+)\*(\d+)$/);
1935
+ const e = r.match(/^(.+)\*(\d+)$/);
1511
1936
  if (e) {
1512
1937
  const t = parseInt(e[2], 10);
1513
- return Array.from({ length: t }, (i, r) => te(e[1], `$${r + 1}`)).join(`
1938
+ return Array.from({ length: t }, (i, s) => me(e[1], `$${s + 1}`)).join(`
1514
1939
  `);
1515
1940
  }
1516
- return te(s, "$1");
1941
+ return me(r, "$1");
1517
1942
  }
1518
- function te(s, e) {
1519
- const t = s.match(/#([\w-]+)/), i = s.match(/\.([\w.-]+)/g), r = s.match(/\[([^\]]+)\]/);
1520
- let n = s.replace(/#[\w-]+/g, "").replace(/\.[\w.-]+/g, "").replace(/\[[^\]]+\]/g, "").trim() || "div", a = "";
1521
- return t && (a += ` id="${t[1]}"`), i && (a += ` class="${i.map((l) => l.slice(1)).join(" ")}"`), r && (a += ` ${r[1]}`), ht.has(n) ? `<${n}${a}>` : `<${n}${a}>${e}</${n}>`;
1943
+ function me(r, e) {
1944
+ const t = r.match(/#([\w-]+)/), i = r.match(/\.([\w.-]+)/g), s = r.match(/\[([^\]]+)\]/);
1945
+ let n = r.replace(/#[\w-]+/g, "").replace(/\.[\w.-]+/g, "").replace(/\[[^\]]+\]/g, "").trim() || "div", o = "";
1946
+ return t && (o += ` id="${t[1]}"`), i && (o += ` class="${i.map((a) => a.slice(1)).join(" ")}"`), s && (o += ` ${s[1]}`), Xt.has(n) ? `<${n}${o}>` : `<${n}${o}>${e}</${n}>`;
1522
1947
  }
1523
- function we(s, e) {
1948
+ function Ve(r, e) {
1524
1949
  let t = e;
1525
- for (; t > 0 && /[\w#.[\]*>+{}()$@:-]/.test(s[t - 1]); ) t--;
1526
- const i = s.slice(t, e);
1950
+ for (; t > 0 && /[\w#.[\]*>+{}()$@:-]/.test(r[t - 1]); ) t--;
1951
+ const i = r.slice(t, e);
1527
1952
  return i.length < 2 ? null : { abbr: i, start: t };
1528
1953
  }
1529
- const pt = [
1954
+ const Zt = [
1530
1955
  {
1531
1956
  label: "fn",
1532
1957
  kind: "snip",
@@ -1688,7 +2113,7 @@ switch (expr) {
1688
2113
  $4
1689
2114
  }`
1690
2115
  }
1691
- ], ut = [
2116
+ ], Qt = [
1692
2117
  {
1693
2118
  label: "flex",
1694
2119
  kind: "snip",
@@ -1757,7 +2182,7 @@ gap: $2;`,
1757
2182
  body: "--$1: $2;",
1758
2183
  language: ["css"]
1759
2184
  }
1760
- ], ft = [
2185
+ ], ei = [
1761
2186
  {
1762
2187
  label: "accordion",
1763
2188
  kind: "snip",
@@ -1842,171 +2267,171 @@ gap: $2;`,
1842
2267
  </table>`
1843
2268
  }
1844
2269
  ];
1845
- function gt(s) {
1846
- const e = [...ft];
1847
- return (s === "typescript" || s === "javascript") && e.push(...pt.filter((t) => !t.language || (Array.isArray(t.language) ? t.language.includes(s) : t.language === s))), s === "css" && e.push(...ut), e;
2270
+ function ti(r) {
2271
+ const e = [...ei];
2272
+ return (r === "typescript" || r === "javascript") && e.push(...Zt.filter((t) => !t.language || (Array.isArray(t.language) ? t.language.includes(r) : t.language === r))), r === "css" && e.push(...Qt), e;
1848
2273
  }
1849
- function bt(s, e, t) {
2274
+ function ii(r, e, t) {
1850
2275
  let i = e;
1851
- for (; i > 0 && /\w/.test(s[i - 1]); ) i--;
1852
- const r = s.slice(i, e);
1853
- if (!r) return null;
1854
- const n = t.find((a) => a.kind === "snip" && a.label === r);
2276
+ for (; i > 0 && /\w/.test(r[i - 1]); ) i--;
2277
+ const s = r.slice(i, e);
2278
+ if (!s) return null;
2279
+ const n = t.find((o) => o.kind === "snip" && o.label === s);
1855
2280
  return n ? { snippet: n, start: i } : null;
1856
2281
  }
1857
- function mt() {
2282
+ function si() {
1858
2283
  return { cursors: [], searchWord: "", lastMatchRow: -1, lastMatchCol: -1 };
1859
2284
  }
1860
- function ke(s, e, t, i) {
1861
- s.cursors.some((n) => n.row === e && n.col === t) || s.cursors.push({ row: e, col: t, sel: i });
2285
+ function Ke(r, e, t, i) {
2286
+ r.cursors.some((n) => n.row === e && n.col === t) || r.cursors.push({ row: e, col: t, sel: i });
1862
2287
  }
1863
- function xe(s) {
1864
- s.cursors = [], s.searchWord = "", s.lastMatchRow = -1, s.lastMatchCol = -1;
2288
+ function Ye(r) {
2289
+ r.cursors = [], r.searchWord = "", r.lastMatchRow = -1, r.lastMatchCol = -1;
1865
2290
  }
1866
- function _t(s, e, t, i, r) {
2291
+ function ni(r, e, t, i, s) {
1867
2292
  const n = [
1868
2293
  { row: e, col: t, isPrimary: !0, idx: 0 },
1869
- ...i.map((d, p) => ({ row: d.row, col: d.col, isPrimary: !1, idx: p + 1 }))
2294
+ ...i.map((d, u) => ({ row: d.row, col: d.col, isPrimary: !1, idx: u + 1 }))
1870
2295
  ];
1871
- n.sort((d, p) => p.row !== d.row ? p.row - d.row : p.col - d.col);
1872
- const a = s.map((d) => d);
1873
- let l = e, o = t;
2296
+ n.sort((d, u) => u.row !== d.row ? u.row - d.row : u.col - d.col);
2297
+ const o = r.map((d) => d);
2298
+ let a = e, l = t;
1874
2299
  const c = i.map((d) => ({ ...d }));
1875
2300
  for (const d of n) {
1876
- const p = a[d.row] ?? "";
1877
- a[d.row] = p.slice(0, d.col) + r + p.slice(d.col);
2301
+ const u = o[d.row] ?? "";
2302
+ o[d.row] = u.slice(0, d.col) + s + u.slice(d.col);
1878
2303
  for (const h of n)
1879
- h !== d && h.row === d.row && h.col >= d.col && (h.col += r.length);
1880
- d.col += r.length, d.isPrimary ? (l = d.row, o = d.col) : (c[d.idx - 1].row = d.row, c[d.idx - 1].col = d.col);
2304
+ h !== d && h.row === d.row && h.col >= d.col && (h.col += s.length);
2305
+ d.col += s.length, d.isPrimary ? (a = d.row, l = d.col) : (c[d.idx - 1].row = d.row, c[d.idx - 1].col = d.col);
1881
2306
  }
1882
- return { doc: a, primaryRow: l, primaryCol: o, extraCursors: c };
2307
+ return { doc: o, primaryRow: a, primaryCol: l, extraCursors: c };
1883
2308
  }
1884
- function yt(s, e, t, i) {
1885
- const r = [
2309
+ function ri(r, e, t, i) {
2310
+ const s = [
1886
2311
  { row: e, col: t, isPrimary: !0, idx: 0 },
1887
2312
  ...i.map((c, d) => ({ row: c.row, col: c.col, isPrimary: !1, idx: d + 1 }))
1888
2313
  ];
1889
- r.sort((c, d) => d.row !== c.row ? d.row - c.row : d.col - c.col);
1890
- const n = s.map((c) => c);
1891
- let a = e, l = t;
1892
- const o = i.map((c) => ({ ...c }));
1893
- for (const c of r) {
2314
+ s.sort((c, d) => d.row !== c.row ? d.row - c.row : d.col - c.col);
2315
+ const n = r.map((c) => c);
2316
+ let o = e, a = t;
2317
+ const l = i.map((c) => ({ ...c }));
2318
+ for (const c of s) {
1894
2319
  if (c.col <= 0) continue;
1895
2320
  const d = n[c.row] ?? "";
1896
2321
  n[c.row] = d.slice(0, c.col - 1) + d.slice(c.col);
1897
- for (const p of r)
1898
- p !== c && p.row === c.row && p.col > c.col && p.col--;
1899
- c.col--, c.isPrimary ? (a = c.row, l = c.col) : o[c.idx - 1].col = c.col;
2322
+ for (const u of s)
2323
+ u !== c && u.row === c.row && u.col > c.col && u.col--;
2324
+ c.col--, c.isPrimary ? (o = c.row, a = c.col) : l[c.idx - 1].col = c.col;
1900
2325
  }
1901
- return { doc: n, primaryRow: a, primaryCol: l, extraCursors: o };
2326
+ return { doc: n, primaryRow: o, primaryCol: a, extraCursors: l };
1902
2327
  }
1903
- function vt(s, e, t, i, r) {
1904
- let n = s.searchWord;
2328
+ function oi(r, e, t, i, s) {
2329
+ let n = r.searchWord;
1905
2330
  if (!n) {
1906
- if (r && r.ar === r.fr && (n = (e[r.ar] ?? "").slice(r.ac, r.fc)), !n) {
1907
- const o = e[t] ?? "", c = le(o, i), d = ce(o, i);
1908
- n = o.slice(c, d);
2331
+ if (s && s.ar === s.fr && (n = (e[s.ar] ?? "").slice(s.ac, s.fc)), !n) {
2332
+ const l = e[t] ?? "", c = Ce(l, i), d = Se(l, i);
2333
+ n = l.slice(c, d);
1909
2334
  }
1910
2335
  if (!n) return null;
1911
- s.searchWord = n, s.lastMatchRow = t, s.lastMatchCol = i;
1912
- }
1913
- const a = s.lastMatchRow, l = s.lastMatchCol;
1914
- for (let o = a; o < e.length; o++) {
1915
- const c = e[o] ?? "";
1916
- let p = o === a ? l : 0;
1917
- for (; p <= c.length - n.length; ) {
1918
- const h = c.indexOf(n, p);
2336
+ r.searchWord = n, r.lastMatchRow = t, r.lastMatchCol = i;
2337
+ }
2338
+ const o = r.lastMatchRow, a = r.lastMatchCol;
2339
+ for (let l = o; l < e.length; l++) {
2340
+ const c = e[l] ?? "";
2341
+ let u = l === o ? a : 0;
2342
+ for (; u <= c.length - n.length; ) {
2343
+ const h = c.indexOf(n, u);
1919
2344
  if (h < 0) break;
1920
- const g = h === 0 || !/\w/.test(c[h - 1]), y = h + n.length >= c.length || !/\w/.test(c[h + n.length]);
1921
- if (g && y)
1922
- return s.lastMatchRow = o, s.lastMatchCol = h + n.length, {
2345
+ const _ = h === 0 || !/\w/.test(c[h - 1]), y = h + n.length >= c.length || !/\w/.test(c[h + n.length]);
2346
+ if (_ && y)
2347
+ return r.lastMatchRow = l, r.lastMatchCol = h + n.length, {
1923
2348
  word: n,
1924
- sel: { ar: o, ac: h, fr: o, fc: h + n.length },
1925
- row: o,
2349
+ sel: { ar: l, ac: h, fr: l, fc: h + n.length },
2350
+ row: l,
1926
2351
  col: h + n.length
1927
2352
  };
1928
- p = h + 1;
2353
+ u = h + 1;
1929
2354
  }
1930
2355
  }
1931
- for (let o = 0; o <= a; o++) {
1932
- const c = e[o] ?? "", d = o === a ? l : c.length;
1933
- let p = 0;
1934
- for (; p < d; ) {
1935
- const h = c.indexOf(n, p);
2356
+ for (let l = 0; l <= o; l++) {
2357
+ const c = e[l] ?? "", d = l === o ? a : c.length;
2358
+ let u = 0;
2359
+ for (; u < d; ) {
2360
+ const h = c.indexOf(n, u);
1936
2361
  if (h < 0 || h >= d) break;
1937
- const g = h === 0 || !/\w/.test(c[h - 1]), y = h + n.length >= c.length || !/\w/.test(c[h + n.length]);
1938
- if (g && y)
1939
- return s.lastMatchRow = o, s.lastMatchCol = h + n.length, {
2362
+ const _ = h === 0 || !/\w/.test(c[h - 1]), y = h + n.length >= c.length || !/\w/.test(c[h + n.length]);
2363
+ if (_ && y)
2364
+ return r.lastMatchRow = l, r.lastMatchCol = h + n.length, {
1940
2365
  word: n,
1941
- sel: { ar: o, ac: h, fr: o, fc: h + n.length },
1942
- row: o,
2366
+ sel: { ar: l, ac: h, fr: l, fc: h + n.length },
2367
+ row: l,
1943
2368
  col: h + n.length
1944
2369
  };
1945
- p = h + 1;
2370
+ u = h + 1;
1946
2371
  }
1947
2372
  }
1948
2373
  return null;
1949
2374
  }
1950
- function wt(s, e, t) {
2375
+ function ai(r, e, t) {
1951
2376
  if (!e) return [];
1952
2377
  const i = [];
1953
- for (let r = 0; r < s.length; r++) {
1954
- const n = s[r] ?? "";
2378
+ for (let s = 0; s < r.length; s++) {
2379
+ const n = r[s] ?? "";
1955
2380
  if (t.useRegex)
1956
2381
  try {
1957
- const a = new RegExp(e, t.caseSensitive ? "g" : "gi");
1958
- let l;
1959
- for (; (l = a.exec(n)) !== null && (i.push({ row: r, col: l.index, len: l[0].length }), !!l[0].length); )
2382
+ const o = new RegExp(e, t.caseSensitive ? "g" : "gi");
2383
+ let a;
2384
+ for (; (a = o.exec(n)) !== null && (i.push({ row: s, col: a.index, len: a[0].length }), !!a[0].length); )
1960
2385
  ;
1961
2386
  } catch {
1962
2387
  }
1963
2388
  else {
1964
- const a = t.caseSensitive ? n : n.toLowerCase(), l = t.caseSensitive ? e : e.toLowerCase();
1965
- let o = 0;
2389
+ const o = t.caseSensitive ? n : n.toLowerCase(), a = t.caseSensitive ? e : e.toLowerCase();
2390
+ let l = 0;
1966
2391
  for (; ; ) {
1967
- const c = a.indexOf(l, o);
2392
+ const c = o.indexOf(a, l);
1968
2393
  if (c === -1) break;
1969
- i.push({ row: r, col: c, len: e.length }), o = c + 1;
2394
+ i.push({ row: s, col: c, len: e.length }), l = c + 1;
1970
2395
  }
1971
2396
  }
1972
2397
  }
1973
2398
  return i;
1974
2399
  }
1975
- function kt(s, e, t, i) {
1976
- const r = e[t];
1977
- if (!r) return s;
1978
- const n = [...s], a = n[r.row] ?? "";
1979
- return n[r.row] = a.slice(0, r.col) + i + a.slice(r.col + r.len), n;
2400
+ function li(r, e, t, i) {
2401
+ const s = e[t];
2402
+ if (!s) return r;
2403
+ const n = [...r], o = n[s.row] ?? "";
2404
+ return n[s.row] = o.slice(0, s.col) + i + o.slice(s.col + s.len), n;
1980
2405
  }
1981
- function xt(s, e, t) {
1982
- const i = [...s];
1983
- for (let r = e.length - 1; r >= 0; r--) {
1984
- const n = e[r], a = i[n.row] ?? "";
1985
- i[n.row] = a.slice(0, n.col) + t + a.slice(n.col + n.len);
2406
+ function ci(r, e, t) {
2407
+ const i = [...r];
2408
+ for (let s = e.length - 1; s >= 0; s--) {
2409
+ const n = e[s], o = i[n.row] ?? "";
2410
+ i[n.row] = o.slice(0, n.col) + t + o.slice(n.col + n.len);
1986
2411
  }
1987
2412
  return i;
1988
2413
  }
1989
- function Tt(s, e, t) {
1990
- return s.length ? (e + t + s.length) % s.length : -1;
2414
+ function di(r, e, t) {
2415
+ return r.length ? (e + t + r.length) % r.length : -1;
1991
2416
  }
1992
- function Ct(s, e, t, i) {
2417
+ function hi(r, e, t, i) {
1993
2418
  if (i) return [];
1994
- const r = s[e] ?? "", n = le(r, t), a = ce(r, t), l = r.slice(n, a);
1995
- if (!l || l.length < 2) return [];
1996
- const o = [];
1997
- for (let c = 0; c < s.length; c++) {
1998
- const d = s[c] ?? "";
1999
- let p = 0;
2000
- for (; p <= d.length - l.length; ) {
2001
- const h = d.indexOf(l, p);
2419
+ const s = r[e] ?? "", n = Ce(s, t), o = Se(s, t), a = s.slice(n, o);
2420
+ if (!a || a.length < 2) return [];
2421
+ const l = [];
2422
+ for (let c = 0; c < r.length; c++) {
2423
+ const d = r[c] ?? "";
2424
+ let u = 0;
2425
+ for (; u <= d.length - a.length; ) {
2426
+ const h = d.indexOf(a, u);
2002
2427
  if (h < 0) break;
2003
- const g = h === 0 || !/\w/.test(d[h - 1]), y = h + l.length >= d.length || !/\w/.test(d[h + l.length]);
2004
- g && y && !(c === e && h === n) && o.push({ row: c, col: h, len: l.length }), p = h + 1;
2428
+ const _ = h === 0 || !/\w/.test(d[h - 1]), y = h + a.length >= d.length || !/\w/.test(d[h + a.length]);
2429
+ _ && y && !(c === e && h === n) && l.push({ row: c, col: h, len: a.length }), u = h + 1;
2005
2430
  }
2006
2431
  }
2007
- return o;
2432
+ return l;
2008
2433
  }
2009
- const ne = [
2434
+ const ve = [
2010
2435
  { label: "console.log", kind: "fn", detail: "void" },
2011
2436
  { label: "console.error", kind: "fn", detail: "void" },
2012
2437
  { label: "console.warn", kind: "fn", detail: "void" },
@@ -2057,7 +2482,7 @@ const ne = [
2057
2482
  { label: "structuredClone", kind: "fn", detail: "T" },
2058
2483
  { label: "queueMicrotask", kind: "fn", detail: "void" },
2059
2484
  { label: "fetch", kind: "fn", detail: "Promise<Response>" }
2060
- ], Mt = [
2485
+ ], pi = [
2061
2486
  // ── Layout ────────────────────────────────────────────────
2062
2487
  { label: "display", kind: "var", detail: "property" },
2063
2488
  { label: "position", kind: "var", detail: "property" },
@@ -2213,92 +2638,92 @@ const ne = [
2213
2638
  { label: "repeat", kind: "fn", detail: "css fn" },
2214
2639
  { label: "minmax", kind: "fn", detail: "css fn" },
2215
2640
  { label: "fit-content", kind: "fn", detail: "css fn" }
2216
- ], Et = {
2217
- typescript: ne,
2218
- javascript: ne,
2219
- css: Mt,
2641
+ ], ui = {
2642
+ typescript: ve,
2643
+ javascript: ve,
2644
+ css: pi,
2220
2645
  json: [],
2221
2646
  markdown: [],
2222
2647
  text: []
2223
2648
  };
2224
- function Te(s, e, t) {
2225
- const i = Ee[s] ?? se, r = Se[s] ?? ae, n = Et[s] ?? ne;
2649
+ function Je(r, e, t) {
2650
+ const i = tt[r] ?? we, s = it[r] ?? ke, n = ui[r] ?? ve;
2226
2651
  return [
2227
- ...[...i, ...e].map((a) => ({ label: a, kind: "kw", detail: "keyword" })),
2228
- ...[...r, ...t].map((a) => ({ label: a, kind: "typ", detail: "type" })),
2652
+ ...[...i, ...e].map((o) => ({ label: o, kind: "kw", detail: "keyword" })),
2653
+ ...[...s, ...t].map((o) => ({ label: o, kind: "typ", detail: "type" })),
2229
2654
  ...n
2230
2655
  ];
2231
2656
  }
2232
- function St(s, e) {
2657
+ function fi(r, e) {
2233
2658
  const t = /* @__PURE__ */ new Set();
2234
- for (const i of s) {
2235
- const r = i.match(/[a-zA-Z_$][\w$]*/g) ?? [];
2236
- for (const n of r)
2659
+ for (const i of r) {
2660
+ const s = i.match(/[a-zA-Z_$][\w$]*/g) ?? [];
2661
+ for (const n of s)
2237
2662
  n !== e && n.length > 2 && t.add(n);
2238
2663
  }
2239
2664
  return t;
2240
2665
  }
2241
- function Ce(s, e) {
2242
- return s.language ? Array.isArray(s.language) ? s.language.includes(e) : s.language === e : !0;
2666
+ function Xe(r, e) {
2667
+ return r.language ? Array.isArray(r.language) ? r.language.includes(e) : r.language === e : !0;
2243
2668
  }
2244
- function It(s, e, t = {}, i = 0, r = 0) {
2669
+ function gi(r, e, t = {}, i = 0, s = 0) {
2245
2670
  if (e.length < 2) return [];
2246
2671
  const n = e.toLowerCase(), {
2247
- language: a = "typescript",
2248
- extraKeywords: l = [],
2249
- extraTypes: o = [],
2672
+ language: o = "typescript",
2673
+ extraKeywords: a = [],
2674
+ extraTypes: l = [],
2250
2675
  completions: c = [],
2251
2676
  replaceBuiltins: d = !1,
2252
- maxResults: p = 14
2253
- } = t, h = c.filter((m) => m.kind === "snip" && !!m.body && Ce(m, a)), g = c.filter((m) => !(m.kind === "snip" && m.body) && Ce(m, a)), y = h.filter((m) => m.label.toLowerCase().startsWith(n));
2254
- let v;
2677
+ maxResults: u = 14
2678
+ } = t, h = c.filter((f) => f.kind === "snip" && !!f.body && Xe(f, o)), _ = c.filter((f) => !(f.kind === "snip" && f.body) && Xe(f, o)), y = h.filter((f) => f.label.toLowerCase().startsWith(n));
2679
+ let g;
2255
2680
  if (t.provideCompletions) {
2256
- const m = {
2257
- line: s[i] ?? "",
2258
- col: r,
2681
+ const f = {
2682
+ line: r[i] ?? "",
2683
+ col: s,
2259
2684
  prefix: e,
2260
- language: a,
2261
- doc: s
2685
+ language: o,
2686
+ doc: r
2262
2687
  };
2263
- let S;
2688
+ let T;
2264
2689
  try {
2265
- S = t.provideCompletions(m);
2266
- } catch (I) {
2267
- console.error("[syncline-editor] provideCompletions threw an error:", I), S = null;
2690
+ T = t.provideCompletions(f);
2691
+ } catch (R) {
2692
+ console.error("[syncline-editor] provideCompletions threw an error:", R), T = null;
2268
2693
  }
2269
- v = S != null ? [...S, ...g] : [...d ? [] : Te(a, l, o), ...g];
2694
+ g = T != null ? [...T, ..._] : [...d ? [] : Je(o, a, l), ..._];
2270
2695
  } else
2271
- v = d ? g : [...Te(a, l, o), ...g];
2272
- const f = new Set(v.map((m) => m.label)), b = v.filter(
2273
- (m) => m.label.toLowerCase().startsWith(n) && m.label !== e
2274
- ), T = new Set(y.map((m) => m.label)), x = [...St(s, e)].filter((m) => m.toLowerCase().startsWith(n) && !f.has(m) && !T.has(m)).slice(0, 8).map((m) => ({ label: m, kind: "var", detail: "in file" }));
2696
+ g = d ? _ : [...Je(o, a, l), ..._];
2697
+ const k = new Set(g.map((f) => f.label)), m = g.filter(
2698
+ (f) => f.label.toLowerCase().startsWith(n) && f.label !== e
2699
+ ), S = new Set(y.map((f) => f.label)), x = [...fi(r, e)].filter((f) => f.toLowerCase().startsWith(n) && !k.has(f) && !S.has(f)).slice(0, 8).map((f) => ({ label: f, kind: "var", detail: "in file" }));
2275
2700
  return [
2276
2701
  ...y,
2277
- ...b.filter((m) => !T.has(m.label)),
2702
+ ...m.filter((f) => !S.has(f.label)),
2278
2703
  ...x
2279
- ].slice(0, p);
2704
+ ].slice(0, u);
2280
2705
  }
2281
- function At(s, e, t = !1) {
2706
+ function bi(r, e, t = !1) {
2282
2707
  let i = e;
2283
- for (; i > 0 && (t ? /[\w$.\-]/ : /[\w$.]/).test(s[i - 1]); ) i--;
2284
- return { prefix: s.slice(i, e), start: i };
2708
+ for (; i > 0 && (t ? /[\w$.\-]/ : /[\w$.]/).test(r[i - 1]); ) i--;
2709
+ return { prefix: r.slice(i, e), start: i };
2285
2710
  }
2286
- function Lt(s, e) {
2711
+ function mi(r, e) {
2287
2712
  const t = (n) => /[\w$]/.test(n);
2288
2713
  let i = e;
2289
- for (; i < s.length && t(s[i]); ) i++;
2290
- let r = e;
2291
- for (; r > 0 && t(s[r - 1]); ) r--;
2292
- if (r === i) return "";
2293
- if (r > 0 && s[r - 1] === ".") {
2294
- let n = r - 1, a = n;
2295
- for (; a > 0 && t(s[a - 1]); ) a--;
2296
- if (a < n)
2297
- return s.slice(a, i);
2298
- }
2299
- return s.slice(r, i);
2714
+ for (; i < r.length && t(r[i]); ) i++;
2715
+ let s = e;
2716
+ for (; s > 0 && t(r[s - 1]); ) s--;
2717
+ if (s === i) return "";
2718
+ if (s > 0 && r[s - 1] === ".") {
2719
+ let n = s - 1, o = n;
2720
+ for (; o > 0 && t(r[o - 1]); ) o--;
2721
+ if (o < n)
2722
+ return r.slice(o, i);
2723
+ }
2724
+ return r.slice(s, i);
2300
2725
  }
2301
- const Dt = {
2726
+ const _i = {
2302
2727
  // ── console ───────────────────────────────────────────────
2303
2728
  console: {
2304
2729
  title: "console",
@@ -2912,166 +3337,192 @@ const Dt = {
2912
3337
  language: ["typescript"]
2913
3338
  }
2914
3339
  };
2915
- function Ht(s, e) {
2916
- const t = Dt[s];
3340
+ function yi(r, e) {
3341
+ const t = _i[r];
2917
3342
  return !t || t.language && !(Array.isArray(t.language) ? t.language : [t.language]).includes(e) ? null : t;
2918
3343
  }
2919
- function Rt(s) {
2920
- var G, K, C, R;
2921
- const { vr: e, visIdx: t, curVisRow: i, wm: r, foldedLines: n, isFoldable: a, opts: l } = s, { docLine: o, segIdx: c, text: d } = e, p = t === i, h = o === ((G = r.visualRows[i]) == null ? void 0 : G.docLine), g = c > 0, y = ((K = r.segments[o]) == null ? void 0 : K.slice(0, c).reduce((w, k) => w + k.length, 0)) ?? 0, v = s.docSel ? fe(s.docSel, o, ((C = (r.segments[o] ?? [""])[c]) == null ? void 0 : C.length) ?? 0) : null;
2922
- let f = null;
2923
- if (v) {
2924
- const w = ((R = (r.segments[o] ?? [""])[c]) == null ? void 0 : R.length) ?? 0, k = fe(s.docSel, o, w + y);
2925
- if (k) {
2926
- const M = k.start - y, H = k.end - y;
2927
- H > 0 && M < d.length && (f = { start: Math.max(0, M), end: Math.min(d.length, H) });
3344
+ function vi(r) {
3345
+ var E, N, V, K;
3346
+ const { vr: e, visIdx: t, curVisRow: i, wm: s, foldedLines: n, isFoldable: o, opts: a } = r, { docLine: l, segIdx: c, text: d } = e, u = t === i, h = l === ((E = s.visualRows[i]) == null ? void 0 : E.docLine), _ = c > 0, y = ((N = s.segments[l]) == null ? void 0 : N.slice(0, c).reduce((v, w) => v + w.length, 0)) ?? 0, g = r.docSel ? Oe(r.docSel, l, ((V = (s.segments[l] ?? [""])[c]) == null ? void 0 : V.length) ?? 0) : null;
3347
+ let k = null;
3348
+ if (g) {
3349
+ const v = ((K = (s.segments[l] ?? [""])[c]) == null ? void 0 : K.length) ?? 0, w = Oe(r.docSel, l, v + y);
3350
+ if (w) {
3351
+ const M = w.start - y, I = w.end - y;
3352
+ I > 0 && M < d.length && (k = { start: Math.max(0, M), end: Math.min(d.length, I) });
2928
3353
  }
2929
3354
  }
2930
- const b = s.findMatches.filter((w) => w.row === o).map((w) => {
2931
- var j, B;
2932
- const k = w.col - y, M = w.col + w.len - y;
2933
- if (M <= 0 || k >= d.length) return null;
2934
- const H = s.findIdx >= 0 && ((j = s.findMatches[s.findIdx]) == null ? void 0 : j.row) === w.row && ((B = s.findMatches[s.findIdx]) == null ? void 0 : B.col) === w.col;
2935
- return { start: Math.max(0, k), end: Math.min(d.length, M), isCur: H };
2936
- }).filter(Boolean), T = s.wordHighlights.filter((w) => w.row === o).map((w) => {
2937
- const k = w.col - y, M = w.col + w.len - y;
2938
- return M <= 0 || k >= d.length ? null : { start: Math.max(0, k), end: Math.min(d.length, M) };
2939
- }).filter(Boolean), _ = [];
2940
- if (s.bracketMatch) {
2941
- for (const w of [s.bracketMatch.open, s.bracketMatch.close])
2942
- if (w.row === o) {
2943
- const k = w.col - y;
2944
- k >= 0 && k < d.length && _.push({ start: k, end: k + 1 });
3355
+ const m = r.findMatches.filter((v) => v.row === l).map((v) => {
3356
+ var F, X;
3357
+ const w = v.col - y, M = v.col + v.len - y;
3358
+ if (M <= 0 || w >= d.length) return null;
3359
+ const I = r.findIdx >= 0 && ((F = r.findMatches[r.findIdx]) == null ? void 0 : F.row) === v.row && ((X = r.findMatches[r.findIdx]) == null ? void 0 : X.col) === v.col;
3360
+ return { start: Math.max(0, w), end: Math.min(d.length, M), isCur: I };
3361
+ }).filter(Boolean), S = r.wordHighlights.filter((v) => v.row === l).map((v) => {
3362
+ const w = v.col - y, M = v.col + v.len - y;
3363
+ return M <= 0 || w >= d.length ? null : { start: Math.max(0, w), end: Math.min(d.length, M) };
3364
+ }).filter(Boolean), b = [];
3365
+ if (r.bracketMatch) {
3366
+ for (const v of [r.bracketMatch.open, r.bracketMatch.close])
3367
+ if (v.row === l) {
3368
+ const w = v.col - y;
3369
+ w >= 0 && w < d.length && b.push({ start: w, end: w + 1 });
2945
3370
  }
2946
3371
  }
2947
- const x = [], m = [];
2948
- for (const w of s.extraCursors) {
2949
- const k = F(r, w.row, w.col);
2950
- if (k.visRow === t && x.push(k.colInSeg), w.sel) {
2951
- const M = jt(w.sel);
2952
- if (o >= M.ar && o <= M.fr) {
2953
- const H = o === M.ar ? M.ac - y : -y, j = o === M.fr ? M.fc - y : d.length + 999;
2954
- j > 0 && H < d.length && m.push({ start: Math.max(0, H), end: Math.min(d.length, j) });
3372
+ const x = [], f = [];
3373
+ for (const v of r.extraCursors) {
3374
+ const w = ee(s, v.row, v.col);
3375
+ if (w.visRow === t && x.push(w.colInSeg), v.sel) {
3376
+ const M = ki(v.sel);
3377
+ if (l >= M.ar && l <= M.fr) {
3378
+ const I = l === M.ar ? M.ac - y : -y, F = l === M.fr ? M.fc - y : d.length + 999;
3379
+ F > 0 && I < d.length && f.push({ start: Math.max(0, I), end: Math.min(d.length, F) });
2955
3380
  }
2956
3381
  }
2957
3382
  }
2958
- const S = Bt(d, l.renderWhitespace), I = p || f || b.length || x.length || T.length || _.length || m.length;
2959
- let U;
2960
- if (I)
2961
- U = $t(
3383
+ const T = [];
3384
+ for (const v of r.remoteCursors) {
3385
+ const w = ee(s, v.row, v.col);
3386
+ w.visRow === t && T.push({ col: w.colInSeg, name: v.name, color: v.color });
3387
+ }
3388
+ const R = [];
3389
+ for (const v of r.remoteSels) {
3390
+ const w = v.from.row < v.to.row || v.from.row === v.to.row && v.from.col <= v.to.col ? v.from : v.to, M = w === v.from ? v.to : v.from;
3391
+ if (l >= w.row && l <= M.row) {
3392
+ const I = l === w.row ? w.col - y : -y, F = l === M.row ? M.col - y : d.length + 999;
3393
+ F > 0 && I < d.length && R.push({ start: Math.max(0, I), end: Math.min(d.length, F), color: v.color });
3394
+ }
3395
+ }
3396
+ const j = wi(d, a.renderWhitespace), G = u || k || m.length || x.length || S.length || b.length || f.length || r.snippetStopCols.length > 0 || T.length > 0 || R.length > 0;
3397
+ let H;
3398
+ if (G)
3399
+ H = Ci(
3400
+ j,
3401
+ u ? r.curColInSeg : -1,
3402
+ k,
3403
+ m,
3404
+ x,
3405
+ r.snippetStopCols,
2962
3406
  S,
2963
- p ? s.curColInSeg : -1,
2964
- f,
2965
3407
  b,
2966
- x,
3408
+ f,
3409
+ a.tokeniserOpts,
2967
3410
  T,
2968
- _,
2969
- m,
2970
- l.tokeniserOpts
3411
+ R,
3412
+ t === 0
2971
3413
  );
2972
3414
  else {
2973
- const w = `${o}:${c}:${l.renderWhitespace}`;
2974
- let k = s.tokenCache.get(w, S);
2975
- k || (k = oe(S, l.tokeniserOpts), s.tokenCache.set(w, S, k)), U = Pt(S, k) || "&#8203;";
2976
- }
2977
- let V = "";
2978
- if (c === 0 && l.showIndentGuides) {
2979
- const w = (d.match(/^(\s*)/) ?? ["", ""])[1].length, k = Math.floor(w / l.tabSize);
2980
- for (let M = 1; M < k; M++) {
2981
- const H = l.codePaddingLeft + M * l.tabSize * l.charWidth;
2982
- V += `<span class="sl-ig" style="left:${H}px"></span>`;
2983
- }
3415
+ const v = `${l}:${c}:${a.renderWhitespace}`;
3416
+ let w = r.tokenCache.get(v, j);
3417
+ w || (w = xe(j, a.tokeniserOpts), r.tokenCache.set(v, j, w)), H = xi(j, w) || "&#8203;";
2984
3418
  }
2985
3419
  let $ = "";
2986
- if (c === 0 && a) {
2987
- const w = n.has(o);
2988
- $ = `<span class="sl-fold-btn" data-row="${o}">${w ? "▸" : "▾"}</span>`;
3420
+ if (c === 0 && a.showIndentGuides) {
3421
+ const v = (d.match(/^(\s*)/) ?? ["", ""])[1].length, w = Math.floor(v / a.tabSize);
3422
+ for (let M = 1; M < w; M++) {
3423
+ const I = a.codePaddingLeft + M * a.tabSize * a.charWidth;
3424
+ $ += `<span class="sl-ig" style="left:${I}px"></span>`;
3425
+ }
3426
+ }
3427
+ let W = "";
3428
+ if (c === 0 && o) {
3429
+ const v = n.has(l);
3430
+ W = `<span class="sl-fold-btn" data-row="${l}">${v ? "▸" : "▾"}</span>`;
2989
3431
  }
2990
- const W = n.has(o) && c === 0, N = c === 0 ? String(o + 1) : "";
3432
+ const U = n.has(l) && c === 0, C = c === 0 ? String(l + 1) : "";
2991
3433
  return `<div class="${[
2992
3434
  "sl-er",
2993
- l.highlightActiveLine && h ? "sl-cur-row" : "",
2994
- g ? "sl-wrap-cont" : "",
2995
- W ? "sl-folded" : ""
2996
- ].filter(Boolean).join(" ")}" style="height:${l.lineHeight}px" data-v="${t}" data-doc="${o}"><div class="sl-eg" style="position:relative">${$}<span class="sl-egn">${N}</span></div><div class="sl-el"><span class="sl-cl">${V}${U}</span></div></div>`;
3435
+ a.highlightActiveLine && h ? "sl-cur-row" : "",
3436
+ _ ? "sl-wrap-cont" : "",
3437
+ U ? "sl-folded" : ""
3438
+ ].filter(Boolean).join(" ")}" style="height:${a.lineHeight}px" data-v="${t}" data-doc="${l}"><div class="sl-eg" style="position:relative">${W}<span class="sl-egn">${C}</span></div><div class="sl-el"><span class="sl-cl">${$}${H}</span></div></div>`;
2997
3439
  }
2998
- function Bt(s, e) {
2999
- if (e === "none") return s;
3440
+ function wi(r, e) {
3441
+ if (e === "none") return r;
3000
3442
  if (e === "all")
3001
- return s.replace(/ /g, "·").replace(/\t/g, "→");
3002
- const t = (s.match(/^ +/) ?? [""])[0].length, i = (s.match(/ +$/) ?? [""])[0].length;
3003
- let r = s;
3004
- return t && (r = "·".repeat(t) + r.slice(t)), i && (r = r.slice(0, r.length - i) + "·".repeat(i)), r.replace(/\t/g, "→");
3443
+ return r.replace(/ /g, "·").replace(/\t/g, "→");
3444
+ const t = (r.match(/^ +/) ?? [""])[0].length, i = (r.match(/ +$/) ?? [""])[0].length;
3445
+ let s = r;
3446
+ return t && (s = "·".repeat(t) + s.slice(t)), i && (s = s.slice(0, s.length - i) + "·".repeat(i)), s.replace(/\t/g, "→");
3005
3447
  }
3006
- function jt(s) {
3007
- return s.ar < s.fr || s.ar === s.fr && s.ac <= s.fc ? s : { ar: s.fr, ac: s.fc, fr: s.ar, fc: s.ac };
3448
+ function ki(r) {
3449
+ return r.ar < r.fr || r.ar === r.fr && r.ac <= r.fc ? r : { ar: r.fr, ac: r.fc, fr: r.ar, fc: r.ac };
3008
3450
  }
3009
- function Pt(s, e) {
3010
- if (!s) return "";
3011
- const t = Ie(s, e);
3012
- let i = "", r = 0, n = t[0];
3013
- const a = (l) => {
3014
- if (l <= r) return;
3015
- const o = q(s.slice(r, l));
3016
- i += n ? `<span class="${n}">${o}</span>` : o;
3451
+ function xi(r, e) {
3452
+ if (!r) return "";
3453
+ const t = st(r, e);
3454
+ let i = "", s = 0, n = t[0];
3455
+ const o = (a) => {
3456
+ if (a <= s) return;
3457
+ const l = ne(r.slice(s, a));
3458
+ i += n ? `<span class="${n}">${l}</span>` : l;
3017
3459
  };
3018
- for (let l = 1; l <= s.length; l++) {
3019
- const o = l < s.length ? t[l] : null;
3020
- o !== n && (a(l), r = l, n = o ?? "");
3460
+ for (let a = 1; a <= r.length; a++) {
3461
+ const l = a < r.length ? t[a] : null;
3462
+ l !== n && (o(a), s = a, n = l ?? "");
3021
3463
  }
3022
3464
  return i;
3023
3465
  }
3024
- function $t(s, e, t, i, r, n, a, l, o) {
3025
- if (s.length === 0) {
3466
+ function Ci(r, e, t, i, s, n, o, a, l, c, d = [], u = [], h = !1) {
3467
+ if (r.length === 0) {
3026
3468
  let f = e >= 0 ? '<span class="sl-cur"></span>' : "";
3027
- for (const b of r) f += '<span class="sl-cur-extra"></span>';
3469
+ for (const T of s) f += '<span class="sl-cur-extra"></span>';
3470
+ for (const T of n) f += '<span class="sl-snip-stop"></span>';
3471
+ for (const T of d)
3472
+ f += `<span class="${h ? "sl-rc sl-rc-flip" : "sl-rc"}" style="--rc-color:${T.color}"><span class="sl-rc-label">${ne(T.name)}</span></span>`;
3028
3473
  return f || "&#8203;";
3029
3474
  }
3030
- const c = oe(s, o), d = Ie(s, c);
3031
- let p = "", h = 0, g = "", y = "";
3032
- const v = (f) => {
3033
- if (f <= h) return;
3034
- const b = q(s.slice(h, f)), T = [g, y].filter(Boolean).join(" ");
3035
- p += T ? `<span class="${T}">${b}</span>` : b;
3475
+ const _ = xe(r, c), y = st(r, _);
3476
+ let g = "", k = 0, m = "", S = "", b = "";
3477
+ const x = (f) => {
3478
+ if (f <= k) return;
3479
+ const T = ne(r.slice(k, f)), R = [m, S, b ? "sl-rs" : ""].filter(Boolean).join(" "), j = b ? ` style="--rs-color:${b}33"` : "";
3480
+ g += R || j ? `<span${j}${R ? ` class="${R}"` : ""}>${T}</span>` : T;
3036
3481
  };
3037
- for (let f = 0; f <= s.length; f++) {
3038
- e === f && (v(f), h = f, p += '<span class="sl-cur"></span>');
3039
- for (const I of r)
3040
- I === f && (v(f), h = f, p += '<span class="sl-cur-extra"></span>');
3041
- if (f === s.length) {
3042
- v(f);
3482
+ for (let f = 0; f <= r.length; f++) {
3483
+ e === f && (x(f), k = f, g += '<span class="sl-cur"></span>');
3484
+ for (const C of s)
3485
+ C === f && (x(f), k = f, g += '<span class="sl-cur-extra"></span>');
3486
+ for (const C of n)
3487
+ C === f && (x(f), k = f, g += '<span class="sl-snip-stop"></span>');
3488
+ for (const C of d)
3489
+ C.col === f && (x(f), k = f, g += `<span class="${h ? "sl-rc sl-rc-flip" : "sl-rc"}" style="--rc-color:${C.color}"><span class="sl-rc-label">${ne(C.name)}</span></span>`);
3490
+ if (f === r.length) {
3491
+ x(f);
3043
3492
  break;
3044
3493
  }
3045
- const b = d[f], T = i.find((I) => f >= I.start && f < I.end), _ = t && f >= t.start && f < t.end || l.some((I) => f >= I.start && f < I.end), x = !_ && !T && n.some((I) => f >= I.start && f < I.end), m = !_ && !T && a.some((I) => f >= I.start && f < I.end);
3046
- let S = "";
3047
- _ ? S = "sl-sh" : T ? S = "sl-fh" + (T.isCur ? " sl-fh-cur" : "") : m ? S = "sl-bm" : x && (S = "sl-wh"), (S !== g || b !== y) && (v(f), h = f, g = S, y = b);
3494
+ const T = y[f] ?? "", R = i.find((C) => f >= C.start && f < C.end), j = t && f >= t.start && f < t.end || l.some((C) => f >= C.start && f < C.end), G = !j && !R && o.some((C) => f >= C.start && f < C.end), H = !j && !R && a.some((C) => f >= C.start && f < C.end);
3495
+ let $ = "";
3496
+ j ? $ = "sl-sh" : R ? $ = "sl-fh" + (R.isCur ? " sl-fh-cur" : "") : H ? $ = "sl-bm" : G && ($ = "sl-wh");
3497
+ const W = j ? void 0 : u.find((C) => f >= C.start && f < C.end), U = (W == null ? void 0 : W.color) ?? "";
3498
+ ($ !== m || T !== S || U !== b) && (x(f), k = f, m = $, S = T, b = U);
3048
3499
  }
3049
- return p || "&#8203;";
3500
+ return g || "&#8203;";
3050
3501
  }
3051
- function ie(s, e, t, i, r) {
3052
- const n = Math.max(0, s * r - t), a = Math.max(0, s * 2 - i), o = (n > 0 ? e / n : 0) * a, c = Math.max(20, t / r * 2), d = e / r * 2 - o;
3053
- return { mmScroll: o, sliderTop: d, sliderHeight: c };
3502
+ function _e(r, e, t, i, s) {
3503
+ const n = Math.max(0, r * s - t), o = Math.max(0, r * q - i), l = (n > 0 ? e / n : 0) * o, c = Math.max(20, t / s * q), d = e / s * q - l;
3504
+ return { mmScroll: l, sliderTop: d, sliderHeight: c };
3054
3505
  }
3055
- function Wt(s, e, t, i, r) {
3056
- const n = Math.max(0, e * r - t), a = Math.max(0, e * 2 - i);
3506
+ function Si(r, e, t, i, s) {
3507
+ const n = Math.max(0, e * s - t), o = Math.max(0, e * q - i);
3057
3508
  if (n <= 0) return 0;
3058
- const l = 2 / r - a / n;
3059
- if (Math.abs(l) < 1e-9) {
3060
- const o = Math.max(20, t / r * 2);
3061
- return Math.max(0, Math.min(n, s / Math.max(1, i - o) * n));
3509
+ const a = q / s - o / n;
3510
+ if (Math.abs(a) < 1e-9) {
3511
+ const l = Math.max(20, t / s * q);
3512
+ return Math.max(0, Math.min(n, r / Math.max(1, i - l) * n));
3062
3513
  }
3063
- return Math.max(0, Math.min(n, s / l));
3514
+ return Math.max(0, Math.min(n, r / a));
3064
3515
  }
3065
- function Nt(s, e, t, i, r, n) {
3066
- const a = Math.max(0, e * n - i), l = Math.max(0, e * 2 - r);
3067
- if (a <= 0) return 0;
3068
- const o = t / a * l, c = (s + o) / 2;
3069
- return Math.max(0, Math.min(a, c * n - i / 2));
3516
+ function Ti(r, e, t, i, s, n) {
3517
+ const o = Math.max(0, e * n - i), a = Math.max(0, e * q - s);
3518
+ if (o <= 0) return 0;
3519
+ const l = t / o * a, c = (r + l) / q;
3520
+ return Math.max(0, Math.min(o, c * n - i / 2));
3070
3521
  }
3071
- function Me(s) {
3522
+ function Ze(r) {
3072
3523
  const e = (t) => {
3073
- const i = s(t);
3074
- return i.startsWith("#") && i.length === 7 ? be(i, 0.85) : i;
3524
+ const i = r(t);
3525
+ return i.startsWith("#") && i.length === 7 ? Fe(i, 0.85) : i;
3075
3526
  };
3076
3527
  return {
3077
3528
  kw: e("--tok-kw"),
@@ -3084,67 +3535,67 @@ function Me(s) {
3084
3535
  dec: e("--tok-dec"),
3085
3536
  op: e("--tok-op"),
3086
3537
  txt: (() => {
3087
- const t = s("--text2");
3088
- return t.startsWith("#") && t.length === 7 ? be(t, 0.28) : "rgba(150,148,140,0.28)";
3538
+ const t = r("--text2");
3539
+ return t.startsWith("#") && t.length === 7 ? Fe(t, 0.28) : "rgba(150,148,140,0.28)";
3089
3540
  })()
3090
3541
  };
3091
3542
  }
3092
- function Ot(s) {
3093
- var G, K;
3543
+ function Mi(r) {
3544
+ var C, te;
3094
3545
  const {
3095
3546
  canvas: e,
3096
3547
  doc: t,
3097
3548
  firstLine: i,
3098
- lastLine: r,
3549
+ lastLine: s,
3099
3550
  subPx: n,
3100
- wrapperWidth: a,
3101
- canvasHeight: l,
3102
- cursorRow: o,
3551
+ wrapperWidth: o,
3552
+ canvasHeight: a,
3553
+ cursorRow: l,
3103
3554
  sel: c,
3104
3555
  findMatches: d,
3105
- findIdx: p,
3556
+ findIdx: u,
3106
3557
  sliderTop: h,
3107
- sliderHeight: g,
3558
+ sliderHeight: _,
3108
3559
  colors: y,
3109
- getCssVar: v,
3110
- dpr: f
3111
- } = s, b = e.getContext("2d");
3112
- if (!b) return;
3113
- b.setTransform(f, 0, 0, f, 0, 0);
3114
- const T = v("--mm-bg") || "#0d0d0f", _ = v("--mm-dim") || "rgba(0,0,0,.30)", x = v("--mm-edge") || "rgba(255,255,255,.18)", m = v("--mm-slider") || "rgba(255,255,255,.07)", S = v("--sel-bg") || "rgba(110,159,255,.22)", I = v("--cur-line-bg") || "rgba(255,255,255,.05)", U = v("--find-border") || "rgba(234,180,86,.50)", V = v("--find-cur-bg") || "rgba(234,180,86,.80)", $ = (C) => (C - i) * 2;
3115
- if (b.fillStyle = T, b.fillRect(0, 0, a, l), o >= i && o < r && (b.fillStyle = I, b.fillRect(0, $(o), a, 2)), c) {
3116
- const C = Math.max(i, c.ar), R = Math.min(r - 1, c.fr);
3117
- R >= C && (b.fillStyle = S, b.fillRect(0, $(C), a, (R - C + 1) * 2));
3118
- }
3119
- for (const C of d) {
3120
- if (C.row < i || C.row >= r) continue;
3121
- const R = p >= 0 && ((G = d[p]) == null ? void 0 : G.row) === C.row && ((K = d[p]) == null ? void 0 : K.col) === C.col;
3122
- b.fillStyle = R ? V : U, b.fillRect(
3123
- 3 + C.col * 1.1,
3124
- $(C.row),
3125
- Math.max(3, C.len * 1.1),
3126
- 2
3560
+ getCssVar: g,
3561
+ dpr: k
3562
+ } = r, m = e.getContext("2d");
3563
+ if (!m) return;
3564
+ m.setTransform(k, 0, 0, k, 0, 0);
3565
+ const S = g("--mm-bg") || "#0d0d0f", b = g("--mm-dim") || "rgba(0,0,0,.30)", x = g("--mm-edge") || "rgba(255,255,255,.18)", f = g("--mm-slider") || "rgba(255,255,255,.07)", T = g("--sel-bg") || "rgba(110,159,255,.22)", R = g("--cur-line-bg") || "rgba(255,255,255,.05)", j = g("--find-border") || "rgba(234,180,86,.50)", G = g("--find-cur-bg") || "rgba(234,180,86,.80)", H = (E) => (E - i) * q;
3566
+ if (m.fillStyle = S, m.fillRect(0, 0, o, a), l >= i && l < s && (m.fillStyle = R, m.fillRect(0, H(l), o, q)), c) {
3567
+ const E = Math.max(i, c.ar), N = Math.min(s - 1, c.fr);
3568
+ N >= E && (m.fillStyle = T, m.fillRect(0, H(E), o, (N - E + 1) * q));
3569
+ }
3570
+ for (const E of d) {
3571
+ if (E.row < i || E.row >= s) continue;
3572
+ const N = u >= 0 && ((C = d[u]) == null ? void 0 : C.row) === E.row && ((te = d[u]) == null ? void 0 : te.col) === E.col;
3573
+ m.fillStyle = N ? G : j, m.fillRect(
3574
+ oe + E.col * Y,
3575
+ H(E.row),
3576
+ Math.max(3, E.len * Y),
3577
+ q
3127
3578
  );
3128
3579
  }
3129
- const W = Math.floor((a - 3) / 1.1);
3130
- for (let C = i; C < r; C++) {
3131
- const R = t[C] ?? "";
3132
- if (!R.trim()) continue;
3133
- const w = $(C), k = 1.5, M = oe(R);
3134
- let H = 0;
3135
- for (const B of M) {
3136
- if (B.start >= W) break;
3137
- B.start > H && (b.fillStyle = y.txt, b.fillRect(3 + H * 1.1, w, (Math.min(B.start, W) - H) * 1.1, k));
3138
- const Le = y[B.cls] ?? y.txt, de = Math.min(B.end, W) - B.start;
3139
- de > 0 && (b.fillStyle = Le, b.fillRect(3 + B.start * 1.1, w, de * 1.1, k)), H = Math.max(H, Math.min(B.end, W));
3580
+ const $ = Math.floor((o - oe) / Y);
3581
+ for (let E = i; E < s; E++) {
3582
+ const N = t[E] ?? "";
3583
+ if (!N.trim()) continue;
3584
+ const V = H(E), K = 1.5, v = xe(N);
3585
+ let w = 0;
3586
+ for (const I of v) {
3587
+ if (I.start >= $) break;
3588
+ I.start > w && (m.fillStyle = y.txt, m.fillRect(oe + w * Y, V, (Math.min(I.start, $) - w) * Y, K));
3589
+ const F = y[I.cls] ?? y.txt, X = Math.min(I.end, $) - I.start;
3590
+ X > 0 && (m.fillStyle = F, m.fillRect(oe + I.start * Y, V, X * Y, K)), w = Math.max(w, Math.min(I.end, $));
3140
3591
  }
3141
- const j = Math.min(R.length, W);
3142
- H < j && (b.fillStyle = y.txt, b.fillRect(3 + H * 1.1, w, (j - H) * 1.1, k));
3592
+ const M = Math.min(N.length, $);
3593
+ w < M && (m.fillStyle = y.txt, m.fillRect(oe + w * Y, V, (M - w) * Y, K));
3143
3594
  }
3144
- const N = h + n, z = N + g;
3145
- b.fillStyle = _, N > 0 && b.fillRect(0, 0, a, N), z < l && b.fillRect(0, z, a, l - z), b.fillStyle = m, b.fillRect(0, N, a, g), b.fillStyle = x, b.fillRect(0, Math.max(0, N), a, 1), b.fillRect(0, Math.max(0, z - 1), a, 1);
3595
+ const W = h + n, U = W + _;
3596
+ m.fillStyle = b, W > 0 && m.fillRect(0, 0, o, W), U < a && m.fillRect(0, U, o, a - U), m.fillStyle = f, m.fillRect(0, W, o, _), m.fillStyle = x, m.fillRect(0, Math.max(0, W), o, 1), m.fillRect(0, Math.max(0, U - 1), o, 1);
3146
3597
  }
3147
- const Ft = {
3598
+ const Ei = {
3148
3599
  value: "",
3149
3600
  language: "typescript",
3150
3601
  theme: "",
@@ -3152,13 +3603,13 @@ const Ft = {
3152
3603
  showMinimap: !0,
3153
3604
  showStatusBar: !0,
3154
3605
  wordWrap: !1,
3155
- wrapColumn: 80,
3606
+ wrapColumn: bt,
3156
3607
  fontFamily: "'JetBrains Mono', monospace",
3157
- fontSize: 13,
3158
- lineHeight: 22,
3159
- tabSize: 2,
3608
+ fontSize: ft,
3609
+ lineHeight: pt,
3610
+ tabSize: gt,
3160
3611
  insertSpaces: !0,
3161
- maxUndoHistory: 300,
3612
+ maxUndoHistory: et,
3162
3613
  showIndentGuides: !0,
3163
3614
  bracketMatching: !0,
3164
3615
  codeFolding: !0,
@@ -3181,118 +3632,130 @@ const Ft = {
3181
3632
  autoClosePairs: { "(": ")", "[": "]", "{": "}", '"': '"', "'": "'", "`": "`" },
3182
3633
  lineCommentToken: "",
3183
3634
  wordSeparators: "",
3184
- undoBatchMs: 700,
3185
- gutterWidth: 60,
3186
- minimapWidth: 120,
3635
+ undoBatchMs: _t,
3636
+ gutterWidth: ut,
3637
+ minimapWidth: mt,
3187
3638
  cursorBlinkRate: 1050,
3188
3639
  cursorStyle: "line",
3189
3640
  renderWhitespace: "none",
3190
3641
  tokenColors: {},
3191
- hover: !0
3642
+ hover: !0,
3643
+ placeholder: "",
3644
+ goToLine: !1
3192
3645
  };
3193
- class Ut {
3646
+ class Ii {
3194
3647
  // ── Constructor ───────────────────────────────────────────
3195
3648
  constructor(e, t = {}) {
3196
3649
  // ── DOM ───────────────────────────────────────────────────
3197
- u(this, "_host");
3198
- u(this, "_shadow");
3199
- u(this, "_editorEl");
3200
- u(this, "_spacerEl");
3201
- u(this, "_vpEl");
3202
- u(this, "_inputEl");
3203
- u(this, "_minimapWrap");
3204
- u(this, "_mmCanvas");
3205
- u(this, "_mmSlider");
3206
- u(this, "_statusBar");
3207
- u(this, "_findBar");
3208
- u(this, "_findInput");
3209
- u(this, "_replaceInput");
3210
- u(this, "_findCount");
3211
- u(this, "_replaceRow");
3212
- u(this, "_acPopup");
3213
- u(this, "_emmetTip");
3214
- u(this, "_snippetTip");
3215
- u(this, "_hoverTip");
3216
- u(this, "_themeOverlay");
3217
- u(this, "_themePanel");
3650
+ p(this, "_host");
3651
+ p(this, "_shadow");
3652
+ p(this, "_editorEl");
3653
+ p(this, "_spacerEl");
3654
+ p(this, "_vpEl");
3655
+ p(this, "_inputEl");
3656
+ p(this, "_minimapWrap");
3657
+ p(this, "_mmCanvas");
3658
+ p(this, "_mmSlider");
3659
+ p(this, "_statusBar");
3660
+ p(this, "_findBar");
3661
+ p(this, "_findInput");
3662
+ p(this, "_replaceInput");
3663
+ p(this, "_findCount");
3664
+ p(this, "_replaceRow");
3665
+ p(this, "_acPopup");
3666
+ p(this, "_emmetTip");
3667
+ p(this, "_snippetTip");
3668
+ p(this, "_hoverTip");
3669
+ p(this, "_themeOverlay");
3670
+ p(this, "_themePanel");
3671
+ p(this, "_placeholderEl");
3672
+ p(this, "_goToLineBar");
3673
+ p(this, "_goToLineInput");
3674
+ p(this, "_goToLineHint");
3218
3675
  // ── State ─────────────────────────────────────────────────
3219
- u(this, "_config");
3220
- u(this, "_tab", ue(1, [""]));
3221
- u(this, "_wm", { segments: [[""]], visualRows: [{ docLine: 0, segIdx: 0, text: "" }], docToVisArr: [0] });
3222
- u(this, "_foldedLines", /* @__PURE__ */ new Map());
3223
- u(this, "_tokenCache", new Ke());
3224
- u(this, "_themeManager");
3676
+ p(this, "_config");
3677
+ p(this, "_tab", We(1, [""]));
3678
+ p(this, "_wm", { segments: [[""]], visualRows: [{ docLine: 0, segIdx: 0, text: "" }], docToVisArr: [0] });
3679
+ p(this, "_foldedLines", /* @__PURE__ */ new Map());
3680
+ p(this, "_tokenCache", new Bt());
3681
+ p(this, "_themeManager");
3225
3682
  // Find
3226
- u(this, "_findMatches", []);
3227
- u(this, "_findIdx", -1);
3228
- u(this, "_findCaseSensitive", !1);
3229
- u(this, "_findRegex", !1);
3683
+ p(this, "_findMatches", []);
3684
+ p(this, "_findIdx", -1);
3685
+ p(this, "_findCaseSensitive", !1);
3686
+ p(this, "_findRegex", !1);
3230
3687
  // Highlights
3231
- u(this, "_wordHighlights", []);
3232
- u(this, "_bracketMatch", null);
3688
+ p(this, "_wordHighlights", []);
3689
+ p(this, "_bracketMatch", null);
3233
3690
  // Autocomplete
3234
- u(this, "_acItems", []);
3235
- u(this, "_acSel", 0);
3236
- u(this, "_acPrefix", "");
3237
- u(this, "_acStartCol", 0);
3238
- u(this, "_emmetAcStartCol", 0);
3691
+ p(this, "_acItems", []);
3692
+ p(this, "_acSel", 0);
3693
+ p(this, "_acPrefix", "");
3694
+ p(this, "_acStartCol", 0);
3695
+ p(this, "_emmetAcStartCol", 0);
3239
3696
  // start col of the emmet abbreviation (may differ from _acStartCol)
3240
3697
  // Multi-cursor
3241
- u(this, "_mc", mt());
3242
- u(this, "_extraCursors", []);
3698
+ p(this, "_mc", si());
3699
+ p(this, "_extraCursors", []);
3243
3700
  // Mouse drag
3244
- u(this, "_isDragging", !1);
3245
- u(this, "_dragAnchor", null);
3701
+ p(this, "_isDragging", !1);
3702
+ p(this, "_dragAnchor", null);
3246
3703
  // Hover
3247
- u(this, "_hoverTimer", null);
3248
- u(this, "_hoverPinned", !1);
3704
+ p(this, "_hoverTimer", null);
3705
+ p(this, "_hoverPinned", !1);
3249
3706
  // Minimap drag
3250
- u(this, "_mmDragMode", "none");
3251
- u(this, "_mmDragStartY", 0);
3252
- u(this, "_mmDragStartScroll", 0);
3253
- u(this, "_mmSliderOffset", 0);
3254
- u(this, "_mmColors");
3707
+ p(this, "_mmDragMode", "none");
3708
+ p(this, "_mmDragStartY", 0);
3709
+ p(this, "_mmDragStartScroll", 0);
3710
+ p(this, "_mmSliderOffset", 0);
3711
+ p(this, "_mmColors");
3255
3712
  // Undo batching
3256
- u(this, "_lastInputTime", 0);
3713
+ p(this, "_lastInputTime", 0);
3257
3714
  // Dynamic styles
3258
- u(this, "_dynamicStyleEl");
3715
+ p(this, "_dynamicStyleEl");
3259
3716
  // Emmet
3260
- u(this, "_emmetExpanded", null);
3717
+ p(this, "_emmetExpanded", null);
3261
3718
  // Snippets
3262
- u(this, "_snippetExpanded", null);
3719
+ p(this, "_snippetExpanded", null);
3720
+ /** Active snippet tab-stop session. Cleared on click, Escape, or structural edit. */
3721
+ p(this, "_snippetSession", null);
3722
+ // ── Collaboration (CRDT) ──────────────────────────────────
3723
+ p(this, "_collabBinding", null);
3724
+ p(this, "_remotePeers", /* @__PURE__ */ new Map());
3263
3725
  // ── Lifecycle / performance ───────────────────────────────
3264
3726
  /** Pending debounce timer ID for autocomplete re-computation. */
3265
- u(this, "_acDebounceTimer", null);
3727
+ p(this, "_acDebounceTimer", null);
3266
3728
  /** Pending requestAnimationFrame ID for coalesced renders. */
3267
- u(this, "_rafId", null);
3729
+ p(this, "_rafId", null);
3268
3730
  // ── Bound window listener refs ────────────────────────────
3269
3731
  // Stored as named references so they can be removed precisely in destroy().
3270
- u(this, "_onWinMouseUp");
3271
- u(this, "_onWinResize");
3272
- u(this, "_onEditorScroll");
3273
- u(this, "_onWinMmMouseMove");
3274
- u(this, "_onWinMmMouseUp");
3732
+ p(this, "_onWinMouseUp");
3733
+ p(this, "_onWinResize");
3734
+ p(this, "_onEditorScroll");
3735
+ p(this, "_onWinMmMouseMove");
3736
+ p(this, "_onWinMmMouseUp");
3275
3737
  // ── ResizeObserver — tracks container size changes ────────
3276
- u(this, "_ro", null);
3277
- u(this, "_onFoldBtnClick", (e) => {
3738
+ p(this, "_ro", null);
3739
+ p(this, "_onFoldBtnClick", (e) => {
3278
3740
  const t = e.target.closest(".sl-fold-btn");
3279
3741
  if (!t) return;
3280
3742
  e.preventDefault(), e.stopPropagation();
3281
3743
  const i = parseInt(t.dataset.row ?? "0", 10);
3282
- this._foldedLines = dt(this._foldedLines, this._tab.doc, i), this._tokenCache.clear(), this._rebuildWrapMap(), this._render();
3744
+ this._foldedLines = Jt(this._foldedLines, this._tab.doc, i), this._tokenCache.clear(), this._rebuildWrapMap(), this._render();
3283
3745
  });
3284
- this._config = { ...Ft, ...ye(t) }, this._onWinMouseUp = () => {
3285
- this._isDragging = !1, this._dragAnchor = null;
3286
- }, this._onEditorScroll = Z(() => {
3746
+ this._config = { ...Ei, ...qe(t) }, this._onWinMouseUp = () => {
3747
+ var l, c, d, u;
3748
+ this._isDragging && ((c = (l = this._config).onCursorChange) == null || c.call(l, { ...this._tab.cur }), (u = (d = this._config).onSelectionChange) == null || u.call(d, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab()), this._isDragging = !1, this._dragAnchor = null;
3749
+ }, this._onEditorScroll = fe(() => {
3287
3750
  this._hideHover(), this._scheduleRender(), this._updateMinimap();
3288
- }, 16), this._onWinResize = Z(() => {
3751
+ }, 16), this._onWinResize = fe(() => {
3289
3752
  this._config.wordWrap && this._rebuildWrapMap(), this._scheduleRender();
3290
- }, 100), this._onWinMmMouseMove = (o) => {
3753
+ }, 100), this._onWinMmMouseMove = (l) => {
3291
3754
  if (this._mmDragMode === "none") return;
3292
3755
  const c = this._minimapWrap.clientHeight;
3293
3756
  if (this._mmDragMode === "slider") {
3294
- const d = o.clientY - this._minimapWrap.getBoundingClientRect().top;
3295
- this._editorEl.scrollTop = Wt(
3757
+ const d = l.clientY - this._minimapWrap.getBoundingClientRect().top;
3758
+ this._editorEl.scrollTop = Si(
3296
3759
  d - this._mmSliderOffset,
3297
3760
  this._tab.doc.length,
3298
3761
  this._editorEl.clientHeight,
@@ -3300,41 +3763,41 @@ class Ut {
3300
3763
  this._config.lineHeight
3301
3764
  );
3302
3765
  } else {
3303
- const d = o.clientY - this._mmDragStartY, p = Math.max(0, this._tab.doc.length * this._config.lineHeight - this._editorEl.clientHeight);
3304
- this._editorEl.scrollTop = Math.max(0, Math.min(p, this._mmDragStartScroll + d / 2 * this._config.lineHeight));
3766
+ const d = l.clientY - this._mmDragStartY, u = Math.max(0, this._tab.doc.length * this._config.lineHeight - this._editorEl.clientHeight);
3767
+ this._editorEl.scrollTop = Math.max(0, Math.min(u, this._mmDragStartScroll + d / 2 * this._config.lineHeight));
3305
3768
  }
3306
3769
  this._render();
3307
3770
  }, this._onWinMmMouseUp = () => {
3308
3771
  this._mmDragMode !== "none" && (this._mmDragMode = "none", this._minimapWrap.style.cursor = "pointer");
3309
3772
  }, this._host = e, this._host.classList.add("sl-host"), this._shadow = this._host.attachShadow({ mode: "open" });
3310
- const i = L("style");
3311
- i.textContent = nt, this._shadow.appendChild(i), this._dynamicStyleEl = L("style"), this._shadow.appendChild(this._dynamicStyleEl), this._themeManager = new rt(this._host);
3312
- const r = typeof this._config.theme == "string" ? this._config.theme : this._config.theme;
3313
- this._themeManager.apply(r);
3314
- const n = L("div", "sl-layout"), a = L("div", "sl-ed-pane");
3315
- this._inputEl = L("textarea", "sl-input"), this._inputEl.setAttribute("autocomplete", "off"), this._inputEl.setAttribute("autocorrect", "off"), this._inputEl.setAttribute("autocapitalize", "off"), this._inputEl.setAttribute("spellcheck", "false"), this._inputEl.setAttribute("role", "textbox"), this._inputEl.setAttribute("aria-multiline", "true"), this._inputEl.setAttribute("aria-label", "Code editor"), this._inputEl.setAttribute("aria-readonly", String(!!this._config.readOnly)), this._inputEl.setAttribute("aria-haspopup", "listbox"), this._editorEl = L("div", "sl-editor"), this._spacerEl = L("div", "sl-spacer"), this._vpEl = L("div", "sl-vp"), this._editorEl.appendChild(this._spacerEl), this._editorEl.appendChild(this._vpEl), this._findBar = this._buildFindBar(), this._findInput = this._findBar.querySelector(".sl-find-input"), this._replaceInput = this._findBar.querySelector(".sl-find-replace-input"), this._findCount = this._findBar.querySelector(".sl-find-count"), this._replaceRow = this._findBar.querySelector(".sl-replace-row"), a.appendChild(this._inputEl), a.appendChild(this._findBar), a.appendChild(this._editorEl), this._minimapWrap = L("div", "sl-minimap"), this._minimapWrap.style.width = `${this._config.minimapWidth}px`, this._mmCanvas = L("canvas", ""), this._mmSlider = L("div", "sl-mm-slider"), this._minimapWrap.appendChild(this._mmCanvas), this._minimapWrap.appendChild(this._mmSlider), n.appendChild(a), this._config.showMinimap && n.appendChild(this._minimapWrap), this._statusBar = this._buildStatusBar(), this._acPopup = L("div", "sl-ac-popup"), this._acPopup.setAttribute("role", "listbox"), this._acPopup.setAttribute("aria-label", "Code suggestions"), this._acPopup.style.display = "none", this._emmetTip = L("div", "sl-emmet-tip"), this._emmetTip.style.display = "none", this._snippetTip = L("div", "sl-emmet-tip"), this._snippetTip.style.display = "none", this._hoverTip = L("div", "sl-hover-tip"), this._hoverTip.style.display = "none", this._hoverTip.addEventListener("mouseenter", () => {
3773
+ const i = D("style");
3774
+ i.textContent = zt, this._shadow.appendChild(i), this._dynamicStyleEl = D("style"), this._shadow.appendChild(this._dynamicStyleEl), this._themeManager = new Ut(this._host);
3775
+ const s = typeof this._config.theme == "string" ? this._config.theme : this._config.theme;
3776
+ this._themeManager.apply(s);
3777
+ const n = D("div", "sl-layout"), o = D("div", "sl-ed-pane");
3778
+ this._inputEl = D("textarea", "sl-input"), this._inputEl.setAttribute("autocomplete", "off"), this._inputEl.setAttribute("autocorrect", "off"), this._inputEl.setAttribute("autocapitalize", "off"), this._inputEl.setAttribute("spellcheck", "false"), this._inputEl.setAttribute("role", "textbox"), this._inputEl.setAttribute("aria-multiline", "true"), this._inputEl.setAttribute("aria-label", "Code editor"), this._inputEl.setAttribute("aria-readonly", String(!!this._config.readOnly)), this._inputEl.setAttribute("aria-haspopup", "listbox"), this._editorEl = D("div", "sl-editor"), this._spacerEl = D("div", "sl-spacer"), this._vpEl = D("div", "sl-vp"), this._editorEl.appendChild(this._spacerEl), this._editorEl.appendChild(this._vpEl), this._findBar = this._buildFindBar(), this._findInput = this._findBar.querySelector(".sl-find-input"), this._replaceInput = this._findBar.querySelector(".sl-find-replace-input"), this._findCount = this._findBar.querySelector(".sl-find-count"), this._replaceRow = this._findBar.querySelector(".sl-replace-row"), this._goToLineBar = this._buildGoToLineBar(), this._goToLineInput = this._goToLineBar.querySelector(".sl-gtl-input"), this._goToLineHint = this._goToLineBar.querySelector(".sl-gtl-hint"), this._placeholderEl = D("div", "sl-placeholder"), this._placeholderEl.textContent = this._config.placeholder, this._placeholderEl.style.display = "none", o.appendChild(this._inputEl), o.appendChild(this._findBar), o.appendChild(this._goToLineBar), o.appendChild(this._placeholderEl), o.appendChild(this._editorEl), this._minimapWrap = D("div", "sl-minimap"), this._minimapWrap.style.width = `${this._config.minimapWidth}px`, this._mmCanvas = D("canvas", ""), this._mmSlider = D("div", "sl-mm-slider"), this._minimapWrap.appendChild(this._mmCanvas), this._minimapWrap.appendChild(this._mmSlider), n.appendChild(o), this._config.showMinimap && n.appendChild(this._minimapWrap), this._statusBar = this._buildStatusBar(), this._acPopup = D("div", "sl-ac-popup"), this._acPopup.setAttribute("role", "listbox"), this._acPopup.setAttribute("aria-label", "Code suggestions"), this._acPopup.style.display = "none", this._emmetTip = D("div", "sl-emmet-tip"), this._emmetTip.style.display = "none", this._snippetTip = D("div", "sl-emmet-tip"), this._snippetTip.style.display = "none", this._hoverTip = D("div", "sl-hover-tip"), this._hoverTip.style.display = "none", this._hoverTip.addEventListener("mouseenter", () => {
3316
3779
  this._hoverPinned = !0;
3317
3780
  }), this._hoverTip.addEventListener("mouseleave", () => {
3318
3781
  this._hoverPinned = !1, this._hideHover();
3319
- }), this._themeOverlay = L("div", "sl-theme-overlay"), this._themeOverlay.style.display = "none", this._themePanel = L("div", "sl-theme-panel"), this._themeOverlay.appendChild(this._themePanel), this._shadow.appendChild(n), this._config.showStatusBar && this._shadow.appendChild(this._statusBar), this._shadow.appendChild(this._acPopup), this._shadow.appendChild(this._emmetTip), this._shadow.appendChild(this._snippetTip), this._shadow.appendChild(this._hoverTip), this._shadow.appendChild(this._themeOverlay);
3320
- const l = typeof this._config.value == "string" ? me(this._config.value) : this._config.value;
3321
- this._tab = ue(1, l.length ? l : [""]), this._mmColors = Me((o) => X(o, this._host)), this._bindEditorEvents(), this._bindMinimapEvents(), this._bindFindEvents(), this._applyDynamicStyles(), typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(Z(() => {
3782
+ }), this._themeOverlay = D("div", "sl-theme-overlay"), this._themeOverlay.style.display = "none", this._themePanel = D("div", "sl-theme-panel"), this._themeOverlay.appendChild(this._themePanel), this._shadow.appendChild(n), this._config.showStatusBar && this._shadow.appendChild(this._statusBar), this._shadow.appendChild(this._acPopup), this._shadow.appendChild(this._emmetTip), this._shadow.appendChild(this._snippetTip), this._shadow.appendChild(this._hoverTip), this._shadow.appendChild(this._themeOverlay);
3783
+ const a = typeof this._config.value == "string" ? Ue(this._config.value) : this._config.value;
3784
+ this._tab = We(1, a.length ? a : [""]), this._mmColors = Ze((l) => ue(l, this._host)), this._bindEditorEvents(), this._bindMinimapEvents(), this._bindFindEvents(), this._applyDynamicStyles(), typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(fe(() => {
3322
3785
  this._config.wordWrap && (this._rebuildWrapMap(), this._scheduleRender());
3323
- }, 60)), this._ro.observe(this._host)), this._rebuildWrapMap(), this._render();
3786
+ }, 60)), this._ro.observe(this._host)), this._rebuildWrapMap(), this._render(), this._config.collab && this._initCollab(this._config.collab);
3324
3787
  }
3325
3788
  // ── Public API ────────────────────────────────────────────
3326
3789
  getValue() {
3327
- return D(this._tab.doc);
3790
+ return P(this._tab.doc);
3328
3791
  }
3329
3792
  setValue(e) {
3330
3793
  var t, i;
3331
- E(this._tab, this._config.maxUndoHistory), this._tab.doc = me(e), this._tab.cur = { row: 0, col: 0 }, this._tab.sel = null, this._tokenCache.clear(), this._foldedLines.clear(), this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, e);
3794
+ A(this._tab, this._config.maxUndoHistory), this._tab.doc = Ue(e), this._tab.cur = { row: 0, col: 0 }, this._tab.sel = null, this._tokenCache.clear(), this._foldedLines.clear(), this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, e);
3332
3795
  }
3333
3796
  getCursor() {
3334
3797
  return { ...this._tab.cur };
3335
3798
  }
3336
3799
  setCursor(e) {
3337
- this._tab.cur = { ...e }, A(this._tab), this._scrollIntoView(), this._render();
3800
+ this._tab.cur = { ...e }, L(this._tab), this._scrollIntoView(), this._render();
3338
3801
  }
3339
3802
  getSelection() {
3340
3803
  return this._tab.sel ? { ...this._tab.sel } : null;
@@ -3343,17 +3806,17 @@ class Ut {
3343
3806
  this._tab.sel = e, this._render();
3344
3807
  }
3345
3808
  insertText(e) {
3346
- this._config.readOnly || (this._insertStr(e, !1), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render());
3809
+ this._config.readOnly || (this._insertStr(e, !1), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render());
3347
3810
  }
3348
3811
  setTheme(e) {
3349
- this._themeManager.apply(e), this._applyTokenOverrides(), this._mmColors = Me((t) => X(t, this._host)), this._tokenCache.clear(), this._render();
3812
+ this._themeManager.apply(e), this._applyTokenOverrides(), this._mmColors = Ze((t) => ue(t, this._host)), this._tokenCache.clear(), this._render();
3350
3813
  }
3351
3814
  updateConfig(e) {
3352
- const t = ye(e);
3815
+ const t = qe(e);
3353
3816
  if (t.autoClosePairs !== void 0) {
3354
3817
  const i = t.autoClosePairs;
3355
3818
  this._config.autoClosePairs = Object.keys(i).length === 0 ? {} : { ...this._config.autoClosePairs, ...i };
3356
- const { autoClosePairs: r, ...n } = t;
3819
+ const { autoClosePairs: s, ...n } = t;
3357
3820
  Object.assign(this._config, n);
3358
3821
  } else
3359
3822
  Object.assign(this._config, t);
@@ -3361,7 +3824,7 @@ class Ut {
3361
3824
  const i = this._shadow.querySelector(".sl-layout");
3362
3825
  e.showMinimap ? i.contains(this._minimapWrap) || i.appendChild(this._minimapWrap) : this._minimapWrap.remove();
3363
3826
  }
3364
- e.showStatusBar !== void 0 && (e.showStatusBar ? this._shadow.contains(this._statusBar) || this._shadow.appendChild(this._statusBar) : this._statusBar.remove()), (e.fontFamily !== void 0 || e.fontSize !== void 0 || e.lineHeight !== void 0 || e.cursorBlinkRate !== void 0 || e.cursorStyle !== void 0 || e.gutterWidth !== void 0 || e.minimapWidth !== void 0 || e.showGutter !== void 0 || e.tokenColors !== void 0) && this._applyDynamicStyles(), (e.language !== void 0 || e.extraKeywords !== void 0 || e.extraTypes !== void 0 || e.renderWhitespace !== void 0 || e.completions !== void 0) && this._tokenCache.clear(), e.find === !1 ? this._closeFind() : e.findReplace === !1 && (this._replaceRow.style.display = "none"), this._render();
3827
+ e.showStatusBar !== void 0 && (e.showStatusBar ? this._shadow.contains(this._statusBar) || this._shadow.appendChild(this._statusBar) : this._statusBar.remove()), (e.fontFamily !== void 0 || e.fontSize !== void 0 || e.lineHeight !== void 0 || e.cursorBlinkRate !== void 0 || e.cursorStyle !== void 0 || e.gutterWidth !== void 0 || e.minimapWidth !== void 0 || e.showGutter !== void 0 || e.tokenColors !== void 0) && this._applyDynamicStyles(), (e.language !== void 0 || e.extraKeywords !== void 0 || e.extraTypes !== void 0 || e.renderWhitespace !== void 0 || e.completions !== void 0) && this._tokenCache.clear(), e.find === !1 ? this._closeFind() : e.findReplace === !1 && (this._replaceRow.style.display = "none"), e.goToLine === !1 && this._closeGoToLine(), e.placeholder !== void 0 && (this._placeholderEl.textContent = e.placeholder), "collab" in e && (e.collab ? this._initCollab(e.collab) : this._destroyCollab()), this._render();
3365
3828
  }
3366
3829
  focus() {
3367
3830
  this._focusInput();
@@ -3374,11 +3837,11 @@ class Ut {
3374
3837
  }
3375
3838
  undo() {
3376
3839
  var e, t;
3377
- Oe(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, D(this._tab.doc)));
3840
+ Mt(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, P(this._tab.doc)));
3378
3841
  }
3379
3842
  redo() {
3380
3843
  var e, t;
3381
- Fe(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, D(this._tab.doc)));
3844
+ Et(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, P(this._tab.doc)));
3382
3845
  }
3383
3846
  executeCommand(e) {
3384
3847
  const t = this._config.readOnly;
@@ -3427,15 +3890,47 @@ class Ut {
3427
3890
  break;
3428
3891
  }
3429
3892
  }
3893
+ // ── Collaboration helpers ──────────────────────────────────
3894
+ _initCollab(e) {
3895
+ this._destroyCollab();
3896
+ const t = new de(e.transport.siteId), i = this._config.onChange;
3897
+ this._collabBinding = new Qe(this, t, e.transport, {
3898
+ name: e.name,
3899
+ onPeersChange: (n) => {
3900
+ var o;
3901
+ this._remotePeers = new Map(n), (o = e.onPeersChange) == null || o.call(e, n), this._scheduleRender();
3902
+ }
3903
+ });
3904
+ const s = this._config.onChange;
3905
+ s !== i && (this._config.onChange = (n) => {
3906
+ s == null || s(n), i == null || i(n);
3907
+ }), this._broadcastCursorToCollab();
3908
+ }
3909
+ _destroyCollab() {
3910
+ this._collabBinding && (this._collabBinding.destroy(), this._collabBinding = null, this._remotePeers = /* @__PURE__ */ new Map(), this._scheduleRender());
3911
+ }
3912
+ /** Notify remote peers of the current local cursor / selection position. */
3913
+ _broadcastCursorToCollab() {
3914
+ if (!this._collabBinding) return;
3915
+ const { row: e, col: t } = this._tab.cur;
3916
+ if (this._collabBinding.awareness.updateCursor(e, t), this._tab.sel) {
3917
+ const i = this._tab.sel;
3918
+ this._collabBinding.awareness.updateSelection(
3919
+ { row: i.ar, col: i.ac },
3920
+ { row: i.fr, col: i.fc }
3921
+ );
3922
+ } else
3923
+ this._collabBinding.awareness.clearSelection();
3924
+ }
3430
3925
  destroy() {
3431
3926
  var t;
3432
3927
  this._acDebounceTimer !== null && (clearTimeout(this._acDebounceTimer), this._acDebounceTimer = null), this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null), this._rafId !== null && (cancelAnimationFrame(this._rafId), this._rafId = null), window.removeEventListener("mouseup", this._onWinMouseUp), window.removeEventListener("resize", this._onWinResize), window.removeEventListener("mousemove", this._onWinMmMouseMove), window.removeEventListener("mouseup", this._onWinMmMouseUp), (t = this._ro) == null || t.disconnect();
3433
3928
  const e = this._mmCanvas.getContext("2d");
3434
- e && e.clearRect(0, 0, this._mmCanvas.width, this._mmCanvas.height), this._shadow.innerHTML = "", this._host.classList.remove("sl-host");
3929
+ e && e.clearRect(0, 0, this._mmCanvas.width, this._mmCanvas.height), this._shadow.innerHTML = "", this._host.classList.remove("sl-host"), this._destroyCollab();
3435
3930
  }
3436
3931
  // ── DOM builders ──────────────────────────────────────────
3437
3932
  _buildFindBar() {
3438
- const e = L("div", "sl-find-bar");
3933
+ const e = D("div", "sl-find-bar");
3439
3934
  return e.innerHTML = `
3440
3935
  <div class="sl-find-row">
3441
3936
  <input class="sl-find-input" placeholder="Find…" autocomplete="off" spellcheck="false">
@@ -3453,8 +3948,40 @@ class Ut {
3453
3948
  </div>
3454
3949
  `, e;
3455
3950
  }
3951
+ _buildGoToLineBar() {
3952
+ const e = D("div", "sl-gtl-bar");
3953
+ e.innerHTML = `
3954
+ <span class="sl-gtl-label">Go to line</span>
3955
+ <input class="sl-gtl-input" type="text" inputmode="numeric" autocomplete="off" spellcheck="false" placeholder="…">
3956
+ <span class="sl-gtl-hint"></span>
3957
+ <span class="sl-find-x sl-gtl-close" title="Close">✕</span>
3958
+ `;
3959
+ const t = e.querySelector(".sl-gtl-input"), i = e.querySelector(".sl-gtl-hint");
3960
+ return t.addEventListener("input", () => {
3961
+ const s = parseInt(t.value, 10), n = !isNaN(s) && s >= 1 && s <= this._tab.doc.length;
3962
+ t.classList.toggle("sl-gtl-err", t.value !== "" && !n), i.textContent = `(1–${this._tab.doc.length})`;
3963
+ }), t.addEventListener("keydown", (s) => {
3964
+ var n, o;
3965
+ if (s.key === "Enter") {
3966
+ s.preventDefault();
3967
+ const a = parseInt(t.value, 10);
3968
+ !isNaN(a) && a >= 1 && a <= this._tab.doc.length && (this._tab.cur.row = a - 1, this._tab.cur.col = Math.min(this._tab.cur.col, (this._tab.doc[a - 1] ?? "").length), L(this._tab), this._tab.sel = null, this._closeGoToLine(), this._scrollIntoView(), this._render(), (o = (n = this._config).onCursorChange) == null || o.call(n, { ...this._tab.cur }), this._broadcastCursorToCollab());
3969
+ } else s.key === "Escape" && (s.preventDefault(), this._closeGoToLine());
3970
+ s.stopPropagation();
3971
+ }), e.querySelector(".sl-gtl-close").addEventListener("click", () => this._closeGoToLine()), e;
3972
+ }
3973
+ _openGoToLine() {
3974
+ if (this._goToLineBar.classList.contains("sl-open")) {
3975
+ this._closeGoToLine();
3976
+ return;
3977
+ }
3978
+ this._goToLineHint.textContent = `(1–${this._tab.doc.length})`, this._goToLineInput.value = String(this._tab.cur.row + 1), this._goToLineInput.classList.remove("sl-gtl-err"), this._goToLineBar.classList.add("sl-open"), this._goToLineInput.focus(), this._goToLineInput.select();
3979
+ }
3980
+ _closeGoToLine() {
3981
+ this._goToLineBar.classList.remove("sl-open"), this._focusInput();
3982
+ }
3456
3983
  _buildStatusBar() {
3457
- const e = L("div", "sl-statusbar");
3984
+ const e = D("div", "sl-statusbar");
3458
3985
  return e.innerHTML = `
3459
3986
  <div class="sl-sb-item sl-no-click sl-sb-lang">⬡ TypeScript</div>
3460
3987
  <div class="sl-sb-sep"></div>
@@ -3481,23 +4008,23 @@ class Ut {
3481
4008
  fontFamily: e,
3482
4009
  fontSize: t,
3483
4010
  lineHeight: i,
3484
- cursorBlinkRate: r,
4011
+ cursorBlinkRate: s,
3485
4012
  cursorStyle: n,
3486
- gutterWidth: a,
3487
- minimapWidth: l,
3488
- showGutter: o
4013
+ gutterWidth: o,
4014
+ minimapWidth: a,
4015
+ showGutter: l
3489
4016
  } = this._config, c = Math.max(2, i - 4), d = Math.floor((i - c) / 2);
3490
- let p = "";
3491
- n === "block" ? p = `width:${7.82}px;opacity:.5;border-radius:1px;` : n === "underline" && (p = `width:${7.82}px;height:2px;top:${i - 2}px;border-radius:0;`);
3492
- const h = o ? a : 0;
4017
+ let u = "";
4018
+ n === "block" ? u = `width:${Q}px;opacity:.5;border-radius:1px;` : n === "underline" && (u = `width:${Q}px;height:2px;top:${i - 2}px;border-radius:0;`);
4019
+ const h = l ? o : 0;
3493
4020
  this._dynamicStyleEl.textContent = `
3494
4021
  .sl-el{font-family:${e};font-size:${t}px;line-height:${i}px}
3495
4022
  .sl-cl{height:${i}px;line-height:${i}px}
3496
4023
  .sl-egn{height:${i}px;line-height:${i}px}
3497
- .sl-eg{min-width:${h}px;width:${h}px;${o ? "" : "display:none"}}
3498
- .sl-cur::after{height:${c}px;top:${d}px;animation-duration:${r}ms;${p}}
3499
- .sl-cur-extra::after{height:${c}px;top:${d}px;animation-duration:${r}ms;${p}}
3500
- `, this._applyTokenOverrides(), this._minimapWrap.style.width = `${l}px`;
4024
+ .sl-eg{min-width:${h}px;width:${h}px;${l ? "" : "display:none"}}
4025
+ .sl-cur::after{height:${c}px;top:${d}px;animation-duration:${s}ms;${u}}
4026
+ .sl-cur-extra::after{height:${c}px;top:${d}px;animation-duration:${s}ms;${u}}
4027
+ `, this._applyTokenOverrides(), this._minimapWrap.style.width = `${a}px`, this._placeholderEl.style.left = `${h + se}px`, this._placeholderEl.style.fontFamily = e, this._placeholderEl.style.fontSize = `${t}px`, this._placeholderEl.style.lineHeight = `${i}px`;
3501
4028
  }
3502
4029
  /**
3503
4030
  * Apply tokenColors overrides as inline styles on the host element.
@@ -3506,10 +4033,10 @@ class Ut {
3506
4033
  * When a token field is empty/absent, restore the active theme's value.
3507
4034
  */
3508
4035
  _applyTokenOverrides() {
3509
- const e = this._config.tokenColors ?? {}, t = this._themeManager.activeTheme, i = this._host.style, r = (a, l, o) => {
3510
- i.setProperty(a, l || o);
4036
+ const e = this._config.tokenColors ?? {}, t = this._themeManager.activeTheme, i = this._host.style, s = (o, a, l) => {
4037
+ i.setProperty(o, a || l);
3511
4038
  }, n = t == null ? void 0 : t.tokens;
3512
- r("--tok-kw", e.keyword, (n == null ? void 0 : n.tokKw) ?? ""), r("--tok-str", e.string, (n == null ? void 0 : n.tokStr) ?? ""), r("--tok-cmt", e.comment, (n == null ? void 0 : n.tokCmt) ?? ""), r("--tok-fn", e.function, (n == null ? void 0 : n.tokFn) ?? ""), r("--tok-num", e.number, (n == null ? void 0 : n.tokNum) ?? ""), r("--tok-cls", e.class, (n == null ? void 0 : n.tokCls) ?? ""), r("--tok-op", e.operator, (n == null ? void 0 : n.tokOp) ?? ""), r("--tok-typ", e.type, (n == null ? void 0 : n.tokTyp) ?? ""), r("--tok-dec", e.decorator, (n == null ? void 0 : n.tokDec) ?? "");
4039
+ s("--tok-kw", e.keyword, (n == null ? void 0 : n.tokKw) ?? ""), s("--tok-str", e.string, (n == null ? void 0 : n.tokStr) ?? ""), s("--tok-cmt", e.comment, (n == null ? void 0 : n.tokCmt) ?? ""), s("--tok-fn", e.function, (n == null ? void 0 : n.tokFn) ?? ""), s("--tok-num", e.number, (n == null ? void 0 : n.tokNum) ?? ""), s("--tok-cls", e.class, (n == null ? void 0 : n.tokCls) ?? ""), s("--tok-op", e.operator, (n == null ? void 0 : n.tokOp) ?? ""), s("--tok-typ", e.type, (n == null ? void 0 : n.tokTyp) ?? ""), s("--tok-dec", e.decorator, (n == null ? void 0 : n.tokDec) ?? "");
3513
4040
  }
3514
4041
  // ── Core render ───────────────────────────────────────────
3515
4042
  /**
@@ -3523,19 +4050,35 @@ class Ut {
3523
4050
  }));
3524
4051
  }
3525
4052
  _render() {
3526
- const { doc: e, cur: t, sel: i } = this._tab, { lineHeight: r } = this._config;
3527
- this._wordHighlights = this._config.wordHighlight ? Ct(e, t.row, t.col, i) : [], this._bracketMatch = this._config.bracketMatching ? ot(e, t) : null;
4053
+ const { doc: e, cur: t, sel: i } = this._tab, { lineHeight: s } = this._config;
4054
+ this._wordHighlights = this._config.wordHighlight ? hi(e, t.row, t.col, i) : [], this._bracketMatch = this._config.bracketMatching ? Vt(e, t) : null;
3528
4055
  const n = this._wm.visualRows.length;
3529
- this._spacerEl.style.height = `${n * r}px`;
3530
- const a = this._editorEl.scrollTop, l = this._editorEl.clientHeight, o = Math.max(0, Math.floor(a / r) - 6), c = Math.min(n - 1, Math.ceil((a + l) / r) + 6);
3531
- this._vpEl.style.transform = `translateY(${o * r}px)`;
3532
- const d = F(this._wm, t.row, t.col);
3533
- let p = "";
3534
- for (let h = o; h <= c; h++) {
3535
- const g = this._wm.visualRows[h];
3536
- g && (p += Rt({
3537
- vr: g,
3538
- visIdx: h,
4056
+ if (this._spacerEl.style.height = `${n * s}px`, this._config.wordWrap)
4057
+ this._spacerEl.style.width = "", this._vpEl.style.width = "";
4058
+ else {
4059
+ const g = e.reduce((S, b) => Math.max(S, b.length), 0), k = this._config.showGutter ? this._config.gutterWidth : 0, m = Math.max(
4060
+ this._editorEl.clientWidth,
4061
+ k + se + Math.ceil(g * Q) + Pe + 64
4062
+ );
4063
+ this._spacerEl.style.width = `${m}px`, this._vpEl.style.width = `${m}px`;
4064
+ }
4065
+ const o = this._editorEl.scrollTop, a = this._editorEl.clientHeight, l = Math.max(0, Math.floor(o / s) - je), c = Math.min(n - 1, Math.ceil((o + a) / s) + je);
4066
+ this._vpEl.style.transform = `translateY(${l * s}px)`;
4067
+ const d = ee(this._wm, t.row, t.col), u = /* @__PURE__ */ new Map();
4068
+ if (this._snippetSession)
4069
+ for (let g = this._snippetSession.idx + 1; g < this._snippetSession.stops.length; g++) {
4070
+ const k = this._snippetSession.stops[g], m = ee(this._wm, k.row, k.col), S = u.get(m.visRow) ?? [];
4071
+ S.push(m.colInSeg), u.set(m.visRow, S);
4072
+ }
4073
+ const h = [], _ = [];
4074
+ for (const g of this._remotePeers.values())
4075
+ g.cursor && h.push({ row: g.cursor.row, col: g.cursor.col, name: g.name, color: g.color }), g.selection && _.push({ from: g.selection.from, to: g.selection.to, color: g.color });
4076
+ let y = "";
4077
+ for (let g = l; g <= c; g++) {
4078
+ const k = this._wm.visualRows[g];
4079
+ k && (y += vi({
4080
+ vr: k,
4081
+ visIdx: g,
3539
4082
  curVisRow: d.visRow,
3540
4083
  curColInSeg: d.colInSeg,
3541
4084
  docSel: i,
@@ -3544,10 +4087,13 @@ class Ut {
3544
4087
  wordHighlights: this._wordHighlights,
3545
4088
  bracketMatch: this._bracketMatch,
3546
4089
  extraCursors: this._extraCursors,
4090
+ snippetStopCols: u.get(g) ?? [],
3547
4091
  foldedLines: this._foldedLines,
3548
- isFoldable: this._config.codeFolding && lt(e, g.docLine),
4092
+ isFoldable: this._config.codeFolding && Kt(e, k.docLine),
3549
4093
  wm: this._wm,
3550
4094
  tokenCache: this._tokenCache,
4095
+ remoteCursors: h,
4096
+ remoteSels: _,
3551
4097
  opts: {
3552
4098
  tokeniserOpts: {
3553
4099
  language: this._config.language,
@@ -3556,63 +4102,67 @@ class Ut {
3556
4102
  },
3557
4103
  showIndentGuides: this._config.showIndentGuides,
3558
4104
  highlightActiveLine: this._config.highlightActiveLine,
3559
- charWidth: 7.82,
3560
- codePaddingLeft: 14,
4105
+ charWidth: Q,
4106
+ codePaddingLeft: se,
3561
4107
  tabSize: this._config.tabSize,
3562
- lineHeight: r,
4108
+ lineHeight: s,
3563
4109
  renderWhitespace: this._config.renderWhitespace
3564
4110
  }
3565
4111
  }));
3566
4112
  }
3567
- this._vpEl.innerHTML = p, this._updateStatusBar(), this._updateMinimap();
4113
+ if (this._vpEl.innerHTML = y, this._updateStatusBar(), this._updateMinimap(), this._config.placeholder) {
4114
+ const g = this._tab.doc.length === 1 && this._tab.doc[0] === "";
4115
+ this._placeholderEl.style.display = g ? "" : "none";
4116
+ } else
4117
+ this._placeholderEl.style.display = "none";
3568
4118
  }
3569
4119
  // ── Status bar ────────────────────────────────────────────
3570
4120
  _updateStatusBar() {
3571
4121
  if (!this._config.showStatusBar) return;
3572
- const { cur: e, doc: t, undoStack: i, redoStack: r } = this._tab, n = this._config.language, a = {
4122
+ const { cur: e, doc: t, undoStack: i, redoStack: s } = this._tab, n = this._config.language, o = {
3573
4123
  typescript: "TypeScript",
3574
4124
  javascript: "JavaScript",
3575
4125
  css: "CSS",
3576
4126
  json: "JSON",
3577
4127
  markdown: "Markdown",
3578
4128
  text: "Text"
3579
- }, l = (h) => this._statusBar.querySelector(h);
3580
- l(".sl-sb-lang").textContent = `⬡ ${a[n] ?? n}`, l(".sl-sb-pos").textContent = `Ln ${e.row + 1}, Col ${e.col + 1}`, l(".sl-sb-lines").textContent = `${t.length.toLocaleString()} lines`;
3581
- const o = Ue(this._tab), c = l(".sl-sb-sel"), d = l(".sl-sb-sel-sep");
3582
- c.textContent = o ? `${o.toLocaleString()} selected` : "", d.style.display = o ? "" : "none", l(".sl-sb-undo").textContent = `↩${i.length} ↪${r.length}`;
3583
- const p = l(".sl-sb-mc");
3584
- this._extraCursors.length ? (p.style.display = "", l(".sl-sb-mc-count").textContent = String(this._extraCursors.length + 1)) : p.style.display = "none";
4129
+ }, a = (h) => this._statusBar.querySelector(h);
4130
+ a(".sl-sb-lang").textContent = `⬡ ${o[n] ?? n}`, a(".sl-sb-pos").textContent = `Ln ${e.row + 1}, Col ${e.col + 1}`, a(".sl-sb-lines").textContent = `${t.length.toLocaleString()} lines`;
4131
+ const l = It(this._tab), c = a(".sl-sb-sel"), d = a(".sl-sb-sel-sep");
4132
+ c.textContent = l ? `${l.toLocaleString()} selected` : "", d.style.display = l ? "" : "none", a(".sl-sb-undo").textContent = `↩${i.length} ↪${s.length}`;
4133
+ const u = a(".sl-sb-mc");
4134
+ this._extraCursors.length ? (u.style.display = "", a(".sl-sb-mc-count").textContent = String(this._extraCursors.length + 1)) : u.style.display = "none";
3585
4135
  }
3586
4136
  // ── Minimap ───────────────────────────────────────────────
3587
4137
  _updateMinimap() {
3588
4138
  if (!this._config.showMinimap) return;
3589
4139
  const e = this._minimapWrap.clientWidth, t = this._minimapWrap.clientHeight;
3590
4140
  if (!e || !t) return;
3591
- const i = this._tab.doc, r = i.length, n = Math.min(window.devicePixelRatio || 1, 2), a = this._config.lineHeight, { mmScroll: l, sliderTop: o, sliderHeight: c } = ie(
3592
- r,
4141
+ const i = this._tab.doc, s = i.length, n = Math.min(window.devicePixelRatio || 1, 2), o = this._config.lineHeight, { mmScroll: a, sliderTop: l, sliderHeight: c } = _e(
4142
+ s,
3593
4143
  this._editorEl.scrollTop,
3594
4144
  this._editorEl.clientHeight,
3595
4145
  t,
3596
- a
3597
- ), d = l / 2, p = Math.floor(d), h = Math.ceil(t / 2) + 2, g = Math.min(r, p + h), y = (g - p) * 2, v = (d - p) * 2, f = Math.round(e * n), b = Math.round(y * n);
3598
- (this._mmCanvas.width !== f || this._mmCanvas.height !== b) && (this._mmCanvas.width = f, this._mmCanvas.height = b, this._mmCanvas.style.width = `${e}px`, this._mmCanvas.style.height = `${y}px`), this._mmCanvas.style.transform = `translateY(${-v}px)`, Ot({
4146
+ o
4147
+ ), d = a / 2, u = Math.floor(d), h = Math.ceil(t / 2) + 2, _ = Math.min(s, u + h), y = (_ - u) * 2, g = (d - u) * 2, k = Math.round(e * n), m = Math.round(y * n);
4148
+ (this._mmCanvas.width !== k || this._mmCanvas.height !== m) && (this._mmCanvas.width = k, this._mmCanvas.height = m, this._mmCanvas.style.width = `${e}px`, this._mmCanvas.style.height = `${y}px`), this._mmCanvas.style.transform = `translateY(${-g}px)`, Mi({
3599
4149
  canvas: this._mmCanvas,
3600
4150
  doc: i,
3601
- firstLine: p,
3602
- lastLine: g,
3603
- subPx: v,
4151
+ firstLine: u,
4152
+ lastLine: _,
4153
+ subPx: g,
3604
4154
  wrapperWidth: e,
3605
4155
  canvasHeight: y,
3606
4156
  cursorRow: this._tab.cur.row,
3607
4157
  sel: this._tab.sel,
3608
4158
  findMatches: this._findMatches,
3609
4159
  findIdx: this._findIdx,
3610
- sliderTop: o,
4160
+ sliderTop: l,
3611
4161
  sliderHeight: c,
3612
4162
  colors: this._mmColors,
3613
- getCssVar: (T) => X(T, this._host),
4163
+ getCssVar: (S) => ue(S, this._host),
3614
4164
  dpr: n
3615
- }), this._mmSlider.style.top = `${Math.max(0, Math.min(t - c, o))}px`, this._mmSlider.style.height = `${c}px`;
4165
+ }), this._mmSlider.style.top = `${Math.max(0, Math.min(t - c, l))}px`, this._mmSlider.style.height = `${c}px`;
3616
4166
  }
3617
4167
  // ── WrapMap ───────────────────────────────────────────────
3618
4168
  _rebuildWrapMap() {
@@ -3620,13 +4170,13 @@ class Ut {
3620
4170
  if (this._config.wordWrap) {
3621
4171
  const t = this._config.showGutter ? this._config.gutterWidth : 0, i = this._editorEl.clientWidth;
3622
4172
  if (i > 0) {
3623
- const r = i - t - 14 - 20;
3624
- e = Math.max(20, Math.floor(r / 7.82));
4173
+ const s = i - t - se - Pe;
4174
+ e = Math.max(20, Math.floor(s / Q));
3625
4175
  } else
3626
4176
  e = this._config.wrapColumn;
3627
4177
  } else
3628
4178
  e = 9999;
3629
- this._wm = Ge(
4179
+ this._wm = Rt(
3630
4180
  this._tab.doc,
3631
4181
  e,
3632
4182
  this._config.wordWrap,
@@ -3635,121 +4185,124 @@ class Ut {
3635
4185
  }
3636
4186
  // ── Scroll ────────────────────────────────────────────────
3637
4187
  _scrollIntoView() {
3638
- const e = this._tab.cur, i = F(this._wm, e.row, e.col).visRow * this._config.lineHeight, r = i + this._config.lineHeight, n = this._editorEl.scrollTop, a = this._editorEl.clientHeight, l = this._config.lineHeight * 3;
3639
- i < n + l ? this._editorEl.scrollTop = Math.max(0, i - l) : r > n + a - l && (this._editorEl.scrollTop = r - a + l);
4188
+ const e = this._config.lineHeight;
4189
+ this._spacerEl.style.height = `${this._wm.visualRows.length * e}px`;
4190
+ const t = this._tab.cur, s = ee(this._wm, t.row, t.col).visRow * e, n = s + e, o = this._editorEl.scrollTop, a = this._editorEl.clientHeight, l = e * 3;
4191
+ s < o + l ? this._editorEl.scrollTop = Math.max(0, s - l) : n > o + a - l && (this._editorEl.scrollTop = n - a + l);
3640
4192
  }
3641
4193
  // ── Input helpers ─────────────────────────────────────────
3642
4194
  _focusInput() {
3643
4195
  this._inputEl.style.pointerEvents = "auto", this._inputEl.focus(), this._inputEl.style.pointerEvents = "none";
3644
4196
  }
3645
4197
  _insertStr(e, t) {
3646
- var d, p;
4198
+ var d, u;
3647
4199
  const i = Date.now();
3648
- (!t || i - this._lastInputTime > this._config.undoBatchMs) && E(this._tab, this._config.maxUndoHistory), this._lastInputTime = i, this._tab.sel && (this._tab.cur = O(this._tab));
3649
- const { doc: r, cur: n } = this._tab, a = e.split(`
3650
- `), l = r[n.row] ?? "", o = l.slice(0, n.col), c = l.slice(n.col);
3651
- if (a.length === 1)
3652
- r[n.row] = o + e + c, n.col += e.length;
4200
+ (!t || i - this._lastInputTime > this._config.undoBatchMs) && A(this._tab, this._config.maxUndoHistory), this._lastInputTime = i, this._tab.sel && (this._tab.cur = re(this._tab));
4201
+ const { doc: s, cur: n } = this._tab, o = e.split(`
4202
+ `), a = s[n.row] ?? "", l = a.slice(0, n.col), c = a.slice(n.col);
4203
+ if (o.length === 1)
4204
+ s[n.row] = l + e + c, n.col += e.length;
3653
4205
  else {
3654
- const h = [o + a[0]];
3655
- for (let g = 1; g < a.length - 1; g++) h.push(a[g]);
3656
- h.push(a[a.length - 1] + c), r.splice(n.row, 1, ...h), n.row += a.length - 1, n.col = a[a.length - 1].length;
4206
+ const h = [l + o[0]];
4207
+ for (let _ = 1; _ < o.length - 1; _++) h.push(o[_]);
4208
+ h.push(o[o.length - 1] + c), s.splice(n.row, 1, ...h), n.row += o.length - 1, n.col = o[o.length - 1].length;
3657
4209
  }
3658
- this._tokenCache.invalidateLine(n.row, (this._wm.segments[n.row] ?? [""]).length), this._tab.dirty = !0, (p = (d = this._config).onChange) == null || p.call(d, D(r));
4210
+ this._tokenCache.invalidateLine(n.row, (this._wm.segments[n.row] ?? [""]).length), this._tab.dirty = !0, (u = (d = this._config).onChange) == null || u.call(d, P(s));
3659
4211
  }
3660
4212
  _doBackspace() {
3661
4213
  var i;
3662
- if (E(this._tab, this._config.maxUndoHistory), this._tab.sel) {
3663
- this._tab.cur = O(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
4214
+ if (A(this._tab, this._config.maxUndoHistory), this._tab.sel) {
4215
+ this._tab.cur = re(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
3664
4216
  return;
3665
4217
  }
3666
4218
  const { doc: e, cur: t } = this._tab;
3667
4219
  if (t.col > 0) {
3668
- const r = e[t.row] ?? "", n = r.slice(0, t.col), a = n.length >= 2 && n.endsWith(" ") && !n.trim() ? 2 : 1;
3669
- e[t.row] = r.slice(0, t.col - a) + r.slice(t.col), t.col -= a, this._tokenCache.invalidateLine(t.row, ((i = this._wm.segments[t.row]) == null ? void 0 : i.length) ?? 1);
4220
+ const s = e[t.row] ?? "", n = s.slice(0, t.col), o = n.length >= 2 && n.endsWith(" ") && !n.trim() ? 2 : 1;
4221
+ e[t.row] = s.slice(0, t.col - o) + s.slice(t.col), t.col -= o, this._tokenCache.invalidateLine(t.row, ((i = this._wm.segments[t.row]) == null ? void 0 : i.length) ?? 1);
3670
4222
  } else if (t.row > 0) {
3671
- const r = (e[t.row - 1] ?? "").length;
3672
- e[t.row - 1] += e[t.row] ?? "", e.splice(t.row, 1), t.row--, t.col = r, this._tokenCache.clear();
4223
+ const s = (e[t.row - 1] ?? "").length;
4224
+ e[t.row - 1] += e[t.row] ?? "", e.splice(t.row, 1), t.row--, t.col = s, this._tokenCache.clear();
3673
4225
  }
3674
4226
  this._tab.dirty = !0;
3675
4227
  }
3676
4228
  _doEnter() {
3677
- E(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = O(this._tab));
3678
- const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "", r = i.slice(0, t.col), n = i.slice(t.col), a = _e(i), l = r.trimEnd().endsWith("{") ? J(this._config.tabSize) : "";
3679
- e[t.row] = r, r.trimEnd().endsWith("{") && n.trimStart() === "}" ? e.splice(t.row + 1, 0, a + l, a + n) : e.splice(t.row + 1, 0, a + l + n), t.row++, t.col = a.length + l.length, this._tokenCache.clear(), this._tab.dirty = !0;
4229
+ A(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = re(this._tab));
4230
+ const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "", s = i.slice(0, t.col), n = i.slice(t.col), o = ze(i), a = s.trimEnd().endsWith("{") ? ce(this._config.tabSize) : "";
4231
+ e[t.row] = s, s.trimEnd().endsWith("{") && n.trimStart() === "}" ? e.splice(t.row + 1, 0, o + a, o + n) : e.splice(t.row + 1, 0, o + a + n), t.row++, t.col = o.length + a.length, this._tokenCache.clear(), this._tab.dirty = !0;
3680
4232
  }
3681
4233
  _doDelete() {
3682
- var r;
3683
- if (E(this._tab, this._config.maxUndoHistory), this._tab.sel) {
3684
- this._tab.cur = O(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
4234
+ var s;
4235
+ if (A(this._tab, this._config.maxUndoHistory), this._tab.sel) {
4236
+ this._tab.cur = re(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
3685
4237
  return;
3686
4238
  }
3687
4239
  const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "";
3688
- t.col < i.length ? (e[t.row] = i.slice(0, t.col) + i.slice(t.col + 1), this._tokenCache.invalidateLine(t.row, ((r = this._wm.segments[t.row]) == null ? void 0 : r.length) ?? 1)) : t.row < e.length - 1 && (e[t.row] = i + (e[t.row + 1] ?? ""), e.splice(t.row + 1, 1), this._tokenCache.clear()), this._tab.dirty = !0;
4240
+ t.col < i.length ? (e[t.row] = i.slice(0, t.col) + i.slice(t.col + 1), this._tokenCache.invalidateLine(t.row, ((s = this._wm.segments[t.row]) == null ? void 0 : s.length) ?? 1)) : t.row < e.length - 1 && (e[t.row] = i + (e[t.row + 1] ?? ""), e.splice(t.row + 1, 1), this._tokenCache.clear()), this._tab.dirty = !0;
3689
4241
  }
3690
4242
  // ── Editing commands ──────────────────────────────────────
3691
4243
  _selectAll() {
4244
+ var i, s, n, o;
3692
4245
  const e = this._tab.doc, t = e.length - 1;
3693
- this._tab.sel = { ar: 0, ac: 0, fr: t, fc: (e[t] ?? "").length }, this._tab.cur = { row: t, col: (e[t] ?? "").length }, this._render();
4246
+ this._tab.sel = { ar: 0, ac: 0, fr: t, fc: (e[t] ?? "").length }, this._tab.cur = { row: t, col: (e[t] ?? "").length }, this._render(), (s = (i = this._config).onCursorChange) == null || s.call(i, { ...this._tab.cur }), (o = (n = this._config).onSelectionChange) == null || o.call(n, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab();
3694
4247
  }
3695
4248
  _doCopy() {
3696
4249
  var t;
3697
- const e = ge(this._tab);
4250
+ const e = Ne(this._tab);
3698
4251
  e && ((t = navigator.clipboard) == null || t.writeText(e).catch(() => {
3699
4252
  }));
3700
4253
  }
3701
4254
  _doCut() {
3702
- var t, i, r;
3703
- const e = ge(this._tab);
4255
+ var t, i, s, n, o, a, l;
4256
+ const e = Ne(this._tab);
3704
4257
  e && ((t = navigator.clipboard) == null || t.writeText(e).catch(() => {
3705
- }), E(this._tab, this._config.maxUndoHistory), this._tab.cur = O(this._tab), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (r = (i = this._config).onChange) == null || r.call(i, D(this._tab.doc)));
4258
+ }), A(this._tab, this._config.maxUndoHistory), this._tab.cur = re(this._tab), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (s = (i = this._config).onChange) == null || s.call(i, P(this._tab.doc)), (o = (n = this._config).onCursorChange) == null || o.call(n, { ...this._tab.cur }), (l = (a = this._config).onSelectionChange) == null || l.call(a, null), this._broadcastCursorToCollab());
3706
4259
  }
3707
4260
  _toggleComment() {
3708
- var n, a;
3709
- E(this._tab, this._config.maxUndoHistory);
3710
- const e = this._getSelRows(), t = this._config.lineCommentToken || Re[this._config.language] || "";
4261
+ var n, o, a, l;
4262
+ A(this._tab, this._config.maxUndoHistory);
4263
+ const e = this._getSelRows(), t = this._config.lineCommentToken || vt[this._config.language] || "";
3711
4264
  if (!t) return;
3712
- const i = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), r = e.every((l) => (this._tab.doc[l] ?? "").trimStart().startsWith(t));
3713
- e.forEach((l) => {
3714
- var c;
3715
- const o = this._tab.doc[l] ?? "";
3716
- this._tab.doc[l] = r ? o.replace(new RegExp(`^(\\s*)${i}\\s?`), "$1") : o.replace(/^(\s*)/, `$1${t} `), this._tokenCache.invalidateLine(l, ((c = this._wm.segments[l]) == null ? void 0 : c.length) ?? 1);
3717
- }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (a = (n = this._config).onChange) == null || a.call(n, D(this._tab.doc));
4265
+ const i = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), s = e.every((c) => (this._tab.doc[c] ?? "").trimStart().startsWith(t));
4266
+ e.forEach((c) => {
4267
+ var u;
4268
+ const d = this._tab.doc[c] ?? "";
4269
+ this._tab.doc[c] = s ? d.replace(new RegExp(`^(\\s*)${i}\\s?`), "$1") : d.replace(/^(\s*)/, `$1${t} `), this._tokenCache.invalidateLine(c, ((u = this._wm.segments[c]) == null ? void 0 : u.length) ?? 1);
4270
+ }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (o = (n = this._config).onChange) == null || o.call(n, P(this._tab.doc)), (l = (a = this._config).onCursorChange) == null || l.call(a, { ...this._tab.cur }), this._broadcastCursorToCollab();
3718
4271
  }
3719
4272
  _duplicateLine() {
3720
- var t, i;
3721
- E(this._tab, this._config.maxUndoHistory);
4273
+ var t, i, s, n;
4274
+ A(this._tab, this._config.maxUndoHistory);
3722
4275
  const e = this._tab.cur.row;
3723
- this._tab.doc.splice(e + 1, 0, this._tab.doc[e] ?? ""), this._tab.cur.row++, this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, D(this._tab.doc));
4276
+ this._tab.doc.splice(e + 1, 0, this._tab.doc[e] ?? ""), this._tab.cur.row++, this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, P(this._tab.doc)), (n = (s = this._config).onCursorChange) == null || n.call(s, { ...this._tab.cur }), this._broadcastCursorToCollab();
3724
4277
  }
3725
4278
  _deleteLine() {
3726
- var i, r;
3727
- E(this._tab, this._config.maxUndoHistory);
4279
+ var i, s, n, o;
4280
+ A(this._tab, this._config.maxUndoHistory);
3728
4281
  const { doc: e, cur: t } = this._tab;
3729
- e.length > 1 ? e.splice(t.row, 1) : (e[0] = "", t.col = 0), this._tokenCache.clear(), this._tab.dirty = !0, A(this._tab), this._rebuildWrapMap(), this._render(), (r = (i = this._config).onChange) == null || r.call(i, D(this._tab.doc));
4282
+ e.length > 1 ? e.splice(t.row, 1) : (e[0] = "", t.col = 0), this._tokenCache.clear(), this._tab.dirty = !0, L(this._tab), this._rebuildWrapMap(), this._render(), (s = (i = this._config).onChange) == null || s.call(i, P(this._tab.doc)), (o = (n = this._config).onCursorChange) == null || o.call(n, { ...this._tab.cur }), this._broadcastCursorToCollab();
3730
4283
  }
3731
4284
  _indentSel() {
3732
- var t, i;
4285
+ var t, i, s, n;
3733
4286
  if (!this._tab.sel) {
3734
- this._insertStr(J(this._config.tabSize), !1);
4287
+ this._insertStr(ce(this._config.tabSize), !1);
3735
4288
  return;
3736
4289
  }
3737
- E(this._tab, this._config.maxUndoHistory);
3738
- const e = J(this._config.tabSize);
3739
- this._getSelRows().forEach((r) => {
3740
- var n;
3741
- this._tab.doc[r] = e + (this._tab.doc[r] ?? ""), this._tokenCache.invalidateLine(r, ((n = this._wm.segments[r]) == null ? void 0 : n.length) ?? 1);
3742
- }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, D(this._tab.doc));
4290
+ A(this._tab, this._config.maxUndoHistory);
4291
+ const e = ce(this._config.tabSize);
4292
+ this._getSelRows().forEach((o) => {
4293
+ var a;
4294
+ this._tab.doc[o] = e + (this._tab.doc[o] ?? ""), this._tokenCache.invalidateLine(o, ((a = this._wm.segments[o]) == null ? void 0 : a.length) ?? 1);
4295
+ }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, P(this._tab.doc)), (n = (s = this._config).onCursorChange) == null || n.call(s, { ...this._tab.cur }), this._broadcastCursorToCollab();
3743
4296
  }
3744
4297
  _unindentSel() {
3745
- var t, i;
3746
- E(this._tab, this._config.maxUndoHistory);
4298
+ var t, i, s, n;
4299
+ A(this._tab, this._config.maxUndoHistory);
3747
4300
  const e = this._config.tabSize;
3748
- this._getSelRows().forEach((r) => {
3749
- var a;
3750
- const n = this._tab.doc[r] ?? "";
3751
- n.startsWith(J(e)) ? this._tab.doc[r] = n.slice(e) : n.startsWith(" ") && (this._tab.doc[r] = n.slice(1)), this._tokenCache.invalidateLine(r, ((a = this._wm.segments[r]) == null ? void 0 : a.length) ?? 1);
3752
- }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, D(this._tab.doc));
4301
+ this._getSelRows().forEach((o) => {
4302
+ var l;
4303
+ const a = this._tab.doc[o] ?? "";
4304
+ a.startsWith(ce(e)) ? this._tab.doc[o] = a.slice(e) : a.startsWith(" ") && (this._tab.doc[o] = a.slice(1)), this._tokenCache.invalidateLine(o, ((l = this._wm.segments[o]) == null ? void 0 : l.length) ?? 1);
4305
+ }), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, P(this._tab.doc)), (n = (s = this._config).onCursorChange) == null || n.call(s, { ...this._tab.cur }), this._broadcastCursorToCollab();
3753
4306
  }
3754
4307
  _toggleWrap() {
3755
4308
  this._config.wordWrap = !this._config.wordWrap, this._vpEl.classList.toggle("sl-wrap-mode", this._config.wordWrap);
@@ -3758,18 +4311,18 @@ class Ut {
3758
4311
  }
3759
4312
  _getSelRows() {
3760
4313
  if (!this._tab.sel) return [this._tab.cur.row];
3761
- const e = P(this._tab.sel), t = [];
4314
+ const e = J(this._tab.sel), t = [];
3762
4315
  for (let i = e.ar; i <= e.fr; i++) t.push(i);
3763
4316
  return t;
3764
4317
  }
3765
4318
  // ── Mouse position helper ─────────────────────────────────
3766
4319
  _posFromMouse(e) {
3767
4320
  var c;
3768
- const t = this._editorEl.getBoundingClientRect(), i = e.clientY - t.top + this._editorEl.scrollTop, r = this._config.showGutter ? this._config.gutterWidth : 0, n = e.clientX - t.left - r - 14, a = this._config.lineHeight, l = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(i / a))), o = Math.max(0, Math.min(
3769
- (((c = this._wm.visualRows[l]) == null ? void 0 : c.text) ?? "").length,
3770
- Math.round(n / 7.82)
4321
+ const t = this._editorEl.getBoundingClientRect(), i = e.clientY - t.top + this._editorEl.scrollTop, s = this._config.showGutter ? this._config.gutterWidth : 0, n = e.clientX - t.left - s - se, o = this._config.lineHeight, a = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(i / o))), l = Math.max(0, Math.min(
4322
+ (((c = this._wm.visualRows[a]) == null ? void 0 : c.text) ?? "").length,
4323
+ Math.round(n / Q)
3771
4324
  ));
3772
- return Y(this._wm, l, o);
4325
+ return le(this._wm, a, l);
3773
4326
  }
3774
4327
  // ── Find ──────────────────────────────────────────────────
3775
4328
  _openFind(e) {
@@ -3779,7 +4332,7 @@ class Ut {
3779
4332
  this._findBar.classList.remove("sl-open"), this._findMatches = [], this._findIdx = -1, this._findCount.textContent = "–", this._focusInput(), this._render();
3780
4333
  }
3781
4334
  _runFind(e) {
3782
- this._findMatches = wt(this._tab.doc, e, {
4335
+ this._findMatches = ai(this._tab.doc, e, {
3783
4336
  caseSensitive: this._findCaseSensitive,
3784
4337
  useRegex: this._findRegex
3785
4338
  });
@@ -3789,7 +4342,7 @@ class Ut {
3789
4342
  this._findCount.textContent = "0/0";
3790
4343
  return;
3791
4344
  }
3792
- this._findIdx = Tt(this._findMatches, this._findIdx, e);
4345
+ this._findIdx = di(this._findMatches, this._findIdx, e);
3793
4346
  const t = this._findMatches[this._findIdx];
3794
4347
  this._tab.cur = { row: t.row, col: t.col }, this._tab.sel = { ar: t.row, ac: t.col, fr: t.row, fc: t.col + t.len }, this._scrollIntoView(), this._render(), this._findCount.textContent = `${this._findIdx + 1}/${this._findMatches.length}`;
3795
4348
  }
@@ -3814,7 +4367,7 @@ class Ut {
3814
4367
  }
3815
4368
  this._acDebounceTimer !== null && clearTimeout(this._acDebounceTimer), this._acDebounceTimer = setTimeout(() => {
3816
4369
  this._acDebounceTimer = null, this._acTriggerNow();
3817
- }, 120);
4370
+ }, yt);
3818
4371
  }
3819
4372
  /** Run an autocomplete refresh immediately (no debounce). */
3820
4373
  _acTriggerNow() {
@@ -3822,21 +4375,21 @@ class Ut {
3822
4375
  this._acHide();
3823
4376
  return;
3824
4377
  }
3825
- const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", r = this._config.language === "css", { prefix: n, start: a } = At(i, e.col, r);
3826
- this._acPrefix = n, this._acStartCol = a;
3827
- const l = [];
4378
+ const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", s = this._config.language === "css", { prefix: n, start: o } = bi(i, e.col, s);
4379
+ this._acPrefix = n, this._acStartCol = o;
4380
+ const a = [];
3828
4381
  if (this._config.emmet) {
3829
- const c = we(i, e.col);
4382
+ const c = Ve(i, e.col);
3830
4383
  if (c) {
3831
- const d = ve(c.abbr);
4384
+ const d = Ge(c.abbr);
3832
4385
  if (d) {
3833
4386
  this._emmetAcStartCol = c.start;
3834
- const p = d.replace(/\n/g, "↵ ").slice(0, 60);
3835
- l.push({ label: c.abbr, kind: "emmet", detail: p, body: d });
4387
+ const u = d.replace(/\n/g, "↵ ").slice(0, 60);
4388
+ a.push({ label: c.abbr, kind: "emmet", detail: u, body: d });
3836
4389
  }
3837
4390
  }
3838
4391
  }
3839
- const o = n.length >= this._config.autocompletePrefixLength ? It(t, n, {
4392
+ const l = n.length >= this._config.autocompletePrefixLength ? gi(t, n, {
3840
4393
  language: this._config.language,
3841
4394
  extraKeywords: this._config.extraKeywords,
3842
4395
  extraTypes: this._config.extraTypes,
@@ -3845,15 +4398,15 @@ class Ut {
3845
4398
  maxResults: this._config.maxCompletions,
3846
4399
  provideCompletions: this._config.provideCompletions
3847
4400
  }, e.row, e.col) : [];
3848
- if (this._acItems = [...l, ...o], !this._acItems.length) {
4401
+ if (this._acItems = [...a, ...l], !this._acItems.length) {
3849
4402
  this._acHide();
3850
4403
  return;
3851
4404
  }
3852
4405
  this._acSel = 0, this._renderAcPopup();
3853
4406
  }
3854
4407
  _renderAcPopup() {
3855
- const e = (o) => {
3856
- switch (o) {
4408
+ const e = (l) => {
4409
+ switch (l) {
3857
4410
  case "kw":
3858
4411
  return "K";
3859
4412
  case "fn":
@@ -3872,39 +4425,39 @@ class Ut {
3872
4425
  }, t = this._acItems[this._acSel];
3873
4426
  let i = "";
3874
4427
  t != null && t.description ? i = t.description : (t == null ? void 0 : t.kind) === "snip" && t.body ? i = t.body.replace(/\$\d/g, "▌") : (t == null ? void 0 : t.kind) === "emmet" && t.body && (i = t.body);
3875
- const r = this._acItems.map((o, c) => {
4428
+ const s = this._acItems.map((l, c) => {
3876
4429
  const d = c === this._acSel;
3877
- return `<div class="sl-ac-item${d ? " sl-sel" : ""}" data-i="${c}" role="option" aria-selected="${d}"><span class="sl-ac-badge ${o.kind}">${e(o.kind)}</span><span class="sl-ac-label">${o.label}</span><span class="sl-ac-detail">${o.detail ?? ""}</span></div>`;
4430
+ return `<div class="sl-ac-item${d ? " sl-sel" : ""}" data-i="${c}" role="option" aria-selected="${d}"><span class="sl-ac-badge ${l.kind}">${e(l.kind)}</span><span class="sl-ac-label">${l.label}</span><span class="sl-ac-detail">${l.detail ?? ""}</span></div>`;
3878
4431
  }).join(""), n = i ? `<div class="sl-ac-desc"><pre class="sl-ac-desc-body">${i.replace(/</g, "&lt;")}</pre></div>` : "";
3879
- this._acPopup.innerHTML = `<div class="sl-ac-list">${r}</div>` + n, this._acPopup.style.display = "flex", this._posAcPopup();
3880
- const a = this._acPopup.querySelector(".sl-ac-list"), l = this._acPopup.querySelector(".sl-ac-item.sl-sel");
3881
- if (a && l) {
3882
- const o = l.offsetTop, c = o + l.offsetHeight;
3883
- c > a.scrollTop + a.clientHeight ? a.scrollTop = c - a.clientHeight : o < a.scrollTop && (a.scrollTop = o);
4432
+ this._acPopup.innerHTML = `<div class="sl-ac-list">${s}</div>` + n, this._acPopup.style.display = "flex", this._posAcPopup();
4433
+ const o = this._acPopup.querySelector(".sl-ac-list"), a = this._acPopup.querySelector(".sl-ac-item.sl-sel");
4434
+ if (o && a) {
4435
+ const l = a.offsetTop, c = l + a.offsetHeight;
4436
+ c > o.scrollTop + o.clientHeight ? o.scrollTop = c - o.clientHeight : l < o.scrollTop && (o.scrollTop = l);
3884
4437
  }
3885
- this._acPopup.querySelectorAll(".sl-ac-item").forEach((o) => {
3886
- o.addEventListener("mousedown", (c) => {
3887
- c.preventDefault(), this._acSel = parseInt(o.dataset.i ?? "0", 10), this._acAccept();
4438
+ this._acPopup.querySelectorAll(".sl-ac-item").forEach((l) => {
4439
+ l.addEventListener("mousedown", (c) => {
4440
+ c.preventDefault(), this._acSel = parseInt(l.dataset.i ?? "0", 10), this._acAccept();
3888
4441
  });
3889
4442
  });
3890
4443
  }
3891
4444
  _posAcPopup() {
3892
- const e = this._editorEl.getBoundingClientRect(), t = F(this._wm, this._tab.cur.row, this._tab.cur.col), i = this._config.showGutter ? this._config.gutterWidth : 0, r = e.left + i + 14 + this._acStartCol * 7.82, n = e.top + (t.visRow * this._config.lineHeight - this._editorEl.scrollTop) + this._config.lineHeight + 2, l = !!this._acPopup.querySelector(".sl-ac-desc") ? 620 : 300, o = Math.min(this._acItems.length * 28 + 8, 320), c = n + o > window.innerHeight - 16;
3893
- this._acPopup.style.left = `${Math.min(r, window.innerWidth - l - 16)}px`, this._acPopup.style.top = `${c ? n - this._config.lineHeight - 2 - o : n}px`;
4445
+ const e = this._editorEl.getBoundingClientRect(), t = ee(this._wm, this._tab.cur.row, this._tab.cur.col), i = this._config.showGutter ? this._config.gutterWidth : 0, s = e.left + i + se + this._acStartCol * Q, n = e.top + (t.visRow * this._config.lineHeight - this._editorEl.scrollTop) + this._config.lineHeight + 2, a = !!this._acPopup.querySelector(".sl-ac-desc") ? 620 : 300, l = Math.min(this._acItems.length * 28 + 8, 320), c = n + l > window.innerHeight - 16;
4446
+ this._acPopup.style.left = `${Math.min(s, window.innerWidth - a - 16)}px`, this._acPopup.style.top = `${c ? n - this._config.lineHeight - 2 - l : n}px`;
3894
4447
  }
3895
4448
  _acAccept() {
3896
4449
  const e = this._acItems[this._acSel];
3897
4450
  if (!e) return;
3898
4451
  if (this._acHide(), e.kind === "emmet" && e.body) {
3899
- E(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._emmetAcStartCol);
4452
+ A(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._emmetAcStartCol);
3900
4453
  return;
3901
4454
  }
3902
4455
  if (e.body) {
3903
- E(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._acStartCol);
4456
+ A(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._acStartCol);
3904
4457
  return;
3905
4458
  }
3906
4459
  const t = e.label.slice(this._acPrefix.length);
3907
- this._insertStr(t, !1), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render();
4460
+ this._insertStr(t, !1), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render();
3908
4461
  }
3909
4462
  // ── Emmet ─────────────────────────────────────────────────
3910
4463
  _emmetCheck() {
@@ -3912,46 +4465,46 @@ class Ut {
3912
4465
  this._emmetExpanded = null;
3913
4466
  return;
3914
4467
  }
3915
- const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", r = we(i, e.col);
3916
- if (!r) {
4468
+ const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", s = Ve(i, e.col);
4469
+ if (!s) {
3917
4470
  this._emmetExpanded = null;
3918
4471
  return;
3919
4472
  }
3920
- const n = ve(r.abbr);
4473
+ const n = Ge(s.abbr);
3921
4474
  if (!n) {
3922
4475
  this._emmetExpanded = null;
3923
4476
  return;
3924
4477
  }
3925
- this._emmetExpanded = { abbr: r.abbr, result: n, start: r.start };
4478
+ this._emmetExpanded = { abbr: s.abbr, result: n, start: s.start };
3926
4479
  }
3927
4480
  _emmetAccept() {
3928
4481
  if (!this._emmetExpanded || this._emmetTip.style.display === "none") return !1;
3929
4482
  const { abbr: e, result: t, start: i } = this._emmetExpanded;
3930
- return E(this._tab, this._config.maxUndoHistory), this._emmetExpanded = null, this._emmetTip.style.display = "none", this._expandBodyAt(t, i), !0;
4483
+ return A(this._tab, this._config.maxUndoHistory), this._emmetExpanded = null, this._emmetTip.style.display = "none", this._expandBodyAt(t, i), !0;
3931
4484
  }
3932
4485
  // ── Snippets / Completions ────────────────────────────────
3933
4486
  /** Returns built-in snippets for the current language merged with user completions.
3934
4487
  * When `replaceBuiltins` is true the language built-ins are suppressed so only
3935
4488
  * the caller-supplied completions (e.g. MDX_SNIPPETS) are active. */
3936
4489
  _allCompletions() {
3937
- return [...this._config.replaceBuiltins ? [] : gt(this._config.language), ...this._config.completions];
4490
+ return [...this._config.replaceBuiltins ? [] : ti(this._config.language), ...this._config.completions];
3938
4491
  }
3939
4492
  _snippetCheck() {
3940
4493
  if (this._snippetTip.style.display = "none", !this._config.snippetExpansion) {
3941
4494
  this._snippetExpanded = null;
3942
4495
  return;
3943
4496
  }
3944
- const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", r = bt(i, e.col, this._allCompletions());
3945
- if (!r) {
4497
+ const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", s = ii(i, e.col, this._allCompletions());
4498
+ if (!s) {
3946
4499
  this._snippetExpanded = null;
3947
4500
  return;
3948
4501
  }
3949
- this._snippetExpanded = { snippet: r.snippet, start: r.start };
4502
+ this._snippetExpanded = { snippet: s.snippet, start: s.start };
3950
4503
  }
3951
4504
  _snippetAccept() {
3952
4505
  if (!this._snippetExpanded || this._snippetTip.style.display === "none") return !1;
3953
4506
  const { snippet: e, start: t } = this._snippetExpanded;
3954
- return e.body ? (E(this._tab, this._config.maxUndoHistory), this._snippetExpanded = null, this._snippetTip.style.display = "none", this._expandBodyAt(e.body, t), !0) : !1;
4507
+ return e.body ? (A(this._tab, this._config.maxUndoHistory), this._snippetExpanded = null, this._snippetTip.style.display = "none", this._expandBodyAt(e.body, t), !0) : !1;
3955
4508
  }
3956
4509
  /**
3957
4510
  * Expand a snippet/emmet body template at the current cursor position.
@@ -3961,17 +4514,19 @@ class Ut {
3961
4514
  * Everything between `triggerStart` and `cur.col` is replaced by `body`.
3962
4515
  */
3963
4516
  _expandBodyAt(e, t) {
3964
- var y, v;
3965
- const { doc: i, cur: r } = this._tab, n = i[r.row] ?? "", a = n.slice(0, t), l = n.slice(r.col), o = _e(n), c = e.split(`
3966
- `).map((f, b) => b === 0 ? f : o + f), d = c.join(`
3967
- `), p = d.indexOf("$1"), h = c.map((f) => f.replace(/\$\d+/g, "")), g = h.length === 1 ? [a + h[0] + l] : [a + h[0], ...h.slice(1, -1), h[h.length - 1] + l];
3968
- if (i.splice(r.row, 1, ...g), p >= 0) {
3969
- const f = d.slice(0, p).split(`
3970
- `), b = f.length - 1, T = f[b].length, _ = (f[b].match(/\$\d+/g) ?? []).join("").length;
3971
- r.row += b, r.col = (b === 0 ? t : o.length) + (T - _);
3972
- } else
3973
- r.row += g.length - 1, r.col = (g[g.length - 1] ?? "").length - l.length;
3974
- this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (v = (y = this._config).onChange) == null || v.call(y, D(this._tab.doc));
4517
+ var m, S;
4518
+ const { doc: i, cur: s } = this._tab, n = s.row, o = i[s.row] ?? "", a = o.slice(0, t), l = o.slice(s.col), c = ze(o), d = e.split(`
4519
+ `).map((b, x) => x === 0 ? b : c + b), u = d.join(`
4520
+ `), h = [], _ = /\$(\d+)/g;
4521
+ let y;
4522
+ for (; (y = _.exec(u)) !== null; ) {
4523
+ const b = parseInt(y[1], 10), f = u.slice(0, y.index).split(`
4524
+ `), T = f.length - 1, R = f[T].length, j = (f[T].match(/\$\d+/g) ?? []).join("").length, G = n + T, H = (T === 0 ? t : c.length) + (R - j);
4525
+ h.push({ n: b, row: G, col: H });
4526
+ }
4527
+ h.sort((b, x) => b.n === 0 ? 1 : x.n === 0 ? -1 : b.n - x.n);
4528
+ const g = d.map((b) => b.replace(/\$\d+/g, "")), k = g.length === 1 ? [a + g[0] + l] : [a + g[0], ...g.slice(1, -1), g[g.length - 1] + l];
4529
+ i.splice(s.row, 1, ...k), h.length > 0 ? (this._snippetSession = { stops: h.map((b) => ({ row: b.row, col: b.col })), idx: 0 }, s.row = h[0].row, s.col = h[0].col) : (this._snippetSession = null, s.row += k.length - 1, s.col = (k[k.length - 1] ?? "").length - l.length), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (S = (m = this._config).onChange) == null || S.call(m, P(this._tab.doc));
3975
4530
  }
3976
4531
  // ── Theme picker ──────────────────────────────────────────
3977
4532
  _openThemePicker() {
@@ -4005,41 +4560,42 @@ class Ut {
4005
4560
  i.target === this._themeOverlay && (this._themeOverlay.style.display = "none");
4006
4561
  }, { once: !0 }), this._themePanel.querySelectorAll(".sl-theme-item").forEach((i) => {
4007
4562
  i.addEventListener("click", () => {
4008
- const r = i.dataset.id ?? "";
4009
- this.setTheme(r), this._themePanel.querySelectorAll(".sl-theme-item").forEach((n) => n.classList.remove("sl-active")), i.classList.add("sl-active");
4563
+ const s = i.dataset.id ?? "";
4564
+ this.setTheme(s), this._themePanel.querySelectorAll(".sl-theme-item").forEach((n) => n.classList.remove("sl-active")), i.classList.add("sl-active");
4010
4565
  });
4011
4566
  });
4012
4567
  }
4013
4568
  // ── Event binding ─────────────────────────────────────────
4014
4569
  _bindEditorEvents() {
4015
4570
  this._vpEl.addEventListener("mousedown", this._onFoldBtnClick), this._editorEl.addEventListener("mousedown", (e) => {
4571
+ var i, s, n, o;
4016
4572
  if (e.button !== 0) return;
4017
- e.preventDefault(), this._focusInput(), this._acHide(), this._emmetTip.style.display = "none", e.altKey || (xe(this._mc), this._extraCursors = []);
4573
+ e.preventDefault(), this._focusInput(), this._acHide(), this._snippetSession = null, this._emmetTip.style.display = "none", e.altKey || (Ye(this._mc), this._extraCursors = []);
4018
4574
  const t = this._posFromMouse(e);
4019
4575
  if (this._tab.cur = { ...t }, e.detail === 3)
4020
4576
  this._tab.sel = { ar: t.row, ac: 0, fr: t.row, fc: (this._tab.doc[t.row] ?? "").length }, this._tab.cur.col = this._tab.sel.fc;
4021
4577
  else if (e.detail === 2 && this._config.wordSelection) {
4022
- const i = this._tab.doc[t.row] ?? "", r = le(i, t.col, this._isWordChar.bind(this)), n = ce(i, t.col, this._isWordChar.bind(this));
4023
- r !== n ? (this._tab.sel = { ar: t.row, ac: r, fr: t.row, fc: n }, this._tab.cur.col = n) : this._tab.sel = null;
4578
+ const a = this._tab.doc[t.row] ?? "", l = Ce(a, t.col, this._isWordChar.bind(this)), c = Se(a, t.col, this._isWordChar.bind(this));
4579
+ l !== c ? (this._tab.sel = { ar: t.row, ac: l, fr: t.row, fc: c }, this._tab.cur.col = c) : this._tab.sel = null;
4024
4580
  } else {
4025
4581
  if (e.altKey && this._config.multiCursor) {
4026
- ke(this._mc, t.row, t.col, null), this._extraCursors = [...this._mc.cursors], this._render();
4582
+ Ke(this._mc, t.row, t.col, null), this._extraCursors = [...this._mc.cursors], this._render();
4027
4583
  return;
4028
4584
  }
4029
4585
  this._tab.sel = null, this._isDragging = !0, this._dragAnchor = { ...t };
4030
4586
  }
4031
- A(this._tab), this._render();
4587
+ L(this._tab), this._render(), (s = (i = this._config).onCursorChange) == null || s.call(i, { ...this._tab.cur }), (o = (n = this._config).onSelectionChange) == null || o.call(n, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab();
4032
4588
  }), this._editorEl.addEventListener("mousemove", (e) => {
4033
4589
  if (this._config.hover && !this._hoverPinned && !this._isDragging && this._scheduleHover(e), !this._isDragging || !this._dragAnchor) return;
4034
4590
  const t = this._posFromMouse(e);
4035
- this._tab.cur = { ...t }, t.row !== this._dragAnchor.row || t.col !== this._dragAnchor.col ? this._tab.sel = { ar: this._dragAnchor.row, ac: this._dragAnchor.col, fr: t.row, fc: t.col } : this._tab.sel = null, A(this._tab), this._render();
4591
+ this._tab.cur = { ...t }, t.row !== this._dragAnchor.row || t.col !== this._dragAnchor.col ? this._tab.sel = { ar: this._dragAnchor.row, ac: this._dragAnchor.col, fr: t.row, fc: t.col } : this._tab.sel = null, L(this._tab), this._render(), this._broadcastCursorToCollab();
4036
4592
  }), this._editorEl.addEventListener("mouseleave", () => {
4037
4593
  this._hoverPinned || this._hideHover();
4038
4594
  }), window.addEventListener("mouseup", this._onWinMouseUp), this._editorEl.addEventListener("scroll", this._onEditorScroll, { passive: !0 }), window.addEventListener("resize", this._onWinResize), this._inputEl.addEventListener("keydown", (e) => this._onKeyDown(e)), this._inputEl.addEventListener("input", (e) => this._onInput(e)), this._inputEl.addEventListener("paste", (e) => {
4039
4595
  var i;
4040
4596
  if (e.preventDefault(), this._config.readOnly) return;
4041
4597
  const t = (i = e.clipboardData ?? window.clipboardData) == null ? void 0 : i.getData("text/plain");
4042
- t && (this._insertStr(t, !1), this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render());
4598
+ t && (this._insertStr(t, !1), this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render());
4043
4599
  }), this._editorEl.addEventListener("mousedown", () => setTimeout(() => this._focusInput(), 0)), this._inputEl.addEventListener("focus", () => {
4044
4600
  var e, t;
4045
4601
  return (t = (e = this._config).onFocus) == null ? void 0 : t.call(e);
@@ -4049,8 +4605,8 @@ class Ut {
4049
4605
  });
4050
4606
  }
4051
4607
  _onKeyDown(e) {
4052
- var a, l, o, c, d, p, h, g, y;
4053
- const t = e.ctrlKey || e.metaKey, i = e.shiftKey, r = e.altKey, n = this._config.readOnly;
4608
+ var o, a, l, c, d, u, h, _, y, g, k, m, S, b, x, f, T, R, j, G, H, $, W, U, C, te, E, N, V, K, v, w, M, I, F, X, Te, Me, Ee, Ie, Le, Re, Be;
4609
+ const t = e.ctrlKey || e.metaKey, i = e.shiftKey, s = e.altKey, n = this._config.readOnly;
4054
4610
  if (this._hideHover(), this._acVisible()) {
4055
4611
  if (e.key === "ArrowDown") {
4056
4612
  e.preventDefault(), this._acSel = Math.min(this._acItems.length - 1, this._acSel + 1), this._renderAcPopup();
@@ -4069,7 +4625,7 @@ class Ut {
4069
4625
  return;
4070
4626
  }
4071
4627
  }
4072
- if (r && (e.key === "z" || e.key === "Z" || e.key === "Ω")) {
4628
+ if (s && (e.key === "z" || e.key === "Z" || e.key === "Ω")) {
4073
4629
  e.preventDefault(), this._toggleWrap();
4074
4630
  return;
4075
4631
  }
@@ -4101,6 +4657,10 @@ class Ut {
4101
4657
  e.preventDefault(), this._config.find && this._config.findReplace && this._openFind(!0);
4102
4658
  return;
4103
4659
  }
4660
+ if (t && e.key === "g") {
4661
+ e.preventDefault(), this._config.goToLine && this._openGoToLine();
4662
+ return;
4663
+ }
4104
4664
  if (t && e.key === "d") {
4105
4665
  e.preventDefault(), !n && this._config.multiCursor && this._ctrlD();
4106
4666
  return;
@@ -4118,7 +4678,7 @@ class Ut {
4118
4678
  return;
4119
4679
  }
4120
4680
  if (e.key === "Escape") {
4121
- this._tab.sel = null, this._acHide(), this._closeFind(), this._emmetTip.style.display = "none", this._snippetTip.style.display = "none", this._snippetExpanded = null, xe(this._mc), this._extraCursors = [], this._mc.searchWord = "", this._render();
4681
+ this._tab.sel = null, this._acHide(), this._closeFind(), this._closeGoToLine(), this._emmetTip.style.display = "none", this._snippetTip.style.display = "none", this._snippetExpanded = null, this._snippetSession = null, Ye(this._mc), this._extraCursors = [], this._mc.searchWord = "", this._render(), (a = (o = this._config).onCursorChange) == null || a.call(o, { ...this._tab.cur }), (c = (l = this._config).onSelectionChange) == null || c.call(l, null), this._broadcastCursorToCollab();
4122
4682
  return;
4123
4683
  }
4124
4684
  if (n) {
@@ -4126,142 +4686,183 @@ class Ut {
4126
4686
  return;
4127
4687
  }
4128
4688
  if (e.key === "Tab") {
4129
- if (e.preventDefault(), !i && this._emmetAccept() || !i && this._snippetAccept()) return;
4130
- i ? this._unindentSel() : this._indentSel(), A(this._tab), this._scrollIntoView(), this._rebuildWrapMap(), this._render();
4689
+ if (e.preventDefault(), this._snippetSession) {
4690
+ if (i) {
4691
+ if (this._snippetSession.idx > 0) {
4692
+ this._snippetSession.idx--;
4693
+ const B = this._snippetSession.stops[this._snippetSession.idx];
4694
+ this._tab.cur.row = B.row, this._tab.cur.col = B.col, this._tab.sel = null, L(this._tab), this._scrollIntoView(), this._render(), (u = (d = this._config).onCursorChange) == null || u.call(d, { ...this._tab.cur }), (_ = (h = this._config).onSelectionChange) == null || _.call(h, null), this._broadcastCursorToCollab();
4695
+ }
4696
+ } else if (this._snippetSession.idx++, this._snippetSession.idx >= this._snippetSession.stops.length)
4697
+ this._snippetSession = null;
4698
+ else {
4699
+ const B = this._snippetSession.stops[this._snippetSession.idx];
4700
+ this._tab.cur.row = B.row, this._tab.cur.col = B.col, this._tab.sel = null, L(this._tab), this._scrollIntoView(), this._render(), (g = (y = this._config).onCursorChange) == null || g.call(y, { ...this._tab.cur }), (m = (k = this._config).onSelectionChange) == null || m.call(k, null), this._broadcastCursorToCollab();
4701
+ }
4702
+ return;
4703
+ }
4704
+ if (!i && this._emmetAccept() || !i && this._snippetAccept()) return;
4705
+ i ? this._unindentSel() : this._indentSel(), L(this._tab), this._scrollIntoView(), this._rebuildWrapMap(), this._render(), (b = (S = this._config).onCursorChange) == null || b.call(S, { ...this._tab.cur }), (f = (x = this._config).onSelectionChange) == null || f.call(x, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab();
4131
4706
  return;
4132
4707
  }
4133
4708
  if (e.key === "Backspace") {
4134
4709
  if (e.preventDefault(), this._extraCursors.length) {
4135
- const v = yt(
4710
+ this._snippetSession = null;
4711
+ const B = ri(
4136
4712
  this._tab.doc,
4137
4713
  this._tab.cur.row,
4138
4714
  this._tab.cur.col,
4139
4715
  this._extraCursors
4140
4716
  );
4141
- this._tab.doc = v.doc, this._tab.cur.row = v.primaryRow, this._tab.cur.col = v.primaryCol, this._extraCursors = v.extraCursors, this._mc.cursors = v.extraCursors;
4142
- } else
4717
+ this._tab.doc = B.doc, this._tab.cur.row = B.primaryRow, this._tab.cur.col = B.primaryCol, this._extraCursors = B.extraCursors, this._mc.cursors = B.extraCursors;
4718
+ } else {
4719
+ if (this._snippetSession) {
4720
+ const B = this._snippetSession.stops[this._snippetSession.idx];
4721
+ if (this._tab.cur.row === B.row && this._tab.cur.col > B.col) {
4722
+ for (let O = this._snippetSession.idx + 1; O < this._snippetSession.stops.length; O++) {
4723
+ const ie = this._snippetSession.stops[O];
4724
+ ie.row === B.row && ie.col >= this._tab.cur.col && ie.col--;
4725
+ }
4726
+ B.col--;
4727
+ } else
4728
+ this._snippetSession = null;
4729
+ }
4143
4730
  this._doBackspace();
4144
- this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (l = (a = this._config).onChange) == null || l.call(a, D(this._tab.doc));
4731
+ }
4732
+ this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (R = (T = this._config).onChange) == null || R.call(T, P(this._tab.doc)), (G = (j = this._config).onCursorChange) == null || G.call(j, { ...this._tab.cur }), ($ = (H = this._config).onSelectionChange) == null || $.call(H, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab();
4145
4733
  return;
4146
4734
  }
4147
4735
  if (e.key === "Delete") {
4148
- e.preventDefault(), this._doDelete(), this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (c = (o = this._config).onChange) == null || c.call(o, D(this._tab.doc));
4736
+ e.preventDefault(), this._snippetSession = null, this._doDelete(), this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (U = (W = this._config).onChange) == null || U.call(W, P(this._tab.doc)), (te = (C = this._config).onCursorChange) == null || te.call(C, { ...this._tab.cur }), (N = (E = this._config).onSelectionChange) == null || N.call(E, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab();
4149
4737
  return;
4150
4738
  }
4151
4739
  if (e.key === "Enter") {
4152
- e.preventDefault(), this._doEnter(), this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (p = (d = this._config).onChange) == null || p.call(d, D(this._tab.doc));
4740
+ e.preventDefault(), this._snippetSession = null, this._doEnter(), this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (K = (V = this._config).onChange) == null || K.call(V, P(this._tab.doc)), (w = (v = this._config).onCursorChange) == null || w.call(v, { ...this._tab.cur }), (I = (M = this._config).onSelectionChange) == null || I.call(M, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab();
4153
4741
  return;
4154
4742
  }
4155
- if (!t && !r && this._config.autoClosePairs[e.key]) {
4156
- e.preventDefault(), E(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = O(this._tab));
4157
- const { doc: v, cur: f } = this._tab, b = v[f.row] ?? "";
4158
- v[f.row] = b.slice(0, f.col) + e.key + this._config.autoClosePairs[e.key] + b.slice(f.col), f.col++, this._tokenCache.invalidateLine(f.row, ((h = this._wm.segments[f.row]) == null ? void 0 : h.length) ?? 1), this._tab.dirty = !0, this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (y = (g = this._config).onChange) == null || y.call(g, D(this._tab.doc));
4743
+ if (!t && !s && this._config.autoClosePairs[e.key]) {
4744
+ e.preventDefault(), A(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = re(this._tab));
4745
+ const { doc: B, cur: O } = this._tab, ie = B[O.row] ?? "";
4746
+ B[O.row] = ie.slice(0, O.col) + e.key + this._config.autoClosePairs[e.key] + ie.slice(O.col), O.col++, this._tokenCache.invalidateLine(O.row, ((F = this._wm.segments[O.row]) == null ? void 0 : F.length) ?? 1), this._tab.dirty = !0, this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (Te = (X = this._config).onChange) == null || Te.call(X, P(this._tab.doc)), (Ee = (Me = this._config).onCursorChange) == null || Ee.call(Me, { ...this._tab.cur }), (Le = (Ie = this._config).onSelectionChange) == null || Le.call(Ie, null), this._broadcastCursorToCollab();
4159
4747
  return;
4160
4748
  }
4161
- if (!t && !r && Object.values(this._config.autoClosePairs).includes(e.key)) {
4162
- const { doc: v, cur: f } = this._tab;
4163
- if ((v[f.row] ?? "")[f.col] === e.key) {
4164
- e.preventDefault(), f.col++, A(this._tab), this._scrollIntoView(), this._render();
4749
+ if (!t && !s && Object.values(this._config.autoClosePairs).includes(e.key)) {
4750
+ const { doc: B, cur: O } = this._tab;
4751
+ if ((B[O.row] ?? "")[O.col] === e.key) {
4752
+ e.preventDefault(), O.col++, L(this._tab), this._scrollIntoView(), this._render(), (Be = (Re = this._config).onCursorChange) == null || Be.call(Re, { ...this._tab.cur }), this._broadcastCursorToCollab();
4165
4753
  return;
4166
4754
  }
4167
4755
  }
4168
- if (r && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
4756
+ if (i && s && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
4757
+ e.preventDefault(), this._duplicateLines(e.key === "ArrowDown");
4758
+ return;
4759
+ }
4760
+ if (s && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
4169
4761
  e.preventDefault(), this._moveLines(e.key === "ArrowUp");
4170
4762
  return;
4171
4763
  }
4172
4764
  this._handleArrowKeys(e, t, i);
4173
4765
  }
4174
4766
  _handleArrowKeys(e, t, i) {
4175
- var g, y, v, f, b, T;
4176
- const { doc: r, cur: n } = this._tab, a = this._config.lineHeight, l = e.metaKey, o = e.ctrlKey, c = e.altKey, d = (_, x) => {
4767
+ var _, y, g, k, m, S;
4768
+ const { doc: s, cur: n } = this._tab, o = this._config.lineHeight, a = e.metaKey, l = e.ctrlKey, c = e.altKey, d = (b, x) => {
4177
4769
  if (i) {
4178
- this._tab.sel || (this._tab.sel = { ar: n.row, ac: n.col, fr: n.row, fc: n.col }), n.row = _, n.col = x;
4179
- const m = this._tab.sel;
4180
- m.fr = _, m.fc = x, m.ar === m.fr && m.ac === m.fc && (this._tab.sel = null);
4770
+ this._tab.sel || (this._tab.sel = { ar: n.row, ac: n.col, fr: n.row, fc: n.col }), n.row = b, n.col = x;
4771
+ const f = this._tab.sel;
4772
+ f.fr = b, f.fc = x, f.ar === f.fr && f.ac === f.fc && (this._tab.sel = null);
4181
4773
  } else
4182
- this._tab.sel = null, n.row = _, n.col = x;
4183
- }, p = (_) => {
4184
- const m = (r[_] ?? "").search(/\S/);
4185
- return m === -1 || n.col === m ? 0 : m;
4186
- }, h = () => ({ row: r.length - 1, col: (r[r.length - 1] ?? "").length });
4774
+ this._tab.sel = null, n.row = b, n.col = x;
4775
+ }, u = (b) => {
4776
+ const f = (s[b] ?? "").search(/\S/);
4777
+ return f === -1 || n.col === f ? 0 : f;
4778
+ }, h = () => ({ row: s.length - 1, col: (s[s.length - 1] ?? "").length });
4187
4779
  switch (e.key) {
4188
4780
  case "ArrowRight":
4189
4781
  if (e.preventDefault(), this._tab.sel && !i) {
4190
- const _ = P(this._tab.sel);
4191
- n.row = _.fr, n.col = _.fc, this._tab.sel = null;
4782
+ const b = J(this._tab.sel);
4783
+ n.row = b.fr, n.col = b.fc, this._tab.sel = null;
4192
4784
  break;
4193
4785
  }
4194
- if (l)
4195
- d(n.row, (r[n.row] ?? "").length);
4196
- else if (o || c) {
4197
- const _ = this._wordSkipRight(r[n.row] ?? "", n.col);
4198
- d(n.row, _);
4199
- } else n.col < (r[n.row] ?? "").length ? d(n.row, n.col + 1) : n.row < r.length - 1 && d(n.row + 1, 0);
4786
+ if (a)
4787
+ d(n.row, (s[n.row] ?? "").length);
4788
+ else if (l || c) {
4789
+ const b = s[n.row] ?? "";
4790
+ if (n.col >= b.length)
4791
+ n.row < s.length - 1 && d(n.row + 1, 0);
4792
+ else {
4793
+ const x = this._wordSkipRight(b, n.col);
4794
+ d(n.row, x);
4795
+ }
4796
+ } else n.col < (s[n.row] ?? "").length ? d(n.row, n.col + 1) : n.row < s.length - 1 && d(n.row + 1, 0);
4200
4797
  break;
4201
4798
  case "ArrowLeft":
4202
4799
  if (e.preventDefault(), this._tab.sel && !i) {
4203
- const _ = P(this._tab.sel);
4204
- n.row = _.ar, n.col = _.ac, this._tab.sel = null;
4800
+ const b = J(this._tab.sel);
4801
+ n.row = b.ar, n.col = b.ac, this._tab.sel = null;
4205
4802
  break;
4206
4803
  }
4207
- if (l)
4208
- d(n.row, p(n.row));
4209
- else if (o || c) {
4210
- const _ = this._wordSkipLeft(r[n.row] ?? "", n.col);
4211
- d(n.row, _);
4212
- } else n.col > 0 ? d(n.row, n.col - 1) : n.row > 0 && d(n.row - 1, (r[n.row - 1] ?? "").length);
4804
+ if (a)
4805
+ d(n.row, u(n.row));
4806
+ else if (l || c)
4807
+ if (n.col === 0)
4808
+ n.row > 0 && d(n.row - 1, (s[n.row - 1] ?? "").length);
4809
+ else {
4810
+ const b = this._wordSkipLeft(s[n.row] ?? "", n.col);
4811
+ d(n.row, b);
4812
+ }
4813
+ else n.col > 0 ? d(n.row, n.col - 1) : n.row > 0 && d(n.row - 1, (s[n.row - 1] ?? "").length);
4213
4814
  break;
4214
4815
  case "ArrowDown":
4215
- if (e.preventDefault(), l) {
4216
- const _ = h();
4217
- d(_.row, _.col);
4816
+ if (e.preventDefault(), a) {
4817
+ const b = h();
4818
+ d(b.row, b.col);
4218
4819
  } else if (this._config.wordWrap) {
4219
- const _ = F(this._wm, n.row, n.col), x = Math.min(this._wm.visualRows.length - 1, _.visRow + 1), m = Y(this._wm, x, Math.min(_.colInSeg, (((g = this._wm.visualRows[x]) == null ? void 0 : g.text) ?? "").length));
4220
- d(m.row, m.col);
4820
+ const b = ee(this._wm, n.row, n.col), x = Math.min(this._wm.visualRows.length - 1, b.visRow + 1), f = le(this._wm, x, Math.min(b.colInSeg, (((_ = this._wm.visualRows[x]) == null ? void 0 : _.text) ?? "").length));
4821
+ d(f.row, f.col);
4221
4822
  } else {
4222
- const _ = Math.min(r.length - 1, n.row + 1);
4223
- d(_, Math.min(n.col, (r[_] ?? "").length));
4823
+ const b = Math.min(s.length - 1, n.row + 1);
4824
+ d(b, Math.min(n.col, (s[b] ?? "").length));
4224
4825
  }
4225
4826
  break;
4226
4827
  case "ArrowUp":
4227
- if (e.preventDefault(), l)
4828
+ if (e.preventDefault(), a)
4228
4829
  d(0, 0);
4229
4830
  else if (this._config.wordWrap) {
4230
- const _ = F(this._wm, n.row, n.col), x = Math.max(0, _.visRow - 1), m = Y(this._wm, x, Math.min(_.colInSeg, (((y = this._wm.visualRows[x]) == null ? void 0 : y.text) ?? "").length));
4231
- d(m.row, m.col);
4831
+ const b = ee(this._wm, n.row, n.col), x = Math.max(0, b.visRow - 1), f = le(this._wm, x, Math.min(b.colInSeg, (((y = this._wm.visualRows[x]) == null ? void 0 : y.text) ?? "").length));
4832
+ d(f.row, f.col);
4232
4833
  } else {
4233
- const _ = Math.max(0, n.row - 1);
4234
- d(_, Math.min(n.col, (r[_] ?? "").length));
4834
+ const b = Math.max(0, n.row - 1);
4835
+ d(b, Math.min(n.col, (s[b] ?? "").length));
4235
4836
  }
4236
4837
  break;
4237
4838
  case "Home":
4238
- e.preventDefault(), o ? d(0, 0) : d(n.row, p(n.row));
4839
+ e.preventDefault(), l ? d(0, 0) : d(n.row, u(n.row));
4239
4840
  break;
4240
4841
  case "End":
4241
- if (e.preventDefault(), o) {
4242
- const _ = h();
4243
- d(_.row, _.col);
4842
+ if (e.preventDefault(), l) {
4843
+ const b = h();
4844
+ d(b.row, b.col);
4244
4845
  } else
4245
- d(n.row, (r[n.row] ?? "").length);
4846
+ d(n.row, (s[n.row] ?? "").length);
4246
4847
  break;
4247
4848
  case "PageDown":
4248
4849
  e.preventDefault();
4249
4850
  {
4250
- const _ = Math.max(1, Math.floor(this._editorEl.clientHeight / a) - 1), x = Math.min(r.length - 1, n.row + _);
4251
- d(x, Math.min(n.col, (r[x] ?? "").length)), this._editorEl.scrollTop += this._editorEl.clientHeight - a;
4851
+ const b = Math.max(1, Math.floor(this._editorEl.clientHeight / o) - 1), x = Math.min(s.length - 1, n.row + b);
4852
+ d(x, Math.min(n.col, (s[x] ?? "").length)), this._editorEl.scrollTop += this._editorEl.clientHeight - o;
4252
4853
  break;
4253
4854
  }
4254
4855
  case "PageUp":
4255
4856
  e.preventDefault();
4256
4857
  {
4257
- const _ = Math.max(1, Math.floor(this._editorEl.clientHeight / a) - 1), x = Math.max(0, n.row - _);
4258
- d(x, Math.min(n.col, (r[x] ?? "").length)), this._editorEl.scrollTop -= this._editorEl.clientHeight - a;
4858
+ const b = Math.max(1, Math.floor(this._editorEl.clientHeight / o) - 1), x = Math.max(0, n.row - b);
4859
+ d(x, Math.min(n.col, (s[x] ?? "").length)), this._editorEl.scrollTop -= this._editorEl.clientHeight - o;
4259
4860
  break;
4260
4861
  }
4261
4862
  default:
4262
4863
  return;
4263
4864
  }
4264
- A(this._tab), this._scrollIntoView(), this._acHide(), (f = (v = this._config).onCursorChange) == null || f.call(v, { ...this._tab.cur }), (T = (b = this._config).onSelectionChange) == null || T.call(b, this._tab.sel ? { ...this._tab.sel } : null), this._render();
4865
+ L(this._tab), this._scrollIntoView(), this._acHide(), (k = (g = this._config).onCursorChange) == null || k.call(g, { ...this._tab.cur }), (S = (m = this._config).onSelectionChange) == null || S.call(m, this._tab.sel ? { ...this._tab.sel } : null), this._broadcastCursorToCollab(), this._render();
4265
4866
  }
4266
4867
  _isWordChar(e) {
4267
4868
  const t = this._config.wordSeparators;
@@ -4269,37 +4870,58 @@ class Ut {
4269
4870
  }
4270
4871
  _wordSkipRight(e, t) {
4271
4872
  let i = t;
4272
- for (; i < e.length && /\s/.test(e[i]); ) i++;
4273
- for (; i < e.length && /\S/.test(e[i]); ) i++;
4873
+ const s = e.length;
4874
+ for (; i < s && /\s/.test(e[i]); ) i++;
4875
+ if (i >= s) return i;
4876
+ if (/\w/.test(e[i]))
4877
+ for (; i < s && /\w/.test(e[i]); ) i++;
4878
+ else
4879
+ for (; i < s && /[^\w\s]/.test(e[i]); ) i++;
4274
4880
  return i;
4275
4881
  }
4276
4882
  _wordSkipLeft(e, t) {
4277
4883
  let i = t;
4278
4884
  for (; i > 0 && /\s/.test(e[i - 1]); ) i--;
4279
- for (; i > 0 && /\S/.test(e[i - 1]); ) i--;
4885
+ if (i <= 0) return i;
4886
+ if (/\w/.test(e[i - 1]))
4887
+ for (; i > 0 && /\w/.test(e[i - 1]); ) i--;
4888
+ else
4889
+ for (; i > 0 && /[^\w\s]/.test(e[i - 1]); ) i--;
4280
4890
  return i;
4281
4891
  }
4282
4892
  // ── Move lines ────────────────────────────────────────────
4893
+ _duplicateLines(e) {
4894
+ var l, c, d, u;
4895
+ const { doc: t, cur: i } = this._tab, s = this._tab.sel;
4896
+ let n = i.row, o = i.row;
4897
+ if (s) {
4898
+ const h = J(s);
4899
+ n = h.ar, o = h.fr, h.fc === 0 && h.fr > h.ar && o--;
4900
+ }
4901
+ A(this._tab, this._config.maxUndoHistory);
4902
+ const a = t.slice(n, o + 1);
4903
+ e ? (t.splice(o + 1, 0, ...a), i.row += a.length, s && (s.ar += a.length, s.fr += a.length)) : t.splice(n, 0, ...a), this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (c = (l = this._config).onChange) == null || c.call(l, P(this._tab.doc)), (u = (d = this._config).onCursorChange) == null || u.call(d, { ...this._tab.cur }), this._broadcastCursorToCollab();
4904
+ }
4283
4905
  _moveLines(e) {
4284
- var l, o, c, d;
4285
- const { doc: t, cur: i } = this._tab, r = this._tab.sel;
4286
- let n = i.row, a = i.row;
4287
- if (r) {
4288
- const p = P(r);
4289
- n = p.ar, a = p.fr, p.fc === 0 && p.fr > p.ar && a--;
4906
+ var a, l, c, d;
4907
+ const { doc: t, cur: i } = this._tab, s = this._tab.sel;
4908
+ let n = i.row, o = i.row;
4909
+ if (s) {
4910
+ const u = J(s);
4911
+ n = u.ar, o = u.fr, u.fc === 0 && u.fr > u.ar && o--;
4290
4912
  }
4291
4913
  if (e) {
4292
4914
  if (n === 0) return;
4293
- E(this._tab, this._config.maxUndoHistory);
4294
- const p = t.splice(n, a - n + 1);
4295
- t.splice(n - 1, 0, ...p), i.row--, r && (r.ar--, r.fr--);
4915
+ A(this._tab, this._config.maxUndoHistory);
4916
+ const u = t.splice(n, o - n + 1);
4917
+ t.splice(n - 1, 0, ...u), i.row--, s && (s.ar--, s.fr--);
4296
4918
  } else {
4297
- if (a >= t.length - 1) return;
4298
- E(this._tab, this._config.maxUndoHistory);
4299
- const p = t.splice(n, a - n + 1);
4300
- t.splice(n + 1, 0, ...p), i.row++, r && (r.ar++, r.fr++);
4919
+ if (o >= t.length - 1) return;
4920
+ A(this._tab, this._config.maxUndoHistory);
4921
+ const u = t.splice(n, o - n + 1);
4922
+ t.splice(n + 1, 0, ...u), i.row++, s && (s.ar++, s.fr++);
4301
4923
  }
4302
- this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), (o = (l = this._config).onChange) == null || o.call(l, D(this._tab.doc)), (d = (c = this._config).onCursorChange) == null || d.call(c, { ...this._tab.cur });
4924
+ this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), (l = (a = this._config).onChange) == null || l.call(a, P(this._tab.doc)), (d = (c = this._config).onCursorChange) == null || d.call(c, { ...this._tab.cur }), this._broadcastCursorToCollab();
4303
4925
  }
4304
4926
  // ── Hover documentation ────────────────────────────────────
4305
4927
  _scheduleHover(e) {
@@ -4310,157 +4932,362 @@ class Ut {
4310
4932
  }, 500);
4311
4933
  }
4312
4934
  _doHover(e, t) {
4313
- var y, v, f;
4935
+ var y, g, k;
4314
4936
  if (!this._config.hover) return;
4315
- const i = this._editorEl.getBoundingClientRect(), r = t - i.top + this._editorEl.scrollTop, n = this._config.showGutter ? this._config.gutterWidth : 0, a = e - i.left - n - 14, l = this._config.lineHeight, o = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(r / l))), c = Math.max(0, Math.min(
4316
- (((y = this._wm.visualRows[o]) == null ? void 0 : y.text) ?? "").length,
4317
- Math.round(a / 7.82)
4318
- )), d = Y(this._wm, o, c), p = this._tab.doc[d.row] ?? "", h = Lt(p, d.col);
4937
+ const i = this._editorEl.getBoundingClientRect(), s = t - i.top + this._editorEl.scrollTop, n = this._config.showGutter ? this._config.gutterWidth : 0, o = e - i.left - n - se, a = this._config.lineHeight, l = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(s / a))), c = Math.max(0, Math.min(
4938
+ (((y = this._wm.visualRows[l]) == null ? void 0 : y.text) ?? "").length,
4939
+ Math.round(o / Q)
4940
+ )), d = le(this._wm, l, c), u = this._tab.doc[d.row] ?? "", h = mi(u, d.col);
4319
4941
  if (!h) return;
4320
- let g = Ht(h, this._config.language);
4321
- if (!g) {
4322
- const b = this._config.completions.find((T) => T.label === h);
4323
- b && (b.description || b.detail) && (g = {
4324
- title: b.label,
4325
- type: b.detail,
4326
- body: b.description ?? ""
4942
+ let _ = yi(h, this._config.language);
4943
+ if (!_) {
4944
+ const m = this._config.completions.find((S) => S.label === h);
4945
+ m && (m.description || m.detail) && (_ = {
4946
+ title: m.label,
4947
+ type: m.detail,
4948
+ body: m.description ?? ""
4327
4949
  });
4328
4950
  }
4329
- if (!g) {
4330
- const b = (f = (v = this._config).provideHover) == null ? void 0 : f.call(v, {
4951
+ if (!_) {
4952
+ const m = (k = (g = this._config).provideHover) == null ? void 0 : k.call(g, {
4331
4953
  word: h,
4332
4954
  row: d.row,
4333
4955
  col: d.col,
4334
- line: p,
4956
+ line: u,
4335
4957
  language: this._config.language,
4336
4958
  doc: this._tab.doc
4337
4959
  });
4338
- b && (g = b);
4960
+ m && (_ = m);
4339
4961
  }
4340
- g && this._showHoverTip(g, e, t);
4962
+ _ && this._showHoverTip(_, e, t);
4341
4963
  }
4342
4964
  _showHoverTip(e, t, i) {
4343
- const r = this._hoverTip;
4965
+ const s = this._hoverTip;
4344
4966
  let n = '<div class="sl-ht-sig">';
4345
- n += `<span class="sl-ht-title">${q(e.title)}</span>`, e.type && (n += `<code class="sl-ht-type">${q(e.type)}</code>`), n += "</div>", e.title && e.body && (n += '<div class="sl-ht-divider"></div>'), e.body && (n += `<div class="sl-ht-body">${q(e.body)}</div>`), r.innerHTML = n, r.style.display = "block";
4346
- const a = 12, l = 18, o = r.offsetWidth || 300, c = r.offsetHeight || 80;
4347
- let d = t, p = i + l;
4348
- p + c > window.innerHeight - a && (p = i - c - 8), d + o > window.innerWidth - a && (d = window.innerWidth - o - a), d < a && (d = a), r.style.left = `${d}px`, r.style.top = `${Math.max(a, p)}px`;
4967
+ n += `<span class="sl-ht-title">${ne(e.title)}</span>`, e.type && (n += `<code class="sl-ht-type">${ne(e.type)}</code>`), n += "</div>", e.title && e.body && (n += '<div class="sl-ht-divider"></div>'), e.body && (n += `<div class="sl-ht-body">${ne(e.body)}</div>`), s.innerHTML = n, s.style.display = "block";
4968
+ const o = 12, a = 18, l = s.offsetWidth || 300, c = s.offsetHeight || 80;
4969
+ let d = t, u = i + a;
4970
+ u + c > window.innerHeight - o && (u = i - c - 8), d + l > window.innerWidth - o && (d = window.innerWidth - l - o), d < o && (d = o), s.style.left = `${d}px`, s.style.top = `${Math.max(o, u)}px`;
4349
4971
  }
4350
4972
  _hideHover() {
4351
4973
  this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null), this._hoverPinned = !1, this._hoverTip.style.display = "none";
4352
4974
  }
4353
4975
  _onInput(e) {
4354
- var n, a, l, o;
4976
+ var n, o, a, l;
4355
4977
  if (this._config.readOnly) {
4356
4978
  e.target.value = "";
4357
4979
  return;
4358
4980
  }
4359
4981
  const t = e.target, i = t.value;
4360
4982
  if (t.value = "", !i || i === "Ω") return;
4361
- const r = i.replace(/[\x00-\x08\x0a-\x1f\x7f]/g, "");
4362
- if (r) {
4983
+ const s = i.replace(/[\x00-\x08\x0a-\x1f\x7f]/g, "");
4984
+ if (s) {
4363
4985
  if (this._extraCursors.length) {
4364
- const c = _t(
4986
+ this._snippetSession = null;
4987
+ const c = ni(
4365
4988
  this._tab.doc,
4366
4989
  this._tab.cur.row,
4367
4990
  this._tab.cur.col,
4368
4991
  this._extraCursors,
4369
- r
4992
+ s
4370
4993
  );
4371
- this._tab.doc = c.doc, this._tab.cur.row = c.primaryRow, this._tab.cur.col = c.primaryCol, this._extraCursors = c.extraCursors, this._mc.cursors = c.extraCursors, this._tab.dirty = !0, (a = (n = this._config).onChange) == null || a.call(n, D(this._tab.doc));
4372
- } else
4373
- this._insertStr(r, !0);
4374
- this._tokenCache.clear(), this._rebuildWrapMap(), A(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (o = (l = this._config).onCursorChange) == null || o.call(l, { ...this._tab.cur });
4994
+ this._tab.doc = c.doc, this._tab.cur.row = c.primaryRow, this._tab.cur.col = c.primaryCol, this._extraCursors = c.extraCursors, this._mc.cursors = c.extraCursors, this._tab.dirty = !0, (o = (n = this._config).onChange) == null || o.call(n, P(this._tab.doc));
4995
+ } else {
4996
+ const c = this._tab.cur.row, d = this._tab.cur.col;
4997
+ if (this._insertStr(s, !0), this._snippetSession) {
4998
+ const u = this._snippetSession, h = u.stops[u.idx];
4999
+ if (this._tab.cur.row === h.row) {
5000
+ const _ = this._tab.cur.col - d;
5001
+ for (let y = u.idx + 1; y < u.stops.length; y++) {
5002
+ const g = u.stops[y];
5003
+ g.row === c && g.col >= d && (g.col += _);
5004
+ }
5005
+ h.col = this._tab.cur.col;
5006
+ } else
5007
+ this._snippetSession = null;
5008
+ }
5009
+ }
5010
+ this._tokenCache.clear(), this._rebuildWrapMap(), L(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (l = (a = this._config).onCursorChange) == null || l.call(a, { ...this._tab.cur }), this._broadcastCursorToCollab();
4375
5011
  }
4376
5012
  }
4377
5013
  _ctrlD() {
4378
5014
  if (!this._config.multiCursor) return;
4379
- const e = vt(
5015
+ const e = oi(
4380
5016
  this._mc,
4381
5017
  this._tab.doc,
4382
5018
  this._tab.cur.row,
4383
5019
  this._tab.cur.col,
4384
5020
  this._tab.sel
4385
5021
  );
4386
- e && (!this._mc.cursors.length || e.word !== this._mc.searchWord ? (this._tab.sel = e.sel, this._tab.cur.col = e.col) : (ke(this._mc, e.row, e.col, e.sel), this._extraCursors = [...this._mc.cursors]), this._mc.searchWord = e.word, this._mc.lastMatchRow = e.row, this._mc.lastMatchCol = e.col, this._scrollIntoView(), this._render());
5022
+ e && (!this._mc.cursors.length || e.word !== this._mc.searchWord ? (this._tab.sel = e.sel, this._tab.cur.col = e.col) : (Ke(this._mc, e.row, e.col, e.sel), this._extraCursors = [...this._mc.cursors]), this._mc.searchWord = e.word, this._mc.lastMatchRow = e.row, this._mc.lastMatchCol = e.col, this._scrollIntoView(), this._render());
4387
5023
  }
4388
5024
  // ── Find event binding ────────────────────────────────────
4389
5025
  _bindFindEvents() {
4390
- var e, t, i, r, n, a, l;
5026
+ var e, t, i, s, n, o, a;
4391
5027
  this._findInput.addEventListener("input", () => {
4392
5028
  this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
4393
- }), this._findInput.addEventListener("keydown", (o) => {
4394
- o.key === "Enter" ? o.shiftKey ? this._navFind(-1) : this._navFind(1) : o.key === "Escape" && this._closeFind(), o.stopPropagation();
4395
- }), this._replaceInput.addEventListener("keydown", (o) => {
4396
- o.key === "Enter" ? this._doReplaceOne() : o.key === "Escape" && this._closeFind(), o.stopPropagation();
4397
- }), (e = this._findBar.querySelector(".sl-find-prev")) == null || e.addEventListener("click", () => this._navFind(-1)), (t = this._findBar.querySelector(".sl-find-next")) == null || t.addEventListener("click", () => this._navFind(1)), (i = this._findBar.querySelector(".sl-find-close")) == null || i.addEventListener("click", () => this._closeFind()), (r = this._findBar.querySelector(".sl-find-case")) == null || r.addEventListener("click", (o) => {
4398
- this._findCaseSensitive = !this._findCaseSensitive, o.target.classList.toggle("sl-active", this._findCaseSensitive), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
4399
- }), (n = this._findBar.querySelector(".sl-find-regex")) == null || n.addEventListener("click", (o) => {
4400
- this._findRegex = !this._findRegex, o.target.classList.toggle("sl-active", this._findRegex), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
4401
- }), (a = this._findBar.querySelector(".sl-replace-one")) == null || a.addEventListener("click", () => this._doReplaceOne()), (l = this._findBar.querySelector(".sl-replace-all")) == null || l.addEventListener("click", () => this._doReplaceAll());
5029
+ }), this._findInput.addEventListener("keydown", (l) => {
5030
+ l.key === "Enter" ? l.shiftKey ? this._navFind(-1) : this._navFind(1) : l.key === "Escape" && this._closeFind(), l.stopPropagation();
5031
+ }), this._replaceInput.addEventListener("keydown", (l) => {
5032
+ l.key === "Enter" ? this._doReplaceOne() : l.key === "Escape" && this._closeFind(), l.stopPropagation();
5033
+ }), (e = this._findBar.querySelector(".sl-find-prev")) == null || e.addEventListener("click", () => this._navFind(-1)), (t = this._findBar.querySelector(".sl-find-next")) == null || t.addEventListener("click", () => this._navFind(1)), (i = this._findBar.querySelector(".sl-find-close")) == null || i.addEventListener("click", () => this._closeFind()), (s = this._findBar.querySelector(".sl-find-case")) == null || s.addEventListener("click", (l) => {
5034
+ this._findCaseSensitive = !this._findCaseSensitive, l.target.classList.toggle("sl-active", this._findCaseSensitive), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
5035
+ }), (n = this._findBar.querySelector(".sl-find-regex")) == null || n.addEventListener("click", (l) => {
5036
+ this._findRegex = !this._findRegex, l.target.classList.toggle("sl-active", this._findRegex), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
5037
+ }), (o = this._findBar.querySelector(".sl-replace-one")) == null || o.addEventListener("click", () => this._doReplaceOne()), (a = this._findBar.querySelector(".sl-replace-all")) == null || a.addEventListener("click", () => this._doReplaceAll());
4402
5038
  }
4403
5039
  _doReplaceOne() {
4404
5040
  var e, t;
4405
- this._findIdx < 0 || !this._findMatches.length || (E(this._tab, this._config.maxUndoHistory), this._tab.doc = kt(this._tab.doc, this._findMatches, this._findIdx, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._runFind(this._findInput.value), this._findMatches.length ? (this._findIdx >= this._findMatches.length && (this._findIdx = 0), this._navFind(0)) : (this._findCount.textContent = "0/0", this._rebuildWrapMap(), this._render()), (t = (e = this._config).onChange) == null || t.call(e, D(this._tab.doc)));
5041
+ this._findIdx < 0 || !this._findMatches.length || (A(this._tab, this._config.maxUndoHistory), this._tab.doc = li(this._tab.doc, this._findMatches, this._findIdx, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._runFind(this._findInput.value), this._findMatches.length ? (this._findIdx >= this._findMatches.length && (this._findIdx = 0), this._navFind(0)) : (this._findCount.textContent = "0/0", this._rebuildWrapMap(), this._render()), (t = (e = this._config).onChange) == null || t.call(e, P(this._tab.doc)));
4406
5042
  }
4407
5043
  _doReplaceAll() {
4408
5044
  var t, i;
4409
5045
  if (!this._findMatches.length) return;
4410
5046
  const e = this._findMatches.length;
4411
- E(this._tab, this._config.maxUndoHistory), this._tab.doc = xt(this._tab.doc, this._findMatches, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._findMatches = [], this._findIdx = -1, this._findCount.textContent = `0/0 (${e} replaced)`, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, D(this._tab.doc));
5047
+ A(this._tab, this._config.maxUndoHistory), this._tab.doc = ci(this._tab.doc, this._findMatches, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._findMatches = [], this._findIdx = -1, this._findCount.textContent = `0/0 (${e} replaced)`, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, P(this._tab.doc));
4412
5048
  }
4413
5049
  // ── Minimap events ────────────────────────────────────────
4414
5050
  _bindMinimapEvents() {
4415
5051
  const e = this._minimapWrap;
4416
5052
  e.addEventListener("mousemove", (t) => {
4417
5053
  if (this._mmDragMode !== "none") return;
4418
- const i = t.clientY - e.getBoundingClientRect().top, { sliderTop: r, sliderHeight: n } = ie(
5054
+ const i = t.clientY - e.getBoundingClientRect().top, { sliderTop: s, sliderHeight: n } = _e(
4419
5055
  this._tab.doc.length,
4420
5056
  this._editorEl.scrollTop,
4421
5057
  this._editorEl.clientHeight,
4422
5058
  e.clientHeight,
4423
5059
  this._config.lineHeight
4424
5060
  );
4425
- e.style.cursor = i >= r && i <= r + n ? "grab" : "pointer";
5061
+ e.style.cursor = i >= s && i <= s + n ? "grab" : "pointer";
4426
5062
  }), e.addEventListener("mousedown", (t) => {
4427
5063
  t.preventDefault();
4428
- const i = e.clientHeight, r = t.clientY - e.getBoundingClientRect().top, { sliderTop: n, sliderHeight: a } = ie(
5064
+ const i = e.clientHeight, s = t.clientY - e.getBoundingClientRect().top, { sliderTop: n, sliderHeight: o } = _e(
4429
5065
  this._tab.doc.length,
4430
5066
  this._editorEl.scrollTop,
4431
5067
  this._editorEl.clientHeight,
4432
5068
  i,
4433
5069
  this._config.lineHeight
4434
5070
  );
4435
- if (r >= n && r <= n + a)
4436
- this._mmDragMode = "slider", this._mmSliderOffset = r - n, this._mmDragStartY = t.clientY, this._mmDragStartScroll = this._editorEl.scrollTop, e.style.cursor = "grabbing";
5071
+ if (s >= n && s <= n + o)
5072
+ this._mmDragMode = "slider", this._mmSliderOffset = s - n, this._mmDragStartY = t.clientY, this._mmDragStartScroll = this._editorEl.scrollTop, e.style.cursor = "grabbing";
4437
5073
  else {
4438
5074
  this._mmDragMode = "jump";
4439
- const l = Nt(
4440
- r,
5075
+ const a = Ti(
5076
+ s,
4441
5077
  this._tab.doc.length,
4442
5078
  this._editorEl.scrollTop,
4443
5079
  this._editorEl.clientHeight,
4444
5080
  i,
4445
5081
  this._config.lineHeight
4446
5082
  );
4447
- this._editorEl.scrollTop = l, this._mmDragStartY = t.clientY, this._mmDragStartScroll = l, this._render();
5083
+ this._editorEl.scrollTop = a, this._mmDragStartY = t.clientY, this._mmDragStartScroll = a, this._render();
4448
5084
  }
4449
5085
  }), window.addEventListener("mousemove", this._onWinMmMouseMove), window.addEventListener("mouseup", this._onWinMmMouseUp);
4450
5086
  }
4451
5087
  }
4452
- function Gt(s, e) {
4453
- return new Ut(s, e);
5088
+ const ae = /* @__PURE__ */ new Map();
5089
+ class Li {
5090
+ constructor(e, t) {
5091
+ p(this, "siteId");
5092
+ p(this, "_room");
5093
+ p(this, "_cbs", /* @__PURE__ */ new Set());
5094
+ p(this, "_receive", (e) => {
5095
+ for (const t of this._cbs) t(e);
5096
+ });
5097
+ this._room = e, this.siteId = t, ae.has(e) || ae.set(e, /* @__PURE__ */ new Set()), ae.get(e).add(this._receive);
5098
+ }
5099
+ send(e) {
5100
+ const t = ae.get(this._room);
5101
+ t && queueMicrotask(() => {
5102
+ for (const i of t)
5103
+ i !== this._receive && i(e);
5104
+ });
5105
+ }
5106
+ onMessage(e) {
5107
+ return this._cbs.add(e), () => this._cbs.delete(e);
5108
+ }
5109
+ close() {
5110
+ var e;
5111
+ (e = ae.get(this._room)) == null || e.delete(this._receive), this._cbs.clear();
5112
+ }
5113
+ }
5114
+ class Ri {
5115
+ constructor(e, t) {
5116
+ p(this, "siteId");
5117
+ p(this, "_channel");
5118
+ p(this, "_cbs", /* @__PURE__ */ new Set());
5119
+ this.siteId = t, this._channel = new BroadcastChannel(e), this._channel.onmessage = (i) => {
5120
+ for (const s of this._cbs) s(i.data);
5121
+ };
5122
+ }
5123
+ send(e) {
5124
+ try {
5125
+ this._channel.postMessage(e);
5126
+ } catch {
5127
+ }
5128
+ }
5129
+ onMessage(e) {
5130
+ return this._cbs.add(e), () => this._cbs.delete(e);
5131
+ }
5132
+ close() {
5133
+ this._channel.close(), this._cbs.clear();
5134
+ }
5135
+ }
5136
+ class Ai {
5137
+ /**
5138
+ * @param serverUrl Base WebSocket URL **without** trailing slash.
5139
+ * Room and siteId are appended automatically.
5140
+ * Example: `"ws://localhost:8080"` → connects to
5141
+ * `ws://localhost:8080/<room>?site=<siteId>`
5142
+ * @param room Document / collaboration room identifier.
5143
+ * @param siteId This peer's unique ID (UUID).
5144
+ * @param opts Optional behaviour hooks and tuning knobs.
5145
+ */
5146
+ constructor(e, t, i, s = {}) {
5147
+ p(this, "siteId");
5148
+ p(this, "_ws", null);
5149
+ p(this, "_baseUrl");
5150
+ p(this, "_cbs", /* @__PURE__ */ new Set());
5151
+ p(this, "_reconnectTimer", null);
5152
+ p(this, "_pingTimer", null);
5153
+ p(this, "_closed", !1);
5154
+ p(this, "_attempt", 0);
5155
+ // reconnection attempt counter
5156
+ p(this, "_queue", []);
5157
+ // buffered while disconnected
5158
+ p(this, "_opts");
5159
+ this.siteId = i;
5160
+ const n = e.replace(/\/$/, "");
5161
+ this._baseUrl = `${n}/${encodeURIComponent(t)}?site=${encodeURIComponent(i)}`, this._opts = {
5162
+ onConnect: s.onConnect ?? (() => {
5163
+ }),
5164
+ onDisconnect: s.onDisconnect ?? (() => {
5165
+ }),
5166
+ onError: s.onError ?? (() => {
5167
+ }),
5168
+ pingIntervalMs: s.pingIntervalMs ?? 25e3,
5169
+ maxBackoffMs: s.maxBackoffMs ?? 3e4
5170
+ }, this._connect();
5171
+ }
5172
+ // ── Connection management ──────────────────────────────────
5173
+ _connect() {
5174
+ this._closed || (this._ws = new WebSocket(this._baseUrl), this._ws.onopen = () => {
5175
+ this._attempt = 0;
5176
+ for (const e of this._queue) this._rawSend(e);
5177
+ this._queue = [], this._startPing(), this._opts.onConnect();
5178
+ }, this._ws.onmessage = (e) => {
5179
+ if (e.data !== "__pong__")
5180
+ try {
5181
+ const t = JSON.parse(e.data);
5182
+ for (const i of this._cbs) i(t);
5183
+ } catch {
5184
+ }
5185
+ }, this._ws.onclose = () => {
5186
+ if (this._stopPing(), this._closed) {
5187
+ this._opts.onDisconnect(!1);
5188
+ return;
5189
+ }
5190
+ this._opts.onDisconnect(!0), this._scheduleReconnect();
5191
+ }, this._ws.onerror = (e) => {
5192
+ var t;
5193
+ this._opts.onError(e), (t = this._ws) == null || t.close();
5194
+ });
5195
+ }
5196
+ /** Exponential back-off: 250 ms × 2^attempt, capped at maxBackoffMs. */
5197
+ _scheduleReconnect() {
5198
+ const e = Math.min(250 * 2 ** this._attempt, this._opts.maxBackoffMs);
5199
+ this._attempt++, this._reconnectTimer = setTimeout(() => this._connect(), e);
5200
+ }
5201
+ _startPing() {
5202
+ this._opts.pingIntervalMs <= 0 || (this._pingTimer = setInterval(() => {
5203
+ var e;
5204
+ ((e = this._ws) == null ? void 0 : e.readyState) === WebSocket.OPEN && this._ws.send("__ping__");
5205
+ }, this._opts.pingIntervalMs));
5206
+ }
5207
+ _stopPing() {
5208
+ this._pingTimer !== null && (clearInterval(this._pingTimer), this._pingTimer = null);
5209
+ }
5210
+ // ── CRDTTransport interface ────────────────────────────────
5211
+ send(e) {
5212
+ var t;
5213
+ ((t = this._ws) == null ? void 0 : t.readyState) === WebSocket.OPEN ? this._rawSend(e) : this._queue.push(e);
5214
+ }
5215
+ _rawSend(e) {
5216
+ try {
5217
+ this._ws.send(JSON.stringify(e));
5218
+ } catch {
5219
+ }
5220
+ }
5221
+ onMessage(e) {
5222
+ return this._cbs.add(e), () => this._cbs.delete(e);
5223
+ }
5224
+ close() {
5225
+ var e;
5226
+ this._closed = !0, this._reconnectTimer !== null && (clearTimeout(this._reconnectTimer), this._reconnectTimer = null), this._stopPing(), (e = this._ws) == null || e.close(), this._cbs.clear();
5227
+ }
5228
+ // ── Diagnostics ────────────────────────────────────────────
5229
+ /** Current WebSocket ready-state as a human-readable string. */
5230
+ get connectionState() {
5231
+ var e;
5232
+ switch ((e = this._ws) == null ? void 0 : e.readyState) {
5233
+ case WebSocket.CONNECTING:
5234
+ return "connecting";
5235
+ case WebSocket.OPEN:
5236
+ return "open";
5237
+ case WebSocket.CLOSING:
5238
+ return "closing";
5239
+ default:
5240
+ return "closed";
5241
+ }
5242
+ }
5243
+ /** Number of messages currently buffered waiting for reconnection. */
5244
+ get queuedMessageCount() {
5245
+ return this._queue.length;
5246
+ }
5247
+ }
5248
+ function Di(r, e = {}) {
5249
+ const t = e.siteId ?? crypto.randomUUID(), i = e.room ?? "syncline-default", s = new de(t);
5250
+ let n;
5251
+ const o = e.transport ?? "local";
5252
+ o === "broadcastchannel" ? n = new Ri(i, t) : typeof o == "function" ? n = new o(i, t) : n = new Li(i, t);
5253
+ const a = new Qe(r, s, n, {
5254
+ name: e.name,
5255
+ onPeersChange: e.onPeersChange
5256
+ });
5257
+ return {
5258
+ binding: a,
5259
+ doc: s,
5260
+ destroy() {
5261
+ a.destroy(), n.close();
5262
+ }
5263
+ };
5264
+ }
5265
+ function ji(r, e) {
5266
+ return new Ii(r, e);
4454
5267
  }
4455
5268
  export {
4456
- tt as BUILT_IN_THEMES,
4457
- Ut as SynclineEditor,
4458
- Je as THEME_DRACULA,
4459
- Xe as THEME_GITHUB_LIGHT,
4460
- Ye as THEME_MONOKAI,
4461
- Ze as THEME_SOLARIZED_LIGHT,
4462
- qe as THEME_VR_DARK,
4463
- Ve as THEME_VSCODE_DARK,
4464
- Gt as createEditor
5269
+ ht as AwarenessManager,
5270
+ Nt as BUILT_IN_THEMES,
5271
+ Ri as BroadcastChannelTransport,
5272
+ Qe as CRDTBinding,
5273
+ Li as LocalTransport,
5274
+ de as RGADocument,
5275
+ Z as ROOT_ID,
5276
+ Ii as SynclineEditor,
5277
+ Pt as THEME_DRACULA,
5278
+ $t as THEME_GITHUB_LIGHT,
5279
+ jt as THEME_MONOKAI,
5280
+ Ht as THEME_SOLARIZED_LIGHT,
5281
+ At as THEME_VR_DARK,
5282
+ Dt as THEME_VSCODE_DARK,
5283
+ Ai as WebSocketTransport,
5284
+ he as charIdEq,
5285
+ z as charIdToStr,
5286
+ Di as createCollabSession,
5287
+ ji as createEditor,
5288
+ lt as diffText,
5289
+ dt as siteColor,
5290
+ at as svFromRecord,
5291
+ pe as svToRecord
4465
5292
  };
4466
5293
  //# sourceMappingURL=syncline-editor.es.js.map