open-edit 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.
@@ -0,0 +1,3333 @@
1
+ //#region src/core/history.ts
2
+ var e = 200, t = class {
3
+ undoStack = [];
4
+ redoStack = [];
5
+ _paused = !1;
6
+ push(t) {
7
+ this._paused || (this.undoStack.push(n(t)), this.undoStack.length > e && this.undoStack.shift(), this.redoStack = []);
8
+ }
9
+ undo(e) {
10
+ return this.undoStack.length === 0 ? null : (this.redoStack.push(n(e)), this.undoStack.pop());
11
+ }
12
+ redo(e) {
13
+ return this.redoStack.length === 0 ? null : (this.undoStack.push(n(e)), this.redoStack.pop());
14
+ }
15
+ canUndo() {
16
+ return this.undoStack.length > 0;
17
+ }
18
+ canRedo() {
19
+ return this.redoStack.length > 0;
20
+ }
21
+ pause() {
22
+ this._paused = !0;
23
+ }
24
+ resume() {
25
+ this._paused = !1;
26
+ }
27
+ clear() {
28
+ this.undoStack = [], this.redoStack = [];
29
+ }
30
+ };
31
+ function n(e) {
32
+ return structuredClone(e);
33
+ }
34
+ //#endregion
35
+ //#region src/core/model.ts
36
+ function r(e) {
37
+ return { children: e ?? [i()] };
38
+ }
39
+ function i(e = "") {
40
+ return {
41
+ type: "paragraph",
42
+ children: e ? [o(e)] : [o("")]
43
+ };
44
+ }
45
+ function a(e, t = "") {
46
+ return {
47
+ type: "heading",
48
+ level: e,
49
+ children: [o(t)]
50
+ };
51
+ }
52
+ function o(e, t = []) {
53
+ return {
54
+ type: "text",
55
+ text: e,
56
+ marks: t
57
+ };
58
+ }
59
+ function s(e = "") {
60
+ return {
61
+ type: "list_item",
62
+ children: [o(e)]
63
+ };
64
+ }
65
+ function c(e = [""]) {
66
+ return {
67
+ type: "bullet_list",
68
+ children: e.map(s)
69
+ };
70
+ }
71
+ function l(e = [""]) {
72
+ return {
73
+ type: "ordered_list",
74
+ children: e.map(s)
75
+ };
76
+ }
77
+ function u(e = "") {
78
+ return {
79
+ type: "blockquote",
80
+ children: [i(e)]
81
+ };
82
+ }
83
+ function d(e = "", t) {
84
+ return {
85
+ type: "code_block",
86
+ lang: t,
87
+ children: [o(e)]
88
+ };
89
+ }
90
+ function f(e = "", t = "info") {
91
+ return {
92
+ type: "callout",
93
+ variant: t,
94
+ children: [o(e)]
95
+ };
96
+ }
97
+ function p() {
98
+ return r([i("")]);
99
+ }
100
+ //#endregion
101
+ //#region src/io/deserializer.ts
102
+ var m = [
103
+ "info",
104
+ "success",
105
+ "warning",
106
+ "danger"
107
+ ];
108
+ function h(e) {
109
+ if (!e || e.trim() === "") return p();
110
+ let t = document.createElement("div");
111
+ t.innerHTML = g(e);
112
+ let n = _(t);
113
+ return n.length === 0 ? p() : { children: n };
114
+ }
115
+ function g(e) {
116
+ return e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/\s+on\w+="[^"]*"/gi, "").replace(/\s+on\w+='[^']*'/gi, "");
117
+ }
118
+ function _(e) {
119
+ let t = [];
120
+ for (let n of Array.from(e.childNodes)) {
121
+ if (n.nodeType === Node.TEXT_NODE) {
122
+ let e = (n.textContent ?? "").trim();
123
+ e && t.push(i(e));
124
+ continue;
125
+ }
126
+ if (n.nodeType !== Node.ELEMENT_NODE) continue;
127
+ let e = n, r = v(e, e.tagName.toLowerCase());
128
+ r && t.push(r);
129
+ }
130
+ return t;
131
+ }
132
+ function v(e, t) {
133
+ switch (t) {
134
+ case "p": return y(e);
135
+ case "h1":
136
+ case "h2":
137
+ case "h3":
138
+ case "h4":
139
+ case "h5":
140
+ case "h6": return b(e, parseInt(t[1]));
141
+ case "blockquote": return x(e);
142
+ case "pre": return ee(e);
143
+ case "ul": return te(e);
144
+ case "ol": return ne(e);
145
+ case "img": return ae(e);
146
+ case "hr": return { type: "hr" };
147
+ case "div": return e.classList.contains("oe-callout") ? ie(e) : _(e)[0] ?? null;
148
+ case "section":
149
+ case "article":
150
+ case "main": return _(e)[0] ?? null;
151
+ case "br": return i("");
152
+ default: return y(e);
153
+ }
154
+ }
155
+ function y(e) {
156
+ let t = se(e), n = S(e);
157
+ return {
158
+ type: "paragraph",
159
+ ...t ? { align: t } : {},
160
+ children: n
161
+ };
162
+ }
163
+ function b(e, t) {
164
+ let n = se(e), r = S(e);
165
+ return {
166
+ type: "heading",
167
+ level: t,
168
+ ...n ? { align: n } : {},
169
+ children: r
170
+ };
171
+ }
172
+ function x(e) {
173
+ let t = _(e);
174
+ return t.length === 0 && t.push(i("")), {
175
+ type: "blockquote",
176
+ children: t
177
+ };
178
+ }
179
+ function ee(e) {
180
+ let t = e.querySelector("code"), n = t ? t.textContent ?? "" : e.textContent ?? "", r = t?.className.match(/language-(\w+)/)?.[1];
181
+ return {
182
+ type: "code_block",
183
+ ...r ? { lang: r } : {},
184
+ children: [o(n)]
185
+ };
186
+ }
187
+ function te(e) {
188
+ let t = Array.from(e.querySelectorAll(":scope > li")).map(re);
189
+ return t.length === 0 && t.push({
190
+ type: "list_item",
191
+ children: [o("")]
192
+ }), {
193
+ type: "bullet_list",
194
+ children: t
195
+ };
196
+ }
197
+ function ne(e) {
198
+ let t = parseInt(e.getAttribute("start") ?? "1"), n = Array.from(e.querySelectorAll(":scope > li")).map(re);
199
+ return n.length === 0 && n.push({
200
+ type: "list_item",
201
+ children: [o("")]
202
+ }), {
203
+ type: "ordered_list",
204
+ ...t === 1 ? {} : { start: t },
205
+ children: n
206
+ };
207
+ }
208
+ function re(e) {
209
+ return {
210
+ type: "list_item",
211
+ children: S(e)
212
+ };
213
+ }
214
+ function ie(e) {
215
+ let t = e.getAttribute("data-callout-variant");
216
+ return {
217
+ type: "callout",
218
+ variant: m.includes(t) ? t : m.find((t) => e.classList.contains(`oe-callout-${t}`)) ?? "info",
219
+ children: S(e)
220
+ };
221
+ }
222
+ function ae(e) {
223
+ return {
224
+ type: "image",
225
+ src: e.getAttribute("src") ?? "",
226
+ alt: e.getAttribute("alt") ?? void 0,
227
+ width: e.getAttribute("width") ? parseInt(e.getAttribute("width")) : void 0,
228
+ height: e.getAttribute("height") ? parseInt(e.getAttribute("height")) : void 0
229
+ };
230
+ }
231
+ function S(e, t = []) {
232
+ let n = [];
233
+ for (let r of Array.from(e.childNodes)) {
234
+ if (r.nodeType === Node.TEXT_NODE) {
235
+ let e = r.textContent ?? "";
236
+ e && n.push(o(e, [...t]));
237
+ continue;
238
+ }
239
+ if (r.nodeType !== Node.ELEMENT_NODE) continue;
240
+ let e = r, i = e.tagName.toLowerCase(), a = oe(i, e, t);
241
+ if (i === "br") {
242
+ n.push({ type: "hardbreak" });
243
+ continue;
244
+ }
245
+ if (i === "img") {
246
+ n.push(o("[image]", t));
247
+ continue;
248
+ }
249
+ n.push(...S(e, a));
250
+ }
251
+ return n.length === 0 && n.push(o("", t)), n;
252
+ }
253
+ function oe(e, t, n) {
254
+ let r = [...n];
255
+ switch (e) {
256
+ case "strong":
257
+ case "b":
258
+ r.some((e) => e.type === "bold") || r.push({ type: "bold" });
259
+ break;
260
+ case "em":
261
+ case "i":
262
+ r.some((e) => e.type === "italic") || r.push({ type: "italic" });
263
+ break;
264
+ case "u":
265
+ r.some((e) => e.type === "underline") || r.push({ type: "underline" });
266
+ break;
267
+ case "s":
268
+ case "del":
269
+ case "strike":
270
+ r.some((e) => e.type === "strikethrough") || r.push({ type: "strikethrough" });
271
+ break;
272
+ case "code":
273
+ r.some((e) => e.type === "code") || r.push({ type: "code" });
274
+ break;
275
+ case "a": {
276
+ let e = {
277
+ type: "link",
278
+ href: t.getAttribute("href") ?? "",
279
+ target: t.getAttribute("target") === "_blank" ? "_blank" : "_self"
280
+ };
281
+ r.some((e) => e.type === "link") || r.push(e);
282
+ break;
283
+ }
284
+ case "mark": break;
285
+ }
286
+ return r;
287
+ }
288
+ function se(e) {
289
+ let t = (e.getAttribute("style") ?? "").match(/text-align\s*:\s*(left|center|right|justify)/);
290
+ return t ? t[1] : void 0;
291
+ }
292
+ //#endregion
293
+ //#region src/io/serializer.ts
294
+ function C(e) {
295
+ return e.children.map(w).join("\n");
296
+ }
297
+ function w(e) {
298
+ switch (e.type) {
299
+ case "paragraph": {
300
+ let t = T(e.children);
301
+ return `<p${e.align && e.align !== "left" ? ` style="text-align:${e.align}"` : ""}>${t || "<br>"}</p>`;
302
+ }
303
+ case "heading": {
304
+ let t = T(e.children), n = e.align && e.align !== "left" ? ` style="text-align:${e.align}"` : "";
305
+ return `<h${e.level}${n}>${t}</h${e.level}>`;
306
+ }
307
+ case "blockquote": return `<blockquote>\n${e.children.map(w).join("\n")}\n</blockquote>`;
308
+ case "code_block": {
309
+ let t = de(e.children.map((e) => e.text).join(""));
310
+ return `<pre><code${e.lang ? ` class="language-${e.lang}"` : ""}>${t}</code></pre>`;
311
+ }
312
+ case "bullet_list": return `<ul>\n${e.children.map((e) => ` <li>${T(e.children)}</li>`).join("\n")}\n</ul>`;
313
+ case "ordered_list": return `<ol${e.start && e.start !== 1 ? ` start="${e.start}"` : ""}>\n${e.children.map((e) => ` <li>${T(e.children)}</li>`).join("\n")}\n</ol>`;
314
+ case "image": {
315
+ let t = e.alt ? ` alt="${E(e.alt)}"` : "", n = e.width ? ` width="${e.width}"` : "", r = e.height ? ` height="${e.height}"` : "";
316
+ return `<img src="${E(e.src)}"${t}${n}${r}>`;
317
+ }
318
+ case "hr": return "<hr>";
319
+ case "callout": {
320
+ let t = T(e.children);
321
+ return `<div class="oe-callout oe-callout-${e.variant}" data-callout-variant="${e.variant}">${t || "<br>"}</div>`;
322
+ }
323
+ default: return "";
324
+ }
325
+ }
326
+ function T(e) {
327
+ return e.map(ce).join("");
328
+ }
329
+ function ce(e) {
330
+ if (e.type === "hardbreak") return "<br>";
331
+ let t = de(e.text);
332
+ if (t === "" && e.marks.length === 0) return "";
333
+ let n = [...e.marks].sort(le);
334
+ for (let e of n) t = ue(t, e);
335
+ return t;
336
+ }
337
+ function le(e, t) {
338
+ let n = [
339
+ "strikethrough",
340
+ "underline",
341
+ "italic",
342
+ "bold",
343
+ "link",
344
+ "code"
345
+ ];
346
+ return n.indexOf(e.type) - n.indexOf(t.type);
347
+ }
348
+ function ue(e, t) {
349
+ switch (t.type) {
350
+ case "bold": return `<strong>${e}</strong>`;
351
+ case "italic": return `<em>${e}</em>`;
352
+ case "underline": return `<u>${e}</u>`;
353
+ case "code": return `<code>${e}</code>`;
354
+ case "strikethrough": return `<s>${e}</s>`;
355
+ case "link": {
356
+ let n = t, r = n.target === "_blank" ? " target=\"_blank\" rel=\"noopener noreferrer\"" : "", i = n.title ? ` title="${E(n.title)}"` : "";
357
+ return `<a href="${E(n.href)}"${r}${i}>${e}</a>`;
358
+ }
359
+ default: return e;
360
+ }
361
+ }
362
+ function de(e) {
363
+ return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
364
+ }
365
+ function E(e) {
366
+ return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
367
+ }
368
+ //#endregion
369
+ //#region src/io/markdown.ts
370
+ function D(e) {
371
+ return e.children.map(fe).filter(Boolean).join("\n\n");
372
+ }
373
+ function fe(e) {
374
+ switch (e.type) {
375
+ case "paragraph": return O(e.children);
376
+ case "heading": return `${"#".repeat(e.level)} ${O(e.children)}`;
377
+ case "blockquote": return e.children.map(fe).join("\n\n").split("\n").map((e) => `> ${e}`).join("\n");
378
+ case "code_block": return `\`\`\`${e.lang ?? ""}\n${e.children.map((e) => e.text).join("")}\n\`\`\``;
379
+ case "bullet_list": return e.children.map((e) => `- ${O(e.children)}`).join("\n");
380
+ case "ordered_list": {
381
+ let t = e.start ?? 1;
382
+ return e.children.map((e, n) => `${t + n}. ${O(e.children)}`).join("\n");
383
+ }
384
+ case "image": return `![${e.alt ?? ""}](${e.src})`;
385
+ case "hr": return "---";
386
+ case "callout": return `> [!${e.variant ?? "info"}]\n${O(e.children).split("\n").map((e) => e ? `> ${e}` : ">").join("\n")}`;
387
+ default: return "";
388
+ }
389
+ }
390
+ function O(e) {
391
+ return e.map(pe).join("");
392
+ }
393
+ function pe(e) {
394
+ if (e.type === "hardbreak") return "\n";
395
+ let t = e.text, n = [...e.marks].sort((e, t) => {
396
+ let n = [
397
+ "link",
398
+ "bold",
399
+ "italic",
400
+ "strikethrough",
401
+ "underline",
402
+ "code"
403
+ ];
404
+ return n.indexOf(e.type) - n.indexOf(t.type);
405
+ });
406
+ for (let e of n) switch (e.type) {
407
+ case "bold":
408
+ t = `**${t}**`;
409
+ break;
410
+ case "italic":
411
+ t = `*${t}*`;
412
+ break;
413
+ case "code":
414
+ t = `\`${t}\``;
415
+ break;
416
+ case "strikethrough":
417
+ t = `~~${t}~~`;
418
+ break;
419
+ case "underline":
420
+ t = `<u>${t}</u>`;
421
+ break;
422
+ case "link": {
423
+ let n = e, r = n.title ? ` "${n.title}"` : "";
424
+ t = `[${t}](${n.href}${r})`;
425
+ break;
426
+ }
427
+ }
428
+ return t;
429
+ }
430
+ function k(e) {
431
+ if (!e || e.trim() === "") return p();
432
+ let t = me(e);
433
+ return t.length > 0 ? { children: t } : p();
434
+ }
435
+ function me(e) {
436
+ let t = e.split("\n"), n = [], r = 0;
437
+ for (; r < t.length;) {
438
+ let e = t[r];
439
+ if (e.trim() === "") {
440
+ r++;
441
+ continue;
442
+ }
443
+ let a = e.match(/^(`{3,}|~{3,})(.*)/);
444
+ if (a) {
445
+ let e = a[1], i = a[2].trim();
446
+ r++;
447
+ let s = [];
448
+ for (; r < t.length && !t[r].startsWith(e);) s.push(t[r]), r++;
449
+ r < t.length && r++, n.push({
450
+ type: "code_block",
451
+ ...i ? { lang: i } : {},
452
+ children: [o(s.join("\n"))]
453
+ });
454
+ continue;
455
+ }
456
+ let s = e.match(/^(#{1,6})\s+(.*)/);
457
+ if (s) {
458
+ let e = s[1].length;
459
+ n.push({
460
+ type: "heading",
461
+ level: e,
462
+ children: A(s[2].trim())
463
+ }), r++;
464
+ continue;
465
+ }
466
+ if (/^[-*_]{3,}\s*$/.test(e.trim())) {
467
+ n.push({ type: "hr" }), r++;
468
+ continue;
469
+ }
470
+ if (e.startsWith(">")) {
471
+ let e = [];
472
+ for (; r < t.length && t[r].startsWith(">");) e.push(t[r].slice(1).trimStart()), r++;
473
+ let a = e[0]?.match(/^\[!(info|success|warning|danger)\]$/i);
474
+ if (a) {
475
+ let t = a[1].toLowerCase(), r = e.slice(1).join("\n");
476
+ n.push({
477
+ type: "callout",
478
+ variant: t,
479
+ children: A(r)
480
+ });
481
+ continue;
482
+ }
483
+ let o = me(e.join("\n"));
484
+ n.push({
485
+ type: "blockquote",
486
+ children: o.length > 0 ? o : [i("")]
487
+ });
488
+ continue;
489
+ }
490
+ if (/^[-*+] /.test(e)) {
491
+ let e = [];
492
+ for (; r < t.length && /^[-*+] /.test(t[r]);) e.push({
493
+ type: "list_item",
494
+ children: A(t[r].replace(/^[-*+]\s+/, ""))
495
+ }), r++;
496
+ n.push({
497
+ type: "bullet_list",
498
+ children: e
499
+ });
500
+ continue;
501
+ }
502
+ if (/^\d+\. /.test(e)) {
503
+ let i = [], a = e.match(/^(\d+)\./), o = a ? parseInt(a[1]) : 1;
504
+ for (; r < t.length && /^\d+\. /.test(t[r]);) i.push({
505
+ type: "list_item",
506
+ children: A(t[r].replace(/^\d+\.\s+/, ""))
507
+ }), r++;
508
+ n.push({
509
+ type: "ordered_list",
510
+ ...o === 1 ? {} : { start: o },
511
+ children: i
512
+ });
513
+ continue;
514
+ }
515
+ let c = e.match(/^!\[([^\]]*)\]\(([^)]+)\)\s*$/);
516
+ if (c) {
517
+ n.push({
518
+ type: "image",
519
+ alt: c[1] || void 0,
520
+ src: c[2]
521
+ }), r++;
522
+ continue;
523
+ }
524
+ let l = [];
525
+ for (; r < t.length && t[r].trim() !== "" && !he(t[r]);) l.push(t[r]), r++;
526
+ l.length > 0 && n.push({
527
+ type: "paragraph",
528
+ children: A(l.join(" "))
529
+ });
530
+ }
531
+ return n;
532
+ }
533
+ function he(e) {
534
+ return /^#{1,6}\s/.test(e) || /^(`{3,}|~{3,})/.test(e) || e.startsWith(">") || /^[-*+] /.test(e) || /^\d+\. /.test(e) || /^[-*_]{3,}\s*$/.test(e.trim());
535
+ }
536
+ var ge = [
537
+ {
538
+ re: /`([^`]+)`/,
539
+ priority: 0,
540
+ handler: (e) => [o(e[1], [{ type: "code" }])]
541
+ },
542
+ {
543
+ re: /\[([^\]]+)\]\(([^) "]+)(?:\s+"([^"]*)")?\)/,
544
+ priority: 1,
545
+ handler: (e) => {
546
+ let t = A(e[1]), n = {
547
+ type: "link",
548
+ href: e[2],
549
+ target: "_self",
550
+ ...e[3] ? { title: e[3] } : {}
551
+ };
552
+ return t.map((e) => e.type === "text" ? o(e.text, [...e.marks, n]) : e);
553
+ }
554
+ },
555
+ {
556
+ re: /!\[([^\]]*)\]\(([^)]+)\)/,
557
+ priority: 1,
558
+ handler: (e) => [o(`[${e[1] || "image"}]`, [])]
559
+ },
560
+ {
561
+ re: /\*\*([^*]+)\*\*|__([^_]+)__/,
562
+ priority: 2,
563
+ handler: (e) => j(e[1] ?? e[2], { type: "bold" })
564
+ },
565
+ {
566
+ re: /\*([^*]+)\*|_([^_]+)_/,
567
+ priority: 3,
568
+ handler: (e) => j(e[1] ?? e[2], { type: "italic" })
569
+ },
570
+ {
571
+ re: /~~([^~]+)~~/,
572
+ priority: 2,
573
+ handler: (e) => j(e[1], { type: "strikethrough" })
574
+ },
575
+ {
576
+ re: /<u>([^<]+)<\/u>/,
577
+ priority: 2,
578
+ handler: (e) => j(e[1], { type: "underline" })
579
+ }
580
+ ];
581
+ function A(e) {
582
+ if (!e) return [o("", [])];
583
+ let t = [], n = e;
584
+ for (; n.length > 0;) {
585
+ let e = null;
586
+ for (let t of ge) {
587
+ let r = new RegExp(t.re.source, t.re.flags.replace("g", "")).exec(n);
588
+ if (r === null) continue;
589
+ let i = r.index;
590
+ (!e || i < e.index || i === e.index && t.priority < e.pattern.priority || i === e.index && t.priority === e.pattern.priority && r[0].length > e.match[0].length) && (e = {
591
+ index: i,
592
+ match: r,
593
+ pattern: t
594
+ });
595
+ }
596
+ if (!e) {
597
+ t.push(o(n, []));
598
+ break;
599
+ }
600
+ e.index > 0 && t.push(o(n.slice(0, e.index), [])), t.push(...e.pattern.handler(e.match)), n = n.slice(e.index + e.match[0].length);
601
+ }
602
+ return t.length > 0 ? t : [o(e, [])];
603
+ }
604
+ function j(e, t) {
605
+ return A(e).map((e) => e.type === "text" ? o(e.text, [...e.marks, t]) : e);
606
+ }
607
+ //#endregion
608
+ //#region src/view/renderer.ts
609
+ function M(e, t) {
610
+ let n = document.createDocumentFragment();
611
+ for (let t of e.children) {
612
+ let e = N(t);
613
+ n.appendChild(e);
614
+ }
615
+ t.innerHTML = "", t.appendChild(n);
616
+ }
617
+ function N(e) {
618
+ switch (e.type) {
619
+ case "paragraph": {
620
+ let t = document.createElement("p");
621
+ return e.align && e.align !== "left" && (t.style.textAlign = e.align), P(e.children, t), t;
622
+ }
623
+ case "heading": {
624
+ let t = document.createElement(`h${e.level}`);
625
+ return e.align && e.align !== "left" && (t.style.textAlign = e.align), P(e.children, t), t;
626
+ }
627
+ case "blockquote": {
628
+ let t = document.createElement("blockquote");
629
+ for (let n of e.children) t.appendChild(N(n));
630
+ return t;
631
+ }
632
+ case "code_block": {
633
+ let t = document.createElement("pre"), n = document.createElement("span");
634
+ n.className = "oe-code-lang-badge", n.contentEditable = "false", n.textContent = e.lang || "plain", t.appendChild(n);
635
+ let r = document.createElement("code");
636
+ return e.lang && (r.className = `language-${e.lang}`), r.textContent = e.children.map((e) => e.text).join(""), t.appendChild(r), t;
637
+ }
638
+ case "bullet_list": {
639
+ let t = document.createElement("ul");
640
+ for (let n of e.children) {
641
+ let e = document.createElement("li");
642
+ P(n.children, e), t.appendChild(e);
643
+ }
644
+ return t;
645
+ }
646
+ case "ordered_list": {
647
+ let t = document.createElement("ol");
648
+ e.start && e.start !== 1 && t.setAttribute("start", String(e.start));
649
+ for (let n of e.children) {
650
+ let e = document.createElement("li");
651
+ P(n.children, e), t.appendChild(e);
652
+ }
653
+ return t;
654
+ }
655
+ case "image": {
656
+ let t = document.createElement("div");
657
+ t.className = "oe-image-wrapper";
658
+ let n = document.createElement("img");
659
+ return n.src = e.src, e.alt && (n.alt = e.alt), e.width && (n.width = e.width), e.height && (n.height = e.height), n.draggable = !1, t.appendChild(n), t;
660
+ }
661
+ case "hr": return document.createElement("hr");
662
+ case "callout": {
663
+ let t = document.createElement("div");
664
+ return t.className = `oe-callout oe-callout-${e.variant}`, t.dataset.calloutVariant = e.variant, P(e.children, t), t;
665
+ }
666
+ default: {
667
+ let e = document.createElement("p");
668
+ return e.textContent = "", e;
669
+ }
670
+ }
671
+ }
672
+ function P(e, t) {
673
+ if (e.length === 0 || e.length === 1 && e[0].type === "text" && e[0].text === "") {
674
+ t.appendChild(document.createElement("br"));
675
+ return;
676
+ }
677
+ for (let n of e) {
678
+ if (n.type === "hardbreak") {
679
+ t.appendChild(document.createElement("br"));
680
+ continue;
681
+ }
682
+ let e = document.createTextNode(n.text), r = [...n.marks];
683
+ for (let t of r.reverse()) e = _e(e, t);
684
+ t.appendChild(e);
685
+ }
686
+ }
687
+ function _e(e, t) {
688
+ let n;
689
+ switch (t.type) {
690
+ case "bold":
691
+ n = document.createElement("strong");
692
+ break;
693
+ case "italic":
694
+ n = document.createElement("em");
695
+ break;
696
+ case "underline":
697
+ n = document.createElement("u");
698
+ break;
699
+ case "strikethrough":
700
+ n = document.createElement("s");
701
+ break;
702
+ case "code":
703
+ n = document.createElement("code");
704
+ break;
705
+ case "link": {
706
+ let e = t, r = document.createElement("a");
707
+ r.href = e.href, e.target === "_blank" && (r.target = "_blank", r.rel = "noopener noreferrer"), e.title && (r.title = e.title), n = r;
708
+ break;
709
+ }
710
+ default: n = document.createElement("span");
711
+ }
712
+ return n.appendChild(e), n;
713
+ }
714
+ //#endregion
715
+ //#region src/core/commands.ts
716
+ function F(e) {
717
+ let t = e.innerHTML;
718
+ return h(t);
719
+ }
720
+ function I(e, t) {
721
+ document.execCommand(e, !1, t ?? void 0);
722
+ }
723
+ function ve(e, t, n, r) {
724
+ let o = [...e.children], s = o[t];
725
+ if (!s) return e;
726
+ let p = R(s), m;
727
+ switch (n) {
728
+ case "paragraph":
729
+ m = {
730
+ ...i(p),
731
+ ...r ?? {}
732
+ };
733
+ break;
734
+ case "heading":
735
+ m = a(r?.level ?? 1, p);
736
+ break;
737
+ case "h1":
738
+ case "H1":
739
+ m = a(1, p);
740
+ break;
741
+ case "h2":
742
+ case "H2":
743
+ m = a(2, p);
744
+ break;
745
+ case "h3":
746
+ case "H3":
747
+ m = a(3, p);
748
+ break;
749
+ case "h4":
750
+ case "H4":
751
+ m = a(4, p);
752
+ break;
753
+ case "h5":
754
+ case "H5":
755
+ m = a(5, p);
756
+ break;
757
+ case "h6":
758
+ case "H6":
759
+ m = a(6, p);
760
+ break;
761
+ case "blockquote":
762
+ case "BLOCKQUOTE":
763
+ m = u(p);
764
+ break;
765
+ case "code_block":
766
+ case "PRE":
767
+ m = d(p, r?.lang);
768
+ break;
769
+ case "bullet_list":
770
+ m = c([p]);
771
+ break;
772
+ case "ordered_list":
773
+ m = l([p]);
774
+ break;
775
+ case "callout":
776
+ m = f(p, r?.variant ?? "info");
777
+ break;
778
+ case "CALLOUT-info":
779
+ case "CALLOUT-success":
780
+ case "CALLOUT-warning":
781
+ case "CALLOUT-danger": {
782
+ let e = n.split("-")[1];
783
+ m = f(p, e);
784
+ break;
785
+ }
786
+ default: m = i(p);
787
+ }
788
+ return o[t] = m, { children: o };
789
+ }
790
+ function ye(e, t, n) {
791
+ let r = [...e.children], a = r[t];
792
+ if (!a) return e;
793
+ if (a.type === n) {
794
+ let e = a.children.map((e) => i(e.children.map((e) => e.type === "text" ? e.text : "").join("")));
795
+ r.splice(t, 1, ...e);
796
+ } else if (a.type === "bullet_list" || a.type === "ordered_list") {
797
+ let e = a;
798
+ n === "bullet_list" ? r[t] = {
799
+ type: "bullet_list",
800
+ children: e.children
801
+ } : r[t] = {
802
+ type: "ordered_list",
803
+ children: e.children
804
+ };
805
+ } else {
806
+ let e = R(a);
807
+ r[t] = n === "bullet_list" ? c([e]) : l([e]);
808
+ }
809
+ return { children: r };
810
+ }
811
+ function be(e, t, n) {
812
+ let r = [...e.children], i = r[t];
813
+ return i ? ((i.type === "paragraph" || i.type === "heading") && (r[t] = {
814
+ ...i,
815
+ align: n
816
+ }), { children: r }) : e;
817
+ }
818
+ function L(e, t, n, r) {
819
+ let a = [...e.children], o = {
820
+ type: "image",
821
+ src: n,
822
+ alt: r
823
+ };
824
+ return a.splice(t + 1, 0, o, i("")), { children: a };
825
+ }
826
+ function xe(e, t) {
827
+ let n = [...e.children];
828
+ return n.splice(t + 1, 0, { type: "hr" }, i("")), { children: n };
829
+ }
830
+ function R(e) {
831
+ return e.type === "paragraph" || e.type === "heading" || e.type === "list_item" || e.type === "code_block" || e.type === "callout" ? e.children.map((e) => e.type === "text" ? e.text : "").join("") : e.type === "bullet_list" || e.type === "ordered_list" ? e.children.map((e) => e.children.map((e) => e.type === "text" ? e.text : "").join("")).join(" ") : e.type === "blockquote" ? e.children.map(R).join(" ") : "";
832
+ }
833
+ function Se(e) {
834
+ let t = window.getSelection();
835
+ if (!t || t.rangeCount === 0) return "p";
836
+ let n = t.anchorNode;
837
+ for (; n && n.parentNode !== e;) n = n.parentNode;
838
+ if (!n || n.nodeType !== Node.ELEMENT_NODE) return "p";
839
+ let r = n.tagName.toLowerCase();
840
+ return r === "h1" ? "H1" : r === "h2" ? "H2" : r === "h3" ? "H3" : r === "h4" ? "H4" : r === "blockquote" ? "BLOCKQUOTE" : r === "pre" ? "PRE" : r === "ul" ? "bullet_list" : r === "ol" ? "ordered_list" : r === "div" && n.classList?.contains("oe-callout") ? `CALLOUT-${n.dataset?.calloutVariant ?? "info"}` : "P";
841
+ }
842
+ function Ce(e, t) {
843
+ document.execCommand("createLink", !1, e);
844
+ let n = window.getSelection();
845
+ if (n && n.rangeCount > 0) {
846
+ let e = n.getRangeAt(0).startContainer.parentElement?.closest("a");
847
+ e && (e.target = t, t === "_blank" && (e.rel = "noopener noreferrer"));
848
+ }
849
+ }
850
+ //#endregion
851
+ //#region src/view/selection.ts
852
+ function z(e, t) {
853
+ let n = window.getSelection();
854
+ if (!n || n.rangeCount === 0) return null;
855
+ let r = n.getRangeAt(0);
856
+ if (!e.contains(r.commonAncestorContainer)) return null;
857
+ let i = B(e, n.anchorNode, n.anchorOffset), a = B(e, n.focusNode, n.focusOffset);
858
+ return !i || !a ? null : {
859
+ anchor: i,
860
+ focus: a,
861
+ isCollapsed: n.isCollapsed
862
+ };
863
+ }
864
+ function B(e, t, n) {
865
+ let r = null, i = t;
866
+ for (; i && i !== e;) {
867
+ if (i.parentNode === e && i.nodeType === Node.ELEMENT_NODE) {
868
+ r = i;
869
+ break;
870
+ }
871
+ i = i.parentNode;
872
+ }
873
+ if (!r) return null;
874
+ let a = Array.from(e.children).indexOf(r);
875
+ if (a < 0) return null;
876
+ let o = Te(r, t, n), s = we(t, r);
877
+ if (s) {
878
+ let e = s.parentElement;
879
+ return {
880
+ blockIndex: a,
881
+ itemIndex: Array.from(e.children).indexOf(s),
882
+ offset: o
883
+ };
884
+ }
885
+ return {
886
+ blockIndex: a,
887
+ offset: o
888
+ };
889
+ }
890
+ function we(e, t) {
891
+ let n = e;
892
+ for (; n && n !== t;) {
893
+ if (n.nodeType === Node.ELEMENT_NODE && n.tagName === "LI") return n;
894
+ n = n.parentNode;
895
+ }
896
+ return null;
897
+ }
898
+ function Te(e, t, n) {
899
+ return V(e, t, n, {
900
+ count: 0,
901
+ done: !1,
902
+ result: 0
903
+ }).result;
904
+ }
905
+ function V(e, t, n, r) {
906
+ if (r.done) return r;
907
+ if (e === t) return r.result = r.count + (e.nodeType === Node.TEXT_NODE ? n : 0), r.done = !0, r;
908
+ if (e.nodeType === Node.TEXT_NODE) return r.count += (e.textContent ?? "").length, r;
909
+ if (e.nodeType === Node.ELEMENT_NODE && e.tagName.toLowerCase() === "br") return e === t && (r.result = r.count, r.done = !0), r;
910
+ for (let i of Array.from(e.childNodes)) if (r = V(i, t, n, r), r.done) break;
911
+ return r;
912
+ }
913
+ function H(e) {
914
+ let t = window.getSelection();
915
+ if (!t || t.rangeCount === 0) return 0;
916
+ let n = t.anchorNode;
917
+ for (; n && n.parentNode !== e;) n = n.parentNode;
918
+ return n ? Array.from(e.children).indexOf(n) : 0;
919
+ }
920
+ function U(e) {
921
+ let t = window.getSelection(), n = /* @__PURE__ */ new Set();
922
+ if (!t || t.rangeCount === 0) return n;
923
+ let r = t.getRangeAt(0);
924
+ if (!e.contains(r.commonAncestorContainer)) return n;
925
+ let i = t.anchorNode;
926
+ for (; i && i !== e;) {
927
+ if (i.nodeType === Node.ELEMENT_NODE) {
928
+ let e = i.tagName.toLowerCase();
929
+ (e === "strong" || e === "b") && n.add("bold"), (e === "em" || e === "i") && n.add("italic"), e === "u" && n.add("underline"), (e === "s" || e === "del") && n.add("strikethrough"), e === "code" && n.add("code"), e === "a" && n.add("link");
930
+ }
931
+ i = i.parentNode;
932
+ }
933
+ return n;
934
+ }
935
+ //#endregion
936
+ //#region src/locales/en.ts
937
+ var W = {
938
+ toolbar: {
939
+ undo: "Undo (Ctrl+Z)",
940
+ redo: "Redo (Ctrl+Y)",
941
+ textFormat: "Text Format",
942
+ paragraph: "Paragraph",
943
+ heading: (e) => `Heading ${e}`,
944
+ quote: "Quote",
945
+ codeBlock: "Code Block",
946
+ bold: "Bold (Ctrl+B)",
947
+ italic: "Italic (Ctrl+I)",
948
+ underline: "Underline (Ctrl+U)",
949
+ inlineCode: "Inline Code (Ctrl+`)",
950
+ alignLeft: "Align Left",
951
+ alignCenter: "Align Center",
952
+ alignRight: "Align Right",
953
+ justify: "Justify",
954
+ bulletList: "Bullet List",
955
+ orderedList: "Ordered List",
956
+ insertLink: "Insert Link",
957
+ insertImage: "Insert Image",
958
+ blockquote: "Blockquote",
959
+ horizontalRule: "Horizontal Rule",
960
+ htmlSource: "Toggle HTML Source",
961
+ calloutInfo: "Callout: Info",
962
+ calloutSuccess: "Callout: Success",
963
+ calloutWarning: "Callout: Warning",
964
+ calloutDanger: "Callout: Danger",
965
+ insertCallout: "Insert Callout"
966
+ },
967
+ statusBar: {
968
+ words: "Words",
969
+ characters: "Characters",
970
+ htmlSource: "HTML"
971
+ },
972
+ dialogs: {
973
+ linkUrl: "Link URL:",
974
+ openInNewTab: "Open in new tab?",
975
+ imageUrl: "Image URL:",
976
+ imageAlt: "Alt text (optional):"
977
+ },
978
+ plugins: {
979
+ ai: {
980
+ panelTitle: "AI Assistant",
981
+ noSelection: "(No text selected — entire document will be used)",
982
+ customPromptPlaceholder: "Enter custom instruction…",
983
+ runButton: "Run",
984
+ applyButton: "Apply",
985
+ generating: "⏳ Generating…",
986
+ noApiKey: "⚠️ No API key configured. Pass apiKey or endpoint when creating the plugin.",
987
+ errorPrefix: "❌ Error: ",
988
+ actions: {
989
+ improve: "Improve",
990
+ shorten: "Shorten",
991
+ expand: "Expand",
992
+ summarize: "Summarize",
993
+ toGerman: "🇩🇪 To German",
994
+ toEnglish: "🇬🇧 To English"
995
+ }
996
+ },
997
+ emoji: {
998
+ buttonTitle: "Insert emoji",
999
+ categories: {
1000
+ faces: "Faces",
1001
+ hearts: "Hearts",
1002
+ gestures: "Gestures",
1003
+ nature: "Nature",
1004
+ food: "Food",
1005
+ objects: "Objects",
1006
+ symbols: "Symbols"
1007
+ }
1008
+ }
1009
+ }
1010
+ }, Ee = "width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"";
1011
+ function G(e) {
1012
+ return `<svg ${Ee}>${e}</svg>`;
1013
+ }
1014
+ var De = {
1015
+ undo: G("<path d=\"M3 7h10a6 6 0 0 1 0 12H9\"/><path d=\"M3 7l4-4M3 7l4 4\"/>"),
1016
+ redo: G("<path d=\"M21 7H11a6 6 0 0 0 0 12h4\"/><path d=\"M21 7l-4-4M21 7l-4 4\"/>"),
1017
+ bold: G("<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/>"),
1018
+ italic: G("<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/>"),
1019
+ underline: G("<path d=\"M6 4v6a6 6 0 0 0 12 0V4\"/><line x1=\"4\" y1=\"20\" x2=\"20\" y2=\"20\"/>"),
1020
+ strikethrough: G("<path d=\"M17.3 12H12m-6 0h3\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><path d=\"M7 7.5C7 5.6 9 4 12 4s5 1.6 5 3.5c0 .7-.3 1.4-.8 2\"/><path d=\"M17 16.5C17 18.4 15 20 12 20s-5-1.6-5-3.5\"/>"),
1021
+ code_inline: G("<polyline points=\"16,18 22,12 16,6\"/><polyline points=\"8,6 2,12 8,18\"/>"),
1022
+ link: G("<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>"),
1023
+ image: G("<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21,15 16,10 5,21\"/>"),
1024
+ blockquote: G("<path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"/>"),
1025
+ hr: G("<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>"),
1026
+ alignLeft: G("<line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/>"),
1027
+ alignCenter: G("<line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/>"),
1028
+ alignRight: G("<line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/>"),
1029
+ alignJustify: G("<line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"/>"),
1030
+ bulletList: G("<circle cx=\"4\" cy=\"7\" r=\"1.5\" fill=\"currentColor\"/><line x1=\"8\" y1=\"7\" x2=\"21\" y2=\"7\"/><circle cx=\"4\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"/><circle cx=\"4\" cy=\"17\" r=\"1.5\" fill=\"currentColor\"/><line x1=\"8\" y1=\"17\" x2=\"21\" y2=\"17\"/>"),
1031
+ orderedList: G("<line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><path d=\"M4 6h1v4\"/><path d=\"M4 10h2\"/><path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\"/>"),
1032
+ htmlToggle: G("<path d=\"M10 9l-3 3 3 3\"/><path d=\"M14 15l3-3-3-3\"/><rect x=\"2\" y=\"3\" width=\"20\" height=\"18\" rx=\"2\"/>"),
1033
+ maximize: G("<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"/><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"/><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"/><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"/>"),
1034
+ callout: G("<circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>")
1035
+ };
1036
+ //#endregion
1037
+ //#region src/view/toolbar.ts
1038
+ function K(e) {
1039
+ let t = e.toolbar;
1040
+ return [
1041
+ {
1042
+ type: "button",
1043
+ id: "undo",
1044
+ icon: "undo",
1045
+ title: t.undo,
1046
+ command: "undo"
1047
+ },
1048
+ {
1049
+ type: "button",
1050
+ id: "redo",
1051
+ icon: "redo",
1052
+ title: t.redo,
1053
+ command: "redo"
1054
+ },
1055
+ { type: "separator" },
1056
+ {
1057
+ type: "select",
1058
+ id: "blockType",
1059
+ title: t.textFormat,
1060
+ command: "setBlock",
1061
+ options: [
1062
+ {
1063
+ label: t.paragraph,
1064
+ value: "P"
1065
+ },
1066
+ {
1067
+ label: t.heading(1),
1068
+ value: "H1"
1069
+ },
1070
+ {
1071
+ label: t.heading(2),
1072
+ value: "H2"
1073
+ },
1074
+ {
1075
+ label: t.heading(3),
1076
+ value: "H3"
1077
+ },
1078
+ {
1079
+ label: t.heading(4),
1080
+ value: "H4"
1081
+ },
1082
+ {
1083
+ label: t.quote,
1084
+ value: "BLOCKQUOTE"
1085
+ },
1086
+ {
1087
+ label: t.codeBlock,
1088
+ value: "PRE"
1089
+ },
1090
+ {
1091
+ label: t.calloutInfo,
1092
+ value: "CALLOUT-info"
1093
+ },
1094
+ {
1095
+ label: t.calloutSuccess,
1096
+ value: "CALLOUT-success"
1097
+ },
1098
+ {
1099
+ label: t.calloutWarning,
1100
+ value: "CALLOUT-warning"
1101
+ },
1102
+ {
1103
+ label: t.calloutDanger,
1104
+ value: "CALLOUT-danger"
1105
+ }
1106
+ ],
1107
+ getValue: (e) => e.getActiveBlockType()
1108
+ },
1109
+ { type: "separator" },
1110
+ {
1111
+ type: "button",
1112
+ id: "bold",
1113
+ icon: "bold",
1114
+ title: t.bold,
1115
+ command: "bold",
1116
+ isActive: (e) => e.isMarkActive("bold")
1117
+ },
1118
+ {
1119
+ type: "button",
1120
+ id: "italic",
1121
+ icon: "italic",
1122
+ title: t.italic,
1123
+ command: "italic",
1124
+ isActive: (e) => e.isMarkActive("italic")
1125
+ },
1126
+ {
1127
+ type: "button",
1128
+ id: "underline",
1129
+ icon: "underline",
1130
+ title: t.underline,
1131
+ command: "underline",
1132
+ isActive: (e) => e.isMarkActive("underline")
1133
+ },
1134
+ {
1135
+ type: "button",
1136
+ id: "code",
1137
+ icon: "code_inline",
1138
+ title: t.inlineCode,
1139
+ command: "code",
1140
+ isActive: (e) => e.isMarkActive("code")
1141
+ },
1142
+ { type: "separator" },
1143
+ {
1144
+ type: "button",
1145
+ id: "alignLeft",
1146
+ icon: "alignLeft",
1147
+ title: t.alignLeft,
1148
+ command: "alignLeft"
1149
+ },
1150
+ {
1151
+ type: "button",
1152
+ id: "alignCenter",
1153
+ icon: "alignCenter",
1154
+ title: t.alignCenter,
1155
+ command: "alignCenter"
1156
+ },
1157
+ {
1158
+ type: "button",
1159
+ id: "alignRight",
1160
+ icon: "alignRight",
1161
+ title: t.alignRight,
1162
+ command: "alignRight"
1163
+ },
1164
+ {
1165
+ type: "button",
1166
+ id: "alignJustify",
1167
+ icon: "alignJustify",
1168
+ title: t.justify,
1169
+ command: "alignJustify"
1170
+ },
1171
+ { type: "separator" },
1172
+ {
1173
+ type: "button",
1174
+ id: "bulletList",
1175
+ icon: "bulletList",
1176
+ title: t.bulletList,
1177
+ command: "bulletList",
1178
+ isActive: (e) => e.getActiveBlockType() === "bullet_list"
1179
+ },
1180
+ {
1181
+ type: "button",
1182
+ id: "orderedList",
1183
+ icon: "orderedList",
1184
+ title: t.orderedList,
1185
+ command: "orderedList",
1186
+ isActive: (e) => e.getActiveBlockType() === "ordered_list"
1187
+ },
1188
+ { type: "separator" },
1189
+ {
1190
+ type: "button",
1191
+ id: "link",
1192
+ icon: "link",
1193
+ title: t.insertLink,
1194
+ command: "link"
1195
+ },
1196
+ {
1197
+ type: "button",
1198
+ id: "image",
1199
+ icon: "image",
1200
+ title: t.insertImage,
1201
+ command: "image"
1202
+ },
1203
+ {
1204
+ type: "button",
1205
+ id: "blockquote",
1206
+ icon: "blockquote",
1207
+ title: t.blockquote,
1208
+ command: "blockquote"
1209
+ },
1210
+ {
1211
+ type: "button",
1212
+ id: "hr",
1213
+ icon: "hr",
1214
+ title: t.horizontalRule,
1215
+ command: "hr"
1216
+ },
1217
+ {
1218
+ type: "button",
1219
+ id: "callout",
1220
+ icon: "callout",
1221
+ title: t.insertCallout,
1222
+ command: "callout",
1223
+ isActive: (e) => e.getActiveBlockType().startsWith("CALLOUT-")
1224
+ }
1225
+ ];
1226
+ }
1227
+ K(W);
1228
+ function Oe(e, t = W) {
1229
+ let n = K(t).filter((t) => t.type === "separator" || t.type === "spacer" ? !0 : "id" in t && e.includes(t.id)), r = [];
1230
+ for (let e of n) if (e.type === "separator") {
1231
+ let t = r[r.length - 1];
1232
+ if (!t || t.type === "separator" || t.type === "spacer") continue;
1233
+ r.push(e);
1234
+ } else r.push(e);
1235
+ for (; r.length > 0;) {
1236
+ let e = r[r.length - 1];
1237
+ if (e.type === "separator" || e.type === "spacer") r.pop();
1238
+ else break;
1239
+ }
1240
+ return r;
1241
+ }
1242
+ var q = "oe-callout-picker-styles";
1243
+ function ke() {
1244
+ if (document.getElementById(q)) return;
1245
+ let e = document.createElement("style");
1246
+ e.id = q, e.textContent = "\n.oe-callout-picker {\n position: fixed;\n z-index: 10000;\n background: var(--oe-bg, #ffffff);\n border: 1px solid var(--oe-border, #e7e5e4);\n border-radius: 10px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.12);\n padding: 5px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 160px;\n font-family: var(--oe-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n}\n.oe-callout-picker-item {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 10px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--oe-text, #1c1917);\n user-select: none;\n transition: background 80ms;\n}\n.oe-callout-picker-item:hover {\n background: var(--oe-btn-hover-bg, #f5f5f4);\n}\n.oe-callout-picker-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n", document.head.appendChild(e);
1247
+ }
1248
+ var Ae = [
1249
+ {
1250
+ variant: "info",
1251
+ label: "Info",
1252
+ color: "#3b82f6"
1253
+ },
1254
+ {
1255
+ variant: "success",
1256
+ label: "Success",
1257
+ color: "#22c55e"
1258
+ },
1259
+ {
1260
+ variant: "warning",
1261
+ label: "Warning",
1262
+ color: "#f59e0b"
1263
+ },
1264
+ {
1265
+ variant: "danger",
1266
+ label: "Danger",
1267
+ color: "#ef4444"
1268
+ }
1269
+ ], je = class {
1270
+ el;
1271
+ editor;
1272
+ config;
1273
+ itemEls = /* @__PURE__ */ new Map();
1274
+ disabled = !1;
1275
+ locale;
1276
+ calloutPickerEl = null;
1277
+ constructor(e, t, n, r, i = W) {
1278
+ this.el = e, this.editor = t, this.locale = i, n ? this.config = n : r ? this.config = Oe(r, i) : this.config = K(i), this.render();
1279
+ }
1280
+ render() {
1281
+ this.el.innerHTML = "", this.el.className = "oe-toolbar";
1282
+ for (let e of this.config) {
1283
+ let t = this.renderItem(e);
1284
+ this.el.appendChild(t);
1285
+ }
1286
+ }
1287
+ renderItem(e) {
1288
+ switch (e.type) {
1289
+ case "separator": {
1290
+ let e = document.createElement("div");
1291
+ return e.className = "oe-toolbar-sep", e;
1292
+ }
1293
+ case "spacer": {
1294
+ let e = document.createElement("div");
1295
+ return e.className = "oe-toolbar-spacer", e;
1296
+ }
1297
+ case "select": {
1298
+ let t = document.createElement("div");
1299
+ t.className = "oe-toolbar-select-wrap";
1300
+ let n = document.createElement("select");
1301
+ n.className = "oe-toolbar-select", n.title = e.title;
1302
+ for (let t of e.options) {
1303
+ let e = document.createElement("option");
1304
+ e.value = t.value, e.textContent = t.label, n.appendChild(e);
1305
+ }
1306
+ return n.addEventListener("change", () => {
1307
+ let e = n.value;
1308
+ this.handleBlockTypeChange(e), setTimeout(() => this.editor.focus(), 0);
1309
+ }), t.appendChild(n), this.itemEls.set(e.id, n), t;
1310
+ }
1311
+ case "button": {
1312
+ let t = document.createElement("button");
1313
+ return t.type = "button", t.className = "oe-toolbar-btn", t.title = e.title, t.innerHTML = De[e.icon] ?? e.icon, t.addEventListener("mousedown", (e) => {
1314
+ e.preventDefault();
1315
+ }), t.addEventListener("click", () => {
1316
+ this.handleCommand(e.command, e);
1317
+ }), this.itemEls.set(e.id, t), t;
1318
+ }
1319
+ }
1320
+ }
1321
+ handleCommand(e, t) {
1322
+ let n = this.editor;
1323
+ switch (e) {
1324
+ case "bold":
1325
+ n.chain().toggleMark("bold").run();
1326
+ break;
1327
+ case "italic":
1328
+ n.chain().toggleMark("italic").run();
1329
+ break;
1330
+ case "underline":
1331
+ n.chain().toggleMark("underline").run();
1332
+ break;
1333
+ case "code":
1334
+ n.chain().toggleMark("code").run();
1335
+ break;
1336
+ case "bulletList":
1337
+ n.chain().toggleList("bullet_list").run();
1338
+ break;
1339
+ case "orderedList":
1340
+ n.chain().toggleList("ordered_list").run();
1341
+ break;
1342
+ case "blockquote":
1343
+ n.chain().setBlock("blockquote").run();
1344
+ break;
1345
+ case "hr":
1346
+ n.chain().insertHr().run();
1347
+ break;
1348
+ case "callout": {
1349
+ let e = t ? this.itemEls.get(t.id) : null;
1350
+ e && this.toggleCalloutPicker(e);
1351
+ break;
1352
+ }
1353
+ case "undo":
1354
+ n.chain().undo().run();
1355
+ break;
1356
+ case "redo":
1357
+ n.chain().redo().run();
1358
+ break;
1359
+ case "alignLeft":
1360
+ n.chain().setAlign("left").run();
1361
+ break;
1362
+ case "alignCenter":
1363
+ n.chain().setAlign("center").run();
1364
+ break;
1365
+ case "alignRight":
1366
+ n.chain().setAlign("right").run();
1367
+ break;
1368
+ case "alignJustify":
1369
+ n.chain().setAlign("justify").run();
1370
+ break;
1371
+ case "link":
1372
+ this.handleLinkCommand();
1373
+ break;
1374
+ case "image":
1375
+ this.handleImageCommand();
1376
+ break;
1377
+ case "htmlToggle":
1378
+ n.toggleHTMLMode?.();
1379
+ break;
1380
+ }
1381
+ }
1382
+ toggleCalloutPicker(e) {
1383
+ if (this.calloutPickerEl) {
1384
+ this.closeCalloutPicker();
1385
+ return;
1386
+ }
1387
+ ke();
1388
+ let t = document.createElement("div");
1389
+ t.className = "oe-callout-picker", this.calloutPickerEl = t;
1390
+ for (let { variant: e, label: n, color: r } of Ae) {
1391
+ let i = document.createElement("div");
1392
+ i.className = "oe-callout-picker-item", i.innerHTML = `<span class="oe-callout-picker-dot" style="background:${r}"></span>${n}`, i.addEventListener("mousedown", (t) => {
1393
+ t.preventDefault(), this.closeCalloutPicker(), this.editor.chain().setBlock("callout", { variant: e }).run();
1394
+ }), t.appendChild(i);
1395
+ }
1396
+ document.body.appendChild(t);
1397
+ let n = e.getBoundingClientRect();
1398
+ t.style.top = `${n.bottom + 4}px`, t.style.left = `${n.left}px`, requestAnimationFrame(() => {
1399
+ if (!t.isConnected) return;
1400
+ let e = window.innerWidth;
1401
+ n.left + t.offsetWidth > e - 8 && (t.style.left = `${e - t.offsetWidth - 8}px`);
1402
+ });
1403
+ let r = (n) => {
1404
+ !t.contains(n.target) && n.target !== e && (this.closeCalloutPicker(), document.removeEventListener("mousedown", r, !0));
1405
+ };
1406
+ setTimeout(() => document.addEventListener("mousedown", r, !0), 0);
1407
+ }
1408
+ closeCalloutPicker() {
1409
+ this.calloutPickerEl?.remove(), this.calloutPickerEl = null;
1410
+ }
1411
+ handleBlockTypeChange(e) {
1412
+ switch (e) {
1413
+ case "P":
1414
+ this.editor.chain().setBlock("paragraph").run();
1415
+ return;
1416
+ case "H1":
1417
+ case "H2":
1418
+ case "H3":
1419
+ case "H4":
1420
+ case "H5":
1421
+ case "H6":
1422
+ this.editor.chain().setBlock("heading", { level: Number(e[1]) }).run();
1423
+ return;
1424
+ case "BLOCKQUOTE":
1425
+ this.editor.chain().setBlock("blockquote").run();
1426
+ return;
1427
+ case "PRE":
1428
+ this.editor.chain().setBlock("code_block").run();
1429
+ return;
1430
+ case "bullet_list":
1431
+ case "ordered_list":
1432
+ this.editor.chain().setBlock(e).run();
1433
+ return;
1434
+ case "CALLOUT-info":
1435
+ case "CALLOUT-success":
1436
+ case "CALLOUT-warning":
1437
+ case "CALLOUT-danger": {
1438
+ let t = e.split("-")[1];
1439
+ this.editor.chain().setBlock("callout", { variant: t }).run();
1440
+ return;
1441
+ }
1442
+ default: this.editor.chain().setBlock("paragraph").run();
1443
+ }
1444
+ }
1445
+ handleLinkCommand() {
1446
+ let e = window.getSelection(), t = e && !e.isCollapsed ? e.toString() : "", n = this.locale.dialogs, r = window.prompt(n.linkUrl, t.startsWith("http") ? t : "https://");
1447
+ if (!r) return;
1448
+ let i = window.confirm(n.openInNewTab) ? "_blank" : "_self";
1449
+ this.editor.chain().toggleMark("link", {
1450
+ href: r,
1451
+ target: i
1452
+ }).run();
1453
+ }
1454
+ handleImageCommand() {
1455
+ let e = this.locale.dialogs, t = window.prompt(e.imageUrl, "https://");
1456
+ if (!t) return;
1457
+ let n = window.prompt(e.imageAlt, "") ?? "";
1458
+ this.editor.chain().insertImage(t, n || void 0).run();
1459
+ }
1460
+ updateActiveState() {
1461
+ if (this.disabled) return;
1462
+ let e = U(this.editor.editorEl), t = this.editor.getActiveBlockType();
1463
+ for (let [n, r] of this.itemEls) {
1464
+ let i = this.config.find((e) => (e.type === "button" || e.type === "select") && "id" in e && e.id === n);
1465
+ if (i) {
1466
+ if (i.type === "select") {
1467
+ r.value = t;
1468
+ continue;
1469
+ }
1470
+ if (i.type === "button") {
1471
+ let a = i.isActive ? i.isActive(this.editor) : n === "bold" && e.has("bold") || n === "italic" && e.has("italic") || n === "underline" && e.has("underline") || n === "code" && e.has("code") || n === "link" && e.has("link") || n === "bulletList" && t === "bullet_list" || n === "orderedList" && t === "ordered_list";
1472
+ r.classList.toggle("oe-active", a);
1473
+ }
1474
+ }
1475
+ }
1476
+ }
1477
+ setDisabled(e) {
1478
+ this.disabled = e, this.el.classList.toggle("oe-toolbar-disabled", e);
1479
+ for (let t of this.itemEls.values()) t instanceof HTMLButtonElement && (t.disabled = e), t instanceof HTMLSelectElement && (t.disabled = e);
1480
+ }
1481
+ }, Me = class {
1482
+ el;
1483
+ editor;
1484
+ locale;
1485
+ hideTimer = null;
1486
+ constructor(e, t, n = W) {
1487
+ this.el = e, this.editor = t, this.locale = n, this.render();
1488
+ }
1489
+ get editorEl() {
1490
+ return this.editor.editorEl;
1491
+ }
1492
+ render() {
1493
+ this.el.className = "oe-bubble-toolbar";
1494
+ let e = this.locale.toolbar, t = this.locale.dialogs, n = [
1495
+ {
1496
+ id: "bold",
1497
+ icon: "bold",
1498
+ title: e.bold,
1499
+ action: () => this.editor.chain().toggleMark("bold").run(),
1500
+ isActive: () => this.editor.isMarkActive("bold")
1501
+ },
1502
+ {
1503
+ id: "italic",
1504
+ icon: "italic",
1505
+ title: e.italic,
1506
+ action: () => this.editor.chain().toggleMark("italic").run(),
1507
+ isActive: () => this.editor.isMarkActive("italic")
1508
+ },
1509
+ {
1510
+ id: "underline",
1511
+ icon: "underline",
1512
+ title: e.underline,
1513
+ action: () => this.editor.chain().toggleMark("underline").run(),
1514
+ isActive: () => this.editor.isMarkActive("underline")
1515
+ },
1516
+ {
1517
+ id: "code_inline",
1518
+ icon: "code_inline",
1519
+ title: e.inlineCode,
1520
+ action: () => this.editor.chain().toggleMark("code").run(),
1521
+ isActive: () => this.editor.isMarkActive("code")
1522
+ },
1523
+ {
1524
+ id: "link",
1525
+ icon: "link",
1526
+ title: e.insertLink,
1527
+ action: () => {
1528
+ let e = window.prompt(t.linkUrl, "https://");
1529
+ if (!e) return;
1530
+ let n = window.confirm(t.openInNewTab) ? "_blank" : "_self";
1531
+ this.editor.chain().toggleMark("link", {
1532
+ href: e,
1533
+ target: n
1534
+ }).run();
1535
+ },
1536
+ isActive: () => this.editor.isMarkActive("link")
1537
+ }
1538
+ ];
1539
+ for (let e of n) {
1540
+ let t = document.createElement("button");
1541
+ t.type = "button", t.className = "oe-bubble-btn", t.title = e.title, t.innerHTML = De[e.icon] ?? e.icon, t.dataset.btnId = e.id, t.addEventListener("mousedown", (e) => {
1542
+ e.preventDefault();
1543
+ }), t.addEventListener("click", () => {
1544
+ e.action(), this.updateActiveState();
1545
+ }), this.el.appendChild(t);
1546
+ }
1547
+ }
1548
+ onSelectionChange() {
1549
+ let e = window.getSelection();
1550
+ if (!e || e.isCollapsed || !this.editorEl.contains(e.anchorNode)) {
1551
+ this.hide();
1552
+ return;
1553
+ }
1554
+ this.hideTimer && clearTimeout(this.hideTimer), setTimeout(() => {
1555
+ let e = window.getSelection();
1556
+ if (!e || e.isCollapsed) {
1557
+ this.hide();
1558
+ return;
1559
+ }
1560
+ this.showAtSelection(), this.updateActiveState();
1561
+ }, 100);
1562
+ }
1563
+ showAtSelection() {
1564
+ let e = window.getSelection();
1565
+ if (!e || e.rangeCount === 0) return;
1566
+ let t = e.getRangeAt(0).getBoundingClientRect();
1567
+ if (!t.width && !t.height) {
1568
+ this.hide();
1569
+ return;
1570
+ }
1571
+ let n = window.scrollY, r = window.scrollX, i = t.top + n - 44 - 8, a = t.left + r + t.width / 2 - 280 / 2;
1572
+ i < n + 8 && (i = t.bottom + n + 8), a < 8 && (a = 8), a + 280 > window.innerWidth - 8 && (a = window.innerWidth - 280 - 8), this.el.style.top = `${i}px`, this.el.style.left = `${a}px`, this.el.classList.add("oe-bubble-visible");
1573
+ }
1574
+ hide() {
1575
+ this.hideTimer = setTimeout(() => {
1576
+ this.el.classList.remove("oe-bubble-visible");
1577
+ }, 200);
1578
+ }
1579
+ updateActiveState() {
1580
+ let e = U(this.editorEl);
1581
+ this.el.querySelectorAll(".oe-bubble-btn").forEach((t) => {
1582
+ let n = t.dataset.btnId ?? "", r = n === "bold" && e.has("bold") || n === "italic" && e.has("italic") || n === "underline" && e.has("underline") || n === "code_inline" && e.has("code") || n === "link" && e.has("link");
1583
+ t.classList.toggle("oe-active", r);
1584
+ });
1585
+ }
1586
+ destroy() {
1587
+ this.hideTimer && clearTimeout(this.hideTimer), this.el.remove();
1588
+ }
1589
+ }, Ne = "openedit-styles";
1590
+ function Pe(e) {
1591
+ if (document.getElementById(Ne)) return;
1592
+ let t = document.createElement("style");
1593
+ t.id = Ne, t.textContent = Fe(), document.head.appendChild(t);
1594
+ }
1595
+ function Fe() {
1596
+ return "\n/* ── CSS Custom Properties (Light Mode defaults) ────────────────────── */\n:root {\n --oe-bg: #ffffff;\n --oe-bg-toolbar: #fafaf9;\n --oe-bg-statusbar: #fafaf9;\n --oe-bg-code: #1c1917;\n --oe-bg-html: #1c1917;\n --oe-border: #e7e5e4;\n --oe-border-inner: #e7e5e4;\n --oe-text: #1c1917;\n --oe-text-muted: #78716c;\n --oe-text-light: #a8a29e;\n --oe-text-code: #f5f5f4;\n --oe-btn-active-bg: #1c1917;\n --oe-btn-active-fg: #ffffff;\n --oe-btn-hover-bg: #f5f5f4;\n --oe-shadow: 0 4px 16px rgba(0,0,0,0.07);\n --oe-radius: 16px;\n --oe-radius-sm: 8px;\n --oe-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --oe-font-mono: \"Fira Code\", \"Cascadia Code\", \"Courier New\", monospace;\n --oe-focus-ring: 0 0 0 4px rgba(28,25,23,0.05);\n --oe-link-color: #2563eb;\n --oe-mark-bg: rgba(251,191,36,0.4);\n --oe-blockquote-border: #d6d3d1;\n}\n\n/* Dark mode via attribute */\n[data-oe-theme=\"dark\"] .oe-container,\n.oe-container[data-oe-theme=\"dark\"] {\n --oe-bg: #1c1917;\n --oe-bg-toolbar: #1c1917;\n --oe-bg-statusbar: #161412;\n --oe-bg-code: #0c0a09;\n --oe-bg-html: #0c0a09;\n --oe-border: #3a3330;\n --oe-border-inner: #2c2a28;\n --oe-text: #e7e5e4;\n --oe-text-muted: #a8a29e;\n --oe-text-light: #78716c;\n --oe-btn-active-bg: #e7e5e4;\n --oe-btn-active-fg: #1c1917;\n --oe-btn-hover-bg: #292524;\n --oe-shadow: 0 4px 16px rgba(0,0,0,0.4);\n --oe-link-color: #60a5fa;\n --oe-mark-bg: rgba(180,130,0,0.3);\n --oe-blockquote-border: #57534e;\n}\n\n/* Auto dark mode (follows OS preference) */\n@media (prefers-color-scheme: dark) {\n [data-oe-theme=\"auto\"] .oe-container,\n .oe-container[data-oe-theme=\"auto\"] {\n --oe-bg: #1c1917;\n --oe-bg-toolbar: #1c1917;\n --oe-bg-statusbar: #161412;\n --oe-bg-code: #0c0a09;\n --oe-bg-html: #0c0a09;\n --oe-border: #3a3330;\n --oe-border-inner: #2c2a28;\n --oe-text: #e7e5e4;\n --oe-text-muted: #a8a29e;\n --oe-text-light: #78716c;\n --oe-btn-active-bg: #e7e5e4;\n --oe-btn-active-fg: #1c1917;\n --oe-btn-hover-bg: #292524;\n --oe-shadow: 0 4px 16px rgba(0,0,0,0.4);\n --oe-link-color: #60a5fa;\n --oe-mark-bg: rgba(180,130,0,0.3);\n --oe-blockquote-border: #57534e;\n }\n}\n\n/* ── Container ──────────────────────────────────────────────────────── */\n.oe-container {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--oe-border);\n border-radius: var(--oe-radius);\n overflow: hidden;\n background: var(--oe-bg);\n box-shadow: var(--oe-shadow);\n font-family: var(--oe-font);\n color: var(--oe-text);\n box-sizing: border-box;\n transition: box-shadow 0.15s, border-color 0.15s;\n}\n\n.oe-container.oe-focused {\n box-shadow: var(--oe-shadow), var(--oe-focus-ring);\n border-color: #a8a29e;\n}\n\n/* ── Toolbar ────────────────────────────────────────────────────────── */\n.oe-toolbar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 2px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--oe-border);\n background: var(--oe-bg-toolbar);\n border-radius: var(--oe-radius) var(--oe-radius) 0 0;\n min-height: 50px;\n box-sizing: border-box;\n}\n\n.oe-toolbar-disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.oe-toolbar-sep {\n width: 1px;\n height: 24px;\n background: var(--oe-border);\n margin: 0 6px;\n flex-shrink: 0;\n}\n\n.oe-toolbar-spacer {\n flex: 1;\n}\n\n.oe-toolbar-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--oe-radius-sm);\n background: transparent;\n color: var(--oe-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n transition: background 0.1s, color 0.1s;\n}\n\n.oe-toolbar-btn:hover {\n background: var(--oe-btn-hover-bg);\n color: var(--oe-text);\n}\n\n.oe-toolbar-btn.oe-active {\n background: var(--oe-btn-active-bg);\n color: var(--oe-btn-active-fg);\n}\n\n.oe-toolbar-btn:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n.oe-toolbar-select-wrap {\n position: relative;\n}\n\n.oe-toolbar-select {\n height: 32px;\n padding: 0 8px;\n border: 1px solid var(--oe-border);\n border-radius: var(--oe-radius-sm);\n background: var(--oe-bg);\n color: var(--oe-text);\n font-family: var(--oe-font);\n font-size: 13px;\n cursor: pointer;\n outline: none;\n min-width: 130px;\n transition: border-color 0.1s;\n}\n\n.oe-toolbar-select:hover {\n border-color: var(--oe-text-light);\n}\n\n.oe-toolbar-select:focus {\n border-color: var(--oe-text-muted);\n}\n\n/* ── Content wrapper ────────────────────────────────────────────────── */\n.oe-content-wrap {\n flex: 1;\n position: relative;\n min-height: 300px;\n display: flex;\n flex-direction: column;\n}\n\n/* ── Editor (contenteditable) ───────────────────────────────────────── */\n.oe-editor {\n flex: 1;\n padding: 28px 32px;\n outline: none;\n min-height: 300px;\n font-size: 15px;\n line-height: 1.7;\n color: var(--oe-text);\n background: var(--oe-bg);\n word-wrap: break-word;\n overflow-wrap: break-word;\n box-sizing: border-box;\n}\n\n/* Placeholder */\n.oe-editor.oe-empty::before {\n content: attr(data-placeholder);\n color: var(--oe-text-light);\n pointer-events: none;\n position: absolute;\n top: 28px;\n left: 32px;\n}\n\n/* Content styles */\n.oe-editor h1 { font-size: 1.875rem; font-weight: 700; margin: 0 0 1rem; color: var(--oe-text); }\n.oe-editor h2 { font-size: 1.5rem; font-weight: 600; margin: 1.4rem 0 0.75rem; color: var(--oe-text); }\n.oe-editor h3 { font-size: 1.25rem; font-weight: 600; margin: 1.2rem 0 0.6rem; color: var(--oe-text); }\n.oe-editor h4 { font-size: 1.125rem; font-weight: 600; margin: 1rem 0 0.5rem; color: var(--oe-text); }\n.oe-editor h1:first-child,\n.oe-editor h2:first-child { margin-top: 0; }\n.oe-editor p { margin: 0 0 0.875rem; }\n.oe-editor p:last-child { margin-bottom: 0; }\n.oe-editor strong, .oe-editor b { font-weight: 600; color: var(--oe-text); }\n.oe-editor em, .oe-editor i { font-style: italic; }\n.oe-editor u { text-decoration: underline; text-underline-offset: 2px; }\n.oe-editor s, .oe-editor del { text-decoration: line-through; color: var(--oe-text-muted); }\n.oe-editor code {\n background: rgba(0,0,0,0.06);\n color: #c2410c;\n border-radius: 4px;\n padding: 1px 5px;\n font-family: var(--oe-font-mono);\n font-size: 0.875em;\n}\n.oe-editor pre {\n background: var(--oe-bg-code);\n color: var(--oe-text-code);\n border-radius: 10px;\n padding: 16px 20px;\n padding-top: 32px;\n font-family: var(--oe-font-mono);\n font-size: 0.875rem;\n overflow-x: auto;\n margin: 0.875rem 0;\n line-height: 1.6;\n position: relative;\n}\n.oe-editor pre code { background: transparent; color: inherit; padding: 0; border-radius: 0; }\n/* Prevent highlight.js from overriding the <pre> background */\n.oe-editor pre code.hljs { background: transparent; }\n\n/* ── Code language badge ─────────────────────────────────────────────────── */\n.oe-code-lang-badge {\n position: absolute;\n top: 8px;\n right: 12px;\n font-size: 11px;\n font-family: var(--oe-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n font-weight: 500;\n color: rgba(255,255,255,0.35);\n background: transparent;\n cursor: pointer;\n user-select: none;\n padding: 2px 7px;\n border-radius: 4px;\n border: 1px solid transparent;\n transition: color 120ms, border-color 120ms;\n line-height: 1.5;\n letter-spacing: 0.02em;\n}\n.oe-code-lang-badge:hover {\n color: rgba(255,255,255,0.7);\n border-color: rgba(255,255,255,0.2);\n}\n\n/* ── Code language picker ────────────────────────────────────────────────── */\n.oe-code-lang-picker {\n position: fixed;\n z-index: 10000;\n background: var(--oe-bg, #ffffff);\n border: 1px solid var(--oe-border, #e7e5e4);\n border-radius: 10px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.13), 0 2px 8px rgba(0,0,0,0.07);\n padding: 6px;\n min-width: 180px;\n max-height: 280px;\n display: flex;\n flex-direction: column;\n font-family: var(--oe-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n}\n.oe-code-lang-picker-input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid var(--oe-border, #e7e5e4);\n border-radius: 6px;\n padding: 6px 9px;\n font-size: 13px;\n font-family: inherit;\n background: var(--oe-bg, #fff);\n color: var(--oe-text, #1c1917);\n outline: none;\n margin-bottom: 4px;\n flex-shrink: 0;\n}\n.oe-code-lang-picker-input:focus {\n border-color: var(--oe-btn-active-bg, #1c1917);\n}\n.oe-code-lang-picker-list {\n overflow-y: auto;\n flex: 1;\n}\n.oe-code-lang-picker-item {\n padding: 6px 10px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--oe-text, #1c1917);\n font-family: var(--oe-font-mono, monospace);\n user-select: none;\n transition: background 80ms;\n}\n.oe-code-lang-picker-item:hover,\n.oe-code-lang-picker-item.oe-active {\n background: var(--oe-btn-hover-bg, #f5f5f4);\n}\n.oe-code-lang-picker-item.oe-active {\n background: var(--oe-btn-active-bg, #1c1917);\n color: var(--oe-btn-active-fg, #ffffff);\n}\n.oe-editor blockquote {\n border-left: 4px solid var(--oe-blockquote-border);\n padding: 4px 0 4px 16px;\n margin: 0.875rem 0;\n color: var(--oe-text-muted);\n font-style: italic;\n background: rgba(0,0,0,0.02);\n border-radius: 0 6px 6px 0;\n}\n.oe-editor ul { list-style: disc; padding-left: 1.5rem; margin: 0.875rem 0; }\n.oe-editor ol { list-style: decimal; padding-left: 1.5rem; margin: 0.875rem 0; }\n.oe-editor li { margin-bottom: 0.25rem; }\n.oe-editor a { color: var(--oe-link-color); text-decoration: underline; text-underline-offset: 2px; }\n.oe-editor mark { background: var(--oe-mark-bg); border-radius: 3px; padding: 0 3px; color: var(--oe-text); }\n.oe-editor hr { border: none; border-top: 2px solid var(--oe-border); margin: 1.5rem 0; }\n.oe-editor img { max-width: 100%; height: auto; border-radius: 8px; border: 1px solid var(--oe-border); cursor: pointer; transition: box-shadow 0.15s; }\n.oe-editor img:hover { box-shadow: 0 0 0 3px rgba(59,130,246,0.35); }\n.oe-image-wrapper { margin: 0.875rem 0; display: block; }\n\n/* ── Callout Blocks ─────────────────────────────────────────────────── */\n.oe-editor .oe-callout {\n display: block;\n position: relative;\n padding: 12px 16px 12px 20px;\n margin: 0.875rem 0;\n border-left: 4px solid var(--oe-callout-border, #3b82f6);\n border-radius: 0 8px 8px 0;\n background: var(--oe-callout-bg, rgba(59,130,246,0.07));\n color: var(--oe-text);\n font-style: normal;\n line-height: 1.6;\n}\n\n/* Info */\n.oe-editor .oe-callout-info {\n --oe-callout-border: #3b82f6;\n --oe-callout-bg: rgba(59,130,246,0.07);\n --oe-callout-icon-color: #3b82f6;\n}\n.oe-editor .oe-callout-info::before {\n content: 'ℹ';\n position: absolute;\n left: -1.45rem;\n top: 50%;\n transform: translateY(-50%);\n font-size: 0.85em;\n color: var(--oe-callout-icon-color);\n line-height: 1;\n}\n\n/* Success */\n.oe-editor .oe-callout-success {\n --oe-callout-border: #22c55e;\n --oe-callout-bg: rgba(34,197,94,0.07);\n --oe-callout-icon-color: #22c55e;\n}\n.oe-editor .oe-callout-success::before {\n content: '✓';\n position: absolute;\n left: -1.3rem;\n top: 50%;\n transform: translateY(-50%);\n font-size: 0.85em;\n font-weight: 700;\n color: var(--oe-callout-icon-color);\n line-height: 1;\n}\n\n/* Warning */\n.oe-editor .oe-callout-warning {\n --oe-callout-border: #f59e0b;\n --oe-callout-bg: rgba(245,158,11,0.07);\n --oe-callout-icon-color: #f59e0b;\n}\n.oe-editor .oe-callout-warning::before {\n content: '⚠';\n position: absolute;\n left: -1.45rem;\n top: 50%;\n transform: translateY(-50%);\n font-size: 0.8em;\n color: var(--oe-callout-icon-color);\n line-height: 1;\n}\n\n/* Danger */\n.oe-editor .oe-callout-danger {\n --oe-callout-border: #ef4444;\n --oe-callout-bg: rgba(239,68,68,0.07);\n --oe-callout-icon-color: #ef4444;\n}\n.oe-editor .oe-callout-danger::before {\n content: '✕';\n position: absolute;\n left: -1.3rem;\n top: 50%;\n transform: translateY(-50%);\n font-size: 0.8em;\n font-weight: 700;\n color: var(--oe-callout-icon-color);\n line-height: 1;\n}\n\n/* Dark mode adjustments */\n[data-oe-theme=\"dark\"] .oe-editor .oe-callout-info,\n.oe-container[data-oe-theme=\"dark\"] .oe-editor .oe-callout-info {\n --oe-callout-bg: rgba(59,130,246,0.12);\n}\n[data-oe-theme=\"dark\"] .oe-editor .oe-callout-success,\n.oe-container[data-oe-theme=\"dark\"] .oe-editor .oe-callout-success {\n --oe-callout-bg: rgba(34,197,94,0.12);\n}\n[data-oe-theme=\"dark\"] .oe-editor .oe-callout-warning,\n.oe-container[data-oe-theme=\"dark\"] .oe-editor .oe-callout-warning {\n --oe-callout-bg: rgba(245,158,11,0.12);\n}\n[data-oe-theme=\"dark\"] .oe-editor .oe-callout-danger,\n.oe-container[data-oe-theme=\"dark\"] .oe-editor .oe-callout-danger {\n --oe-callout-bg: rgba(239,68,68,0.12);\n}\n@media (prefers-color-scheme: dark) {\n [data-oe-theme=\"auto\"] .oe-editor .oe-callout-info { --oe-callout-bg: rgba(59,130,246,0.12); }\n [data-oe-theme=\"auto\"] .oe-editor .oe-callout-success { --oe-callout-bg: rgba(34,197,94,0.12); }\n [data-oe-theme=\"auto\"] .oe-editor .oe-callout-warning { --oe-callout-bg: rgba(245,158,11,0.12); }\n [data-oe-theme=\"auto\"] .oe-editor .oe-callout-danger { --oe-callout-bg: rgba(239,68,68,0.12); }\n}\n\n/* ── Template Tags (K13) ────────────────────────────────────────────── */\n.oe-template-tag {\n display: inline-flex;\n align-items: center;\n background: rgba(99, 102, 241, 0.12);\n color: #4f46e5;\n border: 1px solid rgba(99, 102, 241, 0.25);\n border-radius: 6px;\n padding: 0 6px;\n font-size: 0.8em;\n font-family: var(--oe-font-mono);\n font-weight: 500;\n cursor: default;\n user-select: none;\n white-space: nowrap;\n vertical-align: baseline;\n line-height: 1.6;\n}\n[data-oe-theme=\"dark\"] .oe-template-tag {\n background: rgba(129, 140, 248, 0.15);\n color: #a5b4fc;\n border-color: rgba(129, 140, 248, 0.3);\n}\n\n/* ── HTML Source View ───────────────────────────────────────────────── */\n.oe-html-source {\n flex: 1;\n min-height: 300px;\n display: flex;\n flex-direction: column;\n}\n\n.oe-html-textarea {\n flex: 1;\n min-height: 300px;\n padding: 28px 32px;\n background: var(--oe-bg-html);\n color: #a5f3fc;\n font-family: var(--oe-font-mono);\n font-size: 13px;\n line-height: 1.7;\n border: none;\n outline: none;\n resize: none;\n tab-size: 2;\n box-sizing: border-box;\n}\n\n/* ── Status bar ─────────────────────────────────────────────────────── */\n.oe-statusbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n background: var(--oe-bg-statusbar);\n border-top: 1px solid var(--oe-border);\n border-radius: 0 0 var(--oe-radius) var(--oe-radius);\n font-size: 12px;\n color: var(--oe-text-muted);\n min-height: 38px;\n box-sizing: border-box;\n}\n\n.oe-statusbar-path {\n font-family: var(--oe-font-mono);\n font-size: 11px;\n color: var(--oe-text-light);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 40%;\n}\n\n.oe-statusbar-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.oe-word-count,\n.oe-char-count {\n white-space: nowrap;\n}\n\n.oe-statusbar-divider {\n width: 1px;\n height: 14px;\n background: var(--oe-border);\n}\n\n.oe-html-toggle {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 0;\n background: none;\n border: none;\n color: var(--oe-text-muted);\n cursor: pointer;\n font-size: 12px;\n font-family: var(--oe-font);\n font-weight: 500;\n transition: color 0.1s;\n}\n\n.oe-html-toggle:hover {\n color: var(--oe-text);\n text-decoration: underline;\n}\n\n.oe-html-toggle.oe-active {\n color: var(--oe-text);\n}\n\n/* ── Bubble toolbar ─────────────────────────────────────────────────── */\n.oe-bubble-toolbar {\n position: absolute;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 6px 8px;\n background: var(--oe-text);\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0,0,0,0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n z-index: 9999;\n white-space: nowrap;\n}\n\n.oe-bubble-toolbar.oe-bubble-visible {\n opacity: 1;\n pointer-events: all;\n}\n\n.oe-bubble-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--oe-btn-active-fg);\n cursor: pointer;\n transition: background 0.1s;\n}\n\n.oe-bubble-btn:hover {\n background: rgba(255,255,255,0.15);\n}\n\n.oe-bubble-btn.oe-active {\n background: rgba(255,255,255,0.25);\n}\n";
1597
+ }
1598
+ //#endregion
1599
+ //#region src/view/image-resize.ts
1600
+ var Ie = class {
1601
+ editorEl;
1602
+ syncCallback;
1603
+ overlay = null;
1604
+ selectedImg = null;
1605
+ scrollParents = [];
1606
+ boundUpdatePos = null;
1607
+ constructor(e, t) {
1608
+ this.editorEl = e, this.syncCallback = t, e.addEventListener("click", this.onEditorClick), document.addEventListener("mousedown", this.onDocMousedown, !0);
1609
+ }
1610
+ destroy() {
1611
+ this.editorEl.removeEventListener("click", this.onEditorClick), document.removeEventListener("mousedown", this.onDocMousedown, !0), this.hideOverlay();
1612
+ }
1613
+ onEditorClick = (e) => {
1614
+ e.target instanceof HTMLImageElement && (e.stopPropagation(), this.selectImage(e.target));
1615
+ };
1616
+ onDocMousedown = (e) => {
1617
+ if (!this.overlay) return;
1618
+ let t = e.target;
1619
+ this.overlay.contains(t) || t === this.selectedImg || this.hideOverlay();
1620
+ };
1621
+ selectImage(e) {
1622
+ this.hideOverlay(), this.selectedImg = e;
1623
+ let t = document.createElement("div");
1624
+ t.className = "oe-img-overlay", Object.assign(t.style, {
1625
+ position: "fixed",
1626
+ border: "2px solid #3b82f6",
1627
+ borderRadius: "3px",
1628
+ zIndex: "9900",
1629
+ pointerEvents: "none",
1630
+ boxSizing: "border-box"
1631
+ });
1632
+ for (let n of [
1633
+ "nw",
1634
+ "ne",
1635
+ "sw",
1636
+ "se"
1637
+ ]) {
1638
+ let r = document.createElement("div");
1639
+ r.className = `oe-img-handle oe-img-handle-${n}`, Object.assign(r.style, {
1640
+ position: "absolute",
1641
+ width: "10px",
1642
+ height: "10px",
1643
+ background: "#ffffff",
1644
+ border: "2px solid #3b82f6",
1645
+ borderRadius: "2px",
1646
+ boxSizing: "border-box",
1647
+ pointerEvents: "all",
1648
+ cursor: `${n}-resize`,
1649
+ ...Le(n)
1650
+ }), r.addEventListener("mousedown", (t) => {
1651
+ t.preventDefault(), t.stopPropagation(), this.startResize(t, e, n);
1652
+ }), t.appendChild(r);
1653
+ }
1654
+ let n = document.createElement("div");
1655
+ n.className = "oe-img-label", Object.assign(n.style, {
1656
+ position: "absolute",
1657
+ bottom: "-26px",
1658
+ right: "0",
1659
+ background: "rgba(28,25,23,0.85)",
1660
+ color: "#fff",
1661
+ fontSize: "11px",
1662
+ fontFamily: "monospace",
1663
+ padding: "2px 6px",
1664
+ borderRadius: "4px",
1665
+ whiteSpace: "nowrap",
1666
+ pointerEvents: "none"
1667
+ }), t.appendChild(n), document.body.appendChild(t), this.overlay = t;
1668
+ let r = () => {
1669
+ if (!e.isConnected) {
1670
+ this.hideOverlay();
1671
+ return;
1672
+ }
1673
+ let r = e.getBoundingClientRect();
1674
+ Object.assign(t.style, {
1675
+ top: `${r.top}px`,
1676
+ left: `${r.left}px`,
1677
+ width: `${r.width}px`,
1678
+ height: `${r.height}px`
1679
+ }), n.textContent = `${Math.round(r.width)} × ${Math.round(r.height)}`;
1680
+ };
1681
+ r(), this.boundUpdatePos = r, window.addEventListener("scroll", r, {
1682
+ passive: !0,
1683
+ capture: !0
1684
+ }), window.addEventListener("resize", r, { passive: !0 });
1685
+ }
1686
+ hideOverlay() {
1687
+ this.overlay &&= (this.overlay.remove(), null), this.boundUpdatePos &&= (window.removeEventListener("scroll", this.boundUpdatePos, !0), window.removeEventListener("resize", this.boundUpdatePos), null), this.selectedImg = null;
1688
+ }
1689
+ startResize(e, t, n) {
1690
+ let r = e.clientX, i = e.clientY, a = t.getBoundingClientRect().width, o = a / (t.getBoundingClientRect().height || 1), s = document.body.style.userSelect;
1691
+ document.body.style.userSelect = "none";
1692
+ let c = (e) => {
1693
+ let s = e.clientX - r, c = e.clientY - i, l = n === "ne" || n === "se", u = n === "sw" || n === "se", d = l ? s : -s, f = u ? c : -c, p = Math.abs(d) >= Math.abs(f) ? d : f * o, m = Math.max(40, Math.round(a + p)), h = Math.max(20, Math.round(m / o));
1694
+ t.style.width = `${m}px`, t.style.height = "auto", t.setAttribute("width", String(m)), t.setAttribute("height", String(h)), this.boundUpdatePos?.();
1695
+ }, l = () => {
1696
+ document.removeEventListener("mousemove", c), document.removeEventListener("mouseup", l), document.body.style.userSelect = s, this.syncCallback();
1697
+ };
1698
+ document.addEventListener("mousemove", c), document.addEventListener("mouseup", l);
1699
+ }
1700
+ };
1701
+ function Le(e) {
1702
+ let t = "-6px";
1703
+ switch (e) {
1704
+ case "nw": return {
1705
+ top: t,
1706
+ left: t
1707
+ };
1708
+ case "ne": return {
1709
+ top: t,
1710
+ right: t
1711
+ };
1712
+ case "sw": return {
1713
+ bottom: t,
1714
+ left: t
1715
+ };
1716
+ case "se": return {
1717
+ bottom: t,
1718
+ right: t
1719
+ };
1720
+ }
1721
+ }
1722
+ //#endregion
1723
+ //#region src/view/code-lang-picker.ts
1724
+ var Re = /* @__PURE__ */ "plain.bash.c.cpp.csharp.css.dockerfile.go.graphql.html.java.javascript.json.kotlin.markdown.php.python.ruby.rust.scss.shell.sql.swift.typescript.xml.yaml".split("."), ze = class {
1725
+ editorEl;
1726
+ editor;
1727
+ pickerEl = null;
1728
+ activeIndex = 0;
1729
+ filtered = [];
1730
+ targetPreEl = null;
1731
+ onOutside = null;
1732
+ onOutsideTimer = null;
1733
+ constructor(e, t) {
1734
+ this.editorEl = e, this.editor = t, this.editorEl.addEventListener("mousedown", this.onBadgeMousedown, !0), this.editorEl.addEventListener("click", this.onBadgeClick, !0);
1735
+ }
1736
+ onBadgeMousedown = (e) => {
1737
+ e.target.classList.contains("oe-code-lang-badge") && (e.preventDefault(), e.stopPropagation());
1738
+ };
1739
+ onBadgeClick = (e) => {
1740
+ let t = e.target;
1741
+ if (!t.classList.contains("oe-code-lang-badge")) return;
1742
+ e.preventDefault(), e.stopPropagation();
1743
+ let n = t.closest("pre");
1744
+ if (n) {
1745
+ if (this.pickerEl && this.targetPreEl === n) {
1746
+ this.closePicker();
1747
+ return;
1748
+ }
1749
+ this.closePicker(), this.targetPreEl = n, this.openPicker(t, n);
1750
+ }
1751
+ };
1752
+ openPicker(e, t) {
1753
+ let n = document.createElement("div");
1754
+ n.className = "oe-code-lang-picker", this.pickerEl = n;
1755
+ let r = document.createElement("input");
1756
+ r.type = "text", r.className = "oe-code-lang-picker-input", r.placeholder = "Filter…", n.appendChild(r);
1757
+ let i = document.createElement("div");
1758
+ i.className = "oe-code-lang-picker-list", n.appendChild(i), document.body.appendChild(n), this.renderList(i, "");
1759
+ let a = e.getBoundingClientRect();
1760
+ n.style.top = `${a.bottom + 4}px`, n.style.left = `${a.left}px`, requestAnimationFrame(() => {
1761
+ if (!n.isConnected) return;
1762
+ let e = window.innerWidth;
1763
+ a.left + n.offsetWidth > e - 8 && (n.style.left = `${e - n.offsetWidth - 8}px`), r.focus();
1764
+ }), r.addEventListener("keydown", (e) => {
1765
+ if (e.key === "ArrowDown") e.preventDefault(), this.activeIndex = Math.min(this.activeIndex + 1, this.filtered.length - 1), this.updateActive(i);
1766
+ else if (e.key === "ArrowUp") e.preventDefault(), this.activeIndex = Math.max(this.activeIndex - 1, 0), this.updateActive(i);
1767
+ else if (e.key === "Enter") {
1768
+ e.preventDefault();
1769
+ let n = this.filtered[this.activeIndex];
1770
+ n !== void 0 && this.selectLang(n, t);
1771
+ } else e.key === "Escape" && this.closePicker();
1772
+ }), r.addEventListener("input", () => {
1773
+ this.activeIndex = 0, this.renderList(i, r.value.trim().toLowerCase());
1774
+ }), this.onOutside = (e) => {
1775
+ n.contains(e.target) || this.closePicker();
1776
+ }, this.onOutsideTimer = setTimeout(() => {
1777
+ this.onOutsideTimer = null, this.onOutside && document.addEventListener("mousedown", this.onOutside, !0);
1778
+ }, 0);
1779
+ }
1780
+ renderList(e, t) {
1781
+ this.filtered = t ? Re.filter((e) => e.includes(t)) : Re, e.innerHTML = "", this.filtered.forEach((t, n) => {
1782
+ let r = document.createElement("div");
1783
+ r.className = "oe-code-lang-picker-item" + (n === this.activeIndex ? " oe-active" : ""), r.textContent = t, r.addEventListener("mousedown", (e) => {
1784
+ e.preventDefault(), this.selectLang(t, this.targetPreEl);
1785
+ }), e.appendChild(r);
1786
+ });
1787
+ }
1788
+ updateActive(e) {
1789
+ e.querySelectorAll(".oe-code-lang-picker-item").forEach((e, t) => {
1790
+ e.classList.toggle("oe-active", t === this.activeIndex), t === this.activeIndex && e.scrollIntoView({ block: "nearest" });
1791
+ });
1792
+ }
1793
+ selectLang(e, t) {
1794
+ this.closePicker();
1795
+ let n = t.querySelector("code");
1796
+ if (n) {
1797
+ let e = window.getSelection();
1798
+ if (e) {
1799
+ let t = document.createRange();
1800
+ t.setStart(n, 0), t.collapse(!0), e.removeAllRanges(), e.addRange(t);
1801
+ }
1802
+ }
1803
+ let r = e === "plain" ? void 0 : e;
1804
+ this.editor.chain().setBlock("code_block", { lang: r }).run();
1805
+ }
1806
+ closePicker() {
1807
+ this.onOutsideTimer !== null && (clearTimeout(this.onOutsideTimer), this.onOutsideTimer = null), this.onOutside &&= (document.removeEventListener("mousedown", this.onOutside, !0), null), this.pickerEl?.remove(), this.pickerEl = null, this.targetPreEl = null, this.activeIndex = 0, this.filtered = [];
1808
+ }
1809
+ destroy() {
1810
+ this.closePicker(), this.editorEl.removeEventListener("mousedown", this.onBadgeMousedown, !0), this.editorEl.removeEventListener("click", this.onBadgeClick, !0);
1811
+ }
1812
+ }, J = {
1813
+ toolbar: {
1814
+ undo: "Rückgängig (Ctrl+Z)",
1815
+ redo: "Wiederholen (Ctrl+Y)",
1816
+ textFormat: "Textformat",
1817
+ paragraph: "Absatz",
1818
+ heading: (e) => `Überschrift ${e}`,
1819
+ quote: "Zitat",
1820
+ codeBlock: "Code-Block",
1821
+ bold: "Fett (Ctrl+B)",
1822
+ italic: "Kursiv (Ctrl+I)",
1823
+ underline: "Unterstrichen (Ctrl+U)",
1824
+ inlineCode: "Inline-Code (Ctrl+`)",
1825
+ alignLeft: "Linksbündig",
1826
+ alignCenter: "Zentriert",
1827
+ alignRight: "Rechtsbündig",
1828
+ justify: "Blocksatz",
1829
+ bulletList: "Aufzählungsliste",
1830
+ orderedList: "Nummerierte Liste",
1831
+ insertLink: "Link einfügen",
1832
+ insertImage: "Bild einfügen",
1833
+ blockquote: "Zitat",
1834
+ horizontalRule: "Trennlinie",
1835
+ htmlSource: "HTML-Quellcode anzeigen",
1836
+ calloutInfo: "Hinweis: Info",
1837
+ calloutSuccess: "Hinweis: Erfolg",
1838
+ calloutWarning: "Hinweis: Warnung",
1839
+ calloutDanger: "Hinweis: Gefahr",
1840
+ insertCallout: "Hinweisbox einfügen"
1841
+ },
1842
+ statusBar: {
1843
+ words: "Wörter",
1844
+ characters: "Zeichen",
1845
+ htmlSource: "HTML"
1846
+ },
1847
+ dialogs: {
1848
+ linkUrl: "Link-URL:",
1849
+ openInNewTab: "In neuem Tab öffnen?",
1850
+ imageUrl: "Bild-URL:",
1851
+ imageAlt: "Alternativtext (optional):"
1852
+ },
1853
+ plugins: {
1854
+ ai: {
1855
+ panelTitle: "KI-Assistent",
1856
+ noSelection: "(Kein Text ausgewählt — gesamtes Dokument wird verwendet)",
1857
+ customPromptPlaceholder: "Eigene Anweisung eingeben…",
1858
+ runButton: "Ausführen",
1859
+ applyButton: "Übernehmen",
1860
+ generating: "⏳ Wird generiert…",
1861
+ noApiKey: "⚠️ Kein API-Key konfiguriert. Übergib apiKey oder endpoint beim Erstellen des Plugins.",
1862
+ errorPrefix: "❌ Fehler: ",
1863
+ actions: {
1864
+ improve: "Verbessern",
1865
+ shorten: "Kürzen",
1866
+ expand: "Erweitern",
1867
+ summarize: "Zusammenfassen",
1868
+ toGerman: "🇩🇪 Auf Deutsch",
1869
+ toEnglish: "🇬🇧 To English"
1870
+ }
1871
+ },
1872
+ emoji: {
1873
+ buttonTitle: "Emoji einfügen",
1874
+ categories: {
1875
+ faces: "Gesichter",
1876
+ hearts: "Herzen",
1877
+ gestures: "Gesten",
1878
+ nature: "Natur",
1879
+ food: "Essen",
1880
+ objects: "Objekte",
1881
+ symbols: "Symbole"
1882
+ }
1883
+ }
1884
+ }
1885
+ }, Be = { de: J };
1886
+ function Ve() {
1887
+ return Be[(typeof navigator < "u" ? navigator.language : "").split("-")[0].toLowerCase()] ?? W;
1888
+ }
1889
+ function He(e) {
1890
+ return {
1891
+ toolbar: {
1892
+ ...W.toolbar,
1893
+ ...e.toolbar
1894
+ },
1895
+ statusBar: {
1896
+ ...W.statusBar,
1897
+ ...e.statusBar
1898
+ },
1899
+ dialogs: {
1900
+ ...W.dialogs,
1901
+ ...e.dialogs
1902
+ },
1903
+ plugins: {
1904
+ ai: {
1905
+ ...W.plugins.ai,
1906
+ actions: {
1907
+ ...W.plugins.ai.actions,
1908
+ ...e.plugins?.ai?.actions
1909
+ },
1910
+ ...e.plugins?.ai
1911
+ },
1912
+ emoji: {
1913
+ ...W.plugins.emoji,
1914
+ categories: {
1915
+ ...W.plugins.emoji.categories,
1916
+ ...e.plugins?.emoji?.categories
1917
+ },
1918
+ ...e.plugins?.emoji
1919
+ }
1920
+ }
1921
+ };
1922
+ }
1923
+ var Ue = class {
1924
+ doc;
1925
+ history;
1926
+ root;
1927
+ editorEl;
1928
+ containerEl;
1929
+ toolbar = null;
1930
+ bubbleToolbar = null;
1931
+ imageResizer = null;
1932
+ codeLangPicker = null;
1933
+ plugins = [];
1934
+ options;
1935
+ locale;
1936
+ listeners = {
1937
+ change: /* @__PURE__ */ new Set(),
1938
+ selectionchange: /* @__PURE__ */ new Set(),
1939
+ focus: /* @__PURE__ */ new Set(),
1940
+ blur: /* @__PURE__ */ new Set()
1941
+ };
1942
+ isComposing = !1;
1943
+ _isFocused = !1;
1944
+ isUpdating = !1;
1945
+ syncTimer = null;
1946
+ constructor(e) {
1947
+ this.options = e, this.locale = e.locale ? He(e.locale) : Ve(), this.history = new t();
1948
+ let n = typeof e.element == "string" ? document.querySelector(e.element) : e.element;
1949
+ if (!n) throw Error(`[OpenEdit] Element not found: ${e.element}`);
1950
+ this.root = n, this.doc = e.content ? h(e.content) : p(), this.containerEl = this.buildContainer(), this.editorEl = this.buildEditorEl(), this.root.appendChild(this.containerEl), Pe(e.theme ?? "auto"), M(this.doc, this.editorEl), this.toolbar = new je(this.containerEl.querySelector(".oe-toolbar"), this, e.toolbar, e.toolbarItems, this.locale);
1951
+ let r = document.createElement("div");
1952
+ r.className = "oe-bubble-toolbar", document.body.appendChild(r), this.bubbleToolbar = new Me(r, this, this.locale), this.imageResizer = new Ie(this.editorEl, () => this.scheduleSyncFromDOM()), this.codeLangPicker = new ze(this.editorEl, this), this.updatePlaceholder(), this.attachEvents(), this.applyTheme(e.theme ?? "auto");
1953
+ }
1954
+ buildContainer() {
1955
+ let e = document.createElement("div");
1956
+ e.className = "oe-container", e.innerHTML = `
1957
+ <div class="oe-toolbar"></div>
1958
+ <div class="oe-content-wrap">
1959
+ <div class="oe-editor" contenteditable="true" spellcheck="true"></div>
1960
+ <div class="oe-html-source" style="display:none">
1961
+ <textarea class="oe-html-textarea" spellcheck="false"></textarea>
1962
+ </div>
1963
+ </div>
1964
+ <div class="oe-statusbar">
1965
+ <div class="oe-statusbar-path"></div>
1966
+ <div class="oe-statusbar-right">
1967
+ <span class="oe-word-count">${this.locale.statusBar.words}: 0</span>
1968
+ <span class="oe-char-count">${this.locale.statusBar.characters}: 0</span>
1969
+ <div class="oe-statusbar-divider"></div>
1970
+ <button type="button" class="oe-html-toggle" title="${this.locale.toolbar.htmlSource}">
1971
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 9l-3 3 3 3"/><path d="M14 15l3-3-3-3"/><rect x="2" y="3" width="20" height="18" rx="2"/></svg>
1972
+ ${this.locale.statusBar.htmlSource}
1973
+ </button>
1974
+ </div>
1975
+ </div>
1976
+ `;
1977
+ let t = this.options.statusBar;
1978
+ return t === !1 ? e.querySelector(".oe-statusbar")?.remove() : t !== void 0 && typeof t == "object" && (t.wordCount === !1 && e.querySelector(".oe-word-count")?.remove(), t.charCount === !1 && e.querySelector(".oe-char-count")?.remove(), t.elementPath === !1 && e.querySelector(".oe-statusbar-path")?.remove(), t.htmlToggle === !1 && (e.querySelector(".oe-html-toggle")?.remove(), e.querySelector(".oe-statusbar-divider")?.remove())), e;
1979
+ }
1980
+ buildEditorEl() {
1981
+ let e = this.containerEl.querySelector(".oe-editor");
1982
+ return this.options.placeholder && (e.dataset.placeholder = this.options.placeholder), this.options.readOnly && (e.contentEditable = "false"), e;
1983
+ }
1984
+ attachEvents() {
1985
+ let e = this.editorEl;
1986
+ e.addEventListener("input", this.onInput), e.addEventListener("compositionstart", this.onCompositionStart), e.addEventListener("compositionend", this.onCompositionEnd), document.addEventListener("selectionchange", this.onSelectionChange), e.addEventListener("focus", this.onFocus), e.addEventListener("blur", this.onBlur), e.addEventListener("keydown", this.onKeydown), e.addEventListener("keydown", this.onTabInCodeBlock), this.containerEl.querySelector(".oe-html-toggle").addEventListener("click", this.onHTMLToggleClick), e.addEventListener("paste", this.onPaste), e.addEventListener("drop", this.onDrop);
1987
+ }
1988
+ onInput = () => {
1989
+ this.isComposing || this.isUpdating || this.scheduleSyncFromDOM();
1990
+ };
1991
+ onCompositionStart = () => {
1992
+ this.isComposing = !0;
1993
+ };
1994
+ onCompositionEnd = () => {
1995
+ this.isComposing = !1, this.scheduleSyncFromDOM();
1996
+ };
1997
+ onHTMLToggleClick = () => {
1998
+ this.toggleHTMLMode();
1999
+ };
2000
+ scheduleSyncFromDOM() {
2001
+ this.syncTimer && clearTimeout(this.syncTimer), this.syncTimer = setTimeout(() => {
2002
+ this.history.push(this.doc), this.doc = F(this.editorEl), this.updatePlaceholder(), this.updateStatusBar(), this.emit("change", this.doc), this.options.onChange?.(this.getHTML());
2003
+ }, 0);
2004
+ }
2005
+ syncModelFromDOM() {
2006
+ this.syncTimer && clearTimeout(this.syncTimer), this.syncTimer = setTimeout(() => {
2007
+ this.doc = F(this.editorEl), this.updatePlaceholder(), this.updateStatusBar();
2008
+ }, 0);
2009
+ }
2010
+ onSelectionChange = () => {
2011
+ if (!this.editorEl.contains(document.activeElement) && document.activeElement !== this.editorEl) return;
2012
+ this.toolbar?.updateActiveState(), this.bubbleToolbar?.onSelectionChange(), this.updateElementPath();
2013
+ let e = z(this.editorEl, this.doc);
2014
+ this.emit("selectionchange", e);
2015
+ };
2016
+ onFocus = () => {
2017
+ this._isFocused = !0, this.containerEl.classList.add("oe-focused"), this.emit("focus", void 0);
2018
+ };
2019
+ onBlur = () => {
2020
+ this._isFocused = !1, this.containerEl.classList.remove("oe-focused"), this.emit("blur", void 0);
2021
+ };
2022
+ onKeydown = (e) => {
2023
+ let t = e.ctrlKey || e.metaKey;
2024
+ if (t && e.key === "z") {
2025
+ e.preventDefault(), this.chain().undo().run();
2026
+ return;
2027
+ }
2028
+ if (t && (e.key === "y" || e.key === "Z")) {
2029
+ e.preventDefault(), this.chain().redo().run();
2030
+ return;
2031
+ }
2032
+ if (t && e.key === "b") {
2033
+ e.preventDefault(), this.chain().toggleMark("bold").run();
2034
+ return;
2035
+ }
2036
+ if (t && e.key === "i") {
2037
+ e.preventDefault(), this.chain().toggleMark("italic").run();
2038
+ return;
2039
+ }
2040
+ if (t && e.key === "u") {
2041
+ e.preventDefault(), this.chain().toggleMark("underline").run();
2042
+ return;
2043
+ }
2044
+ if (t && e.key === "`") {
2045
+ e.preventDefault(), this.chain().toggleMark("code").run();
2046
+ return;
2047
+ }
2048
+ for (let t of this.plugins) if (t.keymaps) {
2049
+ for (let [n, r] of Object.entries(t.keymaps)) if (qe(n, e)) {
2050
+ e.preventDefault(), r(this);
2051
+ return;
2052
+ }
2053
+ }
2054
+ };
2055
+ onTabInCodeBlock = (e) => {
2056
+ if (e.key !== "Tab") return;
2057
+ let t = window.getSelection();
2058
+ if (!t || t.rangeCount === 0) return;
2059
+ let n = t.anchorNode;
2060
+ for (; n && n !== this.editorEl;) {
2061
+ if (n.nodeType === Node.ELEMENT_NODE && n.tagName === "PRE") {
2062
+ e.preventDefault(), I("insertText", e.shiftKey ? "" : " ");
2063
+ return;
2064
+ }
2065
+ n = n.parentNode;
2066
+ }
2067
+ };
2068
+ onPaste = (e) => {
2069
+ e.preventDefault();
2070
+ let t = e.clipboardData?.getData("text/html"), n = e.clipboardData?.getData("text/plain") ?? "";
2071
+ if (this.history.push(this.doc), t && t.trim()) I("insertHTML", C(h(t)));
2072
+ else if (n) {
2073
+ let e = n.trim();
2074
+ if (We(e)) {
2075
+ let t = window.getSelection(), n = t && !t.isCollapsed ? t.toString() : "";
2076
+ n ? I("insertHTML", `<a href="${Ke(e)}" target="_blank" rel="noopener noreferrer">${n}</a>`) : I("insertHTML", `<a href="${Ke(e)}" target="_blank" rel="noopener noreferrer">${e}</a>`);
2077
+ } else Ge(n) ? I("insertHTML", C(k(n))) : I("insertText", n);
2078
+ }
2079
+ this.scheduleSyncFromDOM();
2080
+ };
2081
+ onDrop = (e) => {
2082
+ let t = e.dataTransfer?.files;
2083
+ if (!t || t.length === 0) return;
2084
+ let n = Array.from(t).find((e) => e.type.startsWith("image/"));
2085
+ n && this.options.onImageUpload && (e.preventDefault(), this.options.onImageUpload(n).then((e) => {
2086
+ let t = H(this.editorEl);
2087
+ this.history.push(this.doc), this.doc = L(this.doc, t, e, n.name), this.rerender();
2088
+ }).catch(() => {}));
2089
+ };
2090
+ isHTMLMode = !1;
2091
+ toggleHTMLMode() {
2092
+ this.containerEl.querySelector(".oe-content-wrap");
2093
+ let e = this.editorEl, t = this.containerEl.querySelector(".oe-html-source"), n = this.containerEl.querySelector(".oe-html-textarea"), r = this.containerEl.querySelector(".oe-html-toggle");
2094
+ if (!this.isHTMLMode) n.value = this.getHTML(), e.style.display = "none", t.style.display = "", this.isHTMLMode = !0, r.classList.add("oe-active"), this.toolbar?.setDisabled(!0);
2095
+ else {
2096
+ let i = n.value;
2097
+ this.history.push(this.doc), this.doc = h(i), e.style.display = "", t.style.display = "none", this.isHTMLMode = !1, r.classList.remove("oe-active"), this.toolbar?.setDisabled(!1), this.rerender();
2098
+ }
2099
+ }
2100
+ chain() {
2101
+ let e = [], t = !1, n = this, r = {
2102
+ toggleMark(t, i) {
2103
+ return e.push(() => {
2104
+ n.editorEl.focus();
2105
+ let e = {
2106
+ bold: "bold",
2107
+ italic: "italic",
2108
+ underline: "underline",
2109
+ strikethrough: "strikethrough"
2110
+ };
2111
+ if (t === "code") if (U(n.editorEl).has("code")) {
2112
+ let e = window.getSelection();
2113
+ if (e && e.rangeCount > 0) {
2114
+ let t = e.getRangeAt(0).startContainer.parentElement.closest("code");
2115
+ if (t) {
2116
+ let e = t.textContent ?? "";
2117
+ t.replaceWith(document.createTextNode(e));
2118
+ }
2119
+ }
2120
+ } else {
2121
+ let e = window.getSelection();
2122
+ if (e && !e.isCollapsed) {
2123
+ let t = e.getRangeAt(0), n = document.createElement("code");
2124
+ t.surroundContents(n);
2125
+ }
2126
+ }
2127
+ else if (t === "link") {
2128
+ if (i?.href) {
2129
+ let e = i.target ?? "_self";
2130
+ Ce(i.href, e);
2131
+ }
2132
+ } else {
2133
+ let n = e[t];
2134
+ n && I(n);
2135
+ }
2136
+ }), r;
2137
+ },
2138
+ setBlock(i, a) {
2139
+ return t = !0, e.push(() => {
2140
+ n.doc = F(n.editorEl);
2141
+ let e = H(n.editorEl);
2142
+ n.history.push(n.doc), n.doc = ve(n.doc, e, i, a);
2143
+ }), r;
2144
+ },
2145
+ setAlign(i) {
2146
+ return t = !0, e.push(() => {
2147
+ n.doc = F(n.editorEl);
2148
+ let e = H(n.editorEl);
2149
+ n.history.push(n.doc), n.doc = be(n.doc, e, i);
2150
+ }), r;
2151
+ },
2152
+ insertImage(i, a) {
2153
+ return t = !0, e.push(() => {
2154
+ n.doc = F(n.editorEl);
2155
+ let e = H(n.editorEl);
2156
+ n.history.push(n.doc), n.doc = L(n.doc, e, i, a);
2157
+ }), r;
2158
+ },
2159
+ insertHr() {
2160
+ return t = !0, e.push(() => {
2161
+ n.doc = F(n.editorEl);
2162
+ let e = H(n.editorEl);
2163
+ n.history.push(n.doc), n.doc = xe(n.doc, e);
2164
+ }), r;
2165
+ },
2166
+ toggleList(i) {
2167
+ return t = !0, e.push(() => {
2168
+ n.doc = F(n.editorEl);
2169
+ let e = H(n.editorEl);
2170
+ n.history.push(n.doc), n.doc = ye(n.doc, e, i);
2171
+ }), r;
2172
+ },
2173
+ undo() {
2174
+ return t = !0, e.push(() => {
2175
+ let e = n.history.undo(n.doc);
2176
+ e && (n.doc = e);
2177
+ }), r;
2178
+ },
2179
+ redo() {
2180
+ return t = !0, e.push(() => {
2181
+ let e = n.history.redo(n.doc);
2182
+ e && (n.doc = e);
2183
+ }), r;
2184
+ },
2185
+ run() {
2186
+ n.isUpdating = !0;
2187
+ for (let t of e) t();
2188
+ n.isUpdating = !1, t ? n.rerender() : n.syncModelFromDOM(), n.toolbar?.updateActiveState(), n.emit("change", n.doc), n.options.onChange?.(n.getHTML());
2189
+ }
2190
+ };
2191
+ return r;
2192
+ }
2193
+ rerender() {
2194
+ z(this.editorEl, this.doc), M(this.doc, this.editorEl), this.updatePlaceholder(), this.updateStatusBar(), this.editorEl.focus();
2195
+ }
2196
+ updateStatusBar() {
2197
+ let e = this.editorEl.innerText ?? "", t = e.trim().split(/\s+/).filter((e) => e.length > 0), n = this.containerEl.querySelector(".oe-word-count"), r = this.containerEl.querySelector(".oe-char-count");
2198
+ n && (n.textContent = `${this.locale.statusBar.words}: ${t.length}`), r && (r.textContent = `${this.locale.statusBar.characters}: ${e.length}`);
2199
+ }
2200
+ updateElementPath() {
2201
+ let e = this.containerEl.querySelector(".oe-statusbar-path");
2202
+ if (!e) return;
2203
+ let t = window.getSelection();
2204
+ if (!t || t.rangeCount === 0) return;
2205
+ let n = [], r = t.anchorNode;
2206
+ for (; r && r !== this.editorEl;) r.nodeType === Node.ELEMENT_NODE && n.unshift(r.tagName.toLowerCase()), r = r.parentNode;
2207
+ e.textContent = n.join(" › ");
2208
+ }
2209
+ updatePlaceholder() {
2210
+ if (!this.options.placeholder) return;
2211
+ let e = this.editorEl.innerText.trim() === "" && this.editorEl.querySelectorAll("img, hr").length === 0;
2212
+ this.editorEl.classList.toggle("oe-empty", e);
2213
+ }
2214
+ getHTML() {
2215
+ return C(this.doc);
2216
+ }
2217
+ setHTML(e) {
2218
+ this.history.push(this.doc), this.doc = h(e), this.rerender();
2219
+ }
2220
+ getMarkdown() {
2221
+ return D(this.doc);
2222
+ }
2223
+ setMarkdown(e) {
2224
+ this.history.push(this.doc), this.doc = k(e), this.rerender();
2225
+ }
2226
+ getDocument() {
2227
+ return this.doc;
2228
+ }
2229
+ use(e) {
2230
+ return this.plugins.push(e), e.onInit?.(this), this;
2231
+ }
2232
+ on(e, t) {
2233
+ this.listeners[e].add(t);
2234
+ }
2235
+ off(e, t) {
2236
+ this.listeners[e].delete(t);
2237
+ }
2238
+ emit(e, t) {
2239
+ this.listeners[e].forEach((e) => e(t));
2240
+ }
2241
+ destroy() {
2242
+ this.syncTimer && clearTimeout(this.syncTimer), document.removeEventListener("selectionchange", this.onSelectionChange), this.editorEl.removeEventListener("input", this.onInput), this.editorEl.removeEventListener("compositionstart", this.onCompositionStart), this.editorEl.removeEventListener("compositionend", this.onCompositionEnd), this.editorEl.removeEventListener("focus", this.onFocus), this.editorEl.removeEventListener("blur", this.onBlur), this.editorEl.removeEventListener("keydown", this.onKeydown), this.editorEl.removeEventListener("keydown", this.onTabInCodeBlock), this.editorEl.removeEventListener("paste", this.onPaste), this.editorEl.removeEventListener("drop", this.onDrop), this.containerEl.querySelector(".oe-html-toggle")?.removeEventListener("click", this.onHTMLToggleClick), this.bubbleToolbar?.destroy(), this.imageResizer?.destroy(), this.codeLangPicker?.destroy(), this.plugins.forEach((e) => e.onDestroy?.(this)), this.root.innerHTML = "";
2243
+ }
2244
+ focus() {
2245
+ this.editorEl.focus();
2246
+ }
2247
+ blur() {
2248
+ this.editorEl.blur();
2249
+ }
2250
+ isFocused() {
2251
+ return this._isFocused;
2252
+ }
2253
+ getSelection() {
2254
+ return z(this.editorEl, this.doc);
2255
+ }
2256
+ isMarkActive(e) {
2257
+ return U(this.editorEl).has(e);
2258
+ }
2259
+ getActiveBlockType() {
2260
+ return Se(this.editorEl);
2261
+ }
2262
+ isEmpty() {
2263
+ return this.editorEl.innerText.trim() === "" && this.editorEl.querySelectorAll("img, hr").length === 0;
2264
+ }
2265
+ applyTheme(e) {
2266
+ this.containerEl.dataset.oeTheme = e;
2267
+ }
2268
+ };
2269
+ function We(e) {
2270
+ return /^https?:\/\/[^\s]{4,}$/.test(e);
2271
+ }
2272
+ function Ge(e) {
2273
+ return /^#{1,6} /m.test(e) || /\*\*[^*]+\*\*/.test(e) || /^```/m.test(e) || /^[-*+] /m.test(e) || /^\d+\. /m.test(e) || /^> /m.test(e) || /~~[^~]+~~/.test(e);
2274
+ }
2275
+ function Ke(e) {
2276
+ return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
2277
+ }
2278
+ function qe(e, t) {
2279
+ let n = e.toLowerCase().split("+"), r = n[n.length - 1], i = n.includes("ctrl") || n.includes("meta"), a = n.includes("shift"), o = n.includes("alt");
2280
+ return t.key.toLowerCase() === r && (t.ctrlKey || t.metaKey) === i && t.shiftKey === a && t.altKey === o;
2281
+ }
2282
+ //#endregion
2283
+ //#region src/plugins/highlight.ts
2284
+ var Y = null;
2285
+ function Je() {
2286
+ return Y || (Y = new Promise((e, t) => {
2287
+ if (window.hljs) {
2288
+ e(window.hljs);
2289
+ return;
2290
+ }
2291
+ let n = document.createElement("script");
2292
+ n.src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js", n.crossOrigin = "anonymous", n.onload = () => e(window.hljs), n.onerror = t, document.head.appendChild(n);
2293
+ }), Y);
2294
+ }
2295
+ var Ye = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/", Xe = `${Ye}atom-one-dark.min.css`, Ze = `${Ye}atom-one-light.min.css`;
2296
+ function Qe(e, t) {
2297
+ let n = "oe-hljs-theme", r = document.getElementById(n), i;
2298
+ if (i = typeof t == "string" ? t : typeof t == "object" ? e ? t.dark : t.light : e ? Xe : Ze, r) {
2299
+ r.href = i;
2300
+ return;
2301
+ }
2302
+ let a = document.createElement("link");
2303
+ a.id = n, a.rel = "stylesheet", a.href = i, a.crossOrigin = "anonymous", document.head.appendChild(a);
2304
+ }
2305
+ function $e(e = {}) {
2306
+ let t, n = null;
2307
+ function r(e) {
2308
+ if (!t) return;
2309
+ let n = e.querySelectorAll("pre code"), r = document.getSelection()?.anchorNode ?? null;
2310
+ n.forEach((e) => {
2311
+ let n = e.closest("pre");
2312
+ n && r && n.contains(r) || (delete e.dataset.highlighted, e.removeAttribute("data-highlighted"), t.highlightElement(e));
2313
+ });
2314
+ }
2315
+ function i(e) {
2316
+ n && clearTimeout(n), n = setTimeout(() => r(e), 400);
2317
+ }
2318
+ return {
2319
+ name: "highlight",
2320
+ onInit(n) {
2321
+ let a = n.editorEl, o = n.containerEl;
2322
+ Qe(e.theme === "dark" || !e.theme && o?.dataset.oeTheme === "dark", e.themeUrl), Je().then((e) => {
2323
+ t = e, t?.configure({ ignoreUnescapedHTML: !0 }), r(a), n.on("change", () => i(a));
2324
+ }).catch(() => {
2325
+ console.warn("[OpenEdit] highlight.js failed to load from CDN");
2326
+ });
2327
+ },
2328
+ onDestroy() {
2329
+ n && clearTimeout(n);
2330
+ }
2331
+ };
2332
+ }
2333
+ //#endregion
2334
+ //#region src/plugins/emoji.ts
2335
+ var et = {
2336
+ faces: /* @__PURE__ */ "😀.😄.😅.😂.🤣.😊.😇.🙂.🙃.😉.😍.🥰.😘.😎.🤓.🤩.🥳.😏.😔.😢.😭.😤.😠.🥺.🤔.🤗.😴.🤯.🥸.😶".split("."),
2337
+ hearts: [
2338
+ "❤️",
2339
+ "🧡",
2340
+ "💛",
2341
+ "💚",
2342
+ "💙",
2343
+ "💜",
2344
+ "🖤",
2345
+ "🤍",
2346
+ "🤎",
2347
+ "💕",
2348
+ "💞",
2349
+ "💓",
2350
+ "💗",
2351
+ "💖",
2352
+ "💝",
2353
+ "💘",
2354
+ "❣️",
2355
+ "💔",
2356
+ "❤️‍🔥",
2357
+ "💟"
2358
+ ],
2359
+ gestures: [
2360
+ "👋",
2361
+ "🤚",
2362
+ "🖐",
2363
+ "✋",
2364
+ "🖖",
2365
+ "👌",
2366
+ "🤌",
2367
+ "✌️",
2368
+ "🤞",
2369
+ "🤟",
2370
+ "🤘",
2371
+ "👈",
2372
+ "👉",
2373
+ "👆",
2374
+ "👇",
2375
+ "☝️",
2376
+ "👍",
2377
+ "👎",
2378
+ "✊",
2379
+ "👏",
2380
+ "🙌",
2381
+ "🫶",
2382
+ "🤝",
2383
+ "🙏"
2384
+ ],
2385
+ nature: /* @__PURE__ */ "🌸.🌺.🌻.🌹.🌷.🍀.🌿.🌱.🌲.🌳.🌴.🍁.🍂.🍃.🌊.🌈.☀️.🌙.⭐.🌟.💫.⚡.🔥.💧.🌍.🦋.🐾".split("."),
2386
+ food: [
2387
+ "🍎",
2388
+ "🍊",
2389
+ "🍋",
2390
+ "🍇",
2391
+ "🍓",
2392
+ "🍒",
2393
+ "🍑",
2394
+ "🥝",
2395
+ "🍕",
2396
+ "🍔",
2397
+ "🌮",
2398
+ "🌯",
2399
+ "🍜",
2400
+ "🍣",
2401
+ "🍰",
2402
+ "🎂",
2403
+ "☕",
2404
+ "🍵",
2405
+ "🧃",
2406
+ "🥤",
2407
+ "🍺",
2408
+ "🥂",
2409
+ "🍾"
2410
+ ],
2411
+ objects: [
2412
+ "💡",
2413
+ "🔑",
2414
+ "🎵",
2415
+ "🎮",
2416
+ "📱",
2417
+ "💻",
2418
+ "📷",
2419
+ "🎯",
2420
+ "🏆",
2421
+ "💎",
2422
+ "🔮",
2423
+ "📚",
2424
+ "✏️",
2425
+ "📝",
2426
+ "📌",
2427
+ "🔔",
2428
+ "💬",
2429
+ "📧",
2430
+ "🚀",
2431
+ "🎁",
2432
+ "🧩",
2433
+ "⚙️",
2434
+ "🔧",
2435
+ "🎨"
2436
+ ],
2437
+ symbols: [
2438
+ "✅",
2439
+ "❌",
2440
+ "⚠️",
2441
+ "ℹ️",
2442
+ "💯",
2443
+ "🔴",
2444
+ "🟡",
2445
+ "🟢",
2446
+ "🔵",
2447
+ "⚫",
2448
+ "⚪",
2449
+ "🔶",
2450
+ "🔷",
2451
+ "🔸",
2452
+ "🔹",
2453
+ "▶️",
2454
+ "◀️",
2455
+ "🔝",
2456
+ "🔛",
2457
+ "🆕",
2458
+ "🆒",
2459
+ "🆓",
2460
+ "🆙",
2461
+ "🏳️",
2462
+ "🏴"
2463
+ ]
2464
+ };
2465
+ function tt(e) {
2466
+ let t = e.plugins.emoji.categories;
2467
+ return Object.keys(et).map((e) => ({
2468
+ label: t[e],
2469
+ emojis: et[e]
2470
+ }));
2471
+ }
2472
+ var nt = "<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M8 14s1.5 2 4 2 4-2 4-2\"/><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"/><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"/></svg>";
2473
+ function rt() {
2474
+ let e = null, t = null, n = null, r = null, i = W;
2475
+ function a() {
2476
+ e &&= (e.remove(), null), document.removeEventListener("click", o, !0);
2477
+ }
2478
+ function o(n) {
2479
+ let r = n.target;
2480
+ e && !e.contains(r) && !t?.contains(r) && a();
2481
+ }
2482
+ function s(e) {
2483
+ let t = window.getSelection();
2484
+ r && t ? (t.removeAllRanges(), t.addRange(r)) : n && n.focus(), document.execCommand("insertText", !1, e), a(), n?.focus();
2485
+ }
2486
+ function c(t) {
2487
+ a(), e = document.createElement("div"), e.className = "oe-emoji-popup", Object.assign(e.style, {
2488
+ position: "fixed",
2489
+ zIndex: "99999",
2490
+ background: "var(--oe-bg, #ffffff)",
2491
+ border: "1px solid var(--oe-border, #e7e5e4)",
2492
+ borderRadius: "12px",
2493
+ boxShadow: "0 8px 32px rgba(0,0,0,0.14)",
2494
+ padding: "10px 12px",
2495
+ width: "300px",
2496
+ maxHeight: "260px",
2497
+ overflowY: "auto",
2498
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif"
2499
+ });
2500
+ for (let t of tt(i)) {
2501
+ let n = document.createElement("div");
2502
+ Object.assign(n.style, {
2503
+ fontSize: "10px",
2504
+ fontWeight: "600",
2505
+ color: "var(--oe-muted, #78716c)",
2506
+ textTransform: "uppercase",
2507
+ letterSpacing: "0.06em",
2508
+ margin: "6px 0 4px"
2509
+ }), n.textContent = t.label, e.appendChild(n);
2510
+ let r = document.createElement("div");
2511
+ Object.assign(r.style, {
2512
+ display: "flex",
2513
+ flexWrap: "wrap",
2514
+ gap: "1px"
2515
+ });
2516
+ for (let e of t.emojis) {
2517
+ let t = document.createElement("button");
2518
+ t.type = "button", t.textContent = e, t.title = e, Object.assign(t.style, {
2519
+ background: "none",
2520
+ border: "none",
2521
+ cursor: "pointer",
2522
+ padding: "4px",
2523
+ borderRadius: "6px",
2524
+ fontSize: "18px",
2525
+ lineHeight: "1",
2526
+ transition: "background 0.1s"
2527
+ }), t.addEventListener("mouseenter", () => {
2528
+ t.style.background = "var(--oe-btn-hover-bg, #f5f5f4)";
2529
+ }), t.addEventListener("mouseleave", () => {
2530
+ t.style.background = "none";
2531
+ }), t.addEventListener("mousedown", (t) => {
2532
+ t.preventDefault(), s(e);
2533
+ }), r.appendChild(t);
2534
+ }
2535
+ e.appendChild(r);
2536
+ }
2537
+ document.body.appendChild(e);
2538
+ let n = t.getBoundingClientRect(), r = n.bottom + 4, c = n.left;
2539
+ c + 300 > window.innerWidth - 8 && (c = window.innerWidth - 308), c < 8 && (c = 8), r + 260 > window.innerHeight - 8 && (r = n.top - 260 - 4), e.style.top = `${r}px`, e.style.left = `${c}px`, setTimeout(() => {
2540
+ document.addEventListener("click", o, !0);
2541
+ }, 0);
2542
+ }
2543
+ return {
2544
+ name: "emoji",
2545
+ onInit(o) {
2546
+ n = o, i = o.locale ?? W;
2547
+ let s = o.editorEl, l = o.containerEl?.querySelector(".oe-toolbar");
2548
+ if (!l) return;
2549
+ document.addEventListener("selectionchange", () => {
2550
+ let e = window.getSelection();
2551
+ e && e.rangeCount > 0 && s.contains(e.anchorNode) && (r = e.getRangeAt(0).cloneRange());
2552
+ });
2553
+ let u = document.createElement("button");
2554
+ u.type = "button", u.className = "oe-toolbar-btn", u.title = i.plugins.emoji.buttonTitle, u.innerHTML = nt, t = u, u.addEventListener("mousedown", (t) => {
2555
+ t.preventDefault();
2556
+ let n = window.getSelection();
2557
+ n && n.rangeCount > 0 && s.contains(n.anchorNode) && (r = n.getRangeAt(0).cloneRange()), e ? a() : c(u);
2558
+ }), l.appendChild(u);
2559
+ },
2560
+ onDestroy() {
2561
+ a(), n = null, r = null;
2562
+ }
2563
+ };
2564
+ }
2565
+ //#endregion
2566
+ //#region src/plugins/template-tags.ts
2567
+ var X = /\{\{([^{}]+)\}\}/g;
2568
+ function it(e) {
2569
+ let t = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, { acceptNode(e) {
2570
+ let t = e.parentElement;
2571
+ return !t || t.classList.contains("oe-template-tag") || t.tagName === "TEXTAREA" || t.tagName === "SCRIPT" ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT;
2572
+ } }), n = [], r;
2573
+ for (; r = t.nextNode();) (r.textContent ?? "").includes("{{") && n.push(r);
2574
+ for (let e of n) {
2575
+ let t = e.textContent ?? "";
2576
+ if (X.lastIndex = 0, !X.test(t)) continue;
2577
+ X.lastIndex = 0;
2578
+ let n = [], r = 0, i;
2579
+ for (; (i = X.exec(t)) !== null;) i.index > r && n.push({
2580
+ type: "text",
2581
+ value: t.slice(r, i.index)
2582
+ }), n.push({
2583
+ type: "tag",
2584
+ value: i[0]
2585
+ }), r = X.lastIndex;
2586
+ r < t.length && n.push({
2587
+ type: "text",
2588
+ value: t.slice(r)
2589
+ });
2590
+ let a = document.createDocumentFragment();
2591
+ for (let e of n) if (e.type === "tag") {
2592
+ let t = document.createElement("span");
2593
+ t.className = "oe-template-tag", t.contentEditable = "false", t.textContent = e.value, a.appendChild(t);
2594
+ } else e.value && a.appendChild(document.createTextNode(e.value));
2595
+ e.parentNode?.replaceChild(a, e);
2596
+ }
2597
+ }
2598
+ function at() {
2599
+ let e = null;
2600
+ function t(t) {
2601
+ e && clearTimeout(e), e = setTimeout(() => it(t), 200);
2602
+ }
2603
+ return {
2604
+ name: "template-tags",
2605
+ onInit(e) {
2606
+ let n = e.editorEl;
2607
+ e.on("change", () => t(n)), setTimeout(() => it(n), 100);
2608
+ },
2609
+ onDestroy() {
2610
+ e && clearTimeout(e);
2611
+ }
2612
+ };
2613
+ }
2614
+ //#endregion
2615
+ //#region src/plugins/ai.ts
2616
+ var ot = "<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"/></svg>", Z = {
2617
+ improve: "Improve the following text stylistically and grammatically. Return only the improved text, no explanations.",
2618
+ shorten: "Shorten the following text to approximately 50% of its length, keeping all important information. Return only the shortened text.",
2619
+ expand: "Expand the following text with more details, examples, and context. Return only the expanded text.",
2620
+ summarize: "Summarize the following text in 2-3 concise sentences. Return only the summary.",
2621
+ toGerman: "Translate the following text to German. Return only the translation.",
2622
+ toEnglish: "Translate the following text to English. Return only the translation, no explanations."
2623
+ };
2624
+ function st(e) {
2625
+ let t = e.plugins.ai.actions;
2626
+ return [
2627
+ {
2628
+ label: t.improve,
2629
+ prompt: Z.improve
2630
+ },
2631
+ {
2632
+ label: t.shorten,
2633
+ prompt: Z.shorten
2634
+ },
2635
+ {
2636
+ label: t.expand,
2637
+ prompt: Z.expand
2638
+ },
2639
+ {
2640
+ label: t.summarize,
2641
+ prompt: Z.summarize
2642
+ },
2643
+ {
2644
+ label: t.toGerman,
2645
+ prompt: Z.toGerman
2646
+ },
2647
+ {
2648
+ label: t.toEnglish,
2649
+ prompt: Z.toEnglish
2650
+ }
2651
+ ];
2652
+ }
2653
+ async function ct(e, t) {
2654
+ let n = t.endpoint ?? "https://api.anthropic.com/v1/messages", r = t.model ?? "claude-sonnet-4-6", i = { "content-type": "application/json" };
2655
+ t.apiKey && !t.endpoint && (i["x-api-key"] = t.apiKey, i["anthropic-version"] = "2023-06-01", i["anthropic-dangerous-direct-browser-access"] = "true");
2656
+ let a = JSON.stringify({
2657
+ model: r,
2658
+ max_tokens: t.maxTokens ?? 2048,
2659
+ system: "You are a professional writing assistant. Follow the user's instruction exactly and return only the desired result — no introduction, no explanation, no commentary.",
2660
+ messages: [{
2661
+ role: "user",
2662
+ content: e
2663
+ }]
2664
+ }), o = await fetch(n, {
2665
+ method: "POST",
2666
+ headers: i,
2667
+ body: a
2668
+ });
2669
+ if (!o.ok) {
2670
+ let e = await o.text().catch(() => o.statusText);
2671
+ throw Error(`API error ${o.status}: ${e}`);
2672
+ }
2673
+ let s = (await o.json())?.content?.[0]?.text;
2674
+ if (!s) throw Error("Unexpected response format");
2675
+ return s;
2676
+ }
2677
+ function Q(e, t) {
2678
+ Object.assign(e.style, t);
2679
+ }
2680
+ function lt(e = {}) {
2681
+ !e.apiKey && !e.endpoint && console.warn("[OpenEdit AI] No apiKey or endpoint provided — plugin inactive.");
2682
+ let t = null, n = null, r = null, i = null, a = "", o = W;
2683
+ function s() {
2684
+ t &&= (t.remove(), null), document.removeEventListener("click", c, !0);
2685
+ }
2686
+ function c(e) {
2687
+ let r = e.target;
2688
+ t && !t.contains(r) && !n?.contains(r) && s();
2689
+ }
2690
+ function l(e) {
2691
+ let t = window.getSelection();
2692
+ t && t.rangeCount > 0 && e.contains(t.anchorNode) ? (i = t.getRangeAt(0).cloneRange(), a = t.toString().trim()) : (i = null, a = r?.getHTML() ?? "");
2693
+ }
2694
+ function u(e) {
2695
+ if (!r) return;
2696
+ let t = window.getSelection();
2697
+ if (i && t && a) {
2698
+ t.removeAllRanges(), t.addRange(i);
2699
+ let n = C(h(e));
2700
+ document.execCommand("insertHTML", !1, n);
2701
+ } else r.setHTML(e);
2702
+ r.focus();
2703
+ }
2704
+ function d(e) {
2705
+ s(), t = document.createElement("div"), Q(t, {
2706
+ position: "fixed",
2707
+ zIndex: "99999",
2708
+ background: "var(--oe-bg, #fff)",
2709
+ border: "1px solid var(--oe-border, #e7e5e4)",
2710
+ borderRadius: "14px",
2711
+ boxShadow: "0 12px 40px rgba(0,0,0,0.16)",
2712
+ padding: "16px",
2713
+ width: "360px",
2714
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif"
2715
+ });
2716
+ let n = o.plugins.ai, i = document.createElement("div");
2717
+ Q(i, {
2718
+ display: "flex",
2719
+ alignItems: "center",
2720
+ gap: "8px",
2721
+ marginBottom: "12px"
2722
+ }), i.innerHTML = `${ot}<span style="font-size:13px;font-weight:600;color:var(--oe-text,#1c1917)">${n.panelTitle}</span>`, t.appendChild(i);
2723
+ let l = document.createElement("div"), d = a || n.noSelection;
2724
+ Q(l, {
2725
+ fontSize: "12px",
2726
+ color: "var(--oe-text-muted, #78716c)",
2727
+ background: "var(--oe-btn-hover-bg, #f5f5f4)",
2728
+ borderRadius: "8px",
2729
+ padding: "8px 10px",
2730
+ marginBottom: "12px",
2731
+ maxHeight: "64px",
2732
+ overflow: "hidden",
2733
+ lineHeight: "1.5"
2734
+ }), l.textContent = d.length > 140 ? d.slice(0, 140) + "…" : d, t.appendChild(l);
2735
+ let p = document.createElement("div");
2736
+ Q(p, {
2737
+ display: "flex",
2738
+ flexWrap: "wrap",
2739
+ gap: "6px",
2740
+ marginBottom: "12px"
2741
+ });
2742
+ for (let e of st(o)) {
2743
+ let t = document.createElement("button");
2744
+ t.type = "button", t.textContent = e.label, Q(t, {
2745
+ padding: "5px 10px",
2746
+ fontSize: "12px",
2747
+ fontWeight: "500",
2748
+ border: "1px solid var(--oe-border, #e7e5e4)",
2749
+ borderRadius: "6px",
2750
+ background: "var(--oe-bg, #fff)",
2751
+ color: "var(--oe-text, #1c1917)",
2752
+ cursor: "pointer",
2753
+ fontFamily: "inherit",
2754
+ transition: "background 0.1s"
2755
+ }), t.addEventListener("mouseenter", () => {
2756
+ t.style.background = "var(--oe-btn-hover-bg, #f5f5f4)";
2757
+ }), t.addEventListener("mouseleave", () => {
2758
+ t.style.background = "var(--oe-bg, #fff)";
2759
+ }), t.addEventListener("click", () => {
2760
+ let t = a || r?.getHTML() || "";
2761
+ f(`${e.prompt}\n\n${t}`, _, v);
2762
+ }), p.appendChild(t);
2763
+ }
2764
+ t.appendChild(p);
2765
+ let m = document.createElement("div");
2766
+ Q(m, {
2767
+ display: "flex",
2768
+ gap: "6px",
2769
+ marginBottom: "12px"
2770
+ });
2771
+ let h = document.createElement("textarea");
2772
+ h.placeholder = n.customPromptPlaceholder, h.rows = 2, Q(h, {
2773
+ flex: "1",
2774
+ padding: "8px 10px",
2775
+ fontSize: "12px",
2776
+ border: "1px solid var(--oe-border, #e7e5e4)",
2777
+ borderRadius: "8px",
2778
+ background: "var(--oe-bg, #fff)",
2779
+ color: "var(--oe-text, #1c1917)",
2780
+ fontFamily: "inherit",
2781
+ resize: "none",
2782
+ outline: "none"
2783
+ });
2784
+ let g = document.createElement("button");
2785
+ g.type = "button", g.textContent = n.runButton, Q(g, {
2786
+ padding: "0 14px",
2787
+ fontSize: "12px",
2788
+ fontWeight: "600",
2789
+ border: "none",
2790
+ borderRadius: "8px",
2791
+ background: "#1c1917",
2792
+ color: "#fff",
2793
+ cursor: "pointer",
2794
+ fontFamily: "inherit",
2795
+ alignSelf: "stretch"
2796
+ }), g.addEventListener("click", () => {
2797
+ let e = a || r?.getHTML() || "", t = h.value.trim();
2798
+ t && f(`${t}\n\n${e}`, _, v);
2799
+ }), m.appendChild(h), m.appendChild(g), t.appendChild(m);
2800
+ let _ = document.createElement("div");
2801
+ Q(_, {
2802
+ display: "none",
2803
+ fontSize: "12px",
2804
+ color: "var(--oe-text, #1c1917)",
2805
+ background: "var(--oe-btn-hover-bg, #f5f5f4)",
2806
+ borderRadius: "8px",
2807
+ padding: "10px",
2808
+ marginBottom: "10px",
2809
+ lineHeight: "1.6",
2810
+ maxHeight: "120px",
2811
+ overflowY: "auto"
2812
+ }), t.appendChild(_);
2813
+ let v = document.createElement("button");
2814
+ v.type = "button", v.textContent = n.applyButton, v.style.display = "none", Q(v, {
2815
+ width: "100%",
2816
+ padding: "9px",
2817
+ fontSize: "13px",
2818
+ fontWeight: "600",
2819
+ border: "none",
2820
+ borderRadius: "8px",
2821
+ background: "#1c1917",
2822
+ color: "#fff",
2823
+ cursor: "pointer",
2824
+ fontFamily: "inherit"
2825
+ }), v.addEventListener("click", () => {
2826
+ let e = _.dataset.result ?? "";
2827
+ e && (u(e), s());
2828
+ }), t.appendChild(v), document.body.appendChild(t);
2829
+ let y = e.getBoundingClientRect(), b = y.bottom + 4, x = y.left;
2830
+ x + 360 > window.innerWidth - 8 && (x = window.innerWidth - 368), x < 8 && (x = 8), b + 400 > window.innerHeight - 8 && (b = y.top - 400 - 4), t.style.top = `${b}px`, t.style.left = `${x}px`, setTimeout(() => {
2831
+ document.addEventListener("click", c, !0);
2832
+ }, 0);
2833
+ }
2834
+ async function f(t, n, r) {
2835
+ let i = o.plugins.ai;
2836
+ if (!e.apiKey && !e.endpoint) {
2837
+ n.style.display = "block", n.textContent = i.noApiKey;
2838
+ return;
2839
+ }
2840
+ n.style.display = "block", n.textContent = i.generating, r.style.display = "none";
2841
+ try {
2842
+ let i = await ct(t, e);
2843
+ n.textContent = i.length > 400 ? i.slice(0, 400) + "…" : i, n.dataset.result = i, r.style.display = "block";
2844
+ } catch (e) {
2845
+ n.textContent = `${i.errorPrefix}${e instanceof Error ? e.message : String(e)}`;
2846
+ }
2847
+ }
2848
+ return {
2849
+ name: "ai-assistant",
2850
+ onInit(e) {
2851
+ r = e, o = e.locale ?? W;
2852
+ let c = e.editorEl, u = e.containerEl?.querySelector(".oe-toolbar");
2853
+ if (!u) return;
2854
+ document.addEventListener("selectionchange", () => {
2855
+ let e = window.getSelection();
2856
+ e && e.rangeCount > 0 && c.contains(e.anchorNode) && (i = e.getRangeAt(0).cloneRange(), a = e.isCollapsed ? "" : e.toString().trim());
2857
+ });
2858
+ let f = document.createElement("div");
2859
+ f.className = "oe-toolbar-sep";
2860
+ let p = document.createElement("button");
2861
+ p.type = "button", p.className = "oe-toolbar-btn", p.title = o.plugins.ai.panelTitle, p.innerHTML = ot, Q(p, { color: "rgb(99,102,241)" }), n = p, p.addEventListener("mousedown", (e) => {
2862
+ e.preventDefault(), l(c), t ? s() : d(p);
2863
+ }), u.appendChild(f), u.appendChild(p), c.addEventListener("keydown", (e) => {
2864
+ if (e.key === "Enter" && !e.shiftKey) {
2865
+ let t = window.getSelection();
2866
+ if (!t || t.rangeCount === 0) return;
2867
+ let n = t.getRangeAt(0), r = n.startContainer.textContent ?? "";
2868
+ if (r.trim() === "/ai") {
2869
+ e.preventDefault();
2870
+ let t = document.createRange();
2871
+ t.setStart(n.startContainer, 0), t.setEnd(n.startContainer, r.length), t.deleteContents(), l(c), d(p);
2872
+ }
2873
+ }
2874
+ });
2875
+ },
2876
+ onDestroy() {
2877
+ s(), r = null;
2878
+ }
2879
+ };
2880
+ }
2881
+ //#endregion
2882
+ //#region src/plugins/callout.ts
2883
+ var ut = {
2884
+ "/callout": "info",
2885
+ "/callout-info": "info",
2886
+ "/callout-success": "success",
2887
+ "/callout-warning": "warning",
2888
+ "/callout-danger": "danger"
2889
+ };
2890
+ function dt() {
2891
+ let e = null, t = null, n = (n) => {
2892
+ if (n.key !== "Enter" || n.shiftKey || !e) return;
2893
+ let r = window.getSelection();
2894
+ if (!r || r.rangeCount === 0) return;
2895
+ let i = r.getRangeAt(0);
2896
+ if (!i.collapsed) return;
2897
+ let a = i.startContainer;
2898
+ for (; a && a.parentNode !== e;) a = a.parentNode;
2899
+ if (!a || a.nodeType !== Node.ELEMENT_NODE) return;
2900
+ let o = ut[(a.textContent?.trim() ?? "").toLowerCase()];
2901
+ o && (n.preventDefault(), a.innerHTML = "", t?.chain().setBlock("callout", { variant: o }).run());
2902
+ };
2903
+ return {
2904
+ name: "callout",
2905
+ onInit(r) {
2906
+ t = r, e = r.editorEl, e && e.addEventListener("keydown", n);
2907
+ },
2908
+ onDestroy(r) {
2909
+ e && e.removeEventListener("keydown", n), e = null, t = null;
2910
+ },
2911
+ keymaps: { "ctrl+shift+i": (e) => (e.chain().setBlock("callout", { variant: "info" }).run(), !0) }
2912
+ };
2913
+ }
2914
+ //#endregion
2915
+ //#region src/plugins/slash-commands.ts
2916
+ var ft = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13 4v16\"/><path d=\"M17 4H9.5a4.5 4.5 0 0 0 0 9H13\"/></svg>", pt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\"/><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"/></svg>", mt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>", ht = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"9\" y1=\"6\" x2=\"20\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"20\" y2=\"12\"/><line x1=\"9\" y1=\"18\" x2=\"20\" y2=\"18\"/><circle cx=\"4\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/></svg>", gt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><text x=\"2\" y=\"9\" font-size=\"7\" fill=\"currentColor\" stroke=\"none\" font-family=\"sans-serif\" font-weight=\"700\">1.</text><text x=\"2\" y=\"15\" font-size=\"7\" fill=\"currentColor\" stroke=\"none\" font-family=\"sans-serif\" font-weight=\"700\">2.</text><text x=\"2\" y=\"21\" font-size=\"7\" fill=\"currentColor\" stroke=\"none\" font-family=\"sans-serif\" font-weight=\"700\">3.</text></svg>", _t = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/></svg>", vt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/></svg>", yt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/></svg>", bt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></svg>", xt = "<svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/></svg>";
2917
+ function $(e) {
2918
+ return `<span style="font-size:11px;font-weight:700;letter-spacing:-0.5px;line-height:1">H${e}</span>`;
2919
+ }
2920
+ function St() {
2921
+ return [
2922
+ {
2923
+ id: "paragraph",
2924
+ title: "Paragraph",
2925
+ description: "Plain text block",
2926
+ icon: ft,
2927
+ keywords: [
2928
+ "paragraph",
2929
+ "text",
2930
+ "p",
2931
+ "normal"
2932
+ ],
2933
+ execute: (e) => e.chain().setBlock("paragraph").run()
2934
+ },
2935
+ {
2936
+ id: "h1",
2937
+ title: "Heading 1",
2938
+ description: "Large section title",
2939
+ icon: $(1),
2940
+ keywords: [
2941
+ "heading",
2942
+ "h1",
2943
+ "heading1",
2944
+ "title",
2945
+ "1"
2946
+ ],
2947
+ execute: (e) => e.chain().setBlock("heading", { level: 1 }).run()
2948
+ },
2949
+ {
2950
+ id: "h2",
2951
+ title: "Heading 2",
2952
+ description: "Medium section title",
2953
+ icon: $(2),
2954
+ keywords: [
2955
+ "heading",
2956
+ "h2",
2957
+ "heading2",
2958
+ "2"
2959
+ ],
2960
+ execute: (e) => e.chain().setBlock("heading", { level: 2 }).run()
2961
+ },
2962
+ {
2963
+ id: "h3",
2964
+ title: "Heading 3",
2965
+ description: "Small section title",
2966
+ icon: $(3),
2967
+ keywords: [
2968
+ "heading",
2969
+ "h3",
2970
+ "heading3",
2971
+ "3"
2972
+ ],
2973
+ execute: (e) => e.chain().setBlock("heading", { level: 3 }).run()
2974
+ },
2975
+ {
2976
+ id: "h4",
2977
+ title: "Heading 4",
2978
+ icon: $(4),
2979
+ keywords: [
2980
+ "heading",
2981
+ "h4",
2982
+ "heading4",
2983
+ "4"
2984
+ ],
2985
+ execute: (e) => e.chain().setBlock("heading", { level: 4 }).run()
2986
+ },
2987
+ {
2988
+ id: "h5",
2989
+ title: "Heading 5",
2990
+ icon: $(5),
2991
+ keywords: [
2992
+ "heading",
2993
+ "h5",
2994
+ "heading5",
2995
+ "5"
2996
+ ],
2997
+ execute: (e) => e.chain().setBlock("heading", { level: 5 }).run()
2998
+ },
2999
+ {
3000
+ id: "h6",
3001
+ title: "Heading 6",
3002
+ icon: $(6),
3003
+ keywords: [
3004
+ "heading",
3005
+ "h6",
3006
+ "heading6",
3007
+ "6"
3008
+ ],
3009
+ execute: (e) => e.chain().setBlock("heading", { level: 6 }).run()
3010
+ },
3011
+ {
3012
+ id: "quote",
3013
+ title: "Blockquote",
3014
+ description: "Indented citation block",
3015
+ icon: pt,
3016
+ keywords: [
3017
+ "quote",
3018
+ "blockquote",
3019
+ "bq",
3020
+ "citation"
3021
+ ],
3022
+ execute: (e) => e.chain().setBlock("blockquote").run()
3023
+ },
3024
+ {
3025
+ id: "code",
3026
+ title: "Code Block",
3027
+ description: "Monospace preformatted code",
3028
+ icon: mt,
3029
+ keywords: [
3030
+ "code",
3031
+ "codeblock",
3032
+ "pre",
3033
+ "monospace",
3034
+ "snippet"
3035
+ ],
3036
+ execute: (e) => e.chain().setBlock("code_block").run()
3037
+ },
3038
+ {
3039
+ id: "bullet",
3040
+ title: "Bullet List",
3041
+ description: "Unordered list with dots",
3042
+ icon: ht,
3043
+ keywords: [
3044
+ "ul",
3045
+ "bullet",
3046
+ "bulletlist",
3047
+ "unordered",
3048
+ "list",
3049
+ "-"
3050
+ ],
3051
+ execute: (e) => e.chain().toggleList("bullet_list").run()
3052
+ },
3053
+ {
3054
+ id: "numbered",
3055
+ title: "Numbered List",
3056
+ description: "Ordered numbered list",
3057
+ icon: gt,
3058
+ keywords: [
3059
+ "ol",
3060
+ "numbered",
3061
+ "orderedlist",
3062
+ "ordered",
3063
+ "list",
3064
+ "1"
3065
+ ],
3066
+ execute: (e) => e.chain().toggleList("ordered_list").run()
3067
+ },
3068
+ {
3069
+ id: "hr",
3070
+ title: "Divider",
3071
+ description: "Horizontal rule",
3072
+ icon: _t,
3073
+ keywords: [
3074
+ "hr",
3075
+ "divider",
3076
+ "separator",
3077
+ "rule",
3078
+ "---"
3079
+ ],
3080
+ execute: (e) => e.chain().insertHr().run()
3081
+ },
3082
+ {
3083
+ id: "callout-info",
3084
+ title: "Callout: Info",
3085
+ description: "Blue informational callout",
3086
+ icon: vt,
3087
+ keywords: [
3088
+ "callout",
3089
+ "info",
3090
+ "note",
3091
+ "callout-info"
3092
+ ],
3093
+ execute: (e) => e.chain().setBlock("callout", { variant: "info" }).run()
3094
+ },
3095
+ {
3096
+ id: "callout-success",
3097
+ title: "Callout: Success",
3098
+ description: "Green success callout",
3099
+ icon: yt,
3100
+ keywords: [
3101
+ "callout",
3102
+ "success",
3103
+ "done",
3104
+ "callout-success"
3105
+ ],
3106
+ execute: (e) => e.chain().setBlock("callout", { variant: "success" }).run()
3107
+ },
3108
+ {
3109
+ id: "callout-warning",
3110
+ title: "Callout: Warning",
3111
+ description: "Yellow warning callout",
3112
+ icon: bt,
3113
+ keywords: [
3114
+ "callout",
3115
+ "warning",
3116
+ "warn",
3117
+ "caution",
3118
+ "callout-warning"
3119
+ ],
3120
+ execute: (e) => e.chain().setBlock("callout", { variant: "warning" }).run()
3121
+ },
3122
+ {
3123
+ id: "callout-danger",
3124
+ title: "Callout: Danger",
3125
+ description: "Red danger or error callout",
3126
+ icon: xt,
3127
+ keywords: [
3128
+ "callout",
3129
+ "danger",
3130
+ "error",
3131
+ "callout-danger"
3132
+ ],
3133
+ execute: (e) => e.chain().setBlock("callout", { variant: "danger" }).run()
3134
+ }
3135
+ ];
3136
+ }
3137
+ var Ct = "oe-slash-menu-styles";
3138
+ function wt() {
3139
+ if (document.getElementById(Ct)) return;
3140
+ let e = document.createElement("style");
3141
+ e.id = Ct, e.textContent = "\n.oe-slash-menu {\n position: fixed;\n z-index: 10000;\n background: var(--oe-bg, #ffffff);\n border: 1px solid var(--oe-border, #e7e5e4);\n border-radius: 10px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.13), 0 2px 8px rgba(0,0,0,0.07);\n padding: 5px;\n min-width: 230px;\n max-height: 300px;\n overflow-y: auto;\n font-family: var(--oe-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n font-size: 13px;\n scrollbar-width: thin;\n scrollbar-color: var(--oe-border, #e7e5e4) transparent;\n}\n.oe-slash-menu-empty {\n padding: 10px 12px;\n color: var(--oe-text-muted, #78716c);\n font-size: 13px;\n}\n.oe-slash-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n user-select: none;\n transition: background 80ms;\n}\n.oe-slash-menu-item:hover {\n background: var(--oe-btn-hover-bg, #f5f5f4);\n}\n.oe-slash-menu-item.oe-slash-active {\n background: var(--oe-btn-active-bg, #1c1917);\n color: var(--oe-btn-active-fg, #ffffff);\n}\n.oe-slash-menu-item.oe-slash-active .oe-slash-menu-desc {\n color: rgba(255,255,255,0.6);\n}\n.oe-slash-menu-icon {\n width: 30px;\n height: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--oe-btn-hover-bg, #f5f5f4);\n border: 1px solid var(--oe-border, #e7e5e4);\n border-radius: 6px;\n flex-shrink: 0;\n color: var(--oe-text, #1c1917);\n}\n.oe-slash-menu-item.oe-slash-active .oe-slash-menu-icon {\n background: rgba(255,255,255,0.12);\n border-color: rgba(255,255,255,0.2);\n color: #ffffff;\n}\n.oe-slash-menu-text { flex: 1; min-width: 0; }\n.oe-slash-menu-title {\n font-weight: 500;\n color: var(--oe-text, #1c1917);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.oe-slash-menu-item.oe-slash-active .oe-slash-menu-title {\n color: var(--oe-btn-active-fg, #ffffff);\n}\n.oe-slash-menu-desc {\n font-size: 11px;\n color: var(--oe-text-muted, #78716c);\n margin-top: 1px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n", document.head.appendChild(e);
3142
+ }
3143
+ function Tt(e = {}) {
3144
+ let t = e.commands ? e.commands : [...St(), ...e.extraCommands ?? []], n = null, r = null, i = null, a = !1, o = 0, s = [];
3145
+ function c() {
3146
+ let e = window.getSelection();
3147
+ if (!e || e.rangeCount === 0) return null;
3148
+ let t = e.getRangeAt(0);
3149
+ if (!t.collapsed) return null;
3150
+ let r = t.startContainer;
3151
+ for (; r && r.parentNode !== n;) r = r.parentNode;
3152
+ if (!r || r.nodeType !== Node.ELEMENT_NODE) return null;
3153
+ let i = r, a = i.textContent ?? "";
3154
+ return a.startsWith("/") ? {
3155
+ blockEl: i,
3156
+ query: a.slice(1).toLowerCase()
3157
+ } : null;
3158
+ }
3159
+ function l(e) {
3160
+ return e ? t.filter((t) => {
3161
+ let n = e.toLowerCase();
3162
+ return t.id.includes(n) || t.title.toLowerCase().includes(n) || t.keywords.some((e) => e.includes(n));
3163
+ }) : t;
3164
+ }
3165
+ function u() {
3166
+ let e = window.getSelection();
3167
+ if (e && e.rangeCount > 0) {
3168
+ let t = e.getRangeAt(0).getBoundingClientRect();
3169
+ if (t.width > 0 || t.height > 0) return {
3170
+ top: t.bottom + 6,
3171
+ left: t.left
3172
+ };
3173
+ }
3174
+ if (n) {
3175
+ let e = n.getBoundingClientRect();
3176
+ return {
3177
+ top: e.top + 40,
3178
+ left: e.left + 16
3179
+ };
3180
+ }
3181
+ return {
3182
+ top: 100,
3183
+ left: 100
3184
+ };
3185
+ }
3186
+ function d(e, t, n) {
3187
+ let r = window.innerWidth, i = window.innerHeight, a = e.offsetWidth || 240, o = e.offsetHeight || 300;
3188
+ return n + a > r - 8 && (n = r - a - 8), n < 8 && (n = 8), t + o > i - 8 && (t = t - o - 28), t < 8 && (t = 8), {
3189
+ top: t,
3190
+ left: n
3191
+ };
3192
+ }
3193
+ function f() {
3194
+ if (i) {
3195
+ if (s.length === 0) {
3196
+ i.innerHTML = "<div class=\"oe-slash-menu-empty\">No matching blocks</div>";
3197
+ return;
3198
+ }
3199
+ i.innerHTML = s.map((e, t) => `
3200
+ <div class="oe-slash-menu-item${t === o ? " oe-slash-active" : ""}" data-index="${t}">
3201
+ <div class="oe-slash-menu-icon">${e.icon}</div>
3202
+ <div class="oe-slash-menu-text">
3203
+ <div class="oe-slash-menu-title">${e.title}</div>
3204
+ ${e.description ? `<div class="oe-slash-menu-desc">${e.description}</div>` : ""}
3205
+ </div>
3206
+ </div>`).join(""), i.querySelector(".oe-slash-active")?.scrollIntoView({ block: "nearest" });
3207
+ }
3208
+ }
3209
+ function p() {
3210
+ if (!i) return;
3211
+ a = !0, i.style.display = "block";
3212
+ let { top: e, left: t } = u();
3213
+ i.style.top = `${e}px`, i.style.left = `${t}px`, requestAnimationFrame(() => {
3214
+ if (!i) return;
3215
+ let n = d(i, e, t);
3216
+ i.style.top = `${n.top}px`, i.style.left = `${n.left}px`;
3217
+ }), f();
3218
+ }
3219
+ function m() {
3220
+ i && (a = !1, i.style.display = "none", i.innerHTML = "", o = 0, s = []);
3221
+ }
3222
+ function h(e) {
3223
+ if (!r || !n) return;
3224
+ let t = c(), i = -1;
3225
+ if (t) {
3226
+ let e = t.blockEl;
3227
+ i = Array.from(n.children).indexOf(e), e.innerHTML = "";
3228
+ let r = window.getSelection();
3229
+ if (r) {
3230
+ let t = document.createRange();
3231
+ t.setStart(e, 0), t.collapse(!0), r.removeAllRanges(), r.addRange(t);
3232
+ }
3233
+ }
3234
+ m(), e.execute(r), i >= 0 && requestAnimationFrame(() => {
3235
+ if (!n) return;
3236
+ let e = n.children[i];
3237
+ if (!e) return;
3238
+ let t = g(e), r = window.getSelection();
3239
+ if (!r) return;
3240
+ let a = document.createRange();
3241
+ if (t) a.setStart(t, t.length);
3242
+ else if (e instanceof HTMLElement && e.tagName === "HR") {
3243
+ let t = n.children[i + 1] ?? e;
3244
+ a.setStart(t, 0);
3245
+ } else a.setStart(e, 0);
3246
+ a.collapse(!0), r.removeAllRanges(), r.addRange(a);
3247
+ });
3248
+ }
3249
+ function g(e) {
3250
+ for (let t = e.childNodes.length - 1; t >= 0; t--) {
3251
+ let n = g(e.childNodes[t]);
3252
+ if (n) return n;
3253
+ }
3254
+ return e.nodeType === Node.TEXT_NODE ? e : null;
3255
+ }
3256
+ let _ = () => {
3257
+ let e = c();
3258
+ if (!e) {
3259
+ a && m();
3260
+ return;
3261
+ }
3262
+ let { query: t } = e;
3263
+ s = l(t), o >= s.length && (o = 0), s.length, p();
3264
+ }, v = (e) => {
3265
+ if (a) switch (e.key) {
3266
+ case "ArrowDown":
3267
+ e.preventDefault(), e.stopImmediatePropagation(), o = (o + 1) % Math.max(s.length, 1), f();
3268
+ break;
3269
+ case "ArrowUp":
3270
+ e.preventDefault(), e.stopImmediatePropagation(), o = (o - 1 + Math.max(s.length, 1)) % Math.max(s.length, 1), f();
3271
+ break;
3272
+ case "Enter":
3273
+ s.length > 0 && s[o] && (e.preventDefault(), e.stopImmediatePropagation(), h(s[o]));
3274
+ break;
3275
+ case "Escape":
3276
+ e.preventDefault(), e.stopImmediatePropagation(), m();
3277
+ break;
3278
+ case "Tab":
3279
+ s.length > 0 && s[o] && (e.preventDefault(), e.stopImmediatePropagation(), h(s[o]));
3280
+ break;
3281
+ }
3282
+ }, y = (e) => {
3283
+ !a || !i || i.contains(e.target) || m();
3284
+ }, b = (e) => {
3285
+ let t = e.target.closest(".oe-slash-menu-item");
3286
+ if (!t) return;
3287
+ let n = parseInt(t.dataset.index ?? "0", 10), r = s[n];
3288
+ r && h(r);
3289
+ }, x = () => {
3290
+ a && m();
3291
+ };
3292
+ return {
3293
+ name: "slash-commands",
3294
+ onInit(e) {
3295
+ r = e, n = e.editorEl, n && (wt(), i = document.createElement("div"), i.className = "oe-slash-menu", i.style.display = "none", document.body.appendChild(i), n.addEventListener("keydown", v, !0), n.addEventListener("input", _), i.addEventListener("click", b), document.addEventListener("click", y, !0), window.addEventListener("scroll", x, { passive: !0 }));
3296
+ },
3297
+ onDestroy(e) {
3298
+ n && (n.removeEventListener("keydown", v, !0), n.removeEventListener("input", _)), i &&= (i.removeEventListener("click", b), i.remove(), null), document.removeEventListener("click", y, !0), window.removeEventListener("scroll", x), n = null, r = null, a = !1;
3299
+ }
3300
+ };
3301
+ }
3302
+ //#endregion
3303
+ //#region src/index.ts
3304
+ function Et(e, t) {
3305
+ return new Ue({
3306
+ element: e,
3307
+ ...t
3308
+ });
3309
+ }
3310
+ var Dt = {
3311
+ create: Et,
3312
+ version: "0.1.0",
3313
+ locales: {
3314
+ en: W,
3315
+ de: J
3316
+ },
3317
+ plugins: {
3318
+ highlight: $e,
3319
+ emoji: rt,
3320
+ templateTags: at,
3321
+ ai: lt,
3322
+ callout: dt,
3323
+ slashCommands: Tt
3324
+ },
3325
+ markdown: {
3326
+ serialize: D,
3327
+ deserialize: k
3328
+ }
3329
+ };
3330
+ //#endregion
3331
+ export { Ue as Editor, Dt as OpenEdit, Dt as default, lt as createAIPlugin, dt as createCalloutPlugin, rt as createEmojiPlugin, $e as createHighlightPlugin, Tt as createSlashCommandsPlugin, at as createTemplateTagPlugin, J as de, k as deserializeMarkdown, W as en, D as serializeToMarkdown };
3332
+
3333
+ //# sourceMappingURL=open-edit.esm.js.map