@gt-editor/markdown-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3094 @@
1
+ var ge = Object.defineProperty;
2
+ var be = (e, t, n) => t in e ? ge(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var H = (e, t, n) => be(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { jsx as xe } from "react/jsx-runtime";
5
+ import { useRef as Z, useEffect as tt } from "react";
6
+ import { EditorView as B, WidgetType as ht, ViewPlugin as dt, Decoration as w, keymap as xt, lineNumbers as ye, gutter as Ce, GutterMarker as ke, drawSelection as Le, highlightActiveLineGutter as Ee, highlightActiveLine as Me } from "@codemirror/view";
7
+ import { EditorSelection as X, StateField as Ae, Prec as it, RangeSetBuilder as ce, RangeSet as Se, EditorState as vt } from "@codemirror/state";
8
+ import { history as we, addCursorAbove as Rt, addCursorBelow as jt, copyLineUp as Ie, copyLineDown as De, defaultKeymap as Te, historyKeymap as Pe, redo as Fe } from "@codemirror/commands";
9
+ import { highlightSelectionMatches as ve, selectNextOccurrence as $e, selectSelectionMatches as He } from "@codemirror/search";
10
+ import { foldService as Oe, foldable as V, foldedRanges as j, unfoldEffect as ot, foldEffect as Q, indentUnit as ie, codeFolding as We, foldKeymap as Re } from "@codemirror/language";
11
+ import { foldEffect as mo, unfoldEffect as fo } from "@codemirror/language";
12
+ const je = (e = 14, t = 16, n = 16) => B.theme(
13
+ {
14
+ "&": {
15
+ backgroundColor: "#1e1e2e",
16
+ color: "#e8e8e8",
17
+ height: "100%"
18
+ },
19
+ ".cm-content": {
20
+ fontFamily: '"SF Mono", "Fira Code", monospace',
21
+ fontSize: `${e}px`,
22
+ lineHeight: "1.6",
23
+ padding: `${n}px ${t}px`
24
+ },
25
+ ".cm-cursor": {
26
+ borderLeftColor: "#f5e0dc"
27
+ },
28
+ // Secondary cursors (multi-cursor mode)
29
+ ".cm-cursor-secondary": {
30
+ borderLeftColor: "#f5e0dc"
31
+ },
32
+ // Secondary selection (multi-cursor mode)
33
+ "&.cm-focused .cm-selectionBackground-secondary, .cm-selectionBackground-secondary": {
34
+ backgroundColor: "rgba(69, 71, 90, 0.7)"
35
+ },
36
+ ".cm-activeLine": {
37
+ backgroundColor: "rgba(255, 255, 255, 0.02)",
38
+ boxShadow: "inset 0 1px 0 0 rgba(255, 255, 255, 0.08), inset 0 -1px 0 0 rgba(255, 255, 255, 0.08)"
39
+ },
40
+ ".cm-activeLineGutter": {
41
+ backgroundColor: "rgba(255, 255, 255, 0.02)",
42
+ color: "#e8e8e8",
43
+ boxShadow: "inset 0 1px 0 0 rgba(255, 255, 255, 0.08), inset 0 -1px 0 0 rgba(255, 255, 255, 0.08)"
44
+ },
45
+ ".cm-selectionBackground, &.cm-focused .cm-selectionBackground": {
46
+ backgroundColor: "rgba(137, 180, 250, 0.35) !important"
47
+ // Синий, с !important
48
+ },
49
+ ".cm-selectionMatch": {
50
+ backgroundColor: "rgba(137, 180, 250, 0.25)",
51
+ borderRadius: "2px"
52
+ },
53
+ ".cm-gutters": {
54
+ backgroundColor: "#1e1e2e",
55
+ color: "#6c7086",
56
+ border: "none",
57
+ paddingRight: "8px",
58
+ fontSize: `${e}px`,
59
+ fontFamily: '"SF Mono", "Fira Code", monospace',
60
+ position: "relative"
61
+ },
62
+ // foldGutter накладывается поверх контента справа от номеров
63
+ "& .cm-foldGutter": {
64
+ position: "absolute",
65
+ right: "-24px",
66
+ // Выносим за пределы gutters в область контента
67
+ top: "0",
68
+ width: "24px",
69
+ zIndex: "5",
70
+ backgroundColor: "transparent"
71
+ },
72
+ ".cm-hidden-markup": {
73
+ visibility: "hidden"
74
+ },
75
+ ".cm-panels": {
76
+ backgroundColor: "#181825",
77
+ borderBottom: "1px solid #45475a"
78
+ },
79
+ ".cm-panels input, .cm-panels button": {
80
+ color: "#cdd6f4"
81
+ },
82
+ ".cm-searchMatch": {
83
+ backgroundColor: "rgba(249, 226, 175, 0.3)",
84
+ borderRadius: "2px"
85
+ },
86
+ ".cm-searchMatch.cm-searchMatch-selected": {
87
+ backgroundColor: "rgba(249, 226, 175, 0.5)"
88
+ },
89
+ // Markdown styles
90
+ ".cm-md-bold": {
91
+ color: "#ffa348",
92
+ fontWeight: "bold"
93
+ },
94
+ ".cm-md-italic": {
95
+ color: "#69dbdb",
96
+ fontStyle: "italic"
97
+ },
98
+ ".cm-md-strike": {
99
+ color: "#868e96",
100
+ textDecoration: "line-through"
101
+ },
102
+ ".cm-md-code": {
103
+ color: "#50fa7b",
104
+ backgroundColor: "rgba(80, 80, 80, 0.4)",
105
+ borderRadius: "3px",
106
+ padding: "1px 4px"
107
+ },
108
+ ".cm-md-link": {
109
+ color: "#89b4fa",
110
+ textDecoration: "underline",
111
+ cursor: "pointer"
112
+ },
113
+ ".cm-md-heading": {
114
+ fontWeight: "bold"
115
+ },
116
+ // Color only at line level (fontSize moved to mark-level to preserve ch units)
117
+ ".cm-md-h1": { color: "#c678dd" },
118
+ ".cm-md-h2": { color: "#b197fc" },
119
+ ".cm-md-h3": { color: "#a78bfa" },
120
+ ".cm-md-h4": { color: "#9775fa" },
121
+ ".cm-md-h5": { color: "#8b5cf6" },
122
+ ".cm-md-h6": { color: "#7c3aed" },
123
+ // Heading tags [logs], [links], [deprecated] — override heading level color
124
+ ".cm-heading-tag-logs": { color: "#f5a3bb !important" },
125
+ ".cm-heading-tag-links": { color: "#74c7ec !important" },
126
+ ".cm-heading-tag-deprecated": { color: "#fab387 !important" },
127
+ // Font-size on inline mark (span), not on .cm-line — keeps ch unit stable for indent guides
128
+ ".cm-heading-size-1": { fontSize: "1.5em" },
129
+ ".cm-heading-size-2": { fontSize: "1.3em" },
130
+ ".cm-heading-size-3": { fontSize: "1.15em" },
131
+ ".cm-heading-size-4": { fontSize: "1.1em" },
132
+ ".cm-md-markup": {
133
+ color: "#6c7086"
134
+ },
135
+ ".cm-md-heading-muted": {
136
+ color: "#9595c8",
137
+ fontWeight: "normal"
138
+ },
139
+ // List styles — жёлтый
140
+ ".cm-list-bullet": {
141
+ color: "#f9e2af"
142
+ },
143
+ ".cm-md-list-marker": {
144
+ color: "#f9e2af"
145
+ },
146
+ // Image styles
147
+ ".cm-image-container": {
148
+ display: "block",
149
+ marginTop: "0",
150
+ marginBottom: "0"
151
+ },
152
+ ".cm-image-widget": {
153
+ maxWidth: "100%",
154
+ borderRadius: "4px",
155
+ cursor: "pointer"
156
+ },
157
+ // Border when image is active - use outline (doesn't affect layout)
158
+ ".cm-image-active .cm-image-widget": {
159
+ outline: "2px solid #89b4fa",
160
+ outlineOffset: "2px"
161
+ },
162
+ // Muted markdown syntax for image (when active)
163
+ ".cm-md-image-syntax": {
164
+ opacity: 0.5
165
+ },
166
+ // Hidden markdown syntax for image (when not active) - preserves height
167
+ ".cm-md-image-hidden": {
168
+ visibility: "hidden"
169
+ },
170
+ ".cm-md-image-line": {
171
+ whiteSpace: "nowrap",
172
+ overflow: "hidden",
173
+ maxHeight: "1.6em"
174
+ },
175
+ ".cm-image-error": {
176
+ color: "#f38ba8",
177
+ fontStyle: "italic",
178
+ fontSize: "0.9em"
179
+ },
180
+ // Collapsible section styles (base style, can be overridden by headings/inline)
181
+ ".cm-collapsible-header": {
182
+ color: "#cdd6f4"
183
+ // белый по умолчанию, не синий
184
+ },
185
+ // Headings inside collapsible override base color
186
+ ".cm-collapsible-header.cm-md-h1": { color: "#c678dd" },
187
+ ".cm-collapsible-header.cm-md-h2": { color: "#b197fc" },
188
+ ".cm-collapsible-header.cm-md-h3": { color: "#a78bfa" },
189
+ ".cm-collapsible-header.cm-md-h4": { color: "#9775fa" },
190
+ ".cm-collapsible-header.cm-md-h5": { color: "#8b5cf6" },
191
+ ".cm-collapsible-header.cm-md-h6": { color: "#7c3aed" },
192
+ // Inline styles inside collapsible should override base color
193
+ ".cm-collapsible-header .cm-md-bold": {
194
+ color: "#ffa348"
195
+ },
196
+ ".cm-collapsible-header .cm-md-italic": {
197
+ color: "#69dbdb"
198
+ },
199
+ ".cm-collapsible-header .cm-md-code": {
200
+ color: "#50fa7b"
201
+ },
202
+ ".cm-collapsible-header .cm-md-strike": {
203
+ color: "#868e96"
204
+ },
205
+ // Цвет стрелки теперь определяется в JavaScript (CollapsibleArrowWidget)
206
+ ".cm-collapsible-marker": {
207
+ display: "none"
208
+ // Hidden, button is now in gutter
209
+ },
210
+ // Fold marker - белый по умолчанию, больше
211
+ "& .cm-fold-marker": {
212
+ display: "flex",
213
+ alignItems: "center",
214
+ justifyContent: "center",
215
+ height: "100%",
216
+ width: "100%",
217
+ color: "#cdd6f4",
218
+ fontSize: "20px",
219
+ cursor: "pointer",
220
+ opacity: "0.6",
221
+ transition: "opacity 0.15s, color 0.15s"
222
+ },
223
+ "& .cm-fold-marker:hover": {
224
+ opacity: "1",
225
+ color: "#f38ba8"
226
+ },
227
+ ".cm-gutterElement": {
228
+ transition: "color 0.15s"
229
+ },
230
+ // Hover на номерах строк
231
+ ".cm-lineNumbers .cm-gutterElement": {
232
+ cursor: "pointer"
233
+ },
234
+ ".cm-lineNumbers .cm-gutterElement:hover": {
235
+ color: "#f38ba8"
236
+ },
237
+ // Placeholder for folded content
238
+ ".cm-foldPlaceholder": {
239
+ backgroundColor: "rgba(137, 180, 250, 0.2)",
240
+ border: "1px solid rgba(137, 180, 250, 0.4)",
241
+ borderRadius: "4px",
242
+ padding: "2px 12px",
243
+ margin: "0 8px",
244
+ color: "#89b4fa",
245
+ fontSize: "0.9em",
246
+ fontWeight: "500",
247
+ cursor: "pointer",
248
+ verticalAlign: "middle",
249
+ display: "inline-flex",
250
+ alignItems: "center",
251
+ height: "1.4em"
252
+ },
253
+ // Unclosed formatting markers (warning)
254
+ ".cm-md-unclosed": {
255
+ backgroundColor: "rgba(243, 139, 168, 0.25)",
256
+ borderRadius: "2px"
257
+ }
258
+ },
259
+ { dark: !0 }
260
+ );
261
+ function Nt(e, t = 4) {
262
+ let n = 0;
263
+ for (let o = 0; o < e.length; o++) {
264
+ const s = e.charCodeAt(o);
265
+ if (s === 9) n += t - n % t;
266
+ else if (s === 32) n++;
267
+ else break;
268
+ }
269
+ return n;
270
+ }
271
+ const Ne = Oe.of((e, t) => {
272
+ const n = e.doc.lineAt(t), o = n.text, s = o.trim();
273
+ if (!s.startsWith(">>") && !s.startsWith("^^")) return null;
274
+ const c = Nt(o);
275
+ let r = null;
276
+ for (let i = n.number + 1; i <= e.doc.lines; i++) {
277
+ const d = e.doc.line(i).text;
278
+ if (d.trim() === "")
279
+ continue;
280
+ const m = Nt(d);
281
+ if (d.trim() !== "" && m > c)
282
+ r = i;
283
+ else if (d.trim() !== "") break;
284
+ }
285
+ return r !== null ? {
286
+ from: n.to,
287
+ to: e.doc.line(r).to
288
+ } : null;
289
+ });
290
+ class st extends ht {
291
+ toDOM() {
292
+ const t = document.createElement("span");
293
+ return t.className = "cm-hidden-markup", t;
294
+ }
295
+ }
296
+ class ro extends ht {
297
+ toDOM() {
298
+ const t = document.createElement("div");
299
+ return t.className = "cm-horizontal-rule", t;
300
+ }
301
+ }
302
+ class Be extends ht {
303
+ constructor(t, n, o, s, c = !1) {
304
+ super(), this.src = t, this.alt = n, this.width = o, this.resolveImageUrl = s, this.isActive = c;
305
+ }
306
+ eq(t) {
307
+ return t.src === this.src && t.width === this.width;
308
+ }
309
+ updateDOM(t) {
310
+ return this.isActive ? t.classList.add("cm-image-active") : t.classList.remove("cm-image-active"), !0;
311
+ }
312
+ toDOM() {
313
+ const t = document.createElement("div");
314
+ t.className = "cm-image-container" + (this.isActive ? " cm-image-active" : "");
315
+ const n = document.createElement("img"), o = this.resolveImageUrl ? this.resolveImageUrl(this.src) : this.src;
316
+ return n.src = o, n.alt = this.alt, n.className = "cm-image-widget", this.width && (n.style.width = `${this.width}px`), n.onerror = () => {
317
+ t.innerHTML = `<span class="cm-image-error">Image not found: ${this.src}</span>`;
318
+ }, t.appendChild(n), t;
319
+ }
320
+ ignoreEvent() {
321
+ return !1;
322
+ }
323
+ }
324
+ class ze extends ht {
325
+ // position after `- ` (text start)
326
+ constructor(n, o = !1, s, c, r) {
327
+ super();
328
+ H(this, "indent");
329
+ H(this, "hasChildren");
330
+ H(this, "view");
331
+ H(this, "markerStart");
332
+ // position of `-` (after indent)
333
+ H(this, "markerEnd");
334
+ this.indent = n, this.hasChildren = o, this.view = s, this.markerStart = c, this.markerEnd = r;
335
+ }
336
+ eq(n) {
337
+ return this.indent === n.indent && this.hasChildren === n.hasChildren;
338
+ }
339
+ toDOM() {
340
+ const n = document.createElement("span");
341
+ n.className = `cm-list-bullet ${this.hasChildren ? "has-children" : ""}`;
342
+ const o = document.createElement("span");
343
+ o.className = "bullet-indent", o.textContent = this.indent, n.appendChild(o);
344
+ const s = document.createElement("span");
345
+ return s.className = "bullet-icon", s.textContent = "• ", n.appendChild(s), n.addEventListener("mousedown", (c) => {
346
+ c.preventDefault(), c.stopPropagation();
347
+ const r = s.getBoundingClientRect(), i = r.left + r.width / 2, d = c.clientX < i ? this.markerStart : this.markerEnd;
348
+ this.view.dispatch({ selection: { anchor: d } }), this.view.focus();
349
+ }), n;
350
+ }
351
+ ignoreEvent() {
352
+ return !0;
353
+ }
354
+ }
355
+ class co extends ht {
356
+ constructor(n = "") {
357
+ super();
358
+ H(this, "indent");
359
+ this.indent = n;
360
+ }
361
+ toDOM() {
362
+ const n = document.createElement("span");
363
+ if (n.className = "cm-collapsible-marker", this.indent) {
364
+ const o = document.createElement("span");
365
+ o.textContent = this.indent, n.appendChild(o);
366
+ }
367
+ return n;
368
+ }
369
+ eq(n) {
370
+ return this.indent === n.indent;
371
+ }
372
+ }
373
+ const Bt = {
374
+ bold: "#ffa348",
375
+ italic: "#69dbdb",
376
+ code: "#50fa7b",
377
+ strike: "#868e96",
378
+ // Заголовки — фиолетовые оттенки
379
+ h1: "#c678dd",
380
+ h2: "#b197fc",
381
+ h3: "#a78bfa",
382
+ h4: "#9775fa",
383
+ h5: "#8b5cf6",
384
+ h6: "#7c3aed"
385
+ };
386
+ class _e extends ht {
387
+ constructor(t, n, o, s, c = null, r = null) {
388
+ super(), this.indent = t, this.isOpen = n, this.isEmpty = o, this.lineFrom = s, this.formatType = c, this.view = r;
389
+ }
390
+ toDOM() {
391
+ const t = document.createElement("span");
392
+ return t.className = `cm-collapsible-arrow ${this.isOpen ? "open" : "closed"}${this.isEmpty ? " empty" : ""}`, t.textContent = this.isOpen ? "▾" : "▸", t.dataset.lineFrom = String(this.lineFrom), this.formatType && Bt[this.formatType] && (t.style.color = Bt[this.formatType]), t.addEventListener("click", (n) => {
393
+ if (n.preventDefault(), n.stopPropagation(), this.isEmpty || !this.view) return;
394
+ const o = this.view.state.doc.lineAt(this.lineFrom), s = V(this.view.state, o.from, o.to);
395
+ if (!s || s.to - s.from <= 2) return;
396
+ let c = null;
397
+ if (j(this.view.state).between(o.from, o.to, (r, i) => {
398
+ c = { from: r, to: i };
399
+ }), c) {
400
+ const r = this.createMarkerChange(o, "^^", ">>");
401
+ this.view.dispatch({
402
+ effects: ot.of(c),
403
+ changes: r ? [r] : void 0
404
+ });
405
+ } else {
406
+ const r = this.createMarkerChange(o, ">>", "^^");
407
+ this.view.dispatch({
408
+ effects: Q.of(s),
409
+ changes: r ? [r] : void 0
410
+ });
411
+ }
412
+ }), t.addEventListener("mousedown", (n) => {
413
+ n.preventDefault(), n.stopPropagation();
414
+ }), t;
415
+ }
416
+ eq(t) {
417
+ return this.indent === t.indent && this.isOpen === t.isOpen && this.isEmpty === t.isEmpty && this.lineFrom === t.lineFrom && this.formatType === t.formatType && this.view === t.view;
418
+ }
419
+ /**
420
+ * Create a text change to replace marker (>> <-> ^^)
421
+ */
422
+ createMarkerChange(t, n, o) {
423
+ const s = t.text.indexOf(n);
424
+ return s === -1 ? null : {
425
+ from: t.from + s,
426
+ to: t.from + s + n.length,
427
+ insert: o
428
+ };
429
+ }
430
+ ignoreEvent(t) {
431
+ return t.type === "mousedown" || t.type === "click" || t.type === "dblclick";
432
+ }
433
+ }
434
+ const Ue = [
435
+ // Bold: только ** (не __)
436
+ { regex: /\*\*(.+?)\*\*/g, class: "cm-md-bold", startLen: 2, endLen: 2 },
437
+ // Italic: только * (не _)
438
+ { regex: new RegExp("(?<!\\*)\\*(.+?)\\*(?!\\*)", "g"), class: "cm-md-italic", startLen: 1, endLen: 1 },
439
+ { regex: /~~(.+?)~~/g, class: "cm-md-strike", startLen: 2, endLen: 2 },
440
+ { regex: /`([^`]*)`/g, class: "cm-md-code", startLen: 1, endLen: 1 }
441
+ ], zt = /^(\s*)(#{1,6})\s*(.+)$/, _t = /\[(\w+)\]\s*$/, Ut = {
442
+ logs: "cm-heading-tag-logs",
443
+ log: "cm-heading-tag-logs",
444
+ data: "cm-heading-tag-logs",
445
+ links: "cm-heading-tag-links",
446
+ link: "cm-heading-tag-links",
447
+ sources: "cm-heading-tag-links",
448
+ source: "cm-heading-tag-links",
449
+ deprecated: "cm-heading-tag-deprecated",
450
+ old: "cm-heading-tag-deprecated",
451
+ obsolete: "cm-heading-tag-deprecated"
452
+ }, Kt = /^-{3,}$/, Ke = /^(\s*)(-{3,})$/, Yt = /^```[\w-]*$/, qt = /^```$/, Ye = /^(\s*)([*+-])\s+/, qe = /^(\s*)(\d+\.)\s+/, Xe = /^(\s*)(>>|\^\^)\s*(.*)$/, Ve = /\[([^\]]+)\]\(([^)]+)\)/g;
453
+ function Ge(e) {
454
+ const t = e.match(/^(\s*)/), n = t ? t[0] : "";
455
+ return Math.floor(n.replace(/\t/g, " ").length / 4);
456
+ }
457
+ function Je(e = {}) {
458
+ return dt.fromClass(
459
+ class {
460
+ constructor(t) {
461
+ H(this, "decorations");
462
+ try {
463
+ this.decorations = this.buildDecorations(t);
464
+ } catch (n) {
465
+ console.error("[MarkdownSyntax] constructor failed:", n instanceof Error ? n.message : n, {
466
+ docLength: t.state.doc.length,
467
+ docLines: t.state.doc.lines
468
+ }), this.decorations = w.none;
469
+ }
470
+ }
471
+ update(t) {
472
+ if (t.docChanged || t.viewportChanged || t.selectionSet || t.focusChanged)
473
+ try {
474
+ this.decorations = this.buildDecorations(t.view);
475
+ } catch (n) {
476
+ if (console.error("[MarkdownSyntax] buildDecorations failed:", n instanceof Error ? n.message : n, {
477
+ docChanged: t.docChanged,
478
+ docLength: t.state.doc.length,
479
+ docLines: t.state.doc.lines
480
+ }), t.docChanged)
481
+ try {
482
+ this.decorations = this.decorations.map(t.changes);
483
+ } catch {
484
+ this.decorations = w.none;
485
+ }
486
+ }
487
+ }
488
+ buildDecorations(t) {
489
+ const n = [], o = t.state.doc;
490
+ let s = !1;
491
+ const c = /* @__PURE__ */ new Map(), r = [], i = new Array(o.lines + 1).fill(0);
492
+ for (let f = 1; f <= o.lines; f++) {
493
+ const h = o.line(f).text;
494
+ h.trim() !== "" && (i[f] = Ge(h));
495
+ }
496
+ let l = 0;
497
+ for (let f = 1; f <= o.lines; f++)
498
+ if (o.line(f).text.trim() === "") {
499
+ let p = 0;
500
+ for (let y = f + 1; y <= Math.min(f + 5, o.lines); y++)
501
+ if (o.line(y).text.trim() !== "") {
502
+ p = i[y];
503
+ break;
504
+ }
505
+ i[f] = Math.min(l, p);
506
+ } else
507
+ l = i[f];
508
+ const d = /* @__PURE__ */ new Set();
509
+ if (t.hasFocus)
510
+ for (const f of t.state.selection.ranges) {
511
+ const h = o.lineAt(f.from).number, p = o.lineAt(f.to).number;
512
+ for (let y = h; y <= p; y++)
513
+ d.add(y);
514
+ }
515
+ for (let f = 1; f <= o.lines; f++) {
516
+ const h = o.line(f), p = h.text, y = d.has(f), T = i[f], I = Math.min(T, 6), M = I > 0 ? ` cm-indent-L${I}` : "", O = p.trim();
517
+ if (s && qt.test(O)) {
518
+ s = !1, n.push({ from: h.from, decoration: w.line({ class: "cm-code-block-line cm-code-block-end" + M }) });
519
+ continue;
520
+ }
521
+ if (!s && Yt.test(O)) {
522
+ s = !0, n.push({ from: h.from, decoration: w.line({ class: "cm-code-block-line cm-code-block-start" + M }) });
523
+ continue;
524
+ }
525
+ if (s) {
526
+ n.push({ from: h.from, decoration: w.line({ class: "cm-code-block-line" + M }) });
527
+ continue;
528
+ }
529
+ const _ = p.match(zt);
530
+ if (_) {
531
+ const D = _[1].length, A = _[2].length, P = D, R = A + (p.charAt(P + A) === " " ? 1 : 0), q = _[3].match(_t), W = q && Ut[q[1].toLowerCase()] || "";
532
+ n.push({ from: h.from, decoration: w.line({ class: `cm-md-heading cm-md-h${A}${M}${W ? " " + W : ""}` }) }), !y && R > 0 ? (n.push({ from: h.from + P, to: h.from + P + R, decoration: w.replace({ widget: new st() }) }), A <= 4 && h.from + P + R < h.to && n.push({ from: h.from + P + R, to: h.to, decoration: w.mark({ class: `cm-heading-size-${A}` }) })) : A <= 4 && n.push({ from: h.from + P, to: h.to, decoration: w.mark({ class: `cm-heading-size-${A}` }) });
533
+ continue;
534
+ }
535
+ const z = p.match(Ke);
536
+ if (z) {
537
+ const D = z[1].length, A = z[2].length;
538
+ if (n.push({ from: h.from, decoration: w.line({ class: "cm-hr-line" + M }) }), !y) {
539
+ const P = h.from + D, R = P + A;
540
+ n.push({ from: P, to: R, decoration: w.mark({ class: "cm-hr-text-hidden" }) });
541
+ }
542
+ continue;
543
+ }
544
+ const Y = p.match(Ye), F = p.match(qe), N = p.match(Xe);
545
+ if (Y) {
546
+ const [D, A] = Y, P = h.from + A.length, R = h.from + A.length + (D.length - A.length);
547
+ n.push({ from: h.from, decoration: w.line({ class: "cm-list-line" + M }) }), y || n.push({ from: h.from, to: R, decoration: w.replace({ widget: new ze(A, !1, t, P, R) }) });
548
+ } else if (F)
549
+ n.push({ from: h.from, decoration: w.line({ class: "cm-list-line" + M }) });
550
+ else if (N) {
551
+ const D = N[1].length, A = 2, P = D + A + (p.charAt(D + A) === " " ? 1 : 0), R = N[3] || "", et = R.match(/^(#{1,6})\s*(.+)$/);
552
+ if (et) {
553
+ const q = et[1].length, W = et[2].match(_t), U = W && Ut[W[1].toLowerCase()] || "";
554
+ if (n.push({ from: h.from, decoration: w.line({ class: `cm-collapsible-header cm-md-heading cm-md-h${q}${M}${U ? " " + U : ""}` }) }), y)
555
+ q <= 4 && n.push({ from: h.from + P, to: h.to, decoration: w.mark({ class: `cm-heading-size-${q}` }) });
556
+ else {
557
+ const v = q + (R.charAt(q) === " " ? 1 : 0);
558
+ n.push({ from: h.from + P, to: h.from + P + v, decoration: w.replace({ widget: new st() }) }), q <= 4 && h.from + P + v < h.to && n.push({ from: h.from + P + v, to: h.to, decoration: w.mark({ class: `cm-heading-size-${q}` }) });
559
+ }
560
+ } else
561
+ n.push({ from: h.from, decoration: w.line({ class: "cm-collapsible-header" + M }) });
562
+ } else {
563
+ const D = M.trim();
564
+ D && n.push({ from: h.from, decoration: w.line({ class: D }) });
565
+ }
566
+ if (!_ && !Kt.test(O)) {
567
+ let D = p, A = 0;
568
+ if (N) {
569
+ const U = N[1].length + 2, v = p.charAt(U) === " " ? U + 1 : U;
570
+ D = p.substring(v), A = v;
571
+ }
572
+ const P = [];
573
+ for (const W of Ue) {
574
+ const U = new RegExp(W.regex.source, "g");
575
+ let v;
576
+ for (; (v = U.exec(D)) !== null; ) {
577
+ const $ = h.from + A + v.index, G = $ + v[0].length;
578
+ if (P.some((S) => $ < S.to && G > S.from)) continue;
579
+ const K = $ + W.startLen, k = G - W.endLen;
580
+ n.push({ from: K, to: k, decoration: w.mark({ class: W.class }) }), P.push({ from: $, to: G }), r.push({ from: $, to: G }), y || (n.push({ from: $, to: K, decoration: w.replace({ widget: new st() }) }), n.push({ from: k, to: G, decoration: w.replace({ widget: new st() }) }));
581
+ }
582
+ }
583
+ const R = new RegExp(Ve.source, "g");
584
+ let et;
585
+ for (; (et = R.exec(D)) !== null; ) {
586
+ const W = et[0], U = et[1], v = h.from + A + et.index, $ = v + W.length, G = v + 1, K = G + U.length;
587
+ n.push({ from: G, to: K, decoration: w.mark({ class: "cm-md-link" }) }), P.push({ from: v, to: $ }), r.push({ from: v, to: $ }), y || (n.push({ from: v, to: G, decoration: w.replace({ widget: new st() }) }), n.push({ from: K, to: $, decoration: w.replace({ widget: new st() }) }));
588
+ }
589
+ const q = ["**", "~~", "*", "`"];
590
+ for (const W of q) {
591
+ const U = new RegExp(W.replace(/[*]/g, "\\*").replace(/[`]/g, "\\`"), "g");
592
+ let v;
593
+ for (; (v = U.exec(D)) !== null; ) {
594
+ const $ = h.from + A + v.index;
595
+ if (!P.some((K) => $ >= K.from && $ < K.to)) {
596
+ if (W.length === 1) {
597
+ const nt = D[v.index + 1], mt = v.index > 0 ? D[v.index - 1] : "";
598
+ if (nt === W || mt === W) continue;
599
+ }
600
+ const K = D[v.index + W.length], k = v.index > 0 ? D[v.index - 1] : " ";
601
+ (K && K !== " " && K !== " " || k !== " " && k !== " ") && c.set($, W.length);
602
+ }
603
+ }
604
+ }
605
+ }
606
+ }
607
+ const m = [
608
+ { marker: "**", class: "cm-md-bold" },
609
+ { marker: "~~", class: "cm-md-strike" },
610
+ { marker: "*", class: "cm-md-italic" },
611
+ { marker: "`", class: "cm-md-code" }
612
+ ], u = 5, a = [...r], g = /* @__PURE__ */ new Set();
613
+ let C = !1;
614
+ for (let f = 1; f <= o.lines; f++) {
615
+ const h = o.line(f).text.trim();
616
+ C && qt.test(h) ? (g.add(f), C = !1) : !C && Yt.test(h) ? (C = !0, g.add(f)) : C && g.add(f);
617
+ }
618
+ for (let f = 1; f <= o.lines; f++) {
619
+ const h = o.line(f), p = h.text;
620
+ if (!g.has(f) && p.trim() !== "" && !zt.test(p) && !Kt.test(p.trim()))
621
+ for (let y = 0; y < p.length; y++) {
622
+ const T = h.from + y;
623
+ if (!a.some((I) => T >= I.from && T < I.to))
624
+ for (const I of m) {
625
+ const M = I.marker;
626
+ if (p.substr(y, M.length) !== M || M.length === 1 && (y + 1 < p.length && p[y + 1] === M || y > 0 && p[y - 1] === M))
627
+ continue;
628
+ const O = y + M.length;
629
+ if (O >= p.length) continue;
630
+ const _ = p[O];
631
+ if (_ === " " || _ === " " || _ === `
632
+ `) continue;
633
+ let z = !1;
634
+ for (let F = O; F <= p.length - M.length; F++) {
635
+ if (p.substr(F, M.length) !== M || M.length === 1 && (F + 1 < p.length && p[F + 1] === M || F > 0 && p[F - 1] === M) || F > 0 && (p[F - 1] === " " || p[F - 1] === " ")) continue;
636
+ const N = h.from + F;
637
+ if (!r.some((D) => N >= D.from && N < D.to)) {
638
+ z = !0, a.push({ from: T, to: h.from + F + M.length });
639
+ break;
640
+ }
641
+ }
642
+ if (z) break;
643
+ let Y = null;
644
+ for (let F = f + 1; F <= Math.min(f + u, o.lines); F++) {
645
+ const N = o.line(F), D = N.text;
646
+ if (D.trim() === "" || g.has(F)) break;
647
+ for (let A = 0; A <= D.length - M.length; A++) {
648
+ if (D.substr(A, M.length) !== M || M.length === 1 && (A + 1 < D.length && D[A + 1] === M || A > 0 && D[A - 1] === M) || A === 0 || D[A - 1] === " " || D[A - 1] === " ") continue;
649
+ const P = N.from + A;
650
+ if (!r.some((R) => P >= R.from && P < R.to)) {
651
+ Y = { lineNum: F, charIdx: A, absolutePos: N.from + A };
652
+ break;
653
+ }
654
+ }
655
+ if (Y) break;
656
+ }
657
+ if (Y) {
658
+ const F = T, N = T + M.length, D = Y.absolutePos, A = Y.absolutePos + M.length;
659
+ n.push({
660
+ from: N,
661
+ to: D,
662
+ decoration: w.mark({ class: I.class })
663
+ });
664
+ const P = d.has(f), R = d.has(Y.lineNum);
665
+ P || n.push({
666
+ from: F,
667
+ to: N,
668
+ decoration: w.replace({ widget: new st() })
669
+ }), R || n.push({
670
+ from: D,
671
+ to: A,
672
+ decoration: w.replace({ widget: new st() })
673
+ }), a.push({ from: F, to: A });
674
+ break;
675
+ } else if (!z) {
676
+ c.set(T, M.length);
677
+ break;
678
+ }
679
+ }
680
+ }
681
+ }
682
+ for (const [f, h] of c)
683
+ a.some((y) => f >= y.from && f < y.to) || n.push({
684
+ from: f,
685
+ to: f + h,
686
+ decoration: w.mark({ class: "cm-md-unclosed" })
687
+ });
688
+ const x = o.length, E = n.filter((f) => !(f.to !== void 0 && f.from >= f.to || f.from < 0 || f.from > x || f.to !== void 0 && (f.to < 0 || f.to > x))).map((f) => f.to ? f.decoration.range(f.from, f.to) : f.decoration.range(f.from)), L = E.slice().sort((f, h) => f.from - h.from || f.value.startSide - h.value.startSide);
689
+ for (let f = 1; f < L.length; f++) {
690
+ const h = L[f - 1], p = L[f];
691
+ if (h.from === p.from && h.to !== void 0 && p.to !== void 0) {
692
+ const y = h.value.widget !== void 0 && h.from !== h.to, T = p.value.widget !== void 0 && p.from !== p.to;
693
+ if (y && T) {
694
+ const I = o.lineAt(p.from);
695
+ console.warn("[MarkdownSyntax] CONFLICT: overlapping replaces at same from", {
696
+ pos: p.from,
697
+ line: I.number,
698
+ lineText: I.text.substring(0, 80),
699
+ prev: { from: h.from, to: h.to, startSide: h.value.startSide },
700
+ curr: { from: p.from, to: p.to, startSide: p.value.startSide }
701
+ });
702
+ }
703
+ }
704
+ if (h.to !== void 0 && p.from < h.to) {
705
+ const y = h.value.widget !== void 0 && h.from !== h.to, T = p.value.widget !== void 0 && p.from !== p.to;
706
+ if (y || T) {
707
+ const I = o.lineAt(p.from);
708
+ console.warn("[MarkdownSyntax] CONFLICT: overlapping ranges (one is replace)", {
709
+ pos: p.from,
710
+ line: I.number,
711
+ lineText: I.text.substring(0, 80),
712
+ prev: { from: h.from, to: h.to, isReplace: y },
713
+ curr: { from: p.from, to: p.to, isReplace: T }
714
+ });
715
+ }
716
+ }
717
+ }
718
+ return w.set(E, !0);
719
+ }
720
+ },
721
+ { decorations: (t) => t.decorations }
722
+ );
723
+ }
724
+ function Qe() {
725
+ return B.domEventHandlers({
726
+ mousedown(e, t) {
727
+ if (e.button !== 0 || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return !1;
728
+ const n = e.clientX, o = e.clientY, s = t.posAtCoords({ x: n, y: o });
729
+ if (s === null) return !1;
730
+ const c = t.state.doc.lineAt(s);
731
+ let r = null;
732
+ for (let i = c.to; i >= Math.max(c.from, c.to - 8) && (r = t.coordsAtPos(i) || t.coordsAtPos(i, -1), !r); i--)
733
+ ;
734
+ return r && setTimeout(() => {
735
+ const i = t.state.selection.main;
736
+ if (!i.empty) return;
737
+ const l = i.head, d = t.state.doc.lineAt(l);
738
+ l !== d.to && n >= r.left - 1 && o >= r.top && o <= r.bottom && t.dispatch({
739
+ selection: X.cursor(d.to)
740
+ });
741
+ }, 0), !1;
742
+ }
743
+ });
744
+ }
745
+ const Ze = /^!\[([^\]|]*)?(?:\|(\d+))?\]\(([^)]+)\)$/, tn = (e = {}) => Ae.define({
746
+ create(t) {
747
+ return Xt(t, e);
748
+ },
749
+ update(t, n) {
750
+ return n.docChanged || n.selection ? Xt(n.state, e) : t;
751
+ },
752
+ provide: (t) => B.decorations.from(t)
753
+ });
754
+ function Xt(e, t) {
755
+ const n = [], o = e.selection.main.head;
756
+ for (let s = 1; s <= e.doc.lines; s++) {
757
+ const c = e.doc.line(s), i = c.text.match(Ze);
758
+ if (!i) continue;
759
+ const [, l, d, m] = i, u = d ? parseInt(d, 10) : null, a = o >= c.from && o <= c.to;
760
+ n.push({
761
+ from: c.from,
762
+ decoration: w.line({ class: "cm-md-image-line" })
763
+ }), n.push({
764
+ from: c.to,
765
+ decoration: w.widget({
766
+ widget: new Be(m, l || "", u, t.resolveImageUrl, a),
767
+ block: !0,
768
+ side: 1
769
+ })
770
+ }), a ? n.push({
771
+ from: c.from,
772
+ to: c.to,
773
+ decoration: w.mark({ class: "cm-md-image-syntax" })
774
+ }) : n.push({
775
+ from: c.from,
776
+ to: c.to,
777
+ decoration: w.mark({ class: "cm-md-image-hidden" })
778
+ });
779
+ }
780
+ return n.sort((s, c) => s.from - c.from), w.set(
781
+ n.map((s) => s.to !== void 0 ? s.decoration.range(s.from, s.to) : s.decoration.range(s.from)),
782
+ !0
783
+ );
784
+ }
785
+ function en(e, t) {
786
+ var c, r;
787
+ const n = e.split(`
788
+ `);
789
+ if (n.length <= 1) return e;
790
+ let o = 1 / 0;
791
+ for (let i = 0; i < n.length; i++) {
792
+ const l = n[i];
793
+ if (l.trim() === "") continue;
794
+ const d = ((c = l.match(/^[ \t]*/)) == null ? void 0 : c[0]) || "", m = yt(d);
795
+ m < o && (o = m);
796
+ }
797
+ o === 1 / 0 && (o = 0);
798
+ const s = [];
799
+ for (let i = 0; i < n.length; i++) {
800
+ const l = n[i];
801
+ if (l.trim() === "") {
802
+ s.push(i === 0 ? "" : t);
803
+ continue;
804
+ }
805
+ const d = ((r = l.match(/^[ \t]*/)) == null ? void 0 : r[0]) || "", u = yt(d) - o, a = i === 0 ? " ".repeat(Math.max(0, u)) : t + " ".repeat(Math.max(0, u));
806
+ s.push(a + l.slice(d.length));
807
+ }
808
+ return s.join(`
809
+ `);
810
+ }
811
+ function yt(e) {
812
+ let t = 0;
813
+ for (const n of e)
814
+ n === " " ? t += 4 - t % 4 : t++;
815
+ return t;
816
+ }
817
+ function nn(e) {
818
+ const t = e.state.selection.main.head, s = e.state.doc.lineAt(t).text.match(/^[ \t]*/);
819
+ return s ? s[0] : "";
820
+ }
821
+ function Vt(e, t) {
822
+ const n = e.state.selection.main, o = nn(e), s = en(t, o);
823
+ e.dispatch({
824
+ changes: { from: n.from, to: n.to, insert: s },
825
+ selection: { anchor: n.from + s.length }
826
+ });
827
+ }
828
+ function Gt(e) {
829
+ return navigator.clipboard.readText().then((t) => {
830
+ var E, L;
831
+ if (!t) return;
832
+ const n = e.state.selection.main, o = e.state.doc, s = o.lineAt(n.head), c = ((E = s.text.match(/^[ \t]*/)) == null ? void 0 : E[0]) || "", r = yt(c);
833
+ let i = 0;
834
+ for (let f = s.number + 1; f <= o.lines; f++) {
835
+ const h = o.line(f);
836
+ if (h.text.trim() === "") continue;
837
+ const p = yt(((L = h.text.match(/^[ \t]*/)) == null ? void 0 : L[0]) || "");
838
+ if (p <= r) break;
839
+ p > i && (i = p);
840
+ }
841
+ const l = Math.max(r, i), d = " ".repeat(l), m = d + " ", u = t.length, a = `${d}^^ paste text [${u}]`, g = t.split(`
842
+ `).map((f) => m + f), C = a + `
843
+ ` + g.join(`
844
+ `), x = s.from;
845
+ e.dispatch({
846
+ changes: { from: x, to: n.to, insert: C },
847
+ selection: { anchor: x + a.length }
848
+ });
849
+ const b = e.state.doc.lineAt(x);
850
+ if (b.text.trim().startsWith("^^")) {
851
+ let f = !1;
852
+ if (j(e.state).between(b.from, b.to, () => {
853
+ f = !0;
854
+ }), !f) {
855
+ const h = V(e.state, b.from, b.to);
856
+ h && h.to - h.from > 2 && e.dispatch({ effects: Q.of(h) });
857
+ }
858
+ }
859
+ }).catch((t) => console.error("[Clipboard]", t)), !0;
860
+ }
861
+ function Jt(e, t) {
862
+ return navigator.clipboard.readText().then((n) => {
863
+ var E, L;
864
+ if (!n) return;
865
+ const o = e.state.selection.main, s = e.state.doc, c = s.lineAt(o.head), r = ((E = c.text.match(/^[ \t]*/)) == null ? void 0 : E[0]) || "", i = yt(r);
866
+ let l = 0;
867
+ for (let f = c.number + 1; f <= s.lines; f++) {
868
+ const h = s.line(f);
869
+ if (h.text.trim() === "") continue;
870
+ const p = yt(((L = h.text.match(/^[ \t]*/)) == null ? void 0 : L[0]) || "");
871
+ if (p <= i) break;
872
+ p > l && (l = p);
873
+ }
874
+ const d = Math.max(i, l), m = " ".repeat(d), u = m + " ", a = `${m}^^ ⏳`, g = n.split(`
875
+ `).map((f) => u + f), C = a + `
876
+ ` + g.join(`
877
+ `), x = c.from;
878
+ e.dispatch({
879
+ changes: { from: x, to: o.to, insert: C },
880
+ selection: { anchor: x + a.length }
881
+ });
882
+ const b = e.state.doc.lineAt(x);
883
+ if (b.text.trim().startsWith("^^")) {
884
+ let f = !1;
885
+ if (j(e.state).between(b.from, b.to, () => {
886
+ f = !0;
887
+ }), !f) {
888
+ const h = V(e.state, b.from, b.to);
889
+ h && h.to - h.from > 2 && e.dispatch({ effects: Q.of(h) });
890
+ }
891
+ }
892
+ t(n).then((f) => {
893
+ const h = f && f.trim() ? f.trim() : "paste text", p = e.state.doc;
894
+ for (let y = 1; y <= p.lines; y++) {
895
+ const T = p.line(y), I = T.text.match(/^(\s*)\^\^\s*⏳\s*$/);
896
+ if (I) {
897
+ const O = `${I[1]}^^ ${h}`;
898
+ e.dispatch({
899
+ changes: { from: T.from, to: T.to, insert: O }
900
+ });
901
+ break;
902
+ }
903
+ }
904
+ }).catch((f) => {
905
+ console.error("[Clipboard] AI title generation failed:", f);
906
+ const h = e.state.doc;
907
+ for (let p = 1; p <= h.lines; p++) {
908
+ const y = h.line(p), T = y.text.match(/^(\s*)\^\^\s*⏳\s*$/);
909
+ if (T) {
910
+ const M = `${T[1]}^^ paste text`;
911
+ e.dispatch({
912
+ changes: { from: y.from, to: y.to, insert: M }
913
+ });
914
+ break;
915
+ }
916
+ }
917
+ });
918
+ }).catch((n) => console.error("[Clipboard]", n)), !0;
919
+ }
920
+ let At = !1, gt = null;
921
+ function le(e, t) {
922
+ const n = e.state.selection.main.head, o = e.coordsAtPos(n) ?? e.coordsAtPos(n, -1);
923
+ o && (t.style.left = `${o.left}px`, t.style.top = `${o.bottom + 6}px`, requestAnimationFrame(() => {
924
+ if (!t.parentElement) return;
925
+ const s = t.getBoundingClientRect();
926
+ s.right > window.innerWidth && (t.style.left = `${window.innerWidth - s.width - 10}px`);
927
+ }));
928
+ }
929
+ function on(e) {
930
+ At = !0, Ht();
931
+ const t = document.createElement("div");
932
+ t.className = "cm-ai-paste-indicator", t.setAttribute("data-ai-paste-indicator", "true");
933
+ const n = document.createElement("span");
934
+ n.className = "cm-ai-paste-badge", n.textContent = "📋 AI Paste";
935
+ const o = document.createElement("span");
936
+ o.className = "cm-ai-paste-cancel", o.textContent = "✕", o.addEventListener("click", (s) => {
937
+ s.stopPropagation(), sn();
938
+ }), t.appendChild(n), t.appendChild(o), document.body.appendChild(t), gt = t, le(e, t);
939
+ }
940
+ function Ht() {
941
+ gt && (gt.remove(), gt = null);
942
+ }
943
+ function sn() {
944
+ At = !1, Ht();
945
+ }
946
+ const rn = B.updateListener.of((e) => {
947
+ !At || !gt || (e.selectionSet || e.geometryChanged || e.viewportChanged) && le(e.view, gt);
948
+ });
949
+ function cn(e = {}) {
950
+ return xt.of([
951
+ {
952
+ key: "Mod-c",
953
+ run: (t) => {
954
+ const n = t.state.selection.main;
955
+ if (n.empty) return !1;
956
+ const o = t.state.sliceDoc(n.from, n.to);
957
+ return navigator.clipboard.writeText(o).catch((s) => {
958
+ console.error("[Editor] Copy failed:", s);
959
+ }), !0;
960
+ }
961
+ },
962
+ {
963
+ key: "Mod-x",
964
+ run: (t) => {
965
+ const n = t.state.selection.main;
966
+ if (n.empty) return !1;
967
+ const o = t.state.sliceDoc(n.from, n.to);
968
+ return navigator.clipboard.writeText(o).then(() => {
969
+ const s = t.state.selection.main;
970
+ t.dispatch({
971
+ changes: { from: s.from, to: s.to, insert: "" },
972
+ selection: { anchor: s.from }
973
+ });
974
+ }).catch((s) => {
975
+ console.error("[Editor] Cut failed:", s);
976
+ }), !0;
977
+ }
978
+ },
979
+ {
980
+ key: "Mod-v",
981
+ run: (t) => At && e.onGenerateTitle ? (Ht(), At = !1, Jt(t, e.onGenerateTitle)) : (navigator.clipboard.read().then(async (n) => {
982
+ for (const o of n) {
983
+ const s = o.types.find((c) => c.startsWith("image/"));
984
+ if (s && e.onImagePaste)
985
+ try {
986
+ const r = await (await o.getType(s)).arrayBuffer(), i = new Uint8Array(r);
987
+ let l = "";
988
+ for (let u = 0; u < i.length; u++)
989
+ l += String.fromCharCode(i[u]);
990
+ const d = btoa(l), m = await e.onImagePaste(d);
991
+ if (m) {
992
+ const u = `![image](${m})
993
+ `, a = t.state.selection.main.head;
994
+ t.dispatch({
995
+ changes: { from: a, insert: u },
996
+ selection: { anchor: a + u.length }
997
+ });
998
+ }
999
+ return;
1000
+ } catch (c) {
1001
+ console.error("[Clipboard] Image paste failed:", c);
1002
+ }
1003
+ }
1004
+ try {
1005
+ const o = await navigator.clipboard.readText();
1006
+ o && Vt(t, o);
1007
+ } catch (o) {
1008
+ console.error("[Clipboard] Text paste failed:", o);
1009
+ }
1010
+ }).catch((n) => {
1011
+ console.warn("[Clipboard] read() failed, falling back to readText:", n), navigator.clipboard.readText().then((o) => {
1012
+ o && Vt(t, o);
1013
+ }).catch((o) => console.error("[Clipboard]", o));
1014
+ }), !0)
1015
+ },
1016
+ {
1017
+ key: "Alt-Mod-v",
1018
+ run: Gt
1019
+ },
1020
+ {
1021
+ key: "Shift-Mod-v",
1022
+ run: (t) => e.onGenerateTitle ? Jt(t, e.onGenerateTitle) : Gt(t)
1023
+ }
1024
+ ]);
1025
+ }
1026
+ function ln() {
1027
+ const e = {
1028
+ "*": "*",
1029
+ _: "_",
1030
+ "`": "`",
1031
+ '"': '"',
1032
+ "'": "'",
1033
+ "(": ")",
1034
+ "[": "]",
1035
+ "{": "}",
1036
+ "~": "~",
1037
+ // Русская раскладка: ё находится на той же клавише что и `
1038
+ ё: "`",
1039
+ Ё: "`"
1040
+ };
1041
+ return B.domEventHandlers({
1042
+ keydown: (t, n) => {
1043
+ const o = t.key, s = e[o];
1044
+ if (!s) return !1;
1045
+ const c = n.state.selection.main;
1046
+ if (c.empty) return !1;
1047
+ t.preventDefault();
1048
+ const r = n.state.sliceDoc(c.from, c.to), i = o === "ё" || o === "Ё" ? "`" : o;
1049
+ return n.dispatch({
1050
+ changes: {
1051
+ from: c.from,
1052
+ to: c.to,
1053
+ insert: i + r + s
1054
+ },
1055
+ // Select text inside wrapper (without wrapper characters)
1056
+ selection: {
1057
+ anchor: c.from + 1,
1058
+ head: c.from + 1 + r.length
1059
+ }
1060
+ }), !0;
1061
+ }
1062
+ });
1063
+ }
1064
+ function an(e) {
1065
+ return B.domEventHandlers({
1066
+ paste: (t, n) => {
1067
+ var s;
1068
+ if (!e.onImagePaste) return !1;
1069
+ const o = (s = t.clipboardData) == null ? void 0 : s.items;
1070
+ if (!o) return !1;
1071
+ for (const c of o)
1072
+ if (c.type.startsWith("image/")) {
1073
+ t.preventDefault();
1074
+ const r = c.getAsFile();
1075
+ return r ? ((async () => {
1076
+ try {
1077
+ const l = await r.arrayBuffer(), d = new Uint8Array(l);
1078
+ let m = "";
1079
+ for (let g = 0; g < d.length; g++)
1080
+ m += String.fromCharCode(d[g]);
1081
+ const u = btoa(m), a = await e.onImagePaste(u);
1082
+ if (a) {
1083
+ const g = `![image](${a})
1084
+ `, C = n.state.selection.main.head;
1085
+ n.dispatch({
1086
+ changes: { from: C, insert: g },
1087
+ selection: { anchor: C + g.length }
1088
+ });
1089
+ }
1090
+ } catch (l) {
1091
+ console.error("Error pasting image:", l);
1092
+ }
1093
+ })(), !0) : !1;
1094
+ }
1095
+ return !1;
1096
+ }
1097
+ });
1098
+ }
1099
+ const $t = (e) => `md-editor-fold:${e}`, dn = /^\s*(>>|\^\^)/;
1100
+ function mn(e, t) {
1101
+ if (!e) return;
1102
+ const n = j(t.state), o = [];
1103
+ n.between(0, t.state.doc.length, (c, r) => {
1104
+ const i = t.state.doc.lineAt(c).number, l = t.state.doc.lineAt(r).number;
1105
+ o.push({ fromLine: i, toLine: l });
1106
+ });
1107
+ const s = e.split("/").pop();
1108
+ o.length > 0 ? (console.log("[Fold:save]", s, "saving", o.length, "folds:", o), localStorage.setItem($t(e), JSON.stringify(o))) : (console.log("[Fold:save]", s, "no folds — removing from localStorage"), localStorage.removeItem($t(e)));
1109
+ }
1110
+ function fn(e, t) {
1111
+ if (e)
1112
+ try {
1113
+ const n = $t(e), o = localStorage.getItem(n), s = e.split("/").pop();
1114
+ if (console.log("[Fold:load]", s, "localStorage entry:", o ? o.slice(0, 120) : "NULL"), !o) return;
1115
+ const c = JSON.parse(o), r = [];
1116
+ let i = 0;
1117
+ for (const { fromLine: l, toLine: d } of c)
1118
+ if (l <= t.state.doc.lines && d <= t.state.doc.lines) {
1119
+ const m = t.state.doc.line(l);
1120
+ if (!dn.test(m.text)) {
1121
+ i++;
1122
+ continue;
1123
+ }
1124
+ const u = m.to, a = t.state.doc.line(d).to;
1125
+ r.push(Q.of({ from: u, to: a }));
1126
+ }
1127
+ i > 0 && console.warn("[Fold:load] skipped", i, "stale folds (no collapsible marker at saved line)"), r.length > 0 && (console.log("[Fold:load]", e == null ? void 0 : e.split("/").pop(), "restoring", r.length, "folds from saved:", c), t.dispatch({ effects: r }));
1128
+ } catch (n) {
1129
+ console.error("[Fold:load] Failed:", n);
1130
+ }
1131
+ }
1132
+ function un(e) {
1133
+ return e.some((t) => t.is(Q) || t.is(ot));
1134
+ }
1135
+ class hn extends ht {
1136
+ constructor(t, n) {
1137
+ super(), this.path = t, this.onOpenFile = n;
1138
+ }
1139
+ eq(t) {
1140
+ return t.path === this.path;
1141
+ }
1142
+ toDOM() {
1143
+ const t = document.createElement("span");
1144
+ t.className = "cm-include-link";
1145
+ const n = document.createElement("span");
1146
+ n.className = "cm-include-link-icon", n.textContent = "📎", t.appendChild(n);
1147
+ const o = document.createElement("span");
1148
+ if (o.className = "cm-include-link-path", o.textContent = this.path, t.appendChild(o), this.onOpenFile) {
1149
+ const s = document.createElement("button");
1150
+ s.className = "cm-include-link-open", s.textContent = "↗", s.title = "Open file", s.addEventListener("click", (c) => {
1151
+ var r;
1152
+ c.stopPropagation(), c.preventDefault(), (r = this.onOpenFile) == null || r.call(this, this.path);
1153
+ }), t.appendChild(s), t.addEventListener("mousedown", (c) => {
1154
+ var r;
1155
+ (c.metaKey || c.ctrlKey) && (c.stopPropagation(), c.preventDefault(), (r = this.onOpenFile) == null || r.call(this, this.path));
1156
+ });
1157
+ }
1158
+ return t;
1159
+ }
1160
+ ignoreEvent(t) {
1161
+ return t.type === "mousedown";
1162
+ }
1163
+ }
1164
+ const Pt = /^<!--\s*@include:\s*(.+?)\s*-->$/;
1165
+ function pn(e = {}) {
1166
+ return dt.fromClass(
1167
+ class {
1168
+ constructor(t) {
1169
+ H(this, "decorations");
1170
+ H(this, "cmdPressed", !1);
1171
+ this.decorations = this.buildDecorations(t), this.setupCmdListener(t);
1172
+ }
1173
+ setupCmdListener(t) {
1174
+ const n = (c) => {
1175
+ (c.key === "Meta" || c.key === "Control") && (this.cmdPressed = !0, t.contentDOM.classList.add("cm-include-cmd-mode"));
1176
+ }, o = (c) => {
1177
+ (c.key === "Meta" || c.key === "Control") && (this.cmdPressed = !1, t.contentDOM.classList.remove("cm-include-cmd-mode"));
1178
+ }, s = () => {
1179
+ this.cmdPressed = !1, t.contentDOM.classList.remove("cm-include-cmd-mode");
1180
+ };
1181
+ document.addEventListener("keydown", n), document.addEventListener("keyup", o), window.addEventListener("blur", s), t._includeLinkCleanup = () => {
1182
+ document.removeEventListener("keydown", n), document.removeEventListener("keyup", o), window.removeEventListener("blur", s);
1183
+ };
1184
+ }
1185
+ destroy() {
1186
+ }
1187
+ update(t) {
1188
+ (t.docChanged || t.selectionSet || t.focusChanged) && (this.decorations = this.buildDecorations(t.view));
1189
+ }
1190
+ buildDecorations(t) {
1191
+ const n = [], o = t.state.doc, s = /* @__PURE__ */ new Set();
1192
+ if (t.hasFocus)
1193
+ for (const c of t.state.selection.ranges) {
1194
+ const r = o.lineAt(c.from).number, i = o.lineAt(c.to).number;
1195
+ for (let l = r; l <= i; l++)
1196
+ s.add(l);
1197
+ }
1198
+ for (let c = 1; c <= o.lines; c++) {
1199
+ const r = o.line(c), i = r.text.match(Pt);
1200
+ if (i) {
1201
+ if (s.has(c))
1202
+ continue;
1203
+ const l = i[1].trim(), d = new hn(l, e.onOpenFile);
1204
+ n.push({
1205
+ from: r.from,
1206
+ to: r.to,
1207
+ decoration: w.replace({ widget: d })
1208
+ });
1209
+ }
1210
+ }
1211
+ n.sort((c, r) => c.from - r.from);
1212
+ try {
1213
+ return w.set(
1214
+ n.map((c) => c.decoration.range(c.from, c.to)),
1215
+ !0
1216
+ );
1217
+ } catch (c) {
1218
+ return console.error("[IncludeLink] Error:", c), w.none;
1219
+ }
1220
+ }
1221
+ },
1222
+ { decorations: (t) => t.decorations }
1223
+ );
1224
+ }
1225
+ function gn(e = {}) {
1226
+ return it.highest(B.domEventHandlers({
1227
+ mousedown(t, n) {
1228
+ if (!t.metaKey && !t.ctrlKey) return !1;
1229
+ const o = n.posAtCoords({ x: t.clientX, y: t.clientY });
1230
+ if (o === null) return !1;
1231
+ const c = n.state.doc.lineAt(o).text.match(Pt);
1232
+ if (c && e.onOpenFile) {
1233
+ const r = c[1].trim();
1234
+ return t.preventDefault(), t.stopPropagation(), e.onOpenFile(r), !0;
1235
+ }
1236
+ return !1;
1237
+ }
1238
+ }));
1239
+ }
1240
+ async function bn(e, t) {
1241
+ const n = e.split(`
1242
+ `), o = [];
1243
+ for (const s of n) {
1244
+ const c = s.match(Pt);
1245
+ if (c) {
1246
+ const r = c[1].trim();
1247
+ try {
1248
+ const i = await t(r);
1249
+ o.push(i);
1250
+ } catch {
1251
+ o.push(s);
1252
+ }
1253
+ } else
1254
+ o.push(s);
1255
+ }
1256
+ return o.join(`
1257
+ `);
1258
+ }
1259
+ let It = null;
1260
+ const xn = dt.fromClass(class {
1261
+ update(e) {
1262
+ const t = e.state.selection;
1263
+ t.main.empty || (It = t);
1264
+ }
1265
+ });
1266
+ function Ct(e) {
1267
+ const t = e.match(/^[\t ]*/);
1268
+ return t ? t[0] : "";
1269
+ }
1270
+ function ae(e) {
1271
+ let t = 0;
1272
+ for (; t < e.length && (e[t] === " " || e[t] === " "); )
1273
+ t++;
1274
+ if (t + 1 < e.length && (e[t] === ">" && e[t + 1] === ">" || e[t] === "^" && e[t + 1] === "^") && (t += 2, t < e.length && e[t] === " " && t++), t < e.length && e[t] === "#") {
1275
+ let s = 0;
1276
+ for (; t + s < e.length && e[t + s] === "#" && s < 6; )
1277
+ s++;
1278
+ s > 0 && (t + s >= e.length || e[t + s] === " ") && (t += s, t < e.length && e[t] === " " && t++);
1279
+ }
1280
+ const o = e.substring(t).match(/^([*+\-]|\d+\.)\s+/);
1281
+ return o && (t += o[0].length), t;
1282
+ }
1283
+ function yn(e, t) {
1284
+ const { state: n } = e, o = n.selection.main, s = n.doc.lineAt(o.from), c = n.doc.lineAt(o.to), r = [];
1285
+ for (let i = s.number; i <= c.number; i++) {
1286
+ const l = n.doc.line(i), d = l.text, m = Ct(d);
1287
+ d.slice(m.length).startsWith(t) || r.push({
1288
+ from: l.from + m.length,
1289
+ to: l.from + m.length,
1290
+ insert: t
1291
+ });
1292
+ }
1293
+ r.length > 0 && e.dispatch({ changes: r });
1294
+ }
1295
+ function Ot(e, t) {
1296
+ const { state: n } = e, o = n.selection.main, s = n.doc.lineAt(o.from), c = s.text, r = Ct(c), i = c.slice(r.length);
1297
+ {
1298
+ let l = null;
1299
+ if (i.startsWith(">> ") ? l = ">> " : i.startsWith("^^ ") ? l = "^^ " : i.startsWith(">>") ? l = ">>" : i.startsWith("^^") && (l = "^^"), l) {
1300
+ let d = null;
1301
+ if (j(n).between(s.from, n.doc.length, (m, u) => {
1302
+ m >= s.to && m <= s.to + 1 && !d && (d = { from: m, to: u });
1303
+ }), d) {
1304
+ const u = l.startsWith("^^") ? {
1305
+ from: s.from + r.length,
1306
+ to: s.from + r.length + 2,
1307
+ insert: ">>"
1308
+ } : void 0;
1309
+ e.dispatch({
1310
+ effects: ot.of(d),
1311
+ ...u ? { changes: [u] } : {}
1312
+ });
1313
+ const g = e.state.doc.lineAt(o.from), C = Ct(g.text), x = g.text.slice(C.length);
1314
+ let b = null;
1315
+ x.startsWith(">> ") ? b = ">> " : x.startsWith("^^ ") ? b = "^^ " : x.startsWith(">>") ? b = ">>" : x.startsWith("^^") && (b = "^^"), b && e.dispatch({
1316
+ changes: [{
1317
+ from: g.from + C.length,
1318
+ to: g.from + C.length + b.length,
1319
+ insert: ""
1320
+ }]
1321
+ });
1322
+ } else
1323
+ e.dispatch({
1324
+ changes: [{
1325
+ from: s.from + r.length,
1326
+ to: s.from + r.length + l.length,
1327
+ insert: ""
1328
+ }]
1329
+ });
1330
+ } else if (i.trim() === "") {
1331
+ const d = "Bullet", m = s.from + r.length;
1332
+ e.dispatch({
1333
+ changes: [{
1334
+ from: m,
1335
+ to: s.to,
1336
+ insert: t + d
1337
+ }],
1338
+ selection: { anchor: m + t.length + d.length }
1339
+ });
1340
+ } else
1341
+ yn(e, t);
1342
+ return;
1343
+ }
1344
+ }
1345
+ function rt(e, t, n) {
1346
+ const { state: o } = e, s = o.selection.main, c = t;
1347
+ let r = s.from, i = s.to;
1348
+ if (s.empty) {
1349
+ const E = o.doc.lineAt(r), L = E.text;
1350
+ if (L.trim() === "") return;
1351
+ const f = ae(L), h = L.trimEnd().length;
1352
+ if (f >= h) return;
1353
+ r = E.from + f, i = E.from + h;
1354
+ }
1355
+ const l = o.sliceDoc(r, i), d = l.length - l.trimStart().length, m = l.length - l.trimEnd().length, u = l.trim(), a = t.length, g = c.length;
1356
+ u.length >= a + g + 1 && u.startsWith(t) && u.endsWith(c) && (r = r + d + a, i = i - m - g);
1357
+ const C = o.sliceDoc(r, i), x = r >= t.length ? o.sliceDoc(r - t.length, r) : "", b = i + c.length <= o.doc.length ? o.sliceDoc(i, i + c.length) : "";
1358
+ x === t && b === c ? e.dispatch({
1359
+ changes: [
1360
+ { from: r - t.length, to: r, insert: "" },
1361
+ { from: i, to: i + c.length, insert: "" }
1362
+ ],
1363
+ selection: { anchor: r - t.length, head: i - t.length }
1364
+ }) : e.dispatch({
1365
+ changes: [
1366
+ { from: r, to: i, insert: t + C + c }
1367
+ ],
1368
+ selection: { anchor: r + t.length, head: r + t.length + C.length }
1369
+ });
1370
+ }
1371
+ function bt(e, t) {
1372
+ const { state: n } = e, o = n.selection.main, s = n.doc.lineAt(o.from), c = n.doc.lineAt(o.to), r = [];
1373
+ for (let i = s.number; i <= c.number; i++) {
1374
+ const l = n.doc.line(i), d = l.text;
1375
+ let u = Ct(d).length, a = d.slice(u);
1376
+ const g = a.match(/^(>>|\^\^)\s?/);
1377
+ g && (u += g[0].length, a = d.slice(u));
1378
+ const C = a.match(/^#{1,6}\s*/), x = t > 0 ? "#".repeat(t) + " " : "";
1379
+ r.push({
1380
+ from: l.from + u,
1381
+ to: l.from + u + (C ? C[0].length : 0),
1382
+ insert: x
1383
+ });
1384
+ }
1385
+ r.length > 0 && e.dispatch({ changes: r });
1386
+ }
1387
+ function Cn(e) {
1388
+ const { state: t } = e, n = t.selection.main.head, o = t.doc.lineAt(n), s = o.text, c = n - o.from, r = /`([^`]*)`/g;
1389
+ let i;
1390
+ for (; (i = r.exec(s)) !== null; ) {
1391
+ const l = i.index, d = l + i[0].length;
1392
+ if (c >= l && c <= d)
1393
+ return {
1394
+ content: i[1],
1395
+ // Content without backticks
1396
+ from: o.from + l,
1397
+ to: o.from + d
1398
+ };
1399
+ }
1400
+ return null;
1401
+ }
1402
+ async function Qt(e) {
1403
+ try {
1404
+ await navigator.clipboard.writeText(e);
1405
+ } catch {
1406
+ const n = document.createElement("textarea");
1407
+ n.value = e, document.body.appendChild(n), n.select(), document.execCommand("copy"), document.body.removeChild(n);
1408
+ }
1409
+ }
1410
+ function ft(e, t) {
1411
+ const { state: n } = e, o = n.selection.main;
1412
+ let s = o.from, c = o.to;
1413
+ if (o.empty) {
1414
+ const x = n.doc.lineAt(s), b = x.text;
1415
+ if (b.trim() === "") return !1;
1416
+ const E = ae(b), L = b.trimEnd().length;
1417
+ if (E >= L) return !1;
1418
+ s = x.from + E, c = x.from + L;
1419
+ }
1420
+ const r = n.sliceDoc(s, c), i = r.length - r.trimStart().length, l = r.length - r.trimEnd().length, d = s + i, m = c - l, u = r.trim(), a = t.length;
1421
+ u.length >= a * 2 + 1 && u.startsWith(t) && u.endsWith(t) && (s = d + a, c = m - a);
1422
+ const g = s >= t.length ? n.sliceDoc(s - t.length, s) : "", C = c + t.length <= n.doc.length ? n.sliceDoc(c, c + t.length) : "";
1423
+ return g === t && C === t;
1424
+ }
1425
+ function Dt(e, t) {
1426
+ const { state: n } = e, o = n.selection.main, c = n.doc.lineAt(o.from).text, r = Ct(c);
1427
+ return c.slice(r.length).startsWith(t);
1428
+ }
1429
+ function de(e) {
1430
+ const { state: t } = e, n = t.selection.main, s = t.doc.lineAt(n.from).text, c = Ct(s);
1431
+ let r = s.slice(c.length);
1432
+ const i = r.match(/^(>>|\^\^)\s?/);
1433
+ i && (r = r.slice(i[0].length));
1434
+ const l = r.match(/^(#{1,6})\s/);
1435
+ return l ? l[1].length : 0;
1436
+ }
1437
+ function kn(e) {
1438
+ return Pt.test(e);
1439
+ }
1440
+ function Ln(e, t) {
1441
+ var m;
1442
+ const n = [], o = e ? ft(e, "**") : !1, s = e ? ft(e, "*") && !o : !1, c = e ? ft(e, "`") : !1, r = e ? ft(e, "~~") : !1, i = e ? Dt(e, ">> ") || Dt(e, "^^ ") : !1, l = e ? de(e) : 0;
1443
+ if (e) {
1444
+ const u = Cn(e);
1445
+ u && (n.push({
1446
+ label: "Copy block",
1447
+ action: () => {
1448
+ Qt(u.content);
1449
+ }
1450
+ }), n.push({ divider: !0, label: "" }));
1451
+ }
1452
+ if (e && (t != null && t.resolveInclude)) {
1453
+ const u = e.state.doc.toString();
1454
+ kn(u) && (n.push({
1455
+ label: "Copy with includes",
1456
+ action: async () => {
1457
+ try {
1458
+ const a = await bn(u, t.resolveInclude);
1459
+ await Qt(a);
1460
+ } catch (a) {
1461
+ console.error("[ContextMenu] Failed to resolve includes:", a);
1462
+ }
1463
+ }
1464
+ }), n.push({ divider: !0, label: "" }));
1465
+ }
1466
+ n.push({
1467
+ label: "Transform",
1468
+ submenu: [
1469
+ {
1470
+ label: i ? "✓ Collapsible Section" : "Collapsible Section",
1471
+ action: (u) => Ot(u, ">> ")
1472
+ },
1473
+ { divider: !0, label: "" },
1474
+ {
1475
+ label: l === 1 ? "✓ Heading 1" : "Heading 1",
1476
+ action: (u) => bt(u, l === 1 ? 0 : 1)
1477
+ },
1478
+ {
1479
+ label: l === 2 ? "✓ Heading 2" : "Heading 2",
1480
+ action: (u) => bt(u, l === 2 ? 0 : 2)
1481
+ },
1482
+ {
1483
+ label: l === 3 ? "✓ Heading 3" : "Heading 3",
1484
+ action: (u) => bt(u, l === 3 ? 0 : 3)
1485
+ },
1486
+ { divider: !0, label: "" },
1487
+ {
1488
+ label: o ? "✓ Bold" : "Bold",
1489
+ action: (u) => rt(u, "**")
1490
+ },
1491
+ {
1492
+ label: s ? "✓ Italic" : "Italic",
1493
+ action: (u) => rt(u, "*")
1494
+ },
1495
+ {
1496
+ label: c ? "✓ Code" : "Code",
1497
+ action: (u) => rt(u, "`")
1498
+ },
1499
+ {
1500
+ label: r ? "✓ Strikethrough" : "Strikethrough",
1501
+ action: (u) => rt(u, "~~")
1502
+ }
1503
+ ]
1504
+ });
1505
+ const d = ((m = t == null ? void 0 : t.getEmojiShortcuts) == null ? void 0 : m.call(t)) ?? [];
1506
+ return d.length > 0 && (n.push({ divider: !0, label: "" }), n.push({
1507
+ label: "Emoji",
1508
+ submenu: d.map((u) => ({
1509
+ label: `${u.emoji} ${u.name || u.emoji}`,
1510
+ _emojiDescription: u.description,
1511
+ action: (a) => {
1512
+ const g = a.state.selection.main.head;
1513
+ a.dispatch({
1514
+ changes: { from: g, insert: u.emoji }
1515
+ });
1516
+ }
1517
+ }))
1518
+ })), n;
1519
+ }
1520
+ function En(e, t, n, o, s) {
1521
+ const c = Ln(e, s);
1522
+ wt();
1523
+ const r = document.createElement("div");
1524
+ r.className = "cm-context-menu", r.style.left = `${t}px`, r.style.top = `${n}px`, r.setAttribute("data-context-menu", "true");
1525
+ let i = null, l = null;
1526
+ function d(b, E) {
1527
+ m();
1528
+ const L = document.createElement("div");
1529
+ L.className = "cm-emoji-tooltip", L.textContent = E, document.body.appendChild(L);
1530
+ const f = b.getBoundingClientRect();
1531
+ L.style.left = `${f.right + 8}px`, L.style.top = `${f.top}px`, requestAnimationFrame(() => {
1532
+ const h = L.getBoundingClientRect();
1533
+ h.right > window.innerWidth && (L.style.left = `${f.left - h.width - 8}px`), h.bottom > window.innerHeight && (L.style.top = `${window.innerHeight - h.height - 8}px`);
1534
+ }), i = L;
1535
+ }
1536
+ function m() {
1537
+ i && (i.remove(), i = null);
1538
+ }
1539
+ const u = (b) => {
1540
+ b.key === "Meta" && l && d(l.el, l.desc);
1541
+ }, a = (b) => {
1542
+ b.key === "Meta" && m();
1543
+ };
1544
+ document.addEventListener("keydown", u), document.addEventListener("keyup", a), r._emojiCleanup = () => {
1545
+ document.removeEventListener("keydown", u), document.removeEventListener("keyup", a), m(), l = null;
1546
+ };
1547
+ function g(b, E, L = !1) {
1548
+ E.forEach((f) => {
1549
+ if (f.divider) {
1550
+ const p = document.createElement("div");
1551
+ p.className = "cm-context-menu-divider", b.appendChild(p);
1552
+ return;
1553
+ }
1554
+ const h = document.createElement("div");
1555
+ if (h.className = "cm-context-menu-item", f.submenu) {
1556
+ h.classList.add("has-submenu"), h.innerHTML = `<span>${f.label}</span><span class="submenu-arrow">▸</span>`;
1557
+ const p = document.createElement("div");
1558
+ p.className = "cm-context-submenu";
1559
+ let y = null;
1560
+ p.addEventListener("mousemove", (T) => {
1561
+ var O;
1562
+ let I = null;
1563
+ for (const _ of p.children) {
1564
+ const z = _.getBoundingClientRect();
1565
+ if (T.clientY >= z.top && T.clientY <= z.bottom) {
1566
+ I = _;
1567
+ break;
1568
+ }
1569
+ }
1570
+ if (I === y) return;
1571
+ y = I;
1572
+ const M = I == null ? void 0 : I.dataset.emojiDesc;
1573
+ console.log("[EmojiTooltip] Hover changed. Target:", (O = I == null ? void 0 : I.textContent) == null ? void 0 : O.trim(), "Desc:", M, "Meta:", T.metaKey), I && M ? (l = { el: I, desc: M }, T.metaKey && d(I, M)) : (l = null, m());
1574
+ }), p.addEventListener("mouseleave", () => {
1575
+ y = null, l = null, m();
1576
+ }), g(p, f.submenu, !0), h.appendChild(p);
1577
+ } else
1578
+ h.textContent = f.label, h.addEventListener("click", (p) => {
1579
+ var y;
1580
+ p.stopPropagation(), wt(), (y = f.action) == null || y.call(f, e), e.focus();
1581
+ }), f._emojiDescription && (h.dataset.emojiDesc = f._emojiDescription, console.log("[EmojiTooltip] Set data-emoji-desc on item:", f.label, "desc:", f._emojiDescription));
1582
+ b.appendChild(h);
1583
+ });
1584
+ }
1585
+ g(r, c), console.log("[EmojiTooltip] Menu rendered. HTML:", r.innerHTML), document.body.appendChild(r), requestAnimationFrame(() => {
1586
+ const b = r.getBoundingClientRect();
1587
+ let E = t, L = n;
1588
+ b.right > window.innerWidth && (E = window.innerWidth - b.width - 10);
1589
+ const f = window.innerHeight - n, h = n;
1590
+ b.height > f && h > f ? L = n - b.height : b.bottom > window.innerHeight && (L = window.innerHeight - b.height - 10), r.style.left = `${Math.max(10, E)}px`, r.style.top = `${Math.max(10, L)}px`;
1591
+ });
1592
+ const C = (b) => {
1593
+ b.target.closest("[data-context-menu]") || (wt(), document.removeEventListener("click", C));
1594
+ }, x = (b) => {
1595
+ b.key === "Escape" && (wt(), document.removeEventListener("keydown", x));
1596
+ };
1597
+ setTimeout(() => {
1598
+ document.addEventListener("click", C), document.addEventListener("keydown", x);
1599
+ }, 0);
1600
+ }
1601
+ function wt() {
1602
+ var t;
1603
+ const e = document.querySelector("[data-context-menu]");
1604
+ e && ((t = e._emojiCleanup) == null || t.call(e), e.remove());
1605
+ }
1606
+ function Mn(e) {
1607
+ const t = de(e), n = ft(e, "**"), o = ft(e, "*") && !n, s = ft(e, "`");
1608
+ return [
1609
+ { label: Dt(e, ">>") || Dt(e, "^^") ? "✓ Collapsible" : "Collapsible", color: "#868e96", action: (r) => Ot(r, ">> ") },
1610
+ { label: n ? "✓ Bold" : "Bold", color: "#ffa348", action: (r) => rt(r, "**") },
1611
+ { label: o ? "✓ Italic" : "Italic", color: "#69dbdb", action: (r) => rt(r, "*") },
1612
+ { label: s ? "✓ Code" : "Code", color: "#50fa7b", action: (r) => rt(r, "`") },
1613
+ { label: t === 1 ? "✓ H1" : "H1", color: "#c678dd", action: (r) => bt(r, t === 1 ? 0 : 1) },
1614
+ { label: t === 2 ? "✓ H2" : "H2", color: "#b197fc", action: (r) => bt(r, t === 2 ? 0 : 2) },
1615
+ { label: t === 3 ? "✓ H3" : "H3", color: "#a78bfa", action: (r) => bt(r, t === 3 ? 0 : 3) },
1616
+ { label: "📋 AI Paste", color: "#4ecdc4", action: (r) => on(r) }
1617
+ ];
1618
+ }
1619
+ let Et = null, Mt = null;
1620
+ function pt() {
1621
+ const e = document.querySelector("[data-command-palette]");
1622
+ e && e.remove(), Et && (document.removeEventListener("keydown", Et, !0), Et = null), Mt && (document.removeEventListener("click", Mt), Mt = null);
1623
+ }
1624
+ function An(e, t) {
1625
+ pt();
1626
+ let n = t ?? e.state.selection;
1627
+ !t && n.main.empty && It && !It.main.empty && (n = It);
1628
+ const o = n.main;
1629
+ o.empty || e.dispatch({ selection: n });
1630
+ const s = o.head, c = e.coordsAtPos(s) ?? e.coordsAtPos(s, -1);
1631
+ if (!c) return;
1632
+ const r = Mn(e), i = document.createElement("div");
1633
+ if (i.className = "cm-command-palette", i.setAttribute("data-command-palette", "true"), i.style.left = `${c.left}px`, i.style.top = `${c.bottom + 4}px`, !o.empty) {
1634
+ const a = e.state.sliceDoc(o.from, o.to), g = document.createElement("div");
1635
+ g.className = "cm-command-palette-preview";
1636
+ const C = a.length > 30 ? a.slice(0, 30) + "..." : a;
1637
+ g.textContent = C, i.appendChild(g);
1638
+ }
1639
+ const l = document.createElement("div");
1640
+ i.appendChild(l);
1641
+ let d = 0;
1642
+ function m() {
1643
+ l.innerHTML = "", r.forEach((a, g) => {
1644
+ const C = document.createElement("div");
1645
+ C.className = "cm-command-palette-item" + (g === d ? " active" : "");
1646
+ const x = document.createElement("span");
1647
+ x.className = "palette-color", x.style.backgroundColor = a.color;
1648
+ const b = document.createElement("span");
1649
+ b.textContent = a.label, C.appendChild(x), C.appendChild(b), C.addEventListener("click", (E) => {
1650
+ E.stopPropagation(), pt(), a.action(e), e.focus();
1651
+ }), l.appendChild(C);
1652
+ });
1653
+ }
1654
+ m(), document.body.appendChild(i), requestAnimationFrame(() => {
1655
+ const a = i.getBoundingClientRect();
1656
+ a.right > window.innerWidth && (i.style.left = `${window.innerWidth - a.width - 10}px`), a.bottom > window.innerHeight && (i.style.top = `${c.top - a.height - 4}px`), i.style.left = `${Math.max(10, parseInt(i.style.left))}px`, i.style.top = `${Math.max(10, parseInt(i.style.top))}px`;
1657
+ });
1658
+ const u = n;
1659
+ Et = (a) => {
1660
+ if ((a.key === "ArrowDown" || a.key === "ArrowUp" || a.key === "Enter" || a.key === "Escape") && (a.preventDefault(), a.stopPropagation(), a.stopImmediatePropagation()), a.key === "ArrowDown")
1661
+ d = (d + 1) % r.length, m();
1662
+ else if (a.key === "ArrowUp")
1663
+ d = (d - 1 + r.length) % r.length, m();
1664
+ else if (a.key === "Enter") {
1665
+ const g = r[d].action;
1666
+ pt(), e.dispatch({ selection: u }), g(e), e.focus();
1667
+ } else a.key === "Escape" && (pt(), e.dispatch({ selection: u }), e.focus());
1668
+ }, Mt = (a) => {
1669
+ a.target.closest("[data-command-palette]") || pt();
1670
+ }, setTimeout(() => {
1671
+ document.addEventListener("keydown", Et, !0), document.addEventListener("click", Mt);
1672
+ }, 0);
1673
+ }
1674
+ function Sn(e) {
1675
+ return it.highest(B.domEventHandlers({
1676
+ contextmenu: (t, n) => {
1677
+ t.preventDefault();
1678
+ const o = n.state.selection.main, s = n.posAtCoords({ x: t.clientX, y: t.clientY });
1679
+ return s !== null && (!o.empty && s >= o.from && s <= o.to || n.dispatch({
1680
+ selection: { anchor: s }
1681
+ })), En(n, t.clientX, t.clientY, void 0, e), !0;
1682
+ }
1683
+ }));
1684
+ }
1685
+ function Zt(e) {
1686
+ const t = new ce();
1687
+ for (const { from: n, to: o } of e.visibleRanges)
1688
+ for (let s = n; s <= o; ) {
1689
+ const c = e.state.doc.lineAt(s), r = c.text;
1690
+ let i = 0;
1691
+ for (let l = 0; l < r.length; l++)
1692
+ if (r[l] === " ")
1693
+ i++;
1694
+ else if (r[l] === " ")
1695
+ i += 4;
1696
+ else
1697
+ break;
1698
+ if (i > 0) {
1699
+ const l = w.line({
1700
+ attributes: {
1701
+ // FIX: Add 6px (base padding) to padding-left to compensate for negative text-indent.
1702
+ // This ensures the first character stays at the 6px mark instead of jumping to 0px.
1703
+ style: `padding-left: calc(${i}ch + 6px); text-indent: -${i}ch;`
1704
+ }
1705
+ });
1706
+ t.add(c.from, c.from, l);
1707
+ }
1708
+ s = c.to + 1;
1709
+ }
1710
+ return t.finish();
1711
+ }
1712
+ const wn = dt.fromClass(
1713
+ class {
1714
+ constructor(e) {
1715
+ H(this, "decorations");
1716
+ this.decorations = Zt(e);
1717
+ }
1718
+ update(e) {
1719
+ (e.docChanged || e.viewportChanged) && (this.decorations = Zt(e.view));
1720
+ }
1721
+ },
1722
+ {
1723
+ decorations: (e) => e.decorations
1724
+ }
1725
+ );
1726
+ B.domEventHandlers({
1727
+ mousedown(e, t) {
1728
+ const o = e.target.closest(".cm-line");
1729
+ if (!o) return;
1730
+ const s = t.posAtDOM(o), c = t.state.doc.lineAt(s), r = c.text.trim();
1731
+ if (r.startsWith(">>") || r.startsWith("^^")) {
1732
+ let i = !1, l = null;
1733
+ if (j(t.state).between(c.from, c.to, (d, m) => {
1734
+ i = !0, l = { from: d, to: m };
1735
+ }), i && l)
1736
+ t.dispatch({ effects: ot.of(l) });
1737
+ else {
1738
+ const d = V(t.state, c.from, c.to);
1739
+ d && t.dispatch({ effects: Q.of(d) });
1740
+ }
1741
+ return e.preventDefault(), !0;
1742
+ }
1743
+ return !1;
1744
+ }
1745
+ });
1746
+ function me(e = []) {
1747
+ return ye({
1748
+ formatNumber: (t) => {
1749
+ let n = t;
1750
+ for (const o of e)
1751
+ t > o.editorLine && (n += o.diskLines);
1752
+ return String(n);
1753
+ },
1754
+ domEventHandlers: {
1755
+ // mousedown to prevent text selection
1756
+ mousedown(t, n, o) {
1757
+ const s = t.state.doc.lineAt(n.from), c = s.text.trim();
1758
+ if (c.startsWith(">>") || c.startsWith("^^")) {
1759
+ let r = !1, i = null;
1760
+ j(t.state).between(n.from, n.to, (m, u) => {
1761
+ r = !0, i = { from: m, to: u };
1762
+ });
1763
+ const l = s.text, d = (m, u) => {
1764
+ const a = l.indexOf(m);
1765
+ return a === -1 ? null : { from: s.from + a, to: s.from + a + 2, insert: u };
1766
+ };
1767
+ if (r && i) {
1768
+ const m = d("^^", ">>");
1769
+ t.dispatch({
1770
+ effects: ot.of(i),
1771
+ changes: m ? [m] : void 0
1772
+ });
1773
+ } else {
1774
+ const m = V(t.state, n.from, n.to);
1775
+ if (m && m.to - m.from > 2) {
1776
+ const u = d(">>", "^^");
1777
+ t.dispatch({
1778
+ effects: Q.of(m),
1779
+ changes: u ? [u] : void 0
1780
+ });
1781
+ }
1782
+ }
1783
+ return o.preventDefault(), o.stopPropagation(), !0;
1784
+ }
1785
+ return !1;
1786
+ }
1787
+ }
1788
+ });
1789
+ }
1790
+ me([]);
1791
+ class Wt extends ke {
1792
+ constructor(t, n) {
1793
+ super(), this.isOpen = t, this.isEmpty = n;
1794
+ }
1795
+ toDOM() {
1796
+ const t = document.createElement("div");
1797
+ return t.className = `cm-fold-marker ${this.isOpen ? "open" : "closed"}${this.isEmpty ? " empty" : ""}`, t.textContent = this.isOpen ? "▾" : "▸", t;
1798
+ }
1799
+ }
1800
+ const In = new Wt(!0, !1), Dn = new Wt(!1, !1), Tn = new Wt(!1, !0);
1801
+ function te(e, t, n) {
1802
+ const o = V(e.state, t, n);
1803
+ return o !== null && o.to - o.from > 2;
1804
+ }
1805
+ function Pn(e, t, n) {
1806
+ let o = !1;
1807
+ return j(e.state).between(t, n, () => {
1808
+ o = !0;
1809
+ }), o;
1810
+ }
1811
+ Ce({
1812
+ class: "cm-foldGutter",
1813
+ markers: (e) => {
1814
+ const t = [];
1815
+ for (let n = 1; n <= e.state.doc.lines; n++) {
1816
+ const o = e.state.doc.line(n), s = o.text.trim();
1817
+ (s.startsWith(">>") || s.startsWith("^^")) && (te(e, o.from, o.to) ? Pn(e, o.from, o.to) ? t.push({ from: o.from, marker: Dn }) : t.push({ from: o.from, marker: In }) : t.push({ from: o.from, marker: Tn }));
1818
+ }
1819
+ return Se.of(t.map((n) => n.marker.range(n.from)));
1820
+ },
1821
+ domEventHandlers: {
1822
+ mousedown(e, t, n) {
1823
+ const s = e.state.doc.lineAt(t.from).text.trim();
1824
+ if (!s.startsWith(">>") && !s.startsWith("^^")) return !1;
1825
+ if (!te(e, t.from, t.to))
1826
+ return n.preventDefault(), !0;
1827
+ let r = null;
1828
+ if (j(e.state).between(t.from, t.to, (i, l) => {
1829
+ r = { from: i, to: l };
1830
+ }), r)
1831
+ e.dispatch({ effects: ot.of(r) });
1832
+ else {
1833
+ const i = V(e.state, t.from, t.to);
1834
+ i && e.dispatch({ effects: Q.of(i) });
1835
+ }
1836
+ return n.preventDefault(), !0;
1837
+ }
1838
+ }
1839
+ });
1840
+ const at = /^(\s*)(>>|\^\^)/, Lt = { pendingFold: 0, pendingUnfold: 0 };
1841
+ window.__foldDiag = Lt;
1842
+ const Fn = dt.fromClass(
1843
+ class {
1844
+ constructor(e) {
1845
+ H(this, "decorations");
1846
+ this.decorations = this.buildDecorations(e);
1847
+ }
1848
+ update(e) {
1849
+ (e.docChanged || e.selectionSet || this.foldStateChanged(e)) && (this.decorations = this.buildDecorations(e.view)), e.docChanged && (this.autoUnfoldStaleFolds(e.view), this.autoFoldCollapsedMarkers(e.view));
1850
+ }
1851
+ /**
1852
+ * Automatically fold blocks marked with ^^ (collapsed marker)
1853
+ * This ensures pasted ^^ blocks get folded
1854
+ */
1855
+ autoFoldCollapsedMarkers(e) {
1856
+ const t = e.state.doc, n = [];
1857
+ for (let s = 1; s <= t.lines; s++) {
1858
+ const c = t.line(s);
1859
+ if (c.text.trim().startsWith("^^")) {
1860
+ let i = !1;
1861
+ if (j(e.state).between(c.from, c.to, () => {
1862
+ i = !0;
1863
+ }), !i) {
1864
+ const l = V(e.state, c.from, c.to);
1865
+ l && l.to - l.from > 2 && n.push(Q.of(l));
1866
+ }
1867
+ }
1868
+ }
1869
+ let o = 0;
1870
+ for (let s = 1; s <= t.lines; s++)
1871
+ t.line(s).text.trim().startsWith("^^") && o++;
1872
+ if (n.length === 0) {
1873
+ o > 0 && console.log("[Fold:autoFold] ran: 0 to fold, all", o, "^^ blocks already folded");
1874
+ return;
1875
+ }
1876
+ console.log("[Fold:autoFold]", n.length, "/", o, "unfolded ^^ blocks found, scheduling fold"), Lt.pendingFold++, n.length, setTimeout(() => {
1877
+ Lt.pendingFold--, e.dispatch({ effects: n });
1878
+ }, 0);
1879
+ }
1880
+ /**
1881
+ * Auto-unfold stale folds.
1882
+ * When content after a folded section gets indented (Tab) or moved (Alt+Up/Down),
1883
+ * the fold range becomes stale — foldable() returns a different range than stored.
1884
+ * Detect this and unfold + swap ^^ → >> to keep state consistent.
1885
+ */
1886
+ autoUnfoldStaleFolds(e) {
1887
+ const t = e.state.doc, n = [], o = [];
1888
+ j(e.state).between(0, t.length, (s, c) => {
1889
+ const r = t.lineAt(s), i = r.text.match(at);
1890
+ if (!i) return;
1891
+ const l = V(e.state, r.from, r.to);
1892
+ if ((!l || l.to !== c) && (n.push(ot.of({ from: s, to: c })), i[2] === "^^")) {
1893
+ const d = r.from + i[1].length;
1894
+ o.push({ from: d, to: d + 2, insert: ">>" });
1895
+ }
1896
+ }), n.length > 0 && (Lt.pendingUnfold++, setTimeout(() => {
1897
+ Lt.pendingUnfold--, e.dispatch({
1898
+ ...o.length > 0 ? { changes: o } : {},
1899
+ effects: n
1900
+ });
1901
+ }, 0));
1902
+ }
1903
+ foldStateChanged(e) {
1904
+ for (const t of e.transactions || [])
1905
+ for (const n of t.effects)
1906
+ if (n.is(Q) || n.is(ot))
1907
+ return !0;
1908
+ return !1;
1909
+ }
1910
+ buildDecorations(e) {
1911
+ const t = [], n = e.state.doc;
1912
+ for (let o = 1; o <= n.lines; o++) {
1913
+ const s = n.line(o), c = s.text.match(at);
1914
+ if (c) {
1915
+ const r = c[1].length, i = c[2].length, l = s.from + r, d = l + i, m = this.hasContent(e, s.from, s.to), u = this.isFolded(e, s.from, s.to), a = this.detectFormatting(s.text), g = new _e(
1916
+ "",
1917
+ // Отступ не нужен — CodeMirror отрисует его как обычный текст
1918
+ !u,
1919
+ // isOpen (empty sections show ▾ with .empty styling)
1920
+ !m,
1921
+ // isEmpty
1922
+ s.from,
1923
+ a,
1924
+ // Тип форматирования для цвета
1925
+ e
1926
+ // EditorView для обработки кликов
1927
+ );
1928
+ t.push({
1929
+ from: l,
1930
+ to: d,
1931
+ decoration: w.replace({ widget: g })
1932
+ });
1933
+ }
1934
+ }
1935
+ t.sort((o, s) => o.from - s.from);
1936
+ try {
1937
+ return w.set(
1938
+ t.map((o) => o.decoration.range(o.from, o.to)),
1939
+ !0
1940
+ );
1941
+ } catch (o) {
1942
+ return console.error("[CollapsibleArrow] Error:", o), w.none;
1943
+ }
1944
+ }
1945
+ hasContent(e, t, n) {
1946
+ const o = V(e.state, t, n);
1947
+ return o !== null && o.to - o.from > 2;
1948
+ }
1949
+ isFolded(e, t, n) {
1950
+ let o = !1;
1951
+ return j(e.state).between(t, n, () => {
1952
+ o = !0;
1953
+ }), o;
1954
+ }
1955
+ /**
1956
+ * Определяет тип форматирования в тексте заголовка (после >> или ^^)
1957
+ * Приоритет: h1-h6 > bold > italic > code > strike
1958
+ */
1959
+ detectFormatting(e) {
1960
+ const t = e.replace(/^\s*(>>|\^\^)\s*/, ""), n = t.match(/^(#{1,6})\s/);
1961
+ return n ? `h${n[1].length}` : /\*\*[^*]+\*\*/.test(t) ? "bold" : new RegExp("(?<!\\*)\\*[^*]+\\*(?!\\*)").test(t) ? "italic" : /`[^`]+`/.test(t) ? "code" : /~~[^~]+~~/.test(t) ? "strike" : null;
1962
+ }
1963
+ },
1964
+ { decorations: (e) => e.decorations }
1965
+ );
1966
+ function vn() {
1967
+ return B.domEventHandlers({
1968
+ click(e, t) {
1969
+ const n = e.target;
1970
+ if (!n.classList.contains("cm-collapsible-arrow"))
1971
+ return !1;
1972
+ const o = n.dataset.lineFrom;
1973
+ if (!o) return !1;
1974
+ const s = parseInt(o, 10), c = t.state.doc.lineAt(s), r = V(t.state, c.from, c.to);
1975
+ if (!r || r.to - r.from <= 2)
1976
+ return e.preventDefault(), !0;
1977
+ let i = null;
1978
+ return j(t.state).between(c.from, c.to, (l, d) => {
1979
+ i = { from: l, to: d };
1980
+ }), i ? t.dispatch({ effects: ot.of(i) }) : t.dispatch({ effects: Q.of(r) }), e.preventDefault(), !0;
1981
+ }
1982
+ });
1983
+ }
1984
+ function $n() {
1985
+ return it.high(xt.of([
1986
+ {
1987
+ key: "Enter",
1988
+ run: (e) => {
1989
+ var d, m, u;
1990
+ const { state: t } = e, n = t.selection.main;
1991
+ if (!n.empty) return !1;
1992
+ const o = n.head, s = t.doc.lineAt(o);
1993
+ if (o !== s.to) return !1;
1994
+ let c = null;
1995
+ if (j(t).between(o, o, (a, g) => {
1996
+ const C = t.doc.lineAt(a);
1997
+ C.text.match(at) && (o === C.to || o === g) && (c = { from: a, to: g });
1998
+ }), c) {
1999
+ const a = c, C = ((d = t.doc.lineAt(a.from).text.match(/^\s*/)) == null ? void 0 : d[0]) ?? "", x = t.doc.lineAt(a.to);
2000
+ if (x.number < t.doc.lines) {
2001
+ const b = t.doc.line(x.number + 1).from, E = C + `
2002
+ `;
2003
+ e.dispatch({
2004
+ changes: { from: b, insert: E },
2005
+ selection: { anchor: b + C.length }
2006
+ });
2007
+ } else {
2008
+ const b = `
2009
+ ` + C;
2010
+ e.dispatch({
2011
+ changes: { from: t.doc.length, insert: b },
2012
+ selection: { anchor: t.doc.length + b.length }
2013
+ });
2014
+ }
2015
+ return !0;
2016
+ }
2017
+ const r = s.text.match(/^(\s*)(>>)\s/);
2018
+ if (r) {
2019
+ const g = `
2020
+ ` + r[1] + " ";
2021
+ return e.dispatch(
2022
+ t.replaceSelection(g),
2023
+ { scrollIntoView: !0, userEvent: "input" }
2024
+ ), !0;
2025
+ }
2026
+ let i = ((m = /^\s*/.exec(s.text)) == null ? void 0 : m[0]) ?? "";
2027
+ if (s.number < t.doc.lines) {
2028
+ const a = t.doc.line(s.number + 1), g = ((u = /^\s*/.exec(a.text)) == null ? void 0 : u[0]) ?? "";
2029
+ g.length > i.length && (i = g);
2030
+ }
2031
+ const l = `
2032
+ ` + i;
2033
+ return e.dispatch(
2034
+ t.replaceSelection(l),
2035
+ { scrollIntoView: !0, userEvent: "input" }
2036
+ ), !0;
2037
+ }
2038
+ },
2039
+ {
2040
+ key: "Mod-Enter",
2041
+ run: (e) => {
2042
+ var l, d, m;
2043
+ const { state: t } = e, n = t.selection.main;
2044
+ if (!n.empty) return !1;
2045
+ const o = t.doc.lineAt(n.head);
2046
+ let s = null;
2047
+ if (j(t).between(o.from, o.to, (u, a) => {
2048
+ t.doc.lineAt(u).text.match(at) && (s = { from: u, to: a });
2049
+ }), s) {
2050
+ const u = s, g = ((l = t.doc.lineAt(u.from).text.match(/^\s*/)) == null ? void 0 : l[0]) ?? "", C = t.doc.lineAt(u.to);
2051
+ if (C.number < t.doc.lines) {
2052
+ const x = t.doc.line(C.number + 1).from, b = g + `
2053
+ `;
2054
+ e.dispatch({
2055
+ changes: { from: x, insert: b },
2056
+ selection: { anchor: x + g.length },
2057
+ scrollIntoView: !0
2058
+ });
2059
+ } else {
2060
+ const x = `
2061
+ ` + g;
2062
+ e.dispatch({
2063
+ changes: { from: t.doc.length, insert: x },
2064
+ selection: { anchor: t.doc.length + x.length },
2065
+ scrollIntoView: !0
2066
+ });
2067
+ }
2068
+ return !0;
2069
+ }
2070
+ const c = o.text.match(/^(\s*)(>>)\s/);
2071
+ if (c) {
2072
+ const a = `
2073
+ ` + c[1] + " ";
2074
+ return e.dispatch({
2075
+ changes: { from: o.to, insert: a },
2076
+ selection: { anchor: o.to + a.length },
2077
+ scrollIntoView: !0,
2078
+ userEvent: "input"
2079
+ }), !0;
2080
+ }
2081
+ let r = ((d = /^\s*/.exec(o.text)) == null ? void 0 : d[0]) ?? "";
2082
+ if (o.number < t.doc.lines) {
2083
+ const u = t.doc.line(o.number + 1), a = ((m = /^\s*/.exec(u.text)) == null ? void 0 : m[0]) ?? "";
2084
+ a.length > r.length && (r = a);
2085
+ }
2086
+ const i = `
2087
+ ` + r;
2088
+ return e.dispatch({
2089
+ changes: { from: o.to, insert: i },
2090
+ selection: { anchor: o.to + i.length },
2091
+ scrollIntoView: !0,
2092
+ userEvent: "input"
2093
+ }), !0;
2094
+ }
2095
+ }
2096
+ ]));
2097
+ }
2098
+ function Hn() {
2099
+ return it.high(xt.of([{
2100
+ key: "Backspace",
2101
+ run: (e) => {
2102
+ const { state: t } = e, n = t.selection.main;
2103
+ if (!n.empty) return !1;
2104
+ const o = n.head;
2105
+ if (o === 0) return !1;
2106
+ const s = t.doc.lineAt(o);
2107
+ if (o !== s.from) return !1;
2108
+ let c = null;
2109
+ if (j(t).between(o - 1, o - 1, (r, i) => {
2110
+ t.doc.lineAt(r).text.match(at) && (c = { from: r, to: i });
2111
+ }), c) {
2112
+ const r = c, i = t.doc.lineAt(r.from), l = Math.max(i.from, r.from - 1);
2113
+ return e.dispatch({ selection: { anchor: l }, scrollIntoView: !0 }), !0;
2114
+ }
2115
+ return !1;
2116
+ }
2117
+ }]));
2118
+ }
2119
+ function ee(e, t, n) {
2120
+ const o = e.text.match(at);
2121
+ if (!o || o[2] !== t) return null;
2122
+ const s = e.from + o[1].length;
2123
+ return { from: s, to: s + t.length, insert: n };
2124
+ }
2125
+ function ne(e, t, n) {
2126
+ let o = null;
2127
+ if (j(e.state).between(t.from, t.to, (s, c) => {
2128
+ o = { from: s, to: c };
2129
+ }), o) {
2130
+ const s = ee(t, "^^", ">>"), c = [ot.of(o)];
2131
+ e.dispatch({
2132
+ ...s ? { changes: s } : {},
2133
+ effects: c,
2134
+ ...n ? { selection: n } : {}
2135
+ });
2136
+ } else {
2137
+ const s = V(e.state, t.from, t.to);
2138
+ if (!s || s.to - s.from <= 2) return;
2139
+ const c = ee(t, ">>", "^^"), r = [Q.of(s)];
2140
+ e.dispatch({
2141
+ ...c ? { changes: c } : {},
2142
+ effects: r,
2143
+ ...n ? { selection: n } : {}
2144
+ });
2145
+ }
2146
+ }
2147
+ function On(e, t) {
2148
+ const n = e.doc.lineAt(t);
2149
+ for (let o = n.number - 1; o >= 1; o--) {
2150
+ const s = e.doc.line(o);
2151
+ if (!s.text.match(at)) continue;
2152
+ const r = V(e, s.from, s.to);
2153
+ if (r && r.to >= t)
2154
+ return s;
2155
+ let i = null;
2156
+ if (j(e).between(s.from, s.to, (l, d) => {
2157
+ i = { from: l, to: d };
2158
+ }), i && i.to >= t)
2159
+ return s;
2160
+ }
2161
+ return null;
2162
+ }
2163
+ function Wn() {
2164
+ return it.high(xt.of([
2165
+ {
2166
+ key: "Mod-.",
2167
+ run: (e) => {
2168
+ const { state: t } = e, n = t.selection.main.head, o = t.doc.lineAt(n);
2169
+ if (at.test(o.text))
2170
+ return ne(e, o, { anchor: o.to }), !0;
2171
+ const s = On(t, n);
2172
+ if (s) {
2173
+ const c = e.lineBlockAt(n).top, r = e.lineBlockAt(s.from).top, i = e.scrollDOM.scrollTop;
2174
+ return ne(e, s, { anchor: s.to }), e.scrollDOM.scrollTop = i + (r - c), !0;
2175
+ }
2176
+ return !0;
2177
+ }
2178
+ }
2179
+ ]));
2180
+ }
2181
+ const Rn = /^(\s*)(>>|\^\^)/;
2182
+ function jn(e) {
2183
+ const t = e.replace(/^\s*(>>|\^\^)\s*/, ""), n = t.match(/^(#{1,6})\s/);
2184
+ return n ? `h${n[1].length}` : /\*\*[^*]+\*\*/.test(t) ? "bold" : new RegExp("(?<!\\*)\\*[^*]+\\*(?!\\*)").test(t) ? "italic" : /`[^`]+`/.test(t) ? "code" : /~~[^~]+~~/.test(t) ? "strike" : null;
2185
+ }
2186
+ function Nn(e) {
2187
+ const t = e.match(/^(\s*)/);
2188
+ if (!t) return 0;
2189
+ const n = t[1];
2190
+ let o = 0, s = 0;
2191
+ for (const c of n)
2192
+ c === " " ? (o++, s = 0) : c === " " && (s++, s >= 4 && (o++, s = 0));
2193
+ return o;
2194
+ }
2195
+ const Bn = dt.fromClass(
2196
+ class {
2197
+ constructor(e) {
2198
+ H(this, "decorations");
2199
+ this.decorations = this.buildDecorations(e);
2200
+ }
2201
+ update(e) {
2202
+ e.docChanged && (this.decorations = this.buildDecorations(e.view));
2203
+ }
2204
+ buildDecorations(e) {
2205
+ const t = e.state.doc, n = new ce(), o = [], s = /* @__PURE__ */ new Map();
2206
+ for (let r = 1; r <= t.lines; r++) {
2207
+ const l = t.line(r).text, d = Nn(l), m = l.trim() === "";
2208
+ if (!m)
2209
+ for (; o.length > 0; ) {
2210
+ const a = o[o.length - 1];
2211
+ if (d <= a.headerIndentLevel)
2212
+ o.pop();
2213
+ else
2214
+ break;
2215
+ }
2216
+ if (l.match(Rn)) {
2217
+ const a = jn(l);
2218
+ a && o.push({
2219
+ headerLine: r,
2220
+ headerIndentLevel: d,
2221
+ formatType: a,
2222
+ ownsLevel: d + 1
2223
+ });
2224
+ }
2225
+ if (!m && d > 0) {
2226
+ const a = /* @__PURE__ */ new Set();
2227
+ for (const g of o)
2228
+ d >= g.ownsLevel && a.add(`cm-scope-L${g.ownsLevel}-${g.formatType}`);
2229
+ a.size > 0 && s.set(r, a);
2230
+ }
2231
+ if (m && o.length > 0) {
2232
+ const a = /* @__PURE__ */ new Set();
2233
+ for (const g of o)
2234
+ a.add(`cm-scope-L${g.ownsLevel}-${g.formatType}`);
2235
+ a.size > 0 && s.set(r, a);
2236
+ }
2237
+ }
2238
+ const c = Array.from(s.keys()).sort((r, i) => r - i);
2239
+ for (const r of c) {
2240
+ const i = s.get(r), l = t.line(r), d = Array.from(i).join(" ");
2241
+ n.add(l.from, l.from, w.line({ class: d }));
2242
+ }
2243
+ return n.finish();
2244
+ }
2245
+ },
2246
+ { decorations: (e) => e.decorations }
2247
+ ), zn = dt.fromClass(
2248
+ class {
2249
+ constructor(e) {
2250
+ H(this, "layer");
2251
+ H(this, "view");
2252
+ this.view = e, this.layer = document.createElement("div"), this.layer.className = "cm-custom-selection-layer", this.layer.setAttribute("aria-hidden", "true"), e.scrollDOM.appendChild(this.layer), this.measureAndDraw();
2253
+ }
2254
+ update(e) {
2255
+ (e.docChanged || e.selectionSet || e.viewportChanged || e.geometryChanged) && this.measureAndDraw();
2256
+ }
2257
+ destroy() {
2258
+ this.layer.remove();
2259
+ }
2260
+ measureAndDraw() {
2261
+ this.view.requestMeasure({
2262
+ read: (e) => this.readSelections(e),
2263
+ write: (e) => {
2264
+ e && e.length > 0 ? this.drawSelections(e) : this.layer.textContent = "";
2265
+ }
2266
+ });
2267
+ }
2268
+ readSelections(e) {
2269
+ const { selection: t, doc: n } = e.state;
2270
+ if (t.main.empty) return [];
2271
+ const o = [];
2272
+ try {
2273
+ const s = e.scrollDOM.getBoundingClientRect(), c = e.scrollDOM.scrollLeft, r = e.scrollDOM.scrollTop, i = (l) => ({
2274
+ left: l.left - s.left + c,
2275
+ top: l.top - s.top + r,
2276
+ width: l.width,
2277
+ height: l.height
2278
+ });
2279
+ for (const l of t.ranges) {
2280
+ if (l.empty) continue;
2281
+ const d = n.lineAt(l.from), m = n.lineAt(l.to);
2282
+ for (let u = d.number; u <= m.number; u++) {
2283
+ const a = n.line(u);
2284
+ if (u === m.number && l.to === a.from) continue;
2285
+ const g = l.from <= a.from, x = a.from + a.length === n.length ? l.to >= a.to : l.to > a.to;
2286
+ if (g && x)
2287
+ try {
2288
+ let E = e.domAtPos(a.from).node;
2289
+ for (; E && E !== e.contentDOM && !(E.nodeType === 1 && E.classList.contains("cm-line")); )
2290
+ E = E.parentElement;
2291
+ if (E && E.classList.contains("cm-line")) {
2292
+ const L = E, f = L.getBoundingClientRect(), h = window.getComputedStyle(L), p = parseFloat(h.paddingLeft) || 0, y = parseFloat(h.textIndent) || 0, T = p + y, I = f.left + T - s.left + c, M = f.top - s.top + r, O = f.height;
2293
+ o.push({
2294
+ type: "full",
2295
+ top: M,
2296
+ height: O,
2297
+ left: I,
2298
+ width: 0
2299
+ });
2300
+ }
2301
+ } catch {
2302
+ }
2303
+ else
2304
+ try {
2305
+ const b = Math.max(l.from, a.from), E = Math.min(l.to, a.to), L = e.domAtPos(b), f = e.domAtPos(E), h = document.createRange();
2306
+ h.setStart(L.node, L.offset), h.setEnd(f.node, f.offset);
2307
+ const p = h.getClientRects();
2308
+ for (let y = 0; y < p.length; y++) {
2309
+ const T = i(p[y]);
2310
+ o.push({ type: "partial", top: T.top, height: T.height, left: T.left, width: T.width });
2311
+ }
2312
+ } catch {
2313
+ }
2314
+ }
2315
+ }
2316
+ } catch (s) {
2317
+ return console.error("[FullLineSelection] readSelections failed:", {
2318
+ error: s instanceof Error ? s.message : s,
2319
+ selectionRanges: t.ranges.length,
2320
+ mainRange: { from: t.main.from, to: t.main.to },
2321
+ docLength: n.length
2322
+ }), [];
2323
+ }
2324
+ return o;
2325
+ }
2326
+ drawSelections(e) {
2327
+ this.layer.textContent = "";
2328
+ for (const t of e) {
2329
+ const n = document.createElement("div");
2330
+ n.className = "cm-custom-selection-rect", t.type === "full" ? (n.classList.add("cm-full-line-selection"), n.style.top = `${t.top}px`, n.style.height = `${t.height}px`, n.style.left = `${t.left}px`, n.style.right = "0") : (n.classList.add("cm-partial-selection"), n.style.top = `${t.top}px`, n.style.height = `${t.height}px`, n.style.left = `${t.left}px`, n.style.width = `${t.width}px`), this.layer.appendChild(n);
2331
+ }
2332
+ }
2333
+ }
2334
+ ), oe = /[\w\-а-яёА-ЯЁ_]/;
2335
+ function fe(e, t) {
2336
+ const o = e.state.doc.lineAt(t), s = o.text, c = Math.max(0, Math.min(t - o.from, o.length));
2337
+ let r = c, i = c;
2338
+ for (; r > 0 && oe.test(s[r - 1]); ) r--;
2339
+ for (; i < s.length && oe.test(s[i]); ) i++;
2340
+ return {
2341
+ start: o.from + r,
2342
+ end: o.from + i
2343
+ };
2344
+ }
2345
+ function se(e, t, n) {
2346
+ const o = fe(e, t);
2347
+ return n === "left" ? o.start : o.end;
2348
+ }
2349
+ const _n = B.mouseSelectionStyle.of((e, t) => {
2350
+ if (t.detail !== 2) return null;
2351
+ const n = e.posAtCoords({ x: t.clientX, y: t.clientY });
2352
+ if (n === null) return null;
2353
+ const o = fe(e, n);
2354
+ if (o.start === o.end) return null;
2355
+ const s = o.start, r = t.metaKey || t.ctrlKey ? e.state.selection.ranges.slice() : [];
2356
+ return {
2357
+ get(i, l, d) {
2358
+ const m = e.posAtCoords({ x: i.clientX, y: i.clientY });
2359
+ let u;
2360
+ if (m === null)
2361
+ u = X.range(s, o.end);
2362
+ else if (m < o.start) {
2363
+ const a = se(e, m, "left");
2364
+ u = X.range(o.end, a);
2365
+ } else if (m > o.end) {
2366
+ const a = se(e, m, "right");
2367
+ u = X.range(s, a);
2368
+ } else
2369
+ u = X.range(s, o.end);
2370
+ return r.length > 0 ? X.create([...r, u]) : X.create([u]);
2371
+ },
2372
+ update(i) {
2373
+ return !1;
2374
+ }
2375
+ };
2376
+ });
2377
+ function ut(e, t) {
2378
+ let n = 0;
2379
+ for (let o = 0; o < e.length; o++) {
2380
+ const s = e.charCodeAt(o);
2381
+ if (s === 9) n += t - n % t;
2382
+ else if (s === 32) n++;
2383
+ else break;
2384
+ }
2385
+ return n;
2386
+ }
2387
+ function St(e, t, n) {
2388
+ const o = e.line(t), s = ut(o.text, n);
2389
+ let c = t;
2390
+ for (let r = t + 1; r <= e.lines; r++) {
2391
+ const i = e.line(r).text;
2392
+ if (i.trim() === "") continue;
2393
+ if (ut(i, n) > s)
2394
+ c = r;
2395
+ else
2396
+ break;
2397
+ }
2398
+ return { startLine: t, endLine: c };
2399
+ }
2400
+ function Un(e, t, n, o) {
2401
+ if (t <= 1) return null;
2402
+ const s = t - 1;
2403
+ for (let c = t - 1; c >= 1; c--) {
2404
+ const r = e.line(c).text;
2405
+ if (r.trim() === "") continue;
2406
+ const i = ut(r, o);
2407
+ if (i === n)
2408
+ return { startLine: c, endLine: s };
2409
+ if (i > n)
2410
+ continue;
2411
+ return null;
2412
+ }
2413
+ return null;
2414
+ }
2415
+ function ct(e, t, n, o, s) {
2416
+ const c = e.state.doc, r = c.line(t.startLine).from, i = c.line(t.endLine).to, l = c.line(n.startLine).from, d = c.line(n.endLine).to, m = c.sliceString(r, i), a = c.sliceString(l, d) + `
2417
+ ` + m;
2418
+ let g;
2419
+ if (s === "lower") {
2420
+ const h = o - l;
2421
+ g = r + h;
2422
+ } else {
2423
+ const h = d - l, p = o - r;
2424
+ g = r + h + 1 + p;
2425
+ }
2426
+ const C = e.state.doc.length - (d - r) + a.length;
2427
+ g = Math.max(0, Math.min(g, C - 1));
2428
+ const x = e.scrollDOM.scrollTop, b = e.lineBlockAt(c.line(t.startLine).from).top, E = e.lineBlockAt(c.line(n.startLine).from).top, L = E - b;
2429
+ let f;
2430
+ if (n.endLine < c.lines)
2431
+ f = e.lineBlockAt(c.line(n.endLine + 1).from).top - E;
2432
+ else {
2433
+ const h = e.lineBlockAt(c.line(n.endLine).from);
2434
+ f = h.top + h.height - E;
2435
+ }
2436
+ e.dispatch({
2437
+ changes: { from: r, to: d, insert: a },
2438
+ selection: X.cursor(g)
2439
+ }), Kn(e, r, d), s === "lower" ? e.scrollDOM.scrollTop = x - L : e.scrollDOM.scrollTop = x + f;
2440
+ }
2441
+ function Kn(e, t, n) {
2442
+ const o = e.state.doc, s = o.lineAt(t).number, c = o.lineAt(Math.min(n, o.length)).number, r = [];
2443
+ for (let i = s; i <= c; i++) {
2444
+ const l = o.line(i);
2445
+ if (!l.text.trim().startsWith("^^")) continue;
2446
+ let d = !1;
2447
+ if (j(e.state).between(l.from, l.to, () => {
2448
+ d = !0;
2449
+ }), !d) {
2450
+ const m = V(e.state, l.from, l.to);
2451
+ m && m.to - m.from > 2 && r.push(Q.of(m));
2452
+ }
2453
+ }
2454
+ r.length > 0 && e.dispatch({ effects: r });
2455
+ }
2456
+ function Yn(e) {
2457
+ const { state: t } = e, n = t.doc, o = t.tabSize, s = t.selection.main.head, c = n.lineAt(s), r = St(n, c.number, o), i = ut(c.text, o);
2458
+ if (r.startLine <= 1)
2459
+ return !1;
2460
+ const l = n.line(r.startLine - 1);
2461
+ if (l.text.trim() === "")
2462
+ return ct(
2463
+ e,
2464
+ { startLine: l.number, endLine: l.number },
2465
+ r,
2466
+ s,
2467
+ "lower"
2468
+ ), !0;
2469
+ if (ut(l.text, o) < i)
2470
+ return ct(
2471
+ e,
2472
+ { startLine: l.number, endLine: l.number },
2473
+ r,
2474
+ s,
2475
+ "lower"
2476
+ ), !0;
2477
+ const m = Un(n, r.startLine, i, o);
2478
+ return m ? (ct(e, m, r, s, "lower"), !0) : (ct(
2479
+ e,
2480
+ { startLine: l.number, endLine: l.number },
2481
+ r,
2482
+ s,
2483
+ "lower"
2484
+ ), !0);
2485
+ }
2486
+ function qn(e) {
2487
+ const { state: t } = e, n = t.doc, o = t.tabSize, s = t.selection.main.head, c = n.lineAt(s), r = St(n, c.number, o), i = ut(c.text, o);
2488
+ if (r.endLine >= n.lines)
2489
+ return !1;
2490
+ const l = n.line(r.endLine + 1);
2491
+ if (l.text.trim() === "")
2492
+ return ct(
2493
+ e,
2494
+ r,
2495
+ { startLine: l.number, endLine: l.number },
2496
+ s,
2497
+ "upper"
2498
+ ), !0;
2499
+ const d = ut(l.text, o);
2500
+ if (d < i)
2501
+ return ct(
2502
+ e,
2503
+ r,
2504
+ { startLine: l.number, endLine: l.number },
2505
+ s,
2506
+ "upper"
2507
+ ), !0;
2508
+ if (d === i) {
2509
+ const m = St(n, l.number, o);
2510
+ return ct(e, r, m, s, "upper"), !0;
2511
+ }
2512
+ return ct(
2513
+ e,
2514
+ r,
2515
+ { startLine: l.number, endLine: l.number },
2516
+ s,
2517
+ "upper"
2518
+ ), !0;
2519
+ }
2520
+ function lt(e, t) {
2521
+ let n = 0;
2522
+ for (let o = 0; o < e.length; o++)
2523
+ if (e.charCodeAt(o) === 9) n += t - n % t;
2524
+ else if (e.charCodeAt(o) === 32) n++;
2525
+ else break;
2526
+ return n;
2527
+ }
2528
+ function Tt(e) {
2529
+ const t = e.facet(ie);
2530
+ return t === " " ? e.tabSize : t.length;
2531
+ }
2532
+ function kt(e) {
2533
+ return " ".repeat(e);
2534
+ }
2535
+ const re = /^\s*(>>|\^\^)/, Xn = {
2536
+ key: "Tab",
2537
+ run: (e) => {
2538
+ const { state: t } = e, n = Tt(t), o = t.selection.main;
2539
+ if (o.empty) {
2540
+ const c = t.doc.lineAt(o.head);
2541
+ if (re.test(c.text))
2542
+ return ue(e);
2543
+ }
2544
+ const s = t.changeByRange((c) => {
2545
+ const r = [];
2546
+ let i = -1;
2547
+ for (let d = c.from; d <= c.to; ) {
2548
+ const m = t.doc.lineAt(d);
2549
+ if (m.number > i && (c.empty || c.to > m.from)) {
2550
+ i = m.number;
2551
+ const u = /^\s*/.exec(m.text)[0], a = lt(u, t.tabSize), g = (Math.floor(a / n) + 1) * n;
2552
+ r.push({
2553
+ from: m.from,
2554
+ to: m.from + u.length,
2555
+ insert: kt(g)
2556
+ });
2557
+ }
2558
+ d = m.to + 1;
2559
+ }
2560
+ const l = t.changes(r);
2561
+ return {
2562
+ changes: r,
2563
+ range: X.range(
2564
+ l.mapPos(c.anchor, 1),
2565
+ l.mapPos(c.head, 1)
2566
+ )
2567
+ };
2568
+ });
2569
+ return e.dispatch(s, { scrollIntoView: !0, userEvent: "input.indent" }), !0;
2570
+ },
2571
+ shift: (e) => {
2572
+ const { state: t } = e, n = Tt(t), o = t.selection.main;
2573
+ if (o.empty) {
2574
+ const c = t.doc.lineAt(o.head);
2575
+ if (re.test(c.text))
2576
+ return he(e);
2577
+ }
2578
+ const s = t.changeByRange((c) => {
2579
+ const r = [];
2580
+ let i = -1;
2581
+ for (let d = c.from; d <= c.to; ) {
2582
+ const m = t.doc.lineAt(d);
2583
+ if (m.number > i && (c.empty || c.to > m.from)) {
2584
+ i = m.number;
2585
+ const u = /^\s*/.exec(m.text)[0], a = lt(u, t.tabSize);
2586
+ if (a > 0) {
2587
+ const g = Math.max(0, Math.floor((a - 1) / n) * n);
2588
+ r.push({
2589
+ from: m.from,
2590
+ to: m.from + u.length,
2591
+ insert: kt(g)
2592
+ });
2593
+ }
2594
+ }
2595
+ d = m.to + 1;
2596
+ }
2597
+ const l = t.changes(r);
2598
+ return {
2599
+ changes: r,
2600
+ range: X.range(
2601
+ l.mapPos(c.anchor, 1),
2602
+ l.mapPos(c.head, 1)
2603
+ )
2604
+ };
2605
+ });
2606
+ return e.dispatch(s, { scrollIntoView: !0, userEvent: "input.indent" }), !0;
2607
+ },
2608
+ preventDefault: !0
2609
+ };
2610
+ function ue(e) {
2611
+ const { state: t } = e, n = Tt(t), o = t.tabSize, s = t.selection.main;
2612
+ if (s.empty) {
2613
+ const d = t.doc.lineAt(s.head), m = St(t.doc, d.number, o), u = /^\s*/.exec(d.text)[0], a = lt(u, o), C = (Math.floor(a / n) + 1) * n - a, x = [];
2614
+ for (let E = m.startLine; E <= m.endLine; E++) {
2615
+ const L = t.doc.line(E);
2616
+ if (L.text.trim() === "") continue;
2617
+ const f = /^\s*/.exec(L.text)[0], h = lt(f, o);
2618
+ x.push({
2619
+ from: L.from,
2620
+ to: L.from + f.length,
2621
+ insert: kt(h + C)
2622
+ });
2623
+ }
2624
+ if (x.length === 0) return !0;
2625
+ const b = t.changes(x);
2626
+ return e.dispatch({
2627
+ changes: x,
2628
+ selection: X.cursor(b.mapPos(s.head, 1)),
2629
+ scrollIntoView: !0,
2630
+ userEvent: "input.indent"
2631
+ }), !0;
2632
+ }
2633
+ const c = t.doc.lineAt(s.from).number, r = t.doc.lineAt(s.to).number, i = [];
2634
+ for (let d = c; d <= r; d++) {
2635
+ const m = t.doc.line(d);
2636
+ if (m.text.trim() === "") continue;
2637
+ const u = /^\s*/.exec(m.text)[0], a = lt(u, o), g = (Math.floor(a / n) + 1) * n;
2638
+ i.push({
2639
+ from: m.from,
2640
+ to: m.from + u.length,
2641
+ insert: kt(g)
2642
+ });
2643
+ }
2644
+ if (i.length === 0) return !0;
2645
+ const l = t.changes(i);
2646
+ return e.dispatch({
2647
+ changes: i,
2648
+ selection: X.range(l.mapPos(s.anchor, 1), l.mapPos(s.head, 1)),
2649
+ scrollIntoView: !0,
2650
+ userEvent: "input.indent"
2651
+ }), !0;
2652
+ }
2653
+ function he(e) {
2654
+ const { state: t } = e, n = Tt(t), o = t.tabSize, s = t.selection.main;
2655
+ if (s.empty) {
2656
+ const d = t.doc.lineAt(s.head), m = St(t.doc, d.number, o), u = /^\s*/.exec(d.text)[0], a = lt(u, o);
2657
+ if (a === 0) return !0;
2658
+ const C = Math.max(0, Math.floor((a - 1) / n) * n) - a, x = [];
2659
+ for (let E = m.startLine; E <= m.endLine; E++) {
2660
+ const L = t.doc.line(E);
2661
+ if (L.text.trim() === "") continue;
2662
+ const f = /^\s*/.exec(L.text)[0], h = lt(f, o), p = Math.max(0, h + C);
2663
+ p !== h && x.push({
2664
+ from: L.from,
2665
+ to: L.from + f.length,
2666
+ insert: kt(p)
2667
+ });
2668
+ }
2669
+ if (x.length === 0) return !0;
2670
+ const b = t.changes(x);
2671
+ return e.dispatch({
2672
+ changes: x,
2673
+ selection: X.cursor(b.mapPos(s.head, 1)),
2674
+ scrollIntoView: !0,
2675
+ userEvent: "input.indent"
2676
+ }), !0;
2677
+ }
2678
+ const c = t.doc.lineAt(s.from).number, r = t.doc.lineAt(s.to).number, i = [];
2679
+ for (let d = c; d <= r; d++) {
2680
+ const m = t.doc.line(d);
2681
+ if (m.text.trim() === "") continue;
2682
+ const u = /^\s*/.exec(m.text)[0], a = lt(u, o);
2683
+ if (a > 0) {
2684
+ const g = Math.max(0, Math.floor((a - 1) / n) * n);
2685
+ i.push({
2686
+ from: m.from,
2687
+ to: m.from + u.length,
2688
+ insert: kt(g)
2689
+ });
2690
+ }
2691
+ }
2692
+ if (i.length === 0) return !0;
2693
+ const l = t.changes(i);
2694
+ return e.dispatch({
2695
+ changes: i,
2696
+ selection: X.range(l.mapPos(s.anchor, 1), l.mapPos(s.head, 1)),
2697
+ scrollIntoView: !0,
2698
+ userEvent: "input.indent"
2699
+ }), !0;
2700
+ }
2701
+ function Vn(e) {
2702
+ const t = new Intl.Segmenter(void 0, { granularity: "grapheme" });
2703
+ return dt.fromClass(class {
2704
+ constructor(n) {
2705
+ H(this, "tooltip", null);
2706
+ H(this, "currentEmoji", null);
2707
+ H(this, "lastMouseX", 0);
2708
+ H(this, "lastMouseY", 0);
2709
+ // Dynamic <style> tag for cursor override (CM6 resets both .cm-content inline styles
2710
+ // AND .cm-editor className on every update cycle, so neither approach survives)
2711
+ H(this, "cursorStyleEl", null);
2712
+ // Track Meta key at document level (contentDOM keydown requires focus)
2713
+ H(this, "metaDown", !1);
2714
+ H(this, "_onKeyDown");
2715
+ H(this, "_onKeyUp");
2716
+ // Cache: emoji → description (rebuilt when shortcuts change)
2717
+ H(this, "emojiMap", /* @__PURE__ */ new Map());
2718
+ H(this, "lastShortcutsRef", null);
2719
+ this.view = n, this._onKeyDown = (o) => {
2720
+ o.key === "Meta" && (this.metaDown = !0, this.onMetaPress());
2721
+ }, this._onKeyUp = (o) => {
2722
+ o.key === "Meta" && (this.metaDown = !1, this.hideTooltip());
2723
+ }, document.addEventListener("keydown", this._onKeyDown), document.addEventListener("keyup", this._onKeyUp);
2724
+ }
2725
+ getEmojiMap() {
2726
+ const n = e.getEmojiShortcuts();
2727
+ if (n !== this.lastShortcutsRef) {
2728
+ this.lastShortcutsRef = n, this.emojiMap = /* @__PURE__ */ new Map();
2729
+ for (const o of n)
2730
+ o.description && this.emojiMap.set(o.emoji, o.description);
2731
+ }
2732
+ return this.emojiMap;
2733
+ }
2734
+ /** Called when Meta is pressed — show tooltip if mouse is already over an emoji */
2735
+ onMetaPress() {
2736
+ const n = this.view.posAtCoords({ x: this.lastMouseX, y: this.lastMouseY });
2737
+ if (n === null) return;
2738
+ const o = this.matchEmojiAt(this.view, n, this.lastMouseX);
2739
+ o && (this.currentEmoji = o.emoji, this.showTooltip(o.description, this.lastMouseX, this.lastMouseY));
2740
+ }
2741
+ showTooltip(n, o, s) {
2742
+ this.hideTooltip();
2743
+ const c = document.createElement("div");
2744
+ c.className = "cm-emoji-tooltip", c.textContent = n, c.style.left = `${o + 12}px`, c.style.top = `${s + 12}px`, document.body.appendChild(c), requestAnimationFrame(() => {
2745
+ if (!c.isConnected) return;
2746
+ const r = c.getBoundingClientRect();
2747
+ r.right > window.innerWidth && (c.style.left = `${o - r.width - 4}px`), r.bottom > window.innerHeight && (c.style.top = `${s - r.height - 4}px`);
2748
+ }), this.tooltip = c;
2749
+ }
2750
+ hideTooltip() {
2751
+ this.tooltip && (this.tooltip.remove(), this.tooltip = null), this.currentEmoji = null;
2752
+ }
2753
+ setCursorHover(n) {
2754
+ n ? this.cursorStyleEl || (this.cursorStyleEl = document.createElement("style"), this.cursorStyleEl.textContent = ".cm-content { cursor: default !important; }", document.head.appendChild(this.cursorStyleEl)) : this.cursorStyleEl && (this.cursorStyleEl.remove(), this.cursorStyleEl = null);
2755
+ }
2756
+ /**
2757
+ * Extract the grapheme cluster at document position `pos` and check if it's an emoji
2758
+ * from the shortcuts map. Returns the description or null.
2759
+ */
2760
+ matchEmojiAt(n, o, s) {
2761
+ const c = this.getEmojiMap();
2762
+ if (c.size === 0) return null;
2763
+ const r = n.state.doc, i = Math.max(0, o - 8), l = Math.min(r.length, o + 12), d = r.sliceString(i, l);
2764
+ for (const { segment: m, index: u } of t.segment(d)) {
2765
+ const a = i + u, g = a + m.length;
2766
+ if (o >= a && o <= g) {
2767
+ const C = c.get(m);
2768
+ if (C) {
2769
+ const x = n.coordsAtPos(a), b = n.coordsAtPos(g, -1);
2770
+ if (x && b && s >= x.left && s <= b.right)
2771
+ return { emoji: m, description: C };
2772
+ }
2773
+ }
2774
+ }
2775
+ return null;
2776
+ }
2777
+ destroy() {
2778
+ this.cursorStyleEl && (this.cursorStyleEl.remove(), this.cursorStyleEl = null), this.hideTooltip(), document.removeEventListener("keydown", this._onKeyDown), document.removeEventListener("keyup", this._onKeyUp);
2779
+ }
2780
+ }, {
2781
+ eventHandlers: {
2782
+ mousemove(n, o) {
2783
+ this.lastMouseX = n.clientX, this.lastMouseY = n.clientY;
2784
+ const s = o.posAtCoords({ x: n.clientX, y: n.clientY });
2785
+ if (s === null) {
2786
+ this.setCursorHover(!1), this.hideTooltip();
2787
+ return;
2788
+ }
2789
+ const c = this.matchEmojiAt(o, s, this.lastMouseX);
2790
+ if (this.setCursorHover(!!c), !(n.metaKey || this.metaDown)) {
2791
+ this.tooltip && this.hideTooltip();
2792
+ return;
2793
+ }
2794
+ c ? this.currentEmoji !== c.emoji && (this.currentEmoji = c.emoji, this.showTooltip(c.description, n.clientX, n.clientY)) : this.hideTooltip();
2795
+ },
2796
+ mouseleave() {
2797
+ this.setCursorHover(!1), this.hideTooltip();
2798
+ }
2799
+ }
2800
+ });
2801
+ }
2802
+ const Gn = [];
2803
+ function io({
2804
+ content: e,
2805
+ onChange: t,
2806
+ fontSize: n = 14,
2807
+ wordWrap: o = !0,
2808
+ onImagePaste: s,
2809
+ resolveImageUrl: c,
2810
+ foldStateKey: r,
2811
+ onEditorView: i,
2812
+ initialScrollTop: l = 0,
2813
+ resolveInclude: d,
2814
+ onOpenInclude: m,
2815
+ onBlur: u,
2816
+ showLineNumbers: a = !0,
2817
+ compact: g = !1,
2818
+ readOnly: C = !1,
2819
+ contentPaddingX: x = 16,
2820
+ contentPaddingY: b = 16,
2821
+ includeOffsets: E,
2822
+ onGenerateTitle: L,
2823
+ emojiShortcuts: f
2824
+ }) {
2825
+ const h = E ?? Gn, p = Z(null), y = Z(null), T = Z(t), I = Z(s), M = Z(c), O = Z(i), _ = Z(d), z = Z(m), Y = Z(u), F = Z(L), N = Z(f), D = Z(l);
2826
+ return tt(() => {
2827
+ T.current = t;
2828
+ }, [t]), tt(() => {
2829
+ I.current = s;
2830
+ }, [s]), tt(() => {
2831
+ M.current = c;
2832
+ }, [c]), tt(() => {
2833
+ O.current = i;
2834
+ }, [i]), tt(() => {
2835
+ _.current = d;
2836
+ }, [d]), tt(() => {
2837
+ z.current = m;
2838
+ }, [m]), tt(() => {
2839
+ Y.current = u;
2840
+ }, [u]), tt(() => {
2841
+ F.current = L;
2842
+ }, [L]), tt(() => {
2843
+ N.current = f;
2844
+ }, [f]), tt(() => {
2845
+ D.current = l;
2846
+ }, [l]), tt(() => {
2847
+ var K;
2848
+ if (!p.current) return;
2849
+ const A = [
2850
+ { key: "Mod-d", run: $e, preventDefault: !0 },
2851
+ { key: "Mod-Shift-l", run: He, preventDefault: !0 },
2852
+ // Multi-cursor: Ctrl+Shift+Up/Down (VS Code style)
2853
+ { key: "Ctrl-Shift-ArrowUp", run: Rt, preventDefault: !0 },
2854
+ { key: "Ctrl-Shift-ArrowDown", run: jt, preventDefault: !0 },
2855
+ // Also Cmd+Alt+Up/Down (default CodeMirror binding)
2856
+ { key: "Mod-Alt-ArrowUp", run: Rt, preventDefault: !0 },
2857
+ { key: "Mod-Alt-ArrowDown", run: jt, preventDefault: !0 },
2858
+ // Move block up/down: Cmd+Up/Down (block-aware, moves line + deeper children)
2859
+ { key: "Mod-ArrowUp", run: Yn, preventDefault: !0 },
2860
+ { key: "Mod-ArrowDown", run: qn, preventDefault: !0 },
2861
+ // Copy line up/down: Alt+Shift+Up/Down (VS Code style)
2862
+ { key: "Alt-Shift-ArrowUp", run: Ie, preventDefault: !0 },
2863
+ { key: "Alt-Shift-ArrowDown", run: De, preventDefault: !0 },
2864
+ // Block-aware indent/outdent: Cmd+]/[ (line + deeper children)
2865
+ { key: "Mod-]", run: ue, preventDefault: !0 },
2866
+ { key: "Mod-[", run: he, preventDefault: !0 }
2867
+ ], P = B.domEventHandlers({
2868
+ mousedown(k, S) {
2869
+ const J = window.__foldDiag || {};
2870
+ if (J.pendingFold > 0 || J.pendingUnfold > 0) {
2871
+ const nt = [];
2872
+ j(S.state).between(0, S.state.doc.length, (mt, Ft) => {
2873
+ nt.push({ from: mt, to: Ft });
2874
+ }), console.warn("[Fold:mousedown] PENDING OPS AT CLICK", {
2875
+ x: k.clientX,
2876
+ y: k.clientY,
2877
+ folds: nt.length,
2878
+ foldRanges: nt.slice(0, 5),
2879
+ pending: { ...J },
2880
+ docLen: S.state.doc.length
2881
+ });
2882
+ }
2883
+ },
2884
+ blur(k, S) {
2885
+ var J;
2886
+ console.log("[Editor] blur", { scrollTop: S.scrollDOM.scrollTop, foldStateKey: r }), (J = Y.current) == null || J.call(Y);
2887
+ },
2888
+ focus(k, S) {
2889
+ console.log("[Editor] focus", { scrollTop: S.scrollDOM.scrollTop, foldStateKey: r });
2890
+ }
2891
+ }), R = Wn(), et = it.high(xt.of([
2892
+ {
2893
+ key: "Mod-^",
2894
+ run: (k) => (Ot(k, ">> "), !0)
2895
+ }
2896
+ ])), q = it.highest(B.domEventHandlers({
2897
+ keydown(k, S) {
2898
+ if (!(k.metaKey || k.ctrlKey) || k.key !== "/") return !1;
2899
+ k.preventDefault(), k.stopPropagation();
2900
+ const nt = S.state.selection;
2901
+ return document.querySelector("[data-command-palette]") ? (pt(), S.focus(), !0) : (An(S, nt), !0);
2902
+ }
2903
+ })), W = it.highest(B.domEventHandlers({
2904
+ keydown(k, S) {
2905
+ if ((k.metaKey || k.ctrlKey) && !k.shiftKey && (k.key === "8" || k.code === "Digit8")) {
2906
+ k.preventDefault();
2907
+ const J = S.state.selection.main.head;
2908
+ return S.dispatch({ selection: { anchor: J } }), rt(S, "*"), !0;
2909
+ }
2910
+ return !1;
2911
+ }
2912
+ })), U = [
2913
+ // Track selection for Cmd+/ palette (before any handlers)
2914
+ xn,
2915
+ // DOM event handlers (blur для автосохранения)
2916
+ P,
2917
+ // Cmd+. fold/unfold parent, Cmd+^ toggle prefix
2918
+ R,
2919
+ et,
2920
+ // Cmd+/ для command palette
2921
+ q,
2922
+ // Cmd+* для wrap with stars
2923
+ W,
2924
+ we(),
2925
+ // Enable multiple cursors (Cmd+Click, Ctrl+Shift+Up/Down)
2926
+ vt.allowMultipleSelections.of(!0),
2927
+ // Draw cursors and selections (required for multi-cursor visibility)
2928
+ Le(),
2929
+ // 4 spaces for indent
2930
+ ie.of(" "),
2931
+ // Clipboard keymap BEFORE defaultKeymap to intercept Mod-c/v/x
2932
+ cn({
2933
+ onImagePaste: (k) => {
2934
+ var S;
2935
+ return ((S = I.current) == null ? void 0 : S.call(I, k)) ?? Promise.resolve(null);
2936
+ },
2937
+ onGenerateTitle: (k) => F.current ? F.current(k) : Promise.resolve("paste text")
2938
+ }),
2939
+ // Track cursor movement for AI Paste indicator
2940
+ rn,
2941
+ // Tab/Shift+Tab with VS Code-style tab stop snapping
2942
+ xt.of([Xn, ...Re, ...A, ...Te, ...Pe, { key: "Mod-y", run: Fe, preventDefault: !0 }]),
2943
+ je(n, x, b),
2944
+ // Collapsible sections & Highlighting
2945
+ Ne,
2946
+ // headerClickPlugin убран — сворачивание только через gutter
2947
+ We({
2948
+ placeholderDOM: () => {
2949
+ const k = document.createElement("span");
2950
+ return k.style.display = "none", k;
2951
+ }
2952
+ }),
2953
+ // collapsibleGutter убран — используем inline стрелки вместо gutter
2954
+ // Inline стрелки с учётом отступа
2955
+ Fn,
2956
+ vn(),
2957
+ // Enter at end of folded section → insert after fold
2958
+ $n(),
2959
+ // Backspace at line start after folded section → move to header end
2960
+ Hn(),
2961
+ // Цветные indent guides для collapsible секций
2962
+ Bn,
2963
+ // Selection на всю ширину строки
2964
+ zn,
2965
+ Je({}),
2966
+ // Fix: click at visual line end with hidden markup → snap to actual line.to
2967
+ Qe(),
2968
+ // StateField for images (supports block widgets)
2969
+ tn({
2970
+ resolveImageUrl: (k) => {
2971
+ var S;
2972
+ return ((S = M.current) == null ? void 0 : S.call(M, k)) ?? k;
2973
+ }
2974
+ }),
2975
+ ...a ? [me(h), Ee()] : [],
2976
+ Me(),
2977
+ ve(),
2978
+ B.updateListener.of((k) => {
2979
+ k.docChanged && T.current(k.state.doc.toString()), k.transactions.some((S) => un(S.effects)) && mn(r, k.view);
2980
+ }),
2981
+ ...C ? [vt.readOnly.of(!0), B.editable.of(!1)] : [],
2982
+ ...g ? [] : [B.contentAttributes.of({ style: "padding-bottom: calc(100vh - 80px)" })],
2983
+ // Wrap selected text when typing * ` _ etc.
2984
+ ln(),
2985
+ // Image paste handler
2986
+ an({
2987
+ onImagePaste: (k) => {
2988
+ var S;
2989
+ return ((S = I.current) == null ? void 0 : S.call(I, k)) ?? Promise.resolve(null);
2990
+ }
2991
+ }),
2992
+ // Include links (file transclusion)
2993
+ pn({
2994
+ onOpenFile: (k) => {
2995
+ var S;
2996
+ return (S = z.current) == null ? void 0 : S.call(z, k);
2997
+ }
2998
+ }),
2999
+ // Cmd+Click handler for include links
3000
+ gn({
3001
+ onOpenFile: (k) => {
3002
+ var S;
3003
+ return (S = z.current) == null ? void 0 : S.call(z, k);
3004
+ }
3005
+ }),
3006
+ // Context menu
3007
+ Sn({
3008
+ resolveInclude: (k) => {
3009
+ var S;
3010
+ return ((S = _.current) == null ? void 0 : S.call(_, k)) ?? Promise.reject("No resolver");
3011
+ },
3012
+ getEmojiShortcuts: () => N.current ?? []
3013
+ }),
3014
+ // Cmd+Hover on emoji in text → show tooltip with description
3015
+ Vn({
3016
+ getEmojiShortcuts: () => N.current ?? []
3017
+ }),
3018
+ // Stable word selection (fix anchor/head flipping on dblclick + drag)
3019
+ _n
3020
+ ];
3021
+ o && (U.push(B.lineWrapping), U.push(wn));
3022
+ const v = vt.create({
3023
+ doc: e,
3024
+ extensions: U
3025
+ }), $ = new B({
3026
+ state: v,
3027
+ parent: p.current
3028
+ });
3029
+ y.current = $, (K = O.current) == null || K.call(O, $);
3030
+ const G = (k) => {
3031
+ var S, J;
3032
+ if ((S = k.message) != null && S.includes("posBefore") || (J = k.message) != null && J.includes("Invalid child")) {
3033
+ const nt = [];
3034
+ try {
3035
+ j($.state).between(0, $.state.doc.length, (mt, Ft) => {
3036
+ const pe = $.state.doc.lineAt(mt);
3037
+ nt.push({ from: mt, to: Ft, headerText: pe.text.slice(0, 50) });
3038
+ });
3039
+ } catch {
3040
+ }
3041
+ console.error("[Fold:ERROR] posBefore — active folds:", nt, "docLen:", $.state.doc.length);
3042
+ }
3043
+ };
3044
+ return window.addEventListener("error", G), requestAnimationFrame(() => {
3045
+ fn(r, $), requestAnimationFrame(() => {
3046
+ const k = D.current;
3047
+ if (k > 0) {
3048
+ $.scrollDOM.scrollTop = k;
3049
+ const S = $.scrollDOM.scrollTop;
3050
+ console.log("[Editor] scroll restored:", { requested: k, actual: S, scrollHeight: $.scrollDOM.scrollHeight, foldStateKey: r });
3051
+ }
3052
+ });
3053
+ }), () => {
3054
+ var k;
3055
+ window.removeEventListener("error", G), console.log("[Editor] DESTROYING editor", { foldStateKey: r, scrollTop: $.scrollDOM.scrollTop }), $.destroy(), (k = O.current) == null || k.call(O, null);
3056
+ };
3057
+ }, [o, n, r, h, a, g, C, x, b]), tt(() => {
3058
+ if (y.current) {
3059
+ const A = y.current.state.doc.toString();
3060
+ A !== e && (console.warn("[MarkdownEditor] External content sync:", {
3061
+ currentLength: A.length,
3062
+ newLength: e.length,
3063
+ foldStateKey: r
3064
+ }), y.current.dispatch({
3065
+ changes: {
3066
+ from: 0,
3067
+ to: A.length,
3068
+ insert: e
3069
+ }
3070
+ }));
3071
+ }
3072
+ }, [e]), /* @__PURE__ */ xe("div", { ref: p, className: "markdown-editor" });
3073
+ }
3074
+ export {
3075
+ ze as BulletWidget,
3076
+ co as CollapsibleHeaderWidget,
3077
+ st as HiddenWidget,
3078
+ ro as HorizontalRuleWidget,
3079
+ Be as ImageWidget,
3080
+ io as MarkdownEditor,
3081
+ Ne as collapsibleFoldService,
3082
+ cn as createClipboardKeymap,
3083
+ je as createDarkTheme,
3084
+ an as createImagePasteHandler,
3085
+ Je as createMarkdownSyntaxPlugin,
3086
+ ln as createWrapSelectionHandler,
3087
+ io as default,
3088
+ mo as foldEffect,
3089
+ un as hasFoldEffects,
3090
+ fn as loadFoldState,
3091
+ mn as saveFoldState,
3092
+ fo as unfoldEffect
3093
+ };
3094
+ //# sourceMappingURL=index.js.map