@synclineapi/editor 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/syncline-editor.es.js +4635 -0
- package/dist/syncline-editor.es.js.map +1 -0
- package/dist/syncline-editor.umd.js +515 -0
- package/dist/syncline-editor.umd.js.map +1 -0
- package/dist/types/index.d.ts +1262 -0
- package/package.json +3 -3
|
@@ -0,0 +1,4635 @@
|
|
|
1
|
+
var De = Object.defineProperty;
|
|
2
|
+
var He = (s, e, t) => e in s ? De(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
|
|
3
|
+
var g = (s, e, t) => He(s, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
const Re = {
|
|
5
|
+
typescript: "//",
|
|
6
|
+
javascript: "//",
|
|
7
|
+
css: "//",
|
|
8
|
+
json: "",
|
|
9
|
+
markdown: "",
|
|
10
|
+
text: ""
|
|
11
|
+
}, se = /* @__PURE__ */ new Set([
|
|
12
|
+
"function",
|
|
13
|
+
"const",
|
|
14
|
+
"let",
|
|
15
|
+
"var",
|
|
16
|
+
"return",
|
|
17
|
+
"if",
|
|
18
|
+
"else",
|
|
19
|
+
"for",
|
|
20
|
+
"while",
|
|
21
|
+
"class",
|
|
22
|
+
"import",
|
|
23
|
+
"export",
|
|
24
|
+
"default",
|
|
25
|
+
"async",
|
|
26
|
+
"await",
|
|
27
|
+
"new",
|
|
28
|
+
"this",
|
|
29
|
+
"typeof",
|
|
30
|
+
"instanceof",
|
|
31
|
+
"try",
|
|
32
|
+
"catch",
|
|
33
|
+
"finally",
|
|
34
|
+
"throw",
|
|
35
|
+
"extends",
|
|
36
|
+
"interface",
|
|
37
|
+
"type",
|
|
38
|
+
"readonly",
|
|
39
|
+
"private",
|
|
40
|
+
"public",
|
|
41
|
+
"protected",
|
|
42
|
+
"static",
|
|
43
|
+
"override",
|
|
44
|
+
"implements",
|
|
45
|
+
"enum",
|
|
46
|
+
"namespace",
|
|
47
|
+
"declare",
|
|
48
|
+
"abstract",
|
|
49
|
+
"as",
|
|
50
|
+
"from",
|
|
51
|
+
"of",
|
|
52
|
+
"in",
|
|
53
|
+
"void",
|
|
54
|
+
"switch",
|
|
55
|
+
"case",
|
|
56
|
+
"break",
|
|
57
|
+
"continue",
|
|
58
|
+
"do",
|
|
59
|
+
"delete",
|
|
60
|
+
"yield",
|
|
61
|
+
"super",
|
|
62
|
+
"null",
|
|
63
|
+
"true",
|
|
64
|
+
"false",
|
|
65
|
+
"undefined",
|
|
66
|
+
"require",
|
|
67
|
+
"constructor"
|
|
68
|
+
]), Be = /* @__PURE__ */ new Set([
|
|
69
|
+
"function",
|
|
70
|
+
"const",
|
|
71
|
+
"let",
|
|
72
|
+
"var",
|
|
73
|
+
"return",
|
|
74
|
+
"if",
|
|
75
|
+
"else",
|
|
76
|
+
"for",
|
|
77
|
+
"while",
|
|
78
|
+
"class",
|
|
79
|
+
"import",
|
|
80
|
+
"export",
|
|
81
|
+
"default",
|
|
82
|
+
"async",
|
|
83
|
+
"await",
|
|
84
|
+
"new",
|
|
85
|
+
"this",
|
|
86
|
+
"typeof",
|
|
87
|
+
"instanceof",
|
|
88
|
+
"try",
|
|
89
|
+
"catch",
|
|
90
|
+
"finally",
|
|
91
|
+
"throw",
|
|
92
|
+
"extends",
|
|
93
|
+
"as",
|
|
94
|
+
"from",
|
|
95
|
+
"of",
|
|
96
|
+
"in",
|
|
97
|
+
"void",
|
|
98
|
+
"switch",
|
|
99
|
+
"case",
|
|
100
|
+
"break",
|
|
101
|
+
"continue",
|
|
102
|
+
"do",
|
|
103
|
+
"delete",
|
|
104
|
+
"yield",
|
|
105
|
+
"super",
|
|
106
|
+
"null",
|
|
107
|
+
"true",
|
|
108
|
+
"false",
|
|
109
|
+
"undefined",
|
|
110
|
+
"require",
|
|
111
|
+
"constructor",
|
|
112
|
+
"static"
|
|
113
|
+
]), je = /* @__PURE__ */ new Set([
|
|
114
|
+
// At-rules (without @)
|
|
115
|
+
"media",
|
|
116
|
+
"keyframes",
|
|
117
|
+
"import",
|
|
118
|
+
"charset",
|
|
119
|
+
"supports",
|
|
120
|
+
"layer",
|
|
121
|
+
"container",
|
|
122
|
+
"namespace",
|
|
123
|
+
"page",
|
|
124
|
+
// Position values
|
|
125
|
+
"static",
|
|
126
|
+
"relative",
|
|
127
|
+
"absolute",
|
|
128
|
+
"fixed",
|
|
129
|
+
"sticky",
|
|
130
|
+
// Display values
|
|
131
|
+
"block",
|
|
132
|
+
"inline",
|
|
133
|
+
"flex",
|
|
134
|
+
"grid",
|
|
135
|
+
"none",
|
|
136
|
+
"contents",
|
|
137
|
+
"table",
|
|
138
|
+
// Overflow / visibility
|
|
139
|
+
"hidden",
|
|
140
|
+
"visible",
|
|
141
|
+
"scroll",
|
|
142
|
+
"clip",
|
|
143
|
+
"auto",
|
|
144
|
+
// Text / font values
|
|
145
|
+
"bold",
|
|
146
|
+
"normal",
|
|
147
|
+
"italic",
|
|
148
|
+
"underline",
|
|
149
|
+
"uppercase",
|
|
150
|
+
"lowercase",
|
|
151
|
+
"capitalize",
|
|
152
|
+
"left",
|
|
153
|
+
"right",
|
|
154
|
+
"center",
|
|
155
|
+
"justify",
|
|
156
|
+
// Sizing keywords
|
|
157
|
+
"inherit",
|
|
158
|
+
"initial",
|
|
159
|
+
"unset",
|
|
160
|
+
"revert",
|
|
161
|
+
// Misc values
|
|
162
|
+
"pointer",
|
|
163
|
+
"default",
|
|
164
|
+
"transparent",
|
|
165
|
+
"solid",
|
|
166
|
+
"dashed",
|
|
167
|
+
"dotted",
|
|
168
|
+
"double",
|
|
169
|
+
"cover",
|
|
170
|
+
"contain",
|
|
171
|
+
"no-repeat",
|
|
172
|
+
"repeat",
|
|
173
|
+
// CSS functions (used as values)
|
|
174
|
+
"var",
|
|
175
|
+
"calc",
|
|
176
|
+
"min",
|
|
177
|
+
"max",
|
|
178
|
+
"clamp"
|
|
179
|
+
]), Pe = /* @__PURE__ */ new Set(["null", "true", "false"]), pe = /* @__PURE__ */ new Set(), oe = /* @__PURE__ */ new Set([
|
|
180
|
+
"number",
|
|
181
|
+
"string",
|
|
182
|
+
"boolean",
|
|
183
|
+
"any",
|
|
184
|
+
"never",
|
|
185
|
+
"unknown",
|
|
186
|
+
"object",
|
|
187
|
+
"Promise",
|
|
188
|
+
"Array",
|
|
189
|
+
"Map",
|
|
190
|
+
"Set",
|
|
191
|
+
"Record",
|
|
192
|
+
"Partial",
|
|
193
|
+
"Required",
|
|
194
|
+
"Readonly",
|
|
195
|
+
"HTMLElement",
|
|
196
|
+
"KeyboardEvent",
|
|
197
|
+
"Float64Array",
|
|
198
|
+
"EventListener",
|
|
199
|
+
"Document",
|
|
200
|
+
"Window",
|
|
201
|
+
"Node",
|
|
202
|
+
"Element",
|
|
203
|
+
"Event",
|
|
204
|
+
"MouseEvent",
|
|
205
|
+
"CustomEvent"
|
|
206
|
+
]), $e = /* @__PURE__ */ new Set([
|
|
207
|
+
"number",
|
|
208
|
+
"string",
|
|
209
|
+
"boolean",
|
|
210
|
+
"object",
|
|
211
|
+
"Promise",
|
|
212
|
+
"Array",
|
|
213
|
+
"Map",
|
|
214
|
+
"Set",
|
|
215
|
+
"HTMLElement",
|
|
216
|
+
"KeyboardEvent",
|
|
217
|
+
"Float64Array",
|
|
218
|
+
"EventListener",
|
|
219
|
+
"Document",
|
|
220
|
+
"Window",
|
|
221
|
+
"Node",
|
|
222
|
+
"Element",
|
|
223
|
+
"Event",
|
|
224
|
+
"MouseEvent",
|
|
225
|
+
"CustomEvent"
|
|
226
|
+
]), We = /* @__PURE__ */ new Set(), Ne = /* @__PURE__ */ new Set(), he = /* @__PURE__ */ new Set(), Me = {
|
|
227
|
+
typescript: se,
|
|
228
|
+
javascript: Be,
|
|
229
|
+
css: je,
|
|
230
|
+
json: Pe,
|
|
231
|
+
markdown: pe,
|
|
232
|
+
text: pe
|
|
233
|
+
}, Ee = {
|
|
234
|
+
typescript: oe,
|
|
235
|
+
javascript: $e,
|
|
236
|
+
css: We,
|
|
237
|
+
json: Ne,
|
|
238
|
+
markdown: he,
|
|
239
|
+
text: he
|
|
240
|
+
};
|
|
241
|
+
function ue(s, e) {
|
|
242
|
+
return {
|
|
243
|
+
fileId: s,
|
|
244
|
+
doc: [...e],
|
|
245
|
+
cur: { row: 0, col: 0 },
|
|
246
|
+
sel: null,
|
|
247
|
+
dirty: !1,
|
|
248
|
+
undoStack: [],
|
|
249
|
+
redoStack: [],
|
|
250
|
+
scrollTop: 0
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function L(s, e = 300) {
|
|
254
|
+
const t = {
|
|
255
|
+
doc: [...s.doc],
|
|
256
|
+
cur: { ...s.cur },
|
|
257
|
+
sel: s.sel ? { ...s.sel } : null
|
|
258
|
+
};
|
|
259
|
+
s.undoStack.push(t), s.undoStack.length > e && s.undoStack.shift(), s.redoStack = [], s.dirty = !0;
|
|
260
|
+
}
|
|
261
|
+
function Oe(s) {
|
|
262
|
+
if (!s.undoStack.length) return !1;
|
|
263
|
+
const e = {
|
|
264
|
+
doc: [...s.doc],
|
|
265
|
+
cur: { ...s.cur },
|
|
266
|
+
sel: s.sel ? { ...s.sel } : null
|
|
267
|
+
};
|
|
268
|
+
s.redoStack.push(e);
|
|
269
|
+
const t = s.undoStack.pop();
|
|
270
|
+
return s.doc = t.doc, s.cur = t.cur, s.sel = t.sel, !0;
|
|
271
|
+
}
|
|
272
|
+
function Fe(s) {
|
|
273
|
+
if (!s.redoStack.length) return !1;
|
|
274
|
+
const e = {
|
|
275
|
+
doc: [...s.doc],
|
|
276
|
+
cur: { ...s.cur },
|
|
277
|
+
sel: s.sel ? { ...s.sel } : null
|
|
278
|
+
};
|
|
279
|
+
s.undoStack.push(e);
|
|
280
|
+
const t = s.redoStack.pop();
|
|
281
|
+
return s.doc = t.doc, s.cur = t.cur, s.sel = t.sel, !0;
|
|
282
|
+
}
|
|
283
|
+
function S(s) {
|
|
284
|
+
const { doc: e, cur: t } = s;
|
|
285
|
+
t.row = Math.max(0, Math.min(e.length - 1, t.row)), t.col = Math.max(0, Math.min((e[t.row] ?? "").length, t.col));
|
|
286
|
+
}
|
|
287
|
+
function $(s) {
|
|
288
|
+
const { ar: e, ac: t, fr: i, fc: n } = s;
|
|
289
|
+
return e < i || e === i && t <= n ? s : { ar: i, ac: n, fr: e, fc: t };
|
|
290
|
+
}
|
|
291
|
+
function fe(s, e, t) {
|
|
292
|
+
if (!s) return null;
|
|
293
|
+
const i = $(s);
|
|
294
|
+
return e < i.ar || e > i.fr ? null : {
|
|
295
|
+
start: e === i.ar ? i.ac : 0,
|
|
296
|
+
end: e === i.fr ? i.fc : t
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
function Ue(s) {
|
|
300
|
+
if (!s.sel) return 0;
|
|
301
|
+
const e = $(s.sel);
|
|
302
|
+
let t = 0;
|
|
303
|
+
for (let i = e.ar; i <= e.fr; i++) {
|
|
304
|
+
const n = s.doc[i] ?? "", r = i === e.ar ? e.ac : 0, o = i === e.fr ? e.fc : n.length;
|
|
305
|
+
t += o - r;
|
|
306
|
+
}
|
|
307
|
+
return t;
|
|
308
|
+
}
|
|
309
|
+
function ge(s) {
|
|
310
|
+
if (!s.sel) return "";
|
|
311
|
+
const e = $(s.sel), t = [];
|
|
312
|
+
for (let i = e.ar; i <= e.fr; i++) {
|
|
313
|
+
const n = s.doc[i] ?? "";
|
|
314
|
+
t.push(n.slice(i === e.ar ? e.ac : 0, i === e.fr ? e.fc : n.length));
|
|
315
|
+
}
|
|
316
|
+
return t.join(`
|
|
317
|
+
`);
|
|
318
|
+
}
|
|
319
|
+
function G(s) {
|
|
320
|
+
const e = s.sel;
|
|
321
|
+
if (!e) return s.cur;
|
|
322
|
+
const t = $(e), i = (s.doc[t.ar] ?? "").slice(0, t.ac), n = (s.doc[t.fr] ?? "").slice(t.fc);
|
|
323
|
+
return s.doc.splice(t.ar, t.fr - t.ar + 1, i + n), s.sel = null, { row: t.ar, col: t.ac };
|
|
324
|
+
}
|
|
325
|
+
function Ge(s, e, t) {
|
|
326
|
+
if (!t || s.length <= e) return [s];
|
|
327
|
+
const i = [];
|
|
328
|
+
let n = 0;
|
|
329
|
+
for (; n < s.length; ) {
|
|
330
|
+
if (s.length - n <= e) {
|
|
331
|
+
i.push(s.slice(n));
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
const r = n + e;
|
|
335
|
+
let o = -1;
|
|
336
|
+
for (let l = r; l > n; l--)
|
|
337
|
+
if (s[l - 1] === " ") {
|
|
338
|
+
o = l;
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
o === -1 ? (i.push(s.slice(n, r)), n = r) : (i.push(s.slice(n, o)), n = o);
|
|
342
|
+
}
|
|
343
|
+
return i;
|
|
344
|
+
}
|
|
345
|
+
function ze(s, e, t, i) {
|
|
346
|
+
const n = [], r = [], o = [];
|
|
347
|
+
let l = -1;
|
|
348
|
+
for (let a = 0; a < s.length; a++) {
|
|
349
|
+
if (a > 0 && a <= l) {
|
|
350
|
+
o.push(r.length), n.push([s[a] ?? ""]);
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
o.push(r.length);
|
|
354
|
+
const c = Ge(s[a] ?? "", e, t);
|
|
355
|
+
n.push(c), c.forEach((d, h) => r.push({ docLine: a, segIdx: h, text: d })), i.has(a) && (l = i.get(a));
|
|
356
|
+
}
|
|
357
|
+
return { segments: n, visualRows: r, docToVisArr: o };
|
|
358
|
+
}
|
|
359
|
+
function F(s, e, t) {
|
|
360
|
+
const i = s.segments[e] ?? [""];
|
|
361
|
+
let n = t;
|
|
362
|
+
for (let r = 0; r < i.length; r++) {
|
|
363
|
+
if (n <= i[r].length || r === i.length - 1)
|
|
364
|
+
return {
|
|
365
|
+
visRow: s.docToVisArr[e] + r,
|
|
366
|
+
colInSeg: Math.min(n, i[r].length)
|
|
367
|
+
};
|
|
368
|
+
n -= i[r].length;
|
|
369
|
+
}
|
|
370
|
+
return { visRow: s.docToVisArr[e] ?? 0, colInSeg: 0 };
|
|
371
|
+
}
|
|
372
|
+
function Y(s, e, t) {
|
|
373
|
+
var o;
|
|
374
|
+
const i = s.visualRows[e];
|
|
375
|
+
if (!i) return { row: 0, col: 0 };
|
|
376
|
+
const n = s.segments[i.docLine] ?? [""];
|
|
377
|
+
let r = Math.min(t, ((o = n[i.segIdx]) == null ? void 0 : o.length) ?? 0);
|
|
378
|
+
for (let l = 0; l < i.segIdx; l++) r += n[l].length;
|
|
379
|
+
return { row: i.docLine, col: r };
|
|
380
|
+
}
|
|
381
|
+
function ae(s, e = {}) {
|
|
382
|
+
var d, h;
|
|
383
|
+
const t = [], i = s.length;
|
|
384
|
+
let n = 0;
|
|
385
|
+
const r = (p, f, _) => {
|
|
386
|
+
_ > f && t.push({ cls: p, start: f, end: _ });
|
|
387
|
+
}, o = Me[e.language ?? "typescript"] ?? se, l = Ee[e.language ?? "typescript"] ?? oe, a = (d = e.extraKeywords) != null && d.size ? /* @__PURE__ */ new Set([...o, ...e.extraKeywords]) : o, c = (h = e.extraTypes) != null && h.size ? /* @__PURE__ */ new Set([...l, ...e.extraTypes]) : l;
|
|
388
|
+
for (; n < i; ) {
|
|
389
|
+
if (s[n] === "/" && s[n + 1] === "/") {
|
|
390
|
+
r("cmt", n, i);
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
if (s[n] === "*" || s[n] === "/" && s[n + 1] === "*") {
|
|
394
|
+
r("cmt", n, i);
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
if (s[n] === "@") {
|
|
398
|
+
let p = n + 1;
|
|
399
|
+
for (; p < i && /\w/.test(s[p]); ) p++;
|
|
400
|
+
r("dec", n, p), n = p;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (s[n] === '"' || s[n] === "'" || s[n] === "`") {
|
|
404
|
+
const p = s[n];
|
|
405
|
+
let f = n + 1;
|
|
406
|
+
for (; f < i; ) {
|
|
407
|
+
if (s[f] === "\\") {
|
|
408
|
+
f += 2;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (s[f] === p) {
|
|
412
|
+
f++;
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
f++;
|
|
416
|
+
}
|
|
417
|
+
r("str", n, f), n = f;
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
if (/\d/.test(s[n]) && (n === 0 || !/\w/.test(s[n - 1]))) {
|
|
421
|
+
let p = n;
|
|
422
|
+
for (; p < i && /[\d._xXa-fA-F]/.test(s[p]); ) p++;
|
|
423
|
+
r("num", n, p), n = p;
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
if (/[a-zA-Z_$]/.test(s[n])) {
|
|
427
|
+
let p = n;
|
|
428
|
+
for (; p < i && /[\w$]/.test(s[p]); ) p++;
|
|
429
|
+
const f = s.slice(n, p);
|
|
430
|
+
a.has(f) ? r("kw", n, p) : c.has(f) ? r("typ", n, p) : p < i && s[p] === "(" ? r("fn", n, p) : /^[A-Z]/.test(f) && r("cls", n, p), n = p;
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
if (/[=<>!&|+\-*/%^~?:,;.[\]{}()]/.test(s[n])) {
|
|
434
|
+
r("op", n, n + 1), n++;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
n++;
|
|
438
|
+
}
|
|
439
|
+
return t;
|
|
440
|
+
}
|
|
441
|
+
function Le(s, e) {
|
|
442
|
+
const t = new Array(s.length).fill("");
|
|
443
|
+
for (const i of e)
|
|
444
|
+
for (let n = i.start; n < i.end; n++) t[n] = i.cls;
|
|
445
|
+
return t;
|
|
446
|
+
}
|
|
447
|
+
class qe {
|
|
448
|
+
constructor(e = 5e3) {
|
|
449
|
+
g(this, "_cache", /* @__PURE__ */ new Map());
|
|
450
|
+
g(this, "_maxSize");
|
|
451
|
+
// ── Performance counters ──────────────────────────────────
|
|
452
|
+
g(this, "_hits", 0);
|
|
453
|
+
g(this, "_misses", 0);
|
|
454
|
+
g(this, "_evictions", 0);
|
|
455
|
+
this._maxSize = e;
|
|
456
|
+
}
|
|
457
|
+
/** Live snapshot of cache performance. Useful for observability. */
|
|
458
|
+
get metrics() {
|
|
459
|
+
return {
|
|
460
|
+
hits: this._hits,
|
|
461
|
+
misses: this._misses,
|
|
462
|
+
evictions: this._evictions,
|
|
463
|
+
size: this._cache.size
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
get(e, t) {
|
|
467
|
+
const i = this._cache.get(e);
|
|
468
|
+
return i && i.src === t ? (this._hits++, i.segs) : (this._misses++, null);
|
|
469
|
+
}
|
|
470
|
+
set(e, t, i) {
|
|
471
|
+
this._cache.size >= this._maxSize && (this._cache.delete(this._cache.keys().next().value), this._evictions++), this._cache.set(e, { src: t, segs: i });
|
|
472
|
+
}
|
|
473
|
+
invalidateLine(e, t) {
|
|
474
|
+
for (let i = 0; i < t; i++)
|
|
475
|
+
this._cache.delete(`${e}:${i}`);
|
|
476
|
+
}
|
|
477
|
+
/** Clear all cached entries and reset performance counters. */
|
|
478
|
+
clear() {
|
|
479
|
+
this._cache.clear(), this._hits = 0, this._misses = 0, this._evictions = 0;
|
|
480
|
+
}
|
|
481
|
+
/** Reset performance counters without clearing cached entries. */
|
|
482
|
+
resetMetrics() {
|
|
483
|
+
this._hits = 0, this._misses = 0, this._evictions = 0;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const Ke = {
|
|
487
|
+
id: "",
|
|
488
|
+
name: "VR Dark",
|
|
489
|
+
description: "Default deep dark theme",
|
|
490
|
+
light: !1,
|
|
491
|
+
tokens: {
|
|
492
|
+
bg0: "#0d0d0f",
|
|
493
|
+
bg1: "#111115",
|
|
494
|
+
bg2: "#16161b",
|
|
495
|
+
bg3: "#1d1d24",
|
|
496
|
+
bg4: "#24242d",
|
|
497
|
+
border: "rgba(255,255,255,.07)",
|
|
498
|
+
border2: "rgba(255,255,255,.12)",
|
|
499
|
+
border3: "rgba(255,255,255,.19)",
|
|
500
|
+
text: "#c9c7c0",
|
|
501
|
+
text2: "#8b8994",
|
|
502
|
+
text3: "#4e4c58",
|
|
503
|
+
accent: "#6e9fff",
|
|
504
|
+
accent2: "#2f5db0",
|
|
505
|
+
green: "#4ec9a0",
|
|
506
|
+
orange: "#d4976e",
|
|
507
|
+
purple: "#b48eff",
|
|
508
|
+
red: "#f28b82",
|
|
509
|
+
yellow: "#e8c97a",
|
|
510
|
+
cur: "#6e9fff",
|
|
511
|
+
curGlow: "rgba(110,159,255,.65)",
|
|
512
|
+
curLineBg: "rgba(255,255,255,.032)",
|
|
513
|
+
curLineGutter: "#181820",
|
|
514
|
+
gutterBg: "#0f0f12",
|
|
515
|
+
gutterHover: "#181820",
|
|
516
|
+
gutterBorder: "rgba(255,255,255,.06)",
|
|
517
|
+
gutterNum: "#4e4c58",
|
|
518
|
+
gutterNumAct: "#9997a2",
|
|
519
|
+
selBg: "rgba(110,159,255,.22)",
|
|
520
|
+
wordHlBg: "rgba(200,198,210,.09)",
|
|
521
|
+
wordHlBorder: "rgba(200,198,210,.28)",
|
|
522
|
+
bmBorder: "rgba(110,159,255,.65)",
|
|
523
|
+
foldBg: "rgba(110,159,255,.07)",
|
|
524
|
+
foldBorder: "rgba(110,159,255,.30)",
|
|
525
|
+
findBg: "rgba(234,180,86,.18)",
|
|
526
|
+
findBorder: "rgba(234,180,86,.50)",
|
|
527
|
+
findCurBg: "rgba(234,180,86,.80)",
|
|
528
|
+
findCurBorder: "rgba(234,180,86,.95)",
|
|
529
|
+
findCurText: "#1a1000",
|
|
530
|
+
fileActiveBg: "rgba(110,159,255,.11)",
|
|
531
|
+
fileActiveText: "#6e9fff",
|
|
532
|
+
mmBg: "#0d0d0f",
|
|
533
|
+
mmSlider: "rgba(255,255,255,.07)",
|
|
534
|
+
mmDim: "rgba(0,0,0,.30)",
|
|
535
|
+
mmEdge: "rgba(255,255,255,.18)",
|
|
536
|
+
indentGuide: "rgba(255,255,255,.06)",
|
|
537
|
+
tokKw: "#6e9fff",
|
|
538
|
+
tokStr: "#4ec9a0",
|
|
539
|
+
tokCmt: "#4e4c58",
|
|
540
|
+
tokFn: "#d4976e",
|
|
541
|
+
tokNum: "#b48eff",
|
|
542
|
+
tokCls: "#e8c97a",
|
|
543
|
+
tokOp: "#55536a",
|
|
544
|
+
tokTyp: "#6ec9d4",
|
|
545
|
+
tokDec: "#f28b82"
|
|
546
|
+
}
|
|
547
|
+
}, Ve = {
|
|
548
|
+
id: "vscode-dark",
|
|
549
|
+
name: "VSCode Dark+",
|
|
550
|
+
description: "Visual Studio Code dark",
|
|
551
|
+
light: !1,
|
|
552
|
+
tokens: {
|
|
553
|
+
bg0: "#1e1e1e",
|
|
554
|
+
bg1: "#252526",
|
|
555
|
+
bg2: "#1e1e1e",
|
|
556
|
+
bg3: "#2d2d30",
|
|
557
|
+
bg4: "#3a3a3d",
|
|
558
|
+
border: "rgba(255,255,255,.09)",
|
|
559
|
+
border2: "rgba(255,255,255,.15)",
|
|
560
|
+
border3: "rgba(255,255,255,.24)",
|
|
561
|
+
text: "#d4d4d4",
|
|
562
|
+
text2: "#9a9a9a",
|
|
563
|
+
text3: "#505050",
|
|
564
|
+
accent: "#569cd6",
|
|
565
|
+
accent2: "#0e639c",
|
|
566
|
+
green: "#4ec9b0",
|
|
567
|
+
orange: "#ce9178",
|
|
568
|
+
purple: "#c586c0",
|
|
569
|
+
red: "#f44747",
|
|
570
|
+
yellow: "#dcdcaa",
|
|
571
|
+
cur: "#aeafad",
|
|
572
|
+
curGlow: "rgba(174,175,173,.40)",
|
|
573
|
+
curLineBg: "rgba(255,255,255,.038)",
|
|
574
|
+
curLineGutter: "#282828",
|
|
575
|
+
gutterBg: "#1e1e1e",
|
|
576
|
+
gutterHover: "#282828",
|
|
577
|
+
gutterBorder: "rgba(255,255,255,.07)",
|
|
578
|
+
gutterNum: "#838383",
|
|
579
|
+
gutterNumAct: "#c8c8c8",
|
|
580
|
+
selBg: "rgba(38,79,120,.65)",
|
|
581
|
+
wordHlBg: "rgba(173,214,255,.06)",
|
|
582
|
+
wordHlBorder: "rgba(173,214,255,.28)",
|
|
583
|
+
bmBorder: "rgba(86,156,214,.70)",
|
|
584
|
+
foldBg: "rgba(86,156,214,.07)",
|
|
585
|
+
foldBorder: "rgba(86,156,214,.35)",
|
|
586
|
+
findBg: "rgba(255,215,0,.13)",
|
|
587
|
+
findBorder: "rgba(255,215,0,.52)",
|
|
588
|
+
findCurBg: "#f6f6a0",
|
|
589
|
+
findCurBorder: "#d4d400",
|
|
590
|
+
findCurText: "#000",
|
|
591
|
+
fileActiveBg: "rgba(255,255,255,.07)",
|
|
592
|
+
fileActiveText: "#d4d4d4",
|
|
593
|
+
mmBg: "#1e1e1e",
|
|
594
|
+
mmSlider: "rgba(255,255,255,.07)",
|
|
595
|
+
mmDim: "rgba(0,0,0,.32)",
|
|
596
|
+
mmEdge: "rgba(255,255,255,.20)",
|
|
597
|
+
indentGuide: "rgba(255,255,255,.07)",
|
|
598
|
+
tokKw: "#569cd6",
|
|
599
|
+
tokStr: "#ce9178",
|
|
600
|
+
tokCmt: "#6a9955",
|
|
601
|
+
tokFn: "#dcdcaa",
|
|
602
|
+
tokNum: "#b5cea8",
|
|
603
|
+
tokCls: "#4ec9b0",
|
|
604
|
+
tokOp: "#d4d4d4",
|
|
605
|
+
tokTyp: "#4ec9b0",
|
|
606
|
+
tokDec: "#9cdcfe"
|
|
607
|
+
}
|
|
608
|
+
}, Ye = {
|
|
609
|
+
id: "monokai",
|
|
610
|
+
name: "Monokai",
|
|
611
|
+
description: "Classic Sublime Text theme",
|
|
612
|
+
light: !1,
|
|
613
|
+
tokens: {
|
|
614
|
+
bg0: "#272822",
|
|
615
|
+
bg1: "#1e1f1c",
|
|
616
|
+
bg2: "#272822",
|
|
617
|
+
bg3: "#3a3930",
|
|
618
|
+
bg4: "#48473d",
|
|
619
|
+
border: "rgba(255,255,255,.08)",
|
|
620
|
+
border2: "rgba(255,255,255,.13)",
|
|
621
|
+
border3: "rgba(255,255,255,.20)",
|
|
622
|
+
text: "#f8f8f2",
|
|
623
|
+
text2: "#a8a7a0",
|
|
624
|
+
text3: "#58574e",
|
|
625
|
+
accent: "#a6e22e",
|
|
626
|
+
accent2: "#3d5a10",
|
|
627
|
+
green: "#a6e22e",
|
|
628
|
+
orange: "#fd971f",
|
|
629
|
+
purple: "#ae81ff",
|
|
630
|
+
red: "#f92672",
|
|
631
|
+
yellow: "#e6db74",
|
|
632
|
+
cur: "#f8f8f2",
|
|
633
|
+
curGlow: "rgba(248,248,242,.25)",
|
|
634
|
+
curLineBg: "rgba(255,255,255,.042)",
|
|
635
|
+
curLineGutter: "#2c2d27",
|
|
636
|
+
gutterBg: "#1e1f1c",
|
|
637
|
+
gutterHover: "#2c2d27",
|
|
638
|
+
gutterBorder: "rgba(255,255,255,.06)",
|
|
639
|
+
gutterNum: "#6e6d64",
|
|
640
|
+
gutterNumAct: "#cccac0",
|
|
641
|
+
selBg: "rgba(73,72,62,.80)",
|
|
642
|
+
wordHlBg: "rgba(248,248,242,.06)",
|
|
643
|
+
wordHlBorder: "rgba(248,248,242,.22)",
|
|
644
|
+
bmBorder: "rgba(166,226,46,.65)",
|
|
645
|
+
foldBg: "rgba(166,226,46,.07)",
|
|
646
|
+
foldBorder: "rgba(166,226,46,.30)",
|
|
647
|
+
findBg: "rgba(230,219,116,.16)",
|
|
648
|
+
findBorder: "rgba(230,219,116,.52)",
|
|
649
|
+
findCurBg: "#e6db74",
|
|
650
|
+
findCurBorder: "#c9be50",
|
|
651
|
+
findCurText: "#272822",
|
|
652
|
+
fileActiveBg: "rgba(166,226,46,.10)",
|
|
653
|
+
fileActiveText: "#a6e22e",
|
|
654
|
+
mmBg: "#1e1f1c",
|
|
655
|
+
mmSlider: "rgba(255,255,255,.06)",
|
|
656
|
+
mmDim: "rgba(0,0,0,.32)",
|
|
657
|
+
mmEdge: "rgba(255,255,255,.18)",
|
|
658
|
+
indentGuide: "rgba(255,255,255,.06)",
|
|
659
|
+
tokKw: "#f92672",
|
|
660
|
+
tokStr: "#e6db74",
|
|
661
|
+
tokCmt: "#75715e",
|
|
662
|
+
tokFn: "#a6e22e",
|
|
663
|
+
tokNum: "#ae81ff",
|
|
664
|
+
tokCls: "#66d9e8",
|
|
665
|
+
tokOp: "#f8f8f2",
|
|
666
|
+
tokTyp: "#66d9e8",
|
|
667
|
+
tokDec: "#fd971f"
|
|
668
|
+
}
|
|
669
|
+
}, Je = {
|
|
670
|
+
id: "dracula",
|
|
671
|
+
name: "Dracula",
|
|
672
|
+
description: "Purple-tinted dark theme",
|
|
673
|
+
light: !1,
|
|
674
|
+
tokens: {
|
|
675
|
+
bg0: "#282a36",
|
|
676
|
+
bg1: "#21222c",
|
|
677
|
+
bg2: "#282a36",
|
|
678
|
+
bg3: "#333545",
|
|
679
|
+
bg4: "#44475a",
|
|
680
|
+
border: "rgba(255,255,255,.08)",
|
|
681
|
+
border2: "rgba(255,255,255,.14)",
|
|
682
|
+
border3: "rgba(255,255,255,.22)",
|
|
683
|
+
text: "#f8f8f2",
|
|
684
|
+
text2: "#b2b5c8",
|
|
685
|
+
text3: "#5a5e78",
|
|
686
|
+
accent: "#bd93f9",
|
|
687
|
+
accent2: "#5b3fa8",
|
|
688
|
+
green: "#50fa7b",
|
|
689
|
+
orange: "#ffb86c",
|
|
690
|
+
purple: "#bd93f9",
|
|
691
|
+
red: "#ff5555",
|
|
692
|
+
yellow: "#f1fa8c",
|
|
693
|
+
cur: "#f8f8f2",
|
|
694
|
+
curGlow: "rgba(189,147,249,.55)",
|
|
695
|
+
curLineBg: "rgba(255,255,255,.045)",
|
|
696
|
+
curLineGutter: "#2f3144",
|
|
697
|
+
gutterBg: "#21222c",
|
|
698
|
+
gutterHover: "#2f3144",
|
|
699
|
+
gutterBorder: "rgba(255,255,255,.07)",
|
|
700
|
+
gutterNum: "#5e638a",
|
|
701
|
+
gutterNumAct: "#f8f8f2",
|
|
702
|
+
selBg: "rgba(68,71,90,.85)",
|
|
703
|
+
wordHlBg: "rgba(248,248,242,.05)",
|
|
704
|
+
wordHlBorder: "rgba(248,248,242,.20)",
|
|
705
|
+
bmBorder: "rgba(189,147,249,.70)",
|
|
706
|
+
foldBg: "rgba(189,147,249,.08)",
|
|
707
|
+
foldBorder: "rgba(189,147,249,.35)",
|
|
708
|
+
findBg: "rgba(241,250,140,.14)",
|
|
709
|
+
findBorder: "rgba(241,250,140,.52)",
|
|
710
|
+
findCurBg: "#f1fa8c",
|
|
711
|
+
findCurBorder: "#d4dc50",
|
|
712
|
+
findCurText: "#282a36",
|
|
713
|
+
fileActiveBg: "rgba(189,147,249,.12)",
|
|
714
|
+
fileActiveText: "#bd93f9",
|
|
715
|
+
mmBg: "#21222c",
|
|
716
|
+
mmSlider: "rgba(255,255,255,.07)",
|
|
717
|
+
mmDim: "rgba(0,0,0,.32)",
|
|
718
|
+
mmEdge: "rgba(255,255,255,.20)",
|
|
719
|
+
indentGuide: "rgba(255,255,255,.07)",
|
|
720
|
+
tokKw: "#ff79c6",
|
|
721
|
+
tokStr: "#f1fa8c",
|
|
722
|
+
tokCmt: "#6272a4",
|
|
723
|
+
tokFn: "#50fa7b",
|
|
724
|
+
tokNum: "#bd93f9",
|
|
725
|
+
tokCls: "#8be9fd",
|
|
726
|
+
tokOp: "#f8f8f2",
|
|
727
|
+
tokTyp: "#8be9fd",
|
|
728
|
+
tokDec: "#ffb86c"
|
|
729
|
+
}
|
|
730
|
+
}, Xe = {
|
|
731
|
+
id: "github-light",
|
|
732
|
+
name: "GitHub Light",
|
|
733
|
+
description: "GitHub's clean light theme",
|
|
734
|
+
light: !0,
|
|
735
|
+
tokens: {
|
|
736
|
+
bg0: "#ffffff",
|
|
737
|
+
bg1: "#f6f8fa",
|
|
738
|
+
bg2: "#ffffff",
|
|
739
|
+
bg3: "#f0f3f6",
|
|
740
|
+
bg4: "#e7eaee",
|
|
741
|
+
border: "#d0d7de",
|
|
742
|
+
border2: "#bdc4cc",
|
|
743
|
+
border3: "#aab1ba",
|
|
744
|
+
text: "#1f2328",
|
|
745
|
+
text2: "#57606a",
|
|
746
|
+
text3: "#8c959f",
|
|
747
|
+
accent: "#0969da",
|
|
748
|
+
accent2: "#0550ae",
|
|
749
|
+
green: "#1a7f37",
|
|
750
|
+
orange: "#bc4c00",
|
|
751
|
+
purple: "#8250df",
|
|
752
|
+
red: "#cf222e",
|
|
753
|
+
yellow: "#7d4e00",
|
|
754
|
+
cur: "#0969da",
|
|
755
|
+
curGlow: "rgba(9,105,218,.30)",
|
|
756
|
+
curLineBg: "rgba(9,105,218,.055)",
|
|
757
|
+
curLineGutter: "#ebf0f8",
|
|
758
|
+
gutterBg: "#f6f8fa",
|
|
759
|
+
gutterHover: "#eaedf1",
|
|
760
|
+
gutterBorder: "#d0d7de",
|
|
761
|
+
gutterNum: "#9da5b0",
|
|
762
|
+
gutterNumAct: "#1f2328",
|
|
763
|
+
selBg: "rgba(9,105,218,.15)",
|
|
764
|
+
wordHlBg: "rgba(9,105,218,.07)",
|
|
765
|
+
wordHlBorder: "rgba(9,105,218,.28)",
|
|
766
|
+
bmBorder: "rgba(9,105,218,.60)",
|
|
767
|
+
foldBg: "rgba(9,105,218,.06)",
|
|
768
|
+
foldBorder: "rgba(9,105,218,.28)",
|
|
769
|
+
findBg: "rgba(180,100,0,.09)",
|
|
770
|
+
findBorder: "rgba(180,100,0,.42)",
|
|
771
|
+
findCurBg: "rgba(180,100,0,.75)",
|
|
772
|
+
findCurBorder: "rgba(180,100,0,.95)",
|
|
773
|
+
findCurText: "#fff",
|
|
774
|
+
fileActiveBg: "rgba(9,105,218,.09)",
|
|
775
|
+
fileActiveText: "#0969da",
|
|
776
|
+
mmBg: "#f6f8fa",
|
|
777
|
+
mmSlider: "rgba(0,0,0,.06)",
|
|
778
|
+
mmDim: "rgba(0,0,0,.055)",
|
|
779
|
+
mmEdge: "rgba(0,0,0,.18)",
|
|
780
|
+
indentGuide: "rgba(0,0,0,.09)",
|
|
781
|
+
tokKw: "#cf222e",
|
|
782
|
+
tokStr: "#0a3069",
|
|
783
|
+
tokCmt: "#6e7781",
|
|
784
|
+
tokFn: "#8250df",
|
|
785
|
+
tokNum: "#0550ae",
|
|
786
|
+
tokCls: "#953800",
|
|
787
|
+
tokOp: "#1f2328",
|
|
788
|
+
tokTyp: "#0550ae",
|
|
789
|
+
tokDec: "#0969da"
|
|
790
|
+
}
|
|
791
|
+
}, Ze = {
|
|
792
|
+
id: "solarized-light",
|
|
793
|
+
name: "Solarized Light",
|
|
794
|
+
description: "Warm precision light theme",
|
|
795
|
+
light: !0,
|
|
796
|
+
tokens: {
|
|
797
|
+
bg0: "#fdf6e3",
|
|
798
|
+
bg1: "#eee8d5",
|
|
799
|
+
bg2: "#fdf6e3",
|
|
800
|
+
bg3: "#e5dfcc",
|
|
801
|
+
bg4: "#dad4c1",
|
|
802
|
+
border: "#cdc7b4",
|
|
803
|
+
border2: "#bab4a2",
|
|
804
|
+
border3: "#a9a390",
|
|
805
|
+
text: "#002b36",
|
|
806
|
+
text2: "#586e75",
|
|
807
|
+
text3: "#93a1a1",
|
|
808
|
+
accent: "#268bd2",
|
|
809
|
+
accent2: "#1a6fa8",
|
|
810
|
+
green: "#859900",
|
|
811
|
+
orange: "#cb4b16",
|
|
812
|
+
purple: "#6c71c4",
|
|
813
|
+
red: "#dc322f",
|
|
814
|
+
yellow: "#b58900",
|
|
815
|
+
cur: "#268bd2",
|
|
816
|
+
curGlow: "rgba(38,139,210,.32)",
|
|
817
|
+
curLineBg: "rgba(38,139,210,.07)",
|
|
818
|
+
curLineGutter: "#e2dcc8",
|
|
819
|
+
gutterBg: "#eee8d5",
|
|
820
|
+
gutterHover: "#e2dcc8",
|
|
821
|
+
gutterBorder: "#cdc7b4",
|
|
822
|
+
gutterNum: "#93a1a1",
|
|
823
|
+
gutterNumAct: "#002b36",
|
|
824
|
+
selBg: "rgba(38,139,210,.18)",
|
|
825
|
+
wordHlBg: "rgba(38,139,210,.08)",
|
|
826
|
+
wordHlBorder: "rgba(38,139,210,.28)",
|
|
827
|
+
bmBorder: "rgba(38,139,210,.58)",
|
|
828
|
+
foldBg: "rgba(38,139,210,.07)",
|
|
829
|
+
foldBorder: "rgba(38,139,210,.28)",
|
|
830
|
+
findBg: "rgba(181,137,0,.11)",
|
|
831
|
+
findBorder: "rgba(181,137,0,.42)",
|
|
832
|
+
findCurBg: "rgba(181,137,0,.75)",
|
|
833
|
+
findCurBorder: "rgba(181,137,0,.95)",
|
|
834
|
+
findCurText: "#fff",
|
|
835
|
+
fileActiveBg: "rgba(38,139,210,.10)",
|
|
836
|
+
fileActiveText: "#268bd2",
|
|
837
|
+
mmBg: "#eee8d5",
|
|
838
|
+
mmSlider: "rgba(0,0,0,.06)",
|
|
839
|
+
mmDim: "rgba(0,0,0,.055)",
|
|
840
|
+
mmEdge: "rgba(0,0,0,.16)",
|
|
841
|
+
indentGuide: "rgba(0,0,0,.08)",
|
|
842
|
+
tokKw: "#859900",
|
|
843
|
+
tokStr: "#2aa198",
|
|
844
|
+
tokCmt: "#93a1a1",
|
|
845
|
+
tokFn: "#268bd2",
|
|
846
|
+
tokNum: "#d33682",
|
|
847
|
+
tokCls: "#b58900",
|
|
848
|
+
tokOp: "#657b83",
|
|
849
|
+
tokTyp: "#268bd2",
|
|
850
|
+
tokDec: "#cb4b16"
|
|
851
|
+
}
|
|
852
|
+
}, Qe = {
|
|
853
|
+
id: "mdx-dark",
|
|
854
|
+
name: "MDX Dark",
|
|
855
|
+
description: "Catppuccin Mocha — matches .smdx-dark MDX editor chrome, single-colour tokens",
|
|
856
|
+
light: !1,
|
|
857
|
+
tokens: {
|
|
858
|
+
bg0: "#181825",
|
|
859
|
+
bg1: "#1e1e2e",
|
|
860
|
+
bg2: "#1e1e2e",
|
|
861
|
+
bg3: "#2a2a3c",
|
|
862
|
+
bg4: "#313147",
|
|
863
|
+
border: "#374151",
|
|
864
|
+
border2: "rgba(129,140,248,.22)",
|
|
865
|
+
border3: "rgba(129,140,248,.40)",
|
|
866
|
+
text: "#e2e8f0",
|
|
867
|
+
text2: "#94a3b8",
|
|
868
|
+
text3: "#475569",
|
|
869
|
+
accent: "#818cf8",
|
|
870
|
+
accent2: "#6366f1",
|
|
871
|
+
green: "#c3e88d",
|
|
872
|
+
orange: "#f78c6c",
|
|
873
|
+
purple: "#c792ea",
|
|
874
|
+
red: "#f07178",
|
|
875
|
+
yellow: "#ffcb6b",
|
|
876
|
+
cur: "#818cf8",
|
|
877
|
+
curGlow: "rgba(129,140,248,.55)",
|
|
878
|
+
curLineBg: "rgba(129,140,248,.055)",
|
|
879
|
+
curLineGutter: "#252540",
|
|
880
|
+
gutterBg: "#181825",
|
|
881
|
+
gutterHover: "#252540",
|
|
882
|
+
gutterBorder: "#374151",
|
|
883
|
+
gutterNum: "#475569",
|
|
884
|
+
gutterNumAct: "#94a3b8",
|
|
885
|
+
selBg: "rgba(129,140,248,.24)",
|
|
886
|
+
wordHlBg: "rgba(226,232,240,.07)",
|
|
887
|
+
wordHlBorder: "rgba(226,232,240,.25)",
|
|
888
|
+
bmBorder: "rgba(137,221,255,.70)",
|
|
889
|
+
foldBg: "rgba(129,140,248,.07)",
|
|
890
|
+
foldBorder: "rgba(129,140,248,.30)",
|
|
891
|
+
findBg: "rgba(251,191,36,.16)",
|
|
892
|
+
findBorder: "rgba(251,191,36,.50)",
|
|
893
|
+
findCurBg: "rgba(251,191,36,.85)",
|
|
894
|
+
findCurBorder: "rgba(251,191,36,.95)",
|
|
895
|
+
findCurText: "#1a1000",
|
|
896
|
+
fileActiveBg: "rgba(129,140,248,.12)",
|
|
897
|
+
fileActiveText: "#818cf8",
|
|
898
|
+
mmBg: "#181825",
|
|
899
|
+
mmSlider: "rgba(255,255,255,.07)",
|
|
900
|
+
mmDim: "rgba(0,0,0,.30)",
|
|
901
|
+
mmEdge: "rgba(255,255,255,.18)",
|
|
902
|
+
indentGuide: "rgba(255,255,255,.06)",
|
|
903
|
+
// All tokens match prose text — single-colour, distraction-free editing
|
|
904
|
+
tokKw: "#e2e8f0",
|
|
905
|
+
tokStr: "#e2e8f0",
|
|
906
|
+
tokCmt: "#e2e8f0",
|
|
907
|
+
tokFn: "#e2e8f0",
|
|
908
|
+
tokNum: "#e2e8f0",
|
|
909
|
+
tokCls: "#e2e8f0",
|
|
910
|
+
tokOp: "#e2e8f0",
|
|
911
|
+
tokTyp: "#e2e8f0",
|
|
912
|
+
tokDec: "#e2e8f0"
|
|
913
|
+
}
|
|
914
|
+
}, et = {
|
|
915
|
+
id: "mdx-light",
|
|
916
|
+
name: "MDX Light",
|
|
917
|
+
description: "Clean light — matches default .smdx-editor MDX chrome, single-colour tokens",
|
|
918
|
+
light: !0,
|
|
919
|
+
tokens: {
|
|
920
|
+
bg0: "#f1f5f9",
|
|
921
|
+
bg1: "#ffffff",
|
|
922
|
+
bg2: "#ffffff",
|
|
923
|
+
bg3: "#f8fafc",
|
|
924
|
+
bg4: "#f1f5f9",
|
|
925
|
+
border: "#e2e8f0",
|
|
926
|
+
border2: "rgba(99,102,241,.20)",
|
|
927
|
+
border3: "rgba(99,102,241,.40)",
|
|
928
|
+
text: "#1e293b",
|
|
929
|
+
text2: "#64748b",
|
|
930
|
+
text3: "#94a3b8",
|
|
931
|
+
accent: "#6366f1",
|
|
932
|
+
accent2: "#4f46e5",
|
|
933
|
+
green: "#15803d",
|
|
934
|
+
orange: "#c2410c",
|
|
935
|
+
purple: "#7c3aed",
|
|
936
|
+
red: "#dc2626",
|
|
937
|
+
yellow: "#b45309",
|
|
938
|
+
cur: "#6366f1",
|
|
939
|
+
curGlow: "rgba(99,102,241,.35)",
|
|
940
|
+
curLineBg: "rgba(99,102,241,.05)",
|
|
941
|
+
curLineGutter: "#eef2ff",
|
|
942
|
+
gutterBg: "#f8fafc",
|
|
943
|
+
gutterHover: "#eef2ff",
|
|
944
|
+
gutterBorder: "#e2e8f0",
|
|
945
|
+
gutterNum: "#94a3b8",
|
|
946
|
+
gutterNumAct: "#475569",
|
|
947
|
+
selBg: "rgba(99,102,241,.18)",
|
|
948
|
+
wordHlBg: "rgba(99,102,241,.07)",
|
|
949
|
+
wordHlBorder: "rgba(99,102,241,.30)",
|
|
950
|
+
bmBorder: "rgba(14,116,144,.60)",
|
|
951
|
+
foldBg: "rgba(99,102,241,.06)",
|
|
952
|
+
foldBorder: "rgba(99,102,241,.28)",
|
|
953
|
+
findBg: "rgba(180,83,9,.09)",
|
|
954
|
+
findBorder: "rgba(180,83,9,.40)",
|
|
955
|
+
findCurBg: "rgba(180,83,9,.75)",
|
|
956
|
+
findCurBorder: "rgba(180,83,9,.95)",
|
|
957
|
+
findCurText: "#ffffff",
|
|
958
|
+
fileActiveBg: "rgba(99,102,241,.10)",
|
|
959
|
+
fileActiveText: "#6366f1",
|
|
960
|
+
mmBg: "#f8fafc",
|
|
961
|
+
mmSlider: "rgba(0,0,0,.06)",
|
|
962
|
+
mmDim: "rgba(0,0,0,.05)",
|
|
963
|
+
mmEdge: "rgba(0,0,0,.18)",
|
|
964
|
+
indentGuide: "rgba(0,0,0,.08)",
|
|
965
|
+
// All tokens match prose text — single-colour, distraction-free editing
|
|
966
|
+
tokKw: "#1e293b",
|
|
967
|
+
tokStr: "#1e293b",
|
|
968
|
+
tokCmt: "#1e293b",
|
|
969
|
+
tokFn: "#1e293b",
|
|
970
|
+
tokNum: "#1e293b",
|
|
971
|
+
tokCls: "#1e293b",
|
|
972
|
+
tokOp: "#1e293b",
|
|
973
|
+
tokTyp: "#1e293b",
|
|
974
|
+
tokDec: "#1e293b"
|
|
975
|
+
}
|
|
976
|
+
}, tt = [
|
|
977
|
+
Ke,
|
|
978
|
+
Ve,
|
|
979
|
+
Ye,
|
|
980
|
+
Je,
|
|
981
|
+
Xe,
|
|
982
|
+
Ze,
|
|
983
|
+
Qe,
|
|
984
|
+
et
|
|
985
|
+
], it = {
|
|
986
|
+
bg0: "--bg0",
|
|
987
|
+
bg1: "--bg1",
|
|
988
|
+
bg2: "--bg2",
|
|
989
|
+
bg3: "--bg3",
|
|
990
|
+
bg4: "--bg4",
|
|
991
|
+
border: "--border",
|
|
992
|
+
border2: "--border2",
|
|
993
|
+
border3: "--border3",
|
|
994
|
+
text: "--text",
|
|
995
|
+
text2: "--text2",
|
|
996
|
+
text3: "--text3",
|
|
997
|
+
accent: "--accent",
|
|
998
|
+
accent2: "--accent2",
|
|
999
|
+
green: "--green",
|
|
1000
|
+
orange: "--orange",
|
|
1001
|
+
purple: "--purple",
|
|
1002
|
+
red: "--red",
|
|
1003
|
+
yellow: "--yellow",
|
|
1004
|
+
cur: "--cur",
|
|
1005
|
+
curGlow: "--cur-glow",
|
|
1006
|
+
curLineBg: "--cur-line-bg",
|
|
1007
|
+
curLineGutter: "--cur-line-gutter",
|
|
1008
|
+
gutterBg: "--gutter-bg",
|
|
1009
|
+
gutterHover: "--gutter-hover",
|
|
1010
|
+
gutterBorder: "--gutter-border",
|
|
1011
|
+
gutterNum: "--gutter-num",
|
|
1012
|
+
gutterNumAct: "--gutter-num-act",
|
|
1013
|
+
selBg: "--sel-bg",
|
|
1014
|
+
wordHlBg: "--word-hl-bg",
|
|
1015
|
+
wordHlBorder: "--word-hl-border",
|
|
1016
|
+
bmBorder: "--bm-border",
|
|
1017
|
+
foldBg: "--fold-bg",
|
|
1018
|
+
foldBorder: "--fold-border",
|
|
1019
|
+
findBg: "--find-bg",
|
|
1020
|
+
findBorder: "--find-border",
|
|
1021
|
+
findCurBg: "--find-cur-bg",
|
|
1022
|
+
findCurBorder: "--find-cur-border",
|
|
1023
|
+
findCurText: "--find-cur-text",
|
|
1024
|
+
fileActiveBg: "--file-active-bg",
|
|
1025
|
+
fileActiveText: "--file-active-text",
|
|
1026
|
+
mmBg: "--mm-bg",
|
|
1027
|
+
mmSlider: "--mm-slider",
|
|
1028
|
+
mmDim: "--mm-dim",
|
|
1029
|
+
mmEdge: "--mm-edge",
|
|
1030
|
+
indentGuide: "--indent-guide",
|
|
1031
|
+
tokKw: "--tok-kw",
|
|
1032
|
+
tokStr: "--tok-str",
|
|
1033
|
+
tokCmt: "--tok-cmt",
|
|
1034
|
+
tokFn: "--tok-fn",
|
|
1035
|
+
tokNum: "--tok-num",
|
|
1036
|
+
tokCls: "--tok-cls",
|
|
1037
|
+
tokOp: "--tok-op",
|
|
1038
|
+
tokTyp: "--tok-typ",
|
|
1039
|
+
tokDec: "--tok-dec"
|
|
1040
|
+
};
|
|
1041
|
+
class nt {
|
|
1042
|
+
constructor(e) {
|
|
1043
|
+
g(this, "_registry", /* @__PURE__ */ new Map());
|
|
1044
|
+
g(this, "_activeId", "");
|
|
1045
|
+
g(this, "_root");
|
|
1046
|
+
this._root = e;
|
|
1047
|
+
for (const t of tt)
|
|
1048
|
+
this._registry.set(t.id, t);
|
|
1049
|
+
}
|
|
1050
|
+
/** Register a custom or override theme. */
|
|
1051
|
+
register(e) {
|
|
1052
|
+
this._registry.set(e.id, e);
|
|
1053
|
+
}
|
|
1054
|
+
/** Apply a theme by id or by definition. */
|
|
1055
|
+
apply(e) {
|
|
1056
|
+
let t;
|
|
1057
|
+
typeof e == "string" ? (t = this._registry.get(e), t || (console.warn(`[syncline-editor] Unknown theme: "${e}". Falling back to VR Dark.`), t = this._registry.get(""))) : (t = e, this._registry.set(t.id, t)), this._activeId = t.id, this._applyTokens(t.tokens);
|
|
1058
|
+
}
|
|
1059
|
+
get activeId() {
|
|
1060
|
+
return this._activeId;
|
|
1061
|
+
}
|
|
1062
|
+
get activeTheme() {
|
|
1063
|
+
return this._registry.get(this._activeId);
|
|
1064
|
+
}
|
|
1065
|
+
get allIds() {
|
|
1066
|
+
return [...this._registry.keys()];
|
|
1067
|
+
}
|
|
1068
|
+
get all() {
|
|
1069
|
+
return [...this._registry.values()];
|
|
1070
|
+
}
|
|
1071
|
+
_applyTokens(e) {
|
|
1072
|
+
const t = this._root.style;
|
|
1073
|
+
for (const [i, n] of Object.entries(it))
|
|
1074
|
+
t.setProperty(n, e[i]);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
const rt = `
|
|
1078
|
+
/* ── Reset ── */
|
|
1079
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
|
1080
|
+
|
|
1081
|
+
/* ── Host element ── */
|
|
1082
|
+
:host,.sl-host{
|
|
1083
|
+
display:flex;flex-direction:column;
|
|
1084
|
+
height:100%;overflow:hidden;
|
|
1085
|
+
font-family:var(--sans,'Geist',system-ui,sans-serif);
|
|
1086
|
+
color:var(--text,#c9c7c0);
|
|
1087
|
+
background:var(--bg0,#0d0d0f);
|
|
1088
|
+
|
|
1089
|
+
/* Default token vars (can be overridden by theme) */
|
|
1090
|
+
--sans:'Geist',system-ui,sans-serif;
|
|
1091
|
+
--mono:'JetBrains Mono',monospace;
|
|
1092
|
+
|
|
1093
|
+
/* ── VR Dark defaults ── */
|
|
1094
|
+
--bg0:#0d0d0f; --bg1:#111115; --bg2:#16161b; --bg3:#1d1d24; --bg4:#24242d;
|
|
1095
|
+
--border:rgba(255,255,255,.07);
|
|
1096
|
+
--border2:rgba(255,255,255,.12);
|
|
1097
|
+
--border3:rgba(255,255,255,.19);
|
|
1098
|
+
--text:#c9c7c0; --text2:#8b8994; --text3:#4e4c58;
|
|
1099
|
+
--accent:#6e9fff; --accent2:#2f5db0;
|
|
1100
|
+
--green:#4ec9a0; --orange:#d4976e; --purple:#b48eff;
|
|
1101
|
+
--red:#f28b82; --yellow:#e8c97a;
|
|
1102
|
+
--cur:#6e9fff; --cur-glow:rgba(110,159,255,.65);
|
|
1103
|
+
--cur-line-bg:rgba(255,255,255,.032);
|
|
1104
|
+
--cur-line-gutter:#181820;
|
|
1105
|
+
--gutter-bg:#0f0f12; --gutter-hover:#181820;
|
|
1106
|
+
--gutter-border:rgba(255,255,255,.06);
|
|
1107
|
+
--gutter-num:#4e4c58; --gutter-num-act:#9997a2;
|
|
1108
|
+
--sel-bg:rgba(110,159,255,.22);
|
|
1109
|
+
--word-hl-bg:rgba(200,198,210,.09);
|
|
1110
|
+
--word-hl-border:rgba(200,198,210,.28);
|
|
1111
|
+
--bm-border:rgba(110,159,255,.65);
|
|
1112
|
+
--fold-bg:rgba(110,159,255,.07);
|
|
1113
|
+
--fold-border:rgba(110,159,255,.30);
|
|
1114
|
+
--find-bg:rgba(234,180,86,.18);
|
|
1115
|
+
--find-border:rgba(234,180,86,.50);
|
|
1116
|
+
--find-cur-bg:rgba(234,180,86,.80);
|
|
1117
|
+
--find-cur-border:rgba(234,180,86,.95);
|
|
1118
|
+
--find-cur-text:#1a1000;
|
|
1119
|
+
--file-active-bg:rgba(110,159,255,.11);
|
|
1120
|
+
--file-active-text:#6e9fff;
|
|
1121
|
+
--mm-bg:#0d0d0f; --mm-slider:rgba(255,255,255,.07);
|
|
1122
|
+
--mm-dim:rgba(0,0,0,.30); --mm-edge:rgba(255,255,255,.18);
|
|
1123
|
+
--indent-guide:rgba(255,255,255,.06);
|
|
1124
|
+
--tok-kw:#6e9fff; --tok-str:#4ec9a0; --tok-cmt:#4e4c58;
|
|
1125
|
+
--tok-fn:#d4976e; --tok-num:#b48eff; --tok-cls:#e8c97a;
|
|
1126
|
+
--tok-op:#55536a; --tok-typ:#6ec9d4; --tok-dec:#f28b82;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/* ── Layout ── */
|
|
1130
|
+
.sl-layout{display:flex;flex:1;overflow:hidden}
|
|
1131
|
+
.sl-ed-pane{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative;background:var(--bg2)}
|
|
1132
|
+
|
|
1133
|
+
/* ── Hidden textarea (input capture) ── */
|
|
1134
|
+
.sl-input{position:fixed;left:-9999px;top:0;width:200px;height:40px;
|
|
1135
|
+
opacity:0;resize:none;border:none;outline:none;padding:0;margin:0;
|
|
1136
|
+
font-size:16px;background:transparent;color:transparent;
|
|
1137
|
+
caret-color:transparent;pointer-events:none}
|
|
1138
|
+
|
|
1139
|
+
/* ── Editor scroll container ── */
|
|
1140
|
+
.sl-editor{flex:1;overflow-y:scroll;overflow-x:auto;position:relative;
|
|
1141
|
+
cursor:text;scrollbar-width:thin;scrollbar-color:var(--border3) transparent}
|
|
1142
|
+
.sl-editor::-webkit-scrollbar{width:10px;height:8px}
|
|
1143
|
+
.sl-editor::-webkit-scrollbar-track{background:transparent}
|
|
1144
|
+
.sl-editor::-webkit-scrollbar-thumb{background:var(--border3);border-radius:5px;border:2px solid var(--bg2)}
|
|
1145
|
+
.sl-spacer{position:absolute;left:0;top:0;width:1px;pointer-events:none}
|
|
1146
|
+
.sl-vp{position:absolute;left:0;right:0;overflow-x:hidden;will-change:transform}
|
|
1147
|
+
|
|
1148
|
+
/* ── Editor row ── */
|
|
1149
|
+
.sl-er{display:flex;align-items:stretch;position:relative}
|
|
1150
|
+
.sl-er:hover .sl-eg{background:var(--gutter-hover)}
|
|
1151
|
+
.sl-er.sl-cur-row{background:var(--cur-line-bg)}
|
|
1152
|
+
.sl-er.sl-cur-row .sl-eg{background:var(--cur-line-gutter)!important}
|
|
1153
|
+
.sl-eg{min-width:60px;font-family:var(--mono);font-size:11px;color:var(--gutter-num);
|
|
1154
|
+
user-select:none;border-right:1px solid var(--gutter-border);
|
|
1155
|
+
background:var(--gutter-bg);flex-shrink:0;position:sticky;left:0;z-index:2;
|
|
1156
|
+
display:flex;flex-direction:column;justify-content:flex-start;
|
|
1157
|
+
transition:background .12s,color .12s}
|
|
1158
|
+
.sl-er.sl-cur-row .sl-eg{color:var(--gutter-num-act)}
|
|
1159
|
+
.sl-egn{height:22px;line-height:22px;padding-right:10px;text-align:right;display:block}
|
|
1160
|
+
.sl-er.sl-wrap-cont .sl-egn{visibility:hidden}
|
|
1161
|
+
.sl-el{flex:1;font-family:var(--mono);font-size:13px;line-height:22px;
|
|
1162
|
+
color:var(--text);position:relative;min-width:0}
|
|
1163
|
+
.sl-cl{display:block;height:22px;line-height:22px;
|
|
1164
|
+
padding:0 20px 0 14px;white-space:pre;position:relative}
|
|
1165
|
+
.sl-wrap-mode .sl-cl{white-space:pre-wrap;word-break:break-all;height:auto;overflow-wrap:anywhere}
|
|
1166
|
+
|
|
1167
|
+
/* ── Cursor ── */
|
|
1168
|
+
.sl-cur{display:inline;width:0;height:0;position:relative}
|
|
1169
|
+
.sl-cur::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
|
|
1170
|
+
background:var(--cur);border-radius:1px;
|
|
1171
|
+
box-shadow:0 0 8px var(--cur-glow);
|
|
1172
|
+
animation:sl-blink 1.05s step-end infinite;pointer-events:none}
|
|
1173
|
+
@keyframes sl-blink{0%,100%{opacity:1}45%,55%{opacity:0}}
|
|
1174
|
+
|
|
1175
|
+
/* ── Multi-cursor extra beams ── */
|
|
1176
|
+
.sl-cur-extra{display:inline;width:0;height:0;position:relative}
|
|
1177
|
+
.sl-cur-extra::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
|
|
1178
|
+
background:var(--cur);border-radius:1px;
|
|
1179
|
+
box-shadow:0 0 8px var(--cur-glow);
|
|
1180
|
+
animation:sl-blink 1.05s step-end infinite;pointer-events:none}
|
|
1181
|
+
|
|
1182
|
+
/* ── Snippet tab-stop ghost markers ── */
|
|
1183
|
+
.sl-snip-stop{display:inline;width:0;height:0;position:relative}
|
|
1184
|
+
.sl-snip-stop::after{content:'';position:absolute;left:0;top:2px;width:2px;height:18px;
|
|
1185
|
+
background:var(--cur);border-radius:1px;opacity:0.28;pointer-events:none}
|
|
1186
|
+
|
|
1187
|
+
/* ── Overlays ── */
|
|
1188
|
+
.sl-sh{background:var(--sel-bg);border-radius:2px}
|
|
1189
|
+
.sl-fh{background:var(--find-bg);box-shadow:0 0 0 1px var(--find-border);border-radius:2px}
|
|
1190
|
+
.sl-fh.sl-fh-cur{background:var(--find-cur-bg);box-shadow:0 0 0 1px var(--find-cur-border);color:var(--find-cur-text)}
|
|
1191
|
+
.sl-wh{background:var(--word-hl-bg);box-shadow:0 0 0 1px var(--word-hl-border);border-radius:2px}
|
|
1192
|
+
.sl-bm{box-shadow:0 0 0 1px var(--bm-border);border-radius:2px}
|
|
1193
|
+
.sl-ig{position:absolute;top:0;bottom:0;width:1px;background:var(--indent-guide);pointer-events:none}
|
|
1194
|
+
|
|
1195
|
+
/* ── Code folding ── */
|
|
1196
|
+
.sl-fold-btn{position:absolute;left:3px;top:4px;width:13px;height:13px;border-radius:3px;
|
|
1197
|
+
display:flex;align-items:center;justify-content:center;font-size:9px;
|
|
1198
|
+
color:var(--gutter-num);cursor:pointer;opacity:0;
|
|
1199
|
+
transition:opacity .15s,background .1s;user-select:none;line-height:1}
|
|
1200
|
+
.sl-er:hover .sl-fold-btn{opacity:1}
|
|
1201
|
+
.sl-fold-btn:hover{background:var(--border3);color:var(--gutter-num-act)}
|
|
1202
|
+
.sl-folded{background:var(--fold-bg);border-bottom:1px dashed var(--fold-border)}
|
|
1203
|
+
|
|
1204
|
+
/* ── Syntax tokens ── */
|
|
1205
|
+
.kw{color:var(--tok-kw)}.str{color:var(--tok-str)}.cmt{color:var(--tok-cmt);font-style:italic}
|
|
1206
|
+
.fn{color:var(--tok-fn)}.num{color:var(--tok-num)}.cls{color:var(--tok-cls)}
|
|
1207
|
+
.op{color:var(--tok-op)}.typ{color:var(--tok-typ)}.dec{color:var(--tok-dec)}
|
|
1208
|
+
|
|
1209
|
+
/* ── Minimap ── */
|
|
1210
|
+
.sl-minimap{background:var(--mm-bg);border-left:1px solid var(--border);
|
|
1211
|
+
overflow:hidden;position:relative;flex-shrink:0;cursor:pointer;user-select:none}
|
|
1212
|
+
.sl-minimap canvas{display:block;position:absolute;top:0;left:0}
|
|
1213
|
+
.sl-mm-slider{position:absolute;left:0;right:0;pointer-events:none}
|
|
1214
|
+
|
|
1215
|
+
/* ── Status bar ── */
|
|
1216
|
+
.sl-statusbar{height:26px;background:var(--accent2);display:flex;align-items:center;
|
|
1217
|
+
padding:0 6px;font-size:11px;color:rgba(255,255,255,.85);flex-shrink:0;gap:0}
|
|
1218
|
+
.sl-sb-item{display:flex;align-items:center;gap:4px;padding:0 8px;height:100%;
|
|
1219
|
+
cursor:pointer;transition:background .1s;white-space:nowrap;border-radius:3px}
|
|
1220
|
+
.sl-sb-item:hover{background:rgba(255,255,255,.15)}
|
|
1221
|
+
.sl-sb-item.sl-no-click{cursor:default}
|
|
1222
|
+
.sl-sb-item.sl-no-click:hover{background:transparent}
|
|
1223
|
+
.sl-sb-sep{width:1px;height:14px;background:rgba(255,255,255,.22);margin:0 1px;flex-shrink:0}
|
|
1224
|
+
.sl-sb-right{margin-left:auto;display:flex;align-items:center}
|
|
1225
|
+
.sl-sb-wrap.sl-on{font-weight:700}
|
|
1226
|
+
|
|
1227
|
+
/* ── Placeholder ── */
|
|
1228
|
+
.sl-placeholder{position:absolute;top:0;right:0;pointer-events:none;user-select:none;
|
|
1229
|
+
color:var(--text3);white-space:pre;overflow:hidden;z-index:1}
|
|
1230
|
+
|
|
1231
|
+
/* ── Go to Line bar ── */
|
|
1232
|
+
.sl-gtl-bar{position:absolute;top:0;left:50%;z-index:50;background:var(--bg3);
|
|
1233
|
+
border:1px solid var(--border3);border-top:none;border-radius:0 0 10px 10px;
|
|
1234
|
+
display:flex;align-items:center;gap:8px;padding:8px 12px;
|
|
1235
|
+
transform:translateX(-50%) translateY(-100%);transition:transform .18s,box-shadow .18s;pointer-events:none}
|
|
1236
|
+
.sl-gtl-bar.sl-open{transform:translateX(-50%) translateY(0);pointer-events:all;box-shadow:0 8px 28px rgba(0,0,0,.4)}
|
|
1237
|
+
.sl-gtl-label{font-size:12px;color:var(--text2);white-space:nowrap}
|
|
1238
|
+
.sl-gtl-input{width:72px;background:var(--bg4);border:1px solid var(--border3);
|
|
1239
|
+
border-radius:5px;padding:4px 8px;font-size:12px;font-family:var(--mono);
|
|
1240
|
+
color:var(--text);outline:none;transition:border-color .15s;text-align:center}
|
|
1241
|
+
.sl-gtl-input:focus{border-color:var(--accent)}
|
|
1242
|
+
.sl-gtl-input.sl-gtl-err{border-color:#e05252}
|
|
1243
|
+
.sl-gtl-hint{font-size:11px;color:var(--text3);font-family:var(--mono);min-width:40px}
|
|
1244
|
+
|
|
1245
|
+
/* ── Find + Replace bar ── */
|
|
1246
|
+
.sl-find-bar{position:absolute;top:0;right:125px;z-index:50;background:var(--bg3);
|
|
1247
|
+
border:1px solid var(--border3);border-top:none;border-radius:0 0 10px 10px;
|
|
1248
|
+
display:flex;flex-direction:column;overflow:hidden;
|
|
1249
|
+
transform:translateY(-100%);transition:transform .18s,box-shadow .18s;pointer-events:none}
|
|
1250
|
+
.sl-find-bar.sl-open{transform:translateY(0);pointer-events:all;box-shadow:0 8px 28px rgba(0,0,0,.4)}
|
|
1251
|
+
.sl-find-row{display:flex;align-items:center;gap:6px;padding:7px 10px}
|
|
1252
|
+
.sl-find-row+.sl-find-row{border-top:1px solid var(--border)}
|
|
1253
|
+
.sl-find-bar input{width:180px;background:var(--bg4);border:1px solid var(--border3);
|
|
1254
|
+
border-radius:5px;padding:4px 8px;font-size:12px;font-family:var(--mono);
|
|
1255
|
+
color:var(--text);outline:none;transition:border-color .15s}
|
|
1256
|
+
.sl-find-bar input:focus{border-color:var(--accent)}
|
|
1257
|
+
.sl-find-btn{padding:3px 8px;font-size:11px;border:1px solid var(--border3);
|
|
1258
|
+
border-radius:4px;background:transparent;color:var(--text2);cursor:pointer;
|
|
1259
|
+
transition:background .1s;white-space:nowrap}
|
|
1260
|
+
.sl-find-btn:hover{background:var(--border3);color:var(--text)}
|
|
1261
|
+
.sl-find-btn.sl-active{background:var(--accent);border-color:var(--accent);color:#fff}
|
|
1262
|
+
.sl-find-count{font-size:11px;color:var(--text3);font-family:var(--mono);min-width:52px}
|
|
1263
|
+
.sl-find-x{font-size:14px;color:var(--text3);cursor:pointer;padding:2px 5px;
|
|
1264
|
+
border-radius:3px;margin-left:2px}
|
|
1265
|
+
.sl-find-x:hover{color:var(--text);background:var(--border3)}
|
|
1266
|
+
|
|
1267
|
+
/* ── Autocomplete popup (VS Code-style with optional description panel) ── */
|
|
1268
|
+
.sl-ac-popup{position:fixed;z-index:400;background:var(--bg3);
|
|
1269
|
+
border:1px solid var(--border3);border-radius:8px;overflow:hidden;
|
|
1270
|
+
box-shadow:0 12px 40px rgba(0,0,0,.55);
|
|
1271
|
+
display:flex;flex-direction:row;
|
|
1272
|
+
animation:sl-acIn .1s ease;pointer-events:all}
|
|
1273
|
+
@keyframes sl-acIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
|
|
1274
|
+
/* Left: item list */
|
|
1275
|
+
.sl-ac-list{min-width:240px;max-width:300px;max-height:320px;overflow-y:auto;flex-shrink:0}
|
|
1276
|
+
.sl-ac-list::-webkit-scrollbar{width:4px}
|
|
1277
|
+
.sl-ac-list::-webkit-scrollbar-thumb{background:var(--border3);border-radius:2px}
|
|
1278
|
+
.sl-ac-item{display:flex;align-items:center;gap:8px;padding:4px 10px;font-size:12px;
|
|
1279
|
+
font-family:var(--mono);cursor:pointer;color:var(--text2);transition:background .07s;
|
|
1280
|
+
white-space:nowrap}
|
|
1281
|
+
.sl-ac-item:hover,.sl-ac-item.sl-sel{background:var(--bg4);color:var(--text)}
|
|
1282
|
+
.sl-ac-badge{width:18px;height:18px;border-radius:4px;display:flex;align-items:center;
|
|
1283
|
+
justify-content:center;font-size:9px;font-weight:700;flex-shrink:0;font-family:var(--sans)}
|
|
1284
|
+
.sl-ac-badge.kw{background:rgba(110,159,255,.18);color:var(--tok-kw)}
|
|
1285
|
+
.sl-ac-badge.fn{background:rgba(212,151,110,.18);color:var(--tok-fn)}
|
|
1286
|
+
.sl-ac-badge.typ{background:rgba(110,201,212,.18);color:var(--tok-typ)}
|
|
1287
|
+
.sl-ac-badge.cls{background:rgba(232,201,122,.18);color:var(--tok-cls)}
|
|
1288
|
+
.sl-ac-badge.var{background:rgba(78,201,160,.18);color:var(--tok-str)}
|
|
1289
|
+
.sl-ac-badge.snip{background:rgba(155,100,255,.18);color:#a78bfa}
|
|
1290
|
+
.sl-ac-badge.emmet{background:rgba(255,140,0,.18);color:#fb923c}
|
|
1291
|
+
.sl-ac-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1292
|
+
.sl-ac-detail{font-size:10px;color:var(--text3);flex-shrink:0;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-left:4px}
|
|
1293
|
+
/* Right: description / docs panel */
|
|
1294
|
+
.sl-ac-desc{width:260px;max-height:320px;overflow-y:auto;
|
|
1295
|
+
border-left:1px solid var(--border3);padding:10px 12px;flex-shrink:0}
|
|
1296
|
+
.sl-ac-desc::-webkit-scrollbar{width:4px}
|
|
1297
|
+
.sl-ac-desc::-webkit-scrollbar-thumb{background:var(--border3);border-radius:2px}
|
|
1298
|
+
.sl-ac-desc-body{margin:0;font-size:11.5px;font-family:var(--mono);
|
|
1299
|
+
color:var(--text2);line-height:1.6;white-space:pre-wrap;word-break:break-word}
|
|
1300
|
+
|
|
1301
|
+
/* ── Hover documentation tooltip ── */
|
|
1302
|
+
.sl-hover-tip{position:fixed;z-index:500;background:var(--bg3);
|
|
1303
|
+
border:1px solid var(--border3);border-radius:8px;
|
|
1304
|
+
box-shadow:0 8px 32px rgba(0,0,0,.55);
|
|
1305
|
+
max-width:380px;min-width:180px;padding:10px 14px;
|
|
1306
|
+
pointer-events:all;cursor:default;
|
|
1307
|
+
animation:sl-hoverIn .12s ease}
|
|
1308
|
+
@keyframes sl-hoverIn{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
|
|
1309
|
+
.sl-ht-sig{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;margin-bottom:5px}
|
|
1310
|
+
.sl-ht-title{font-size:12.5px;font-family:var(--mono);font-weight:600;color:var(--tok-fn)}
|
|
1311
|
+
.sl-ht-type{font-size:11px;font-family:var(--mono);color:var(--tok-typ);opacity:.9;word-break:break-all}
|
|
1312
|
+
.sl-ht-body{font-size:12px;font-family:var(--sans);color:var(--text2);line-height:1.55;
|
|
1313
|
+
max-height:120px;overflow-y:auto}
|
|
1314
|
+
.sl-ht-body::-webkit-scrollbar{width:3px}
|
|
1315
|
+
.sl-ht-body::-webkit-scrollbar-thumb{background:var(--border3);border-radius:2px}
|
|
1316
|
+
.sl-hover-tip .sl-ht-divider{height:1px;background:var(--border);margin:6px 0}
|
|
1317
|
+
|
|
1318
|
+
/* ── Emmet tooltip ── */
|
|
1319
|
+
.sl-emmet-tip{position:fixed;z-index:600;background:var(--bg3);
|
|
1320
|
+
border:1px solid var(--border3);border-radius:6px;padding:4px 10px;
|
|
1321
|
+
font-size:11px;font-family:var(--mono);color:var(--accent);
|
|
1322
|
+
pointer-events:none;box-shadow:0 4px 16px rgba(0,0,0,.45);
|
|
1323
|
+
white-space:nowrap;max-width:400px;overflow:hidden;text-overflow:ellipsis}
|
|
1324
|
+
|
|
1325
|
+
/* ── Theme picker ── */
|
|
1326
|
+
.sl-theme-overlay{position:fixed;inset:0;z-index:700;
|
|
1327
|
+
background:rgba(0,0,0,.50);backdrop-filter:blur(2px)}
|
|
1328
|
+
.sl-theme-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);
|
|
1329
|
+
z-index:701;background:var(--bg2);border:1px solid var(--border3);
|
|
1330
|
+
border-radius:14px;overflow:hidden;width:420px;
|
|
1331
|
+
box-shadow:0 32px 80px rgba(0,0,0,.65),0 0 0 1px var(--border2)}
|
|
1332
|
+
.sl-theme-header{padding:16px 20px 12px;display:flex;align-items:center;
|
|
1333
|
+
justify-content:space-between;border-bottom:1px solid var(--border)}
|
|
1334
|
+
.sl-theme-title{font-size:13px;font-weight:600;color:var(--text);letter-spacing:.01em}
|
|
1335
|
+
.sl-theme-close{width:24px;height:24px;border-radius:6px;display:flex;align-items:center;
|
|
1336
|
+
justify-content:center;font-size:14px;color:var(--text3);cursor:pointer;
|
|
1337
|
+
transition:background .1s,color .1s}
|
|
1338
|
+
.sl-theme-close:hover{background:var(--border3);color:var(--text)}
|
|
1339
|
+
.sl-theme-list{padding:8px 8px 10px}
|
|
1340
|
+
.sl-theme-item{display:flex;align-items:center;gap:14px;padding:10px 12px;
|
|
1341
|
+
border-radius:9px;cursor:pointer;transition:background .1s;
|
|
1342
|
+
border:1px solid transparent;margin-bottom:2px}
|
|
1343
|
+
.sl-theme-item:hover{background:var(--bg4)}
|
|
1344
|
+
.sl-theme-item.sl-active{background:var(--bg4);border-color:var(--border3)}
|
|
1345
|
+
.sl-theme-check{width:18px;height:18px;margin-left:auto;color:var(--accent);
|
|
1346
|
+
font-size:13px;font-weight:700;flex-shrink:0;opacity:0}
|
|
1347
|
+
.sl-theme-item.sl-active .sl-theme-check{opacity:1}
|
|
1348
|
+
.sl-theme-swatch{width:46px;height:30px;border-radius:7px;flex-shrink:0;
|
|
1349
|
+
overflow:hidden;border:1px solid rgba(0,0,0,.15);
|
|
1350
|
+
display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr}
|
|
1351
|
+
.sl-theme-swatch span{display:block}
|
|
1352
|
+
.sl-theme-name{font-size:13px;color:var(--text);font-weight:500;line-height:1.3}
|
|
1353
|
+
.sl-theme-desc{font-size:11px;color:var(--text3);margin-top:2px}
|
|
1354
|
+
.sl-theme-tag{display:inline-block;font-size:9px;font-weight:600;letter-spacing:.08em;
|
|
1355
|
+
text-transform:uppercase;padding:1px 5px;border-radius:3px;margin-left:6px;
|
|
1356
|
+
background:var(--border3);color:var(--text3);vertical-align:middle}
|
|
1357
|
+
.sl-theme-tag.sl-light{background:rgba(255,200,50,.15);color:#b58900}
|
|
1358
|
+
|
|
1359
|
+
/* ── Empty state ── */
|
|
1360
|
+
.sl-empty{flex:1;display:flex;flex-direction:column;align-items:center;
|
|
1361
|
+
justify-content:center;gap:10px;color:var(--text3);font-size:13px}
|
|
1362
|
+
`;
|
|
1363
|
+
function I(s, e, t) {
|
|
1364
|
+
const i = document.createElement(s);
|
|
1365
|
+
return e && (i.className = e), i;
|
|
1366
|
+
}
|
|
1367
|
+
function V(s) {
|
|
1368
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1369
|
+
}
|
|
1370
|
+
function X(s, e = document.documentElement) {
|
|
1371
|
+
return getComputedStyle(e).getPropertyValue(s).trim();
|
|
1372
|
+
}
|
|
1373
|
+
function be(s, e) {
|
|
1374
|
+
const t = s.replace("#", ""), i = parseInt(t.slice(0, 2), 16), n = parseInt(t.slice(2, 4), 16), r = parseInt(t.slice(4, 6), 16);
|
|
1375
|
+
return `rgba(${i},${n},${r},${e})`;
|
|
1376
|
+
}
|
|
1377
|
+
function me(s) {
|
|
1378
|
+
return s.split(`
|
|
1379
|
+
`);
|
|
1380
|
+
}
|
|
1381
|
+
function A(s) {
|
|
1382
|
+
return s.join(`
|
|
1383
|
+
`);
|
|
1384
|
+
}
|
|
1385
|
+
function _e(s) {
|
|
1386
|
+
return (s.match(/^(\s*)/) ?? ["", ""])[1];
|
|
1387
|
+
}
|
|
1388
|
+
function J(s) {
|
|
1389
|
+
return " ".repeat(Math.max(0, s));
|
|
1390
|
+
}
|
|
1391
|
+
function Ie(s) {
|
|
1392
|
+
return /[\w$]/.test(s);
|
|
1393
|
+
}
|
|
1394
|
+
function le(s, e, t = Ie) {
|
|
1395
|
+
let i = e;
|
|
1396
|
+
for (; i > 0 && t(s[i - 1]); ) i--;
|
|
1397
|
+
return i;
|
|
1398
|
+
}
|
|
1399
|
+
function ce(s, e, t = Ie) {
|
|
1400
|
+
let i = e;
|
|
1401
|
+
for (; i < s.length && t(s[i]); ) i++;
|
|
1402
|
+
return i;
|
|
1403
|
+
}
|
|
1404
|
+
function Z(s, e) {
|
|
1405
|
+
let t = 0, i = null;
|
|
1406
|
+
return (...n) => {
|
|
1407
|
+
const r = Date.now(), o = e - (r - t);
|
|
1408
|
+
o <= 0 ? (i !== null && (clearTimeout(i), i = null), t = r, s(...n)) : i === null && (i = setTimeout(() => {
|
|
1409
|
+
t = Date.now(), i = null, s(...n);
|
|
1410
|
+
}, o));
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1413
|
+
const st = {
|
|
1414
|
+
fontSize: [8, 72, 13],
|
|
1415
|
+
lineHeight: [14, 64, 22],
|
|
1416
|
+
tabSize: [1, 16, 2],
|
|
1417
|
+
wrapColumn: [20, 500, 80],
|
|
1418
|
+
maxCompletions: [1, 50, 14],
|
|
1419
|
+
autocompletePrefixLength: [1, 10, 2],
|
|
1420
|
+
gutterWidth: [30, 200, 60],
|
|
1421
|
+
minimapWidth: [60, 300, 120],
|
|
1422
|
+
cursorBlinkRate: [200, 5e3, 1050],
|
|
1423
|
+
maxUndoHistory: [10, 5e3, 300],
|
|
1424
|
+
undoBatchMs: [0, 5e3, 700]
|
|
1425
|
+
};
|
|
1426
|
+
function ot(s, e, t, i) {
|
|
1427
|
+
const n = Number(s);
|
|
1428
|
+
return Number.isFinite(n) ? Math.max(e, Math.min(t, Math.round(n))) : i;
|
|
1429
|
+
}
|
|
1430
|
+
function ye(s) {
|
|
1431
|
+
const e = { ...s };
|
|
1432
|
+
for (const [t, i] of Object.entries(st))
|
|
1433
|
+
if (t in s && s[t] !== void 0) {
|
|
1434
|
+
const [n, r, o] = i;
|
|
1435
|
+
e[t] = ot(s[t], n, r, o);
|
|
1436
|
+
}
|
|
1437
|
+
return e;
|
|
1438
|
+
}
|
|
1439
|
+
const Q = { "(": ")", "{": "}", "[": "]" }, ee = { ")": "(", "}": "{", "]": "[" };
|
|
1440
|
+
function at(s, e) {
|
|
1441
|
+
const { row: t, col: i } = e, n = s[t] ?? "";
|
|
1442
|
+
let r = n[i], o = i;
|
|
1443
|
+
if (!Q[r] && !ee[r] && (r = n[i - 1], o = i - 1), !r) return null;
|
|
1444
|
+
if (Q[r]) {
|
|
1445
|
+
const l = Q[r];
|
|
1446
|
+
let a = 0;
|
|
1447
|
+
for (let c = t; c < Math.min(s.length, t + 500); c++) {
|
|
1448
|
+
const d = s[c] ?? "", h = c === t ? o : 0;
|
|
1449
|
+
for (let p = h; p < d.length; p++)
|
|
1450
|
+
if (d[p] === r) a++;
|
|
1451
|
+
else if (d[p] === l && (a--, a === 0))
|
|
1452
|
+
return {
|
|
1453
|
+
open: { row: t, col: o },
|
|
1454
|
+
close: { row: c, col: p }
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
} else if (ee[r]) {
|
|
1458
|
+
const l = ee[r];
|
|
1459
|
+
let a = 0;
|
|
1460
|
+
for (let c = t; c >= Math.max(0, t - 500); c--) {
|
|
1461
|
+
const d = s[c] ?? "", h = c === t ? o : d.length - 1;
|
|
1462
|
+
for (let p = h; p >= 0; p--)
|
|
1463
|
+
if (d[p] === r) a++;
|
|
1464
|
+
else if (d[p] === l && (a--, a === 0))
|
|
1465
|
+
return {
|
|
1466
|
+
open: { row: c, col: p },
|
|
1467
|
+
close: { row: t, col: o }
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
return null;
|
|
1472
|
+
}
|
|
1473
|
+
function lt(s, e) {
|
|
1474
|
+
const t = s[e] ?? "";
|
|
1475
|
+
let i = 0;
|
|
1476
|
+
for (const n of t)
|
|
1477
|
+
n === "{" ? i++ : n === "}" && i--;
|
|
1478
|
+
return i > 0;
|
|
1479
|
+
}
|
|
1480
|
+
function ct(s, e) {
|
|
1481
|
+
let t = 0;
|
|
1482
|
+
for (let i = e; i < s.length; i++)
|
|
1483
|
+
for (const n of s[i] ?? "")
|
|
1484
|
+
if (n === "{") t++;
|
|
1485
|
+
else if (n === "}" && (t--, t === 0))
|
|
1486
|
+
return i;
|
|
1487
|
+
return null;
|
|
1488
|
+
}
|
|
1489
|
+
function dt(s, e, t) {
|
|
1490
|
+
const i = new Map(s);
|
|
1491
|
+
if (i.has(t))
|
|
1492
|
+
i.delete(t);
|
|
1493
|
+
else {
|
|
1494
|
+
const n = ct(e, t);
|
|
1495
|
+
n !== null && n > t && i.set(t, n);
|
|
1496
|
+
}
|
|
1497
|
+
return i;
|
|
1498
|
+
}
|
|
1499
|
+
const pt = /* @__PURE__ */ new Set([
|
|
1500
|
+
"img",
|
|
1501
|
+
"input",
|
|
1502
|
+
"br",
|
|
1503
|
+
"hr",
|
|
1504
|
+
"meta",
|
|
1505
|
+
"link",
|
|
1506
|
+
"area",
|
|
1507
|
+
"base",
|
|
1508
|
+
"col",
|
|
1509
|
+
"embed",
|
|
1510
|
+
"param",
|
|
1511
|
+
"source",
|
|
1512
|
+
"track",
|
|
1513
|
+
"wbr"
|
|
1514
|
+
]);
|
|
1515
|
+
function ve(s) {
|
|
1516
|
+
const e = s.trim();
|
|
1517
|
+
if (!e) return null;
|
|
1518
|
+
try {
|
|
1519
|
+
const t = ne(e);
|
|
1520
|
+
return t === e ? null : t;
|
|
1521
|
+
} catch {
|
|
1522
|
+
return null;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
function ne(s) {
|
|
1526
|
+
if (s.includes(">")) {
|
|
1527
|
+
const t = s.indexOf(">");
|
|
1528
|
+
return te(s.slice(0, t), ne(s.slice(t + 1)));
|
|
1529
|
+
}
|
|
1530
|
+
if (s.includes("+"))
|
|
1531
|
+
return s.split("+").map((t) => ne(t.trim())).join(`
|
|
1532
|
+
`);
|
|
1533
|
+
const e = s.match(/^(.+)\*(\d+)$/);
|
|
1534
|
+
if (e) {
|
|
1535
|
+
const t = parseInt(e[2], 10);
|
|
1536
|
+
return Array.from({ length: t }, (i, n) => te(e[1], `$${n + 1}`)).join(`
|
|
1537
|
+
`);
|
|
1538
|
+
}
|
|
1539
|
+
return te(s, "$1");
|
|
1540
|
+
}
|
|
1541
|
+
function te(s, e) {
|
|
1542
|
+
const t = s.match(/#([\w-]+)/), i = s.match(/\.([\w.-]+)/g), n = s.match(/\[([^\]]+)\]/);
|
|
1543
|
+
let r = s.replace(/#[\w-]+/g, "").replace(/\.[\w.-]+/g, "").replace(/\[[^\]]+\]/g, "").trim() || "div", o = "";
|
|
1544
|
+
return t && (o += ` id="${t[1]}"`), i && (o += ` class="${i.map((l) => l.slice(1)).join(" ")}"`), n && (o += ` ${n[1]}`), pt.has(r) ? `<${r}${o}>` : `<${r}${o}>${e}</${r}>`;
|
|
1545
|
+
}
|
|
1546
|
+
function we(s, e) {
|
|
1547
|
+
let t = e;
|
|
1548
|
+
for (; t > 0 && /[\w#.[\]*>+{}()$@:-]/.test(s[t - 1]); ) t--;
|
|
1549
|
+
const i = s.slice(t, e);
|
|
1550
|
+
return i.length < 2 ? null : { abbr: i, start: t };
|
|
1551
|
+
}
|
|
1552
|
+
const ht = [
|
|
1553
|
+
{
|
|
1554
|
+
label: "fn",
|
|
1555
|
+
kind: "snip",
|
|
1556
|
+
detail: "function declaration",
|
|
1557
|
+
description: `Declares a named function.
|
|
1558
|
+
|
|
1559
|
+
function name(params) {
|
|
1560
|
+
// body
|
|
1561
|
+
}`,
|
|
1562
|
+
body: `function $1($2) {
|
|
1563
|
+
$3
|
|
1564
|
+
}`
|
|
1565
|
+
},
|
|
1566
|
+
{
|
|
1567
|
+
label: "afn",
|
|
1568
|
+
kind: "snip",
|
|
1569
|
+
detail: "arrow function",
|
|
1570
|
+
description: `Declares a const arrow function.
|
|
1571
|
+
|
|
1572
|
+
const name = (params) => {
|
|
1573
|
+
// body
|
|
1574
|
+
};`,
|
|
1575
|
+
body: `const $1 = ($2) => {
|
|
1576
|
+
$3
|
|
1577
|
+
};`
|
|
1578
|
+
},
|
|
1579
|
+
{
|
|
1580
|
+
label: "asyncfn",
|
|
1581
|
+
kind: "snip",
|
|
1582
|
+
detail: "async function",
|
|
1583
|
+
description: `Declares an async function returning a Promise.
|
|
1584
|
+
|
|
1585
|
+
async function name(params): Promise<T> {
|
|
1586
|
+
// body
|
|
1587
|
+
}`,
|
|
1588
|
+
body: `async function $1($2): Promise<$3> {
|
|
1589
|
+
$4
|
|
1590
|
+
}`
|
|
1591
|
+
},
|
|
1592
|
+
{
|
|
1593
|
+
label: "cl",
|
|
1594
|
+
kind: "snip",
|
|
1595
|
+
detail: "class declaration",
|
|
1596
|
+
description: `Declares a class with a constructor.
|
|
1597
|
+
|
|
1598
|
+
class Name {
|
|
1599
|
+
constructor(params) { ... }
|
|
1600
|
+
}`,
|
|
1601
|
+
body: `class $1 {
|
|
1602
|
+
constructor($2) {
|
|
1603
|
+
$3
|
|
1604
|
+
}
|
|
1605
|
+
}`
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
label: "forof",
|
|
1609
|
+
kind: "snip",
|
|
1610
|
+
detail: "for…of loop",
|
|
1611
|
+
description: `Iterates over the values of an iterable (array, string, Map, etc.).
|
|
1612
|
+
|
|
1613
|
+
for (const item of iterable) { ... }`,
|
|
1614
|
+
body: `for (const $1 of $2) {
|
|
1615
|
+
$3
|
|
1616
|
+
}`
|
|
1617
|
+
},
|
|
1618
|
+
{
|
|
1619
|
+
label: "forin",
|
|
1620
|
+
kind: "snip",
|
|
1621
|
+
detail: "for…in loop",
|
|
1622
|
+
description: `Iterates over the enumerable property keys of an object.
|
|
1623
|
+
|
|
1624
|
+
for (const key in object) { ... }`,
|
|
1625
|
+
body: `for (const $1 in $2) {
|
|
1626
|
+
$3
|
|
1627
|
+
}`
|
|
1628
|
+
},
|
|
1629
|
+
{
|
|
1630
|
+
label: "trycatch",
|
|
1631
|
+
kind: "snip",
|
|
1632
|
+
detail: "try / catch block",
|
|
1633
|
+
description: `Wraps code in a try/catch to handle runtime errors.
|
|
1634
|
+
|
|
1635
|
+
try {
|
|
1636
|
+
...
|
|
1637
|
+
} catch (error) {
|
|
1638
|
+
...
|
|
1639
|
+
}`,
|
|
1640
|
+
body: `try {
|
|
1641
|
+
$1
|
|
1642
|
+
} catch ($2error) {
|
|
1643
|
+
$3
|
|
1644
|
+
}`
|
|
1645
|
+
},
|
|
1646
|
+
{
|
|
1647
|
+
label: "promise",
|
|
1648
|
+
kind: "snip",
|
|
1649
|
+
detail: "new Promise",
|
|
1650
|
+
description: `Creates a new Promise with resolve and reject handlers.
|
|
1651
|
+
|
|
1652
|
+
new Promise<T>((resolve, reject) => { ... })`,
|
|
1653
|
+
body: `new Promise<$1>((resolve, reject) => {
|
|
1654
|
+
$2
|
|
1655
|
+
})`
|
|
1656
|
+
},
|
|
1657
|
+
{
|
|
1658
|
+
label: "imp",
|
|
1659
|
+
kind: "snip",
|
|
1660
|
+
detail: "import statement",
|
|
1661
|
+
description: `Adds a named import from a module.
|
|
1662
|
+
|
|
1663
|
+
import { name } from 'module';`,
|
|
1664
|
+
body: "import { $1 } from '$2';"
|
|
1665
|
+
},
|
|
1666
|
+
{
|
|
1667
|
+
label: "iface",
|
|
1668
|
+
kind: "snip",
|
|
1669
|
+
detail: "interface (TypeScript)",
|
|
1670
|
+
description: `Declares a TypeScript interface.
|
|
1671
|
+
|
|
1672
|
+
interface Name {
|
|
1673
|
+
field: Type;
|
|
1674
|
+
}`,
|
|
1675
|
+
body: `interface $1 {
|
|
1676
|
+
$2: $3;
|
|
1677
|
+
}`,
|
|
1678
|
+
language: ["typescript"]
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
label: "ife",
|
|
1682
|
+
kind: "snip",
|
|
1683
|
+
detail: "immediately-invoked function expression",
|
|
1684
|
+
description: `An IIFE — defines and immediately calls a function.
|
|
1685
|
+
|
|
1686
|
+
((params) => {
|
|
1687
|
+
...
|
|
1688
|
+
})(args);`,
|
|
1689
|
+
body: `(($1) => {
|
|
1690
|
+
$2
|
|
1691
|
+
})($3);`
|
|
1692
|
+
},
|
|
1693
|
+
{
|
|
1694
|
+
label: "sw",
|
|
1695
|
+
kind: "snip",
|
|
1696
|
+
detail: "switch statement",
|
|
1697
|
+
description: `A switch/case statement with a default branch.
|
|
1698
|
+
|
|
1699
|
+
switch (expr) {
|
|
1700
|
+
case value:
|
|
1701
|
+
...
|
|
1702
|
+
break;
|
|
1703
|
+
default:
|
|
1704
|
+
...
|
|
1705
|
+
}`,
|
|
1706
|
+
body: `switch ($1) {
|
|
1707
|
+
case $2:
|
|
1708
|
+
$3
|
|
1709
|
+
break;
|
|
1710
|
+
default:
|
|
1711
|
+
$4
|
|
1712
|
+
}`
|
|
1713
|
+
}
|
|
1714
|
+
], ut = [
|
|
1715
|
+
{
|
|
1716
|
+
label: "flex",
|
|
1717
|
+
kind: "snip",
|
|
1718
|
+
detail: "flexbox container",
|
|
1719
|
+
description: `Sets up a flex container with centered alignment.
|
|
1720
|
+
|
|
1721
|
+
display: flex;
|
|
1722
|
+
align-items: center;
|
|
1723
|
+
justify-content: center;`,
|
|
1724
|
+
body: `display: flex;
|
|
1725
|
+
align-items: $1center;
|
|
1726
|
+
justify-content: $2center;`,
|
|
1727
|
+
language: ["css"]
|
|
1728
|
+
},
|
|
1729
|
+
{
|
|
1730
|
+
label: "grid",
|
|
1731
|
+
kind: "snip",
|
|
1732
|
+
detail: "CSS grid",
|
|
1733
|
+
description: `Sets up a CSS grid with equal columns and gap.
|
|
1734
|
+
|
|
1735
|
+
display: grid;
|
|
1736
|
+
grid-template-columns: repeat(3, 1fr);
|
|
1737
|
+
gap: 16px;`,
|
|
1738
|
+
body: `display: grid;
|
|
1739
|
+
grid-template-columns: $1repeat(3, 1fr);
|
|
1740
|
+
gap: $2;`,
|
|
1741
|
+
language: ["css"]
|
|
1742
|
+
},
|
|
1743
|
+
{
|
|
1744
|
+
label: "media",
|
|
1745
|
+
kind: "snip",
|
|
1746
|
+
detail: "@media query",
|
|
1747
|
+
description: `A responsive media query breakpoint.
|
|
1748
|
+
|
|
1749
|
+
@media (max-width: 768px) {
|
|
1750
|
+
...
|
|
1751
|
+
}`,
|
|
1752
|
+
body: `@media ($1max-width: 768px) {
|
|
1753
|
+
$2
|
|
1754
|
+
}`,
|
|
1755
|
+
language: ["css"]
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
label: "anim",
|
|
1759
|
+
kind: "snip",
|
|
1760
|
+
detail: "@keyframes animation",
|
|
1761
|
+
description: `A CSS keyframes animation block.
|
|
1762
|
+
|
|
1763
|
+
@keyframes name {
|
|
1764
|
+
from { ... }
|
|
1765
|
+
to { ... }
|
|
1766
|
+
}`,
|
|
1767
|
+
body: `@keyframes $1 {
|
|
1768
|
+
from { $2 }
|
|
1769
|
+
to { $3 }
|
|
1770
|
+
}`,
|
|
1771
|
+
language: ["css"]
|
|
1772
|
+
},
|
|
1773
|
+
{
|
|
1774
|
+
label: "var",
|
|
1775
|
+
kind: "snip",
|
|
1776
|
+
detail: "CSS custom property",
|
|
1777
|
+
description: `Declares a CSS custom property (variable).
|
|
1778
|
+
|
|
1779
|
+
--name: value;`,
|
|
1780
|
+
body: "--$1: $2;",
|
|
1781
|
+
language: ["css"]
|
|
1782
|
+
}
|
|
1783
|
+
], ft = [
|
|
1784
|
+
{
|
|
1785
|
+
label: "accordion",
|
|
1786
|
+
kind: "snip",
|
|
1787
|
+
detail: "HTML details/summary",
|
|
1788
|
+
description: `An accessible accordion using the native <details> and <summary> elements.
|
|
1789
|
+
|
|
1790
|
+
<details>
|
|
1791
|
+
<summary>Title</summary>
|
|
1792
|
+
<div>content</div>
|
|
1793
|
+
</details>`,
|
|
1794
|
+
body: `<details>
|
|
1795
|
+
<summary>$1Title</summary>
|
|
1796
|
+
<div>
|
|
1797
|
+
$2
|
|
1798
|
+
</div>
|
|
1799
|
+
</details>`
|
|
1800
|
+
},
|
|
1801
|
+
{
|
|
1802
|
+
label: "card",
|
|
1803
|
+
kind: "snip",
|
|
1804
|
+
detail: "card component",
|
|
1805
|
+
description: "A generic card component with header, body, and footer sections.",
|
|
1806
|
+
body: `<div class="card">
|
|
1807
|
+
<div class="card-header">$1</div>
|
|
1808
|
+
<div class="card-body">$2</div>
|
|
1809
|
+
<div class="card-footer">$3</div>
|
|
1810
|
+
</div>`
|
|
1811
|
+
},
|
|
1812
|
+
{
|
|
1813
|
+
label: "navbar",
|
|
1814
|
+
kind: "snip",
|
|
1815
|
+
detail: "navigation bar",
|
|
1816
|
+
description: `A simple navigation bar with anchor links.
|
|
1817
|
+
|
|
1818
|
+
<nav class="navbar">
|
|
1819
|
+
<a href="#">Home</a> ...
|
|
1820
|
+
</nav>`,
|
|
1821
|
+
body: `<nav class="navbar">
|
|
1822
|
+
<a href="$1#">Home</a>
|
|
1823
|
+
<a href="$2#">About</a>
|
|
1824
|
+
<a href="$3#">Contact</a>
|
|
1825
|
+
</nav>`
|
|
1826
|
+
},
|
|
1827
|
+
{
|
|
1828
|
+
label: "modal",
|
|
1829
|
+
kind: "snip",
|
|
1830
|
+
detail: "modal dialog",
|
|
1831
|
+
description: `A modal dialog layout with header, body, and footer.
|
|
1832
|
+
|
|
1833
|
+
<div class="modal">
|
|
1834
|
+
<div class="modal-dialog"> ... </div>
|
|
1835
|
+
</div>`,
|
|
1836
|
+
body: `<div class="modal">
|
|
1837
|
+
<div class="modal-dialog">
|
|
1838
|
+
<div class="modal-header">$1</div>
|
|
1839
|
+
<div class="modal-body">$2</div>
|
|
1840
|
+
<div class="modal-footer">$3</div>
|
|
1841
|
+
</div>
|
|
1842
|
+
</div>`
|
|
1843
|
+
},
|
|
1844
|
+
{
|
|
1845
|
+
label: "table",
|
|
1846
|
+
kind: "snip",
|
|
1847
|
+
detail: "HTML table",
|
|
1848
|
+
description: `A semantic HTML table with thead and tbody.
|
|
1849
|
+
|
|
1850
|
+
<table>
|
|
1851
|
+
<thead><tr><th>...</th></tr></thead>
|
|
1852
|
+
<tbody><tr><td>...</td></tr></tbody>
|
|
1853
|
+
</table>`,
|
|
1854
|
+
body: `<table>
|
|
1855
|
+
<thead>
|
|
1856
|
+
<tr>
|
|
1857
|
+
<th>$1</th>
|
|
1858
|
+
</tr>
|
|
1859
|
+
</thead>
|
|
1860
|
+
<tbody>
|
|
1861
|
+
<tr>
|
|
1862
|
+
<td>$2</td>
|
|
1863
|
+
</tr>
|
|
1864
|
+
</tbody>
|
|
1865
|
+
</table>`
|
|
1866
|
+
}
|
|
1867
|
+
];
|
|
1868
|
+
function gt(s) {
|
|
1869
|
+
const e = [...ft];
|
|
1870
|
+
return (s === "typescript" || s === "javascript") && e.push(...ht.filter((t) => !t.language || (Array.isArray(t.language) ? t.language.includes(s) : t.language === s))), s === "css" && e.push(...ut), e;
|
|
1871
|
+
}
|
|
1872
|
+
function bt(s, e, t) {
|
|
1873
|
+
let i = e;
|
|
1874
|
+
for (; i > 0 && /\w/.test(s[i - 1]); ) i--;
|
|
1875
|
+
const n = s.slice(i, e);
|
|
1876
|
+
if (!n) return null;
|
|
1877
|
+
const r = t.find((o) => o.kind === "snip" && o.label === n);
|
|
1878
|
+
return r ? { snippet: r, start: i } : null;
|
|
1879
|
+
}
|
|
1880
|
+
function mt() {
|
|
1881
|
+
return { cursors: [], searchWord: "", lastMatchRow: -1, lastMatchCol: -1 };
|
|
1882
|
+
}
|
|
1883
|
+
function ke(s, e, t, i) {
|
|
1884
|
+
s.cursors.some((r) => r.row === e && r.col === t) || s.cursors.push({ row: e, col: t, sel: i });
|
|
1885
|
+
}
|
|
1886
|
+
function xe(s) {
|
|
1887
|
+
s.cursors = [], s.searchWord = "", s.lastMatchRow = -1, s.lastMatchCol = -1;
|
|
1888
|
+
}
|
|
1889
|
+
function _t(s, e, t, i, n) {
|
|
1890
|
+
const r = [
|
|
1891
|
+
{ row: e, col: t, isPrimary: !0, idx: 0 },
|
|
1892
|
+
...i.map((d, h) => ({ row: d.row, col: d.col, isPrimary: !1, idx: h + 1 }))
|
|
1893
|
+
];
|
|
1894
|
+
r.sort((d, h) => h.row !== d.row ? h.row - d.row : h.col - d.col);
|
|
1895
|
+
const o = s.map((d) => d);
|
|
1896
|
+
let l = e, a = t;
|
|
1897
|
+
const c = i.map((d) => ({ ...d }));
|
|
1898
|
+
for (const d of r) {
|
|
1899
|
+
const h = o[d.row] ?? "";
|
|
1900
|
+
o[d.row] = h.slice(0, d.col) + n + h.slice(d.col);
|
|
1901
|
+
for (const p of r)
|
|
1902
|
+
p !== d && p.row === d.row && p.col >= d.col && (p.col += n.length);
|
|
1903
|
+
d.col += n.length, d.isPrimary ? (l = d.row, a = d.col) : (c[d.idx - 1].row = d.row, c[d.idx - 1].col = d.col);
|
|
1904
|
+
}
|
|
1905
|
+
return { doc: o, primaryRow: l, primaryCol: a, extraCursors: c };
|
|
1906
|
+
}
|
|
1907
|
+
function yt(s, e, t, i) {
|
|
1908
|
+
const n = [
|
|
1909
|
+
{ row: e, col: t, isPrimary: !0, idx: 0 },
|
|
1910
|
+
...i.map((c, d) => ({ row: c.row, col: c.col, isPrimary: !1, idx: d + 1 }))
|
|
1911
|
+
];
|
|
1912
|
+
n.sort((c, d) => d.row !== c.row ? d.row - c.row : d.col - c.col);
|
|
1913
|
+
const r = s.map((c) => c);
|
|
1914
|
+
let o = e, l = t;
|
|
1915
|
+
const a = i.map((c) => ({ ...c }));
|
|
1916
|
+
for (const c of n) {
|
|
1917
|
+
if (c.col <= 0) continue;
|
|
1918
|
+
const d = r[c.row] ?? "";
|
|
1919
|
+
r[c.row] = d.slice(0, c.col - 1) + d.slice(c.col);
|
|
1920
|
+
for (const h of n)
|
|
1921
|
+
h !== c && h.row === c.row && h.col > c.col && h.col--;
|
|
1922
|
+
c.col--, c.isPrimary ? (o = c.row, l = c.col) : a[c.idx - 1].col = c.col;
|
|
1923
|
+
}
|
|
1924
|
+
return { doc: r, primaryRow: o, primaryCol: l, extraCursors: a };
|
|
1925
|
+
}
|
|
1926
|
+
function vt(s, e, t, i, n) {
|
|
1927
|
+
let r = s.searchWord;
|
|
1928
|
+
if (!r) {
|
|
1929
|
+
if (n && n.ar === n.fr && (r = (e[n.ar] ?? "").slice(n.ac, n.fc)), !r) {
|
|
1930
|
+
const a = e[t] ?? "", c = le(a, i), d = ce(a, i);
|
|
1931
|
+
r = a.slice(c, d);
|
|
1932
|
+
}
|
|
1933
|
+
if (!r) return null;
|
|
1934
|
+
s.searchWord = r, s.lastMatchRow = t, s.lastMatchCol = i;
|
|
1935
|
+
}
|
|
1936
|
+
const o = s.lastMatchRow, l = s.lastMatchCol;
|
|
1937
|
+
for (let a = o; a < e.length; a++) {
|
|
1938
|
+
const c = e[a] ?? "";
|
|
1939
|
+
let h = a === o ? l : 0;
|
|
1940
|
+
for (; h <= c.length - r.length; ) {
|
|
1941
|
+
const p = c.indexOf(r, h);
|
|
1942
|
+
if (p < 0) break;
|
|
1943
|
+
const f = p === 0 || !/\w/.test(c[p - 1]), _ = p + r.length >= c.length || !/\w/.test(c[p + r.length]);
|
|
1944
|
+
if (f && _)
|
|
1945
|
+
return s.lastMatchRow = a, s.lastMatchCol = p + r.length, {
|
|
1946
|
+
word: r,
|
|
1947
|
+
sel: { ar: a, ac: p, fr: a, fc: p + r.length },
|
|
1948
|
+
row: a,
|
|
1949
|
+
col: p + r.length
|
|
1950
|
+
};
|
|
1951
|
+
h = p + 1;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
for (let a = 0; a <= o; a++) {
|
|
1955
|
+
const c = e[a] ?? "", d = a === o ? l : c.length;
|
|
1956
|
+
let h = 0;
|
|
1957
|
+
for (; h < d; ) {
|
|
1958
|
+
const p = c.indexOf(r, h);
|
|
1959
|
+
if (p < 0 || p >= d) break;
|
|
1960
|
+
const f = p === 0 || !/\w/.test(c[p - 1]), _ = p + r.length >= c.length || !/\w/.test(c[p + r.length]);
|
|
1961
|
+
if (f && _)
|
|
1962
|
+
return s.lastMatchRow = a, s.lastMatchCol = p + r.length, {
|
|
1963
|
+
word: r,
|
|
1964
|
+
sel: { ar: a, ac: p, fr: a, fc: p + r.length },
|
|
1965
|
+
row: a,
|
|
1966
|
+
col: p + r.length
|
|
1967
|
+
};
|
|
1968
|
+
h = p + 1;
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
return null;
|
|
1972
|
+
}
|
|
1973
|
+
function wt(s, e, t) {
|
|
1974
|
+
if (!e) return [];
|
|
1975
|
+
const i = [];
|
|
1976
|
+
for (let n = 0; n < s.length; n++) {
|
|
1977
|
+
const r = s[n] ?? "";
|
|
1978
|
+
if (t.useRegex)
|
|
1979
|
+
try {
|
|
1980
|
+
const o = new RegExp(e, t.caseSensitive ? "g" : "gi");
|
|
1981
|
+
let l;
|
|
1982
|
+
for (; (l = o.exec(r)) !== null && (i.push({ row: n, col: l.index, len: l[0].length }), !!l[0].length); )
|
|
1983
|
+
;
|
|
1984
|
+
} catch {
|
|
1985
|
+
}
|
|
1986
|
+
else {
|
|
1987
|
+
const o = t.caseSensitive ? r : r.toLowerCase(), l = t.caseSensitive ? e : e.toLowerCase();
|
|
1988
|
+
let a = 0;
|
|
1989
|
+
for (; ; ) {
|
|
1990
|
+
const c = o.indexOf(l, a);
|
|
1991
|
+
if (c === -1) break;
|
|
1992
|
+
i.push({ row: n, col: c, len: e.length }), a = c + 1;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
return i;
|
|
1997
|
+
}
|
|
1998
|
+
function kt(s, e, t, i) {
|
|
1999
|
+
const n = e[t];
|
|
2000
|
+
if (!n) return s;
|
|
2001
|
+
const r = [...s], o = r[n.row] ?? "";
|
|
2002
|
+
return r[n.row] = o.slice(0, n.col) + i + o.slice(n.col + n.len), r;
|
|
2003
|
+
}
|
|
2004
|
+
function xt(s, e, t) {
|
|
2005
|
+
const i = [...s];
|
|
2006
|
+
for (let n = e.length - 1; n >= 0; n--) {
|
|
2007
|
+
const r = e[n], o = i[r.row] ?? "";
|
|
2008
|
+
i[r.row] = o.slice(0, r.col) + t + o.slice(r.col + r.len);
|
|
2009
|
+
}
|
|
2010
|
+
return i;
|
|
2011
|
+
}
|
|
2012
|
+
function Tt(s, e, t) {
|
|
2013
|
+
return s.length ? (e + t + s.length) % s.length : -1;
|
|
2014
|
+
}
|
|
2015
|
+
function Ct(s, e, t, i) {
|
|
2016
|
+
if (i) return [];
|
|
2017
|
+
const n = s[e] ?? "", r = le(n, t), o = ce(n, t), l = n.slice(r, o);
|
|
2018
|
+
if (!l || l.length < 2) return [];
|
|
2019
|
+
const a = [];
|
|
2020
|
+
for (let c = 0; c < s.length; c++) {
|
|
2021
|
+
const d = s[c] ?? "";
|
|
2022
|
+
let h = 0;
|
|
2023
|
+
for (; h <= d.length - l.length; ) {
|
|
2024
|
+
const p = d.indexOf(l, h);
|
|
2025
|
+
if (p < 0) break;
|
|
2026
|
+
const f = p === 0 || !/\w/.test(d[p - 1]), _ = p + l.length >= d.length || !/\w/.test(d[p + l.length]);
|
|
2027
|
+
f && _ && !(c === e && p === r) && a.push({ row: c, col: p, len: l.length }), h = p + 1;
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
return a;
|
|
2031
|
+
}
|
|
2032
|
+
const re = [
|
|
2033
|
+
{ label: "console.log", kind: "fn", detail: "void" },
|
|
2034
|
+
{ label: "console.error", kind: "fn", detail: "void" },
|
|
2035
|
+
{ label: "console.warn", kind: "fn", detail: "void" },
|
|
2036
|
+
{ label: "console.info", kind: "fn", detail: "void" },
|
|
2037
|
+
{ label: "console.table", kind: "fn", detail: "void" },
|
|
2038
|
+
{ label: "document.getElementById", kind: "fn", detail: "HTMLElement | null" },
|
|
2039
|
+
{ label: "document.querySelector", kind: "fn", detail: "Element | null" },
|
|
2040
|
+
{ label: "document.querySelectorAll", kind: "fn", detail: "NodeList" },
|
|
2041
|
+
{ label: "document.createElement", kind: "fn", detail: "HTMLElement" },
|
|
2042
|
+
{ label: "document.createTextNode", kind: "fn", detail: "Text" },
|
|
2043
|
+
{ label: "addEventListener", kind: "fn", detail: "(ev, cb) => void" },
|
|
2044
|
+
{ label: "removeEventListener", kind: "fn", detail: "(ev, cb) => void" },
|
|
2045
|
+
{ label: "requestAnimationFrame", kind: "fn", detail: "(cb) => number" },
|
|
2046
|
+
{ label: "cancelAnimationFrame", kind: "fn", detail: "(id) => void" },
|
|
2047
|
+
{ label: "setTimeout", kind: "fn", detail: "(cb, ms) => id" },
|
|
2048
|
+
{ label: "clearTimeout", kind: "fn", detail: "(id) => void" },
|
|
2049
|
+
{ label: "setInterval", kind: "fn", detail: "(cb, ms) => id" },
|
|
2050
|
+
{ label: "clearInterval", kind: "fn", detail: "(id) => void" },
|
|
2051
|
+
{ label: "JSON.stringify", kind: "fn", detail: "string" },
|
|
2052
|
+
{ label: "JSON.parse", kind: "fn", detail: "any" },
|
|
2053
|
+
{ label: "Math.max", kind: "fn", detail: "number" },
|
|
2054
|
+
{ label: "Math.min", kind: "fn", detail: "number" },
|
|
2055
|
+
{ label: "Math.floor", kind: "fn", detail: "number" },
|
|
2056
|
+
{ label: "Math.ceil", kind: "fn", detail: "number" },
|
|
2057
|
+
{ label: "Math.round", kind: "fn", detail: "number" },
|
|
2058
|
+
{ label: "Math.abs", kind: "fn", detail: "number" },
|
|
2059
|
+
{ label: "Math.pow", kind: "fn", detail: "number" },
|
|
2060
|
+
{ label: "Math.sqrt", kind: "fn", detail: "number" },
|
|
2061
|
+
{ label: "Math.random", kind: "fn", detail: "number" },
|
|
2062
|
+
{ label: "Object.keys", kind: "fn", detail: "string[]" },
|
|
2063
|
+
{ label: "Object.values", kind: "fn", detail: "any[]" },
|
|
2064
|
+
{ label: "Object.entries", kind: "fn", detail: "[string, any][]" },
|
|
2065
|
+
{ label: "Object.assign", kind: "fn", detail: "T & U" },
|
|
2066
|
+
{ label: "Object.freeze", kind: "fn", detail: "Readonly<T>" },
|
|
2067
|
+
{ label: "Object.create", kind: "fn", detail: "object" },
|
|
2068
|
+
{ label: "Array.from", kind: "fn", detail: "T[]" },
|
|
2069
|
+
{ label: "Array.isArray", kind: "fn", detail: "boolean" },
|
|
2070
|
+
{ label: "Promise.all", kind: "fn", detail: "Promise<T[]>" },
|
|
2071
|
+
{ label: "Promise.resolve", kind: "fn", detail: "Promise<T>" },
|
|
2072
|
+
{ label: "Promise.reject", kind: "fn", detail: "Promise<never>" },
|
|
2073
|
+
{ label: "Promise.allSettled", kind: "fn", detail: "Promise<...>" },
|
|
2074
|
+
{ label: "parseInt", kind: "fn", detail: "number" },
|
|
2075
|
+
{ label: "parseFloat", kind: "fn", detail: "number" },
|
|
2076
|
+
{ label: "isNaN", kind: "fn", detail: "boolean" },
|
|
2077
|
+
{ label: "isFinite", kind: "fn", detail: "boolean" },
|
|
2078
|
+
{ label: "encodeURIComponent", kind: "fn", detail: "string" },
|
|
2079
|
+
{ label: "decodeURIComponent", kind: "fn", detail: "string" },
|
|
2080
|
+
{ label: "structuredClone", kind: "fn", detail: "T" },
|
|
2081
|
+
{ label: "queueMicrotask", kind: "fn", detail: "void" },
|
|
2082
|
+
{ label: "fetch", kind: "fn", detail: "Promise<Response>" }
|
|
2083
|
+
], St = [
|
|
2084
|
+
// ── Layout ────────────────────────────────────────────────
|
|
2085
|
+
{ label: "display", kind: "var", detail: "property" },
|
|
2086
|
+
{ label: "position", kind: "var", detail: "property" },
|
|
2087
|
+
{ label: "top", kind: "var", detail: "property" },
|
|
2088
|
+
{ label: "right", kind: "var", detail: "property" },
|
|
2089
|
+
{ label: "bottom", kind: "var", detail: "property" },
|
|
2090
|
+
{ label: "left", kind: "var", detail: "property" },
|
|
2091
|
+
{ label: "width", kind: "var", detail: "property" },
|
|
2092
|
+
{ label: "height", kind: "var", detail: "property" },
|
|
2093
|
+
{ label: "min-width", kind: "var", detail: "property" },
|
|
2094
|
+
{ label: "max-width", kind: "var", detail: "property" },
|
|
2095
|
+
{ label: "min-height", kind: "var", detail: "property" },
|
|
2096
|
+
{ label: "max-height", kind: "var", detail: "property" },
|
|
2097
|
+
{ label: "z-index", kind: "var", detail: "property" },
|
|
2098
|
+
{ label: "overflow", kind: "var", detail: "property" },
|
|
2099
|
+
{ label: "overflow-x", kind: "var", detail: "property" },
|
|
2100
|
+
{ label: "overflow-y", kind: "var", detail: "property" },
|
|
2101
|
+
{ label: "box-sizing", kind: "var", detail: "property" },
|
|
2102
|
+
// ── Flexbox ───────────────────────────────────────────────
|
|
2103
|
+
{ label: "flex", kind: "var", detail: "property" },
|
|
2104
|
+
{ label: "flex-direction", kind: "var", detail: "property" },
|
|
2105
|
+
{ label: "flex-wrap", kind: "var", detail: "property" },
|
|
2106
|
+
{ label: "flex-grow", kind: "var", detail: "property" },
|
|
2107
|
+
{ label: "flex-shrink", kind: "var", detail: "property" },
|
|
2108
|
+
{ label: "flex-basis", kind: "var", detail: "property" },
|
|
2109
|
+
{ label: "flex-flow", kind: "var", detail: "property" },
|
|
2110
|
+
{ label: "align-items", kind: "var", detail: "property" },
|
|
2111
|
+
{ label: "align-content", kind: "var", detail: "property" },
|
|
2112
|
+
{ label: "align-self", kind: "var", detail: "property" },
|
|
2113
|
+
{ label: "justify-content", kind: "var", detail: "property" },
|
|
2114
|
+
{ label: "justify-items", kind: "var", detail: "property" },
|
|
2115
|
+
{ label: "justify-self", kind: "var", detail: "property" },
|
|
2116
|
+
{ label: "gap", kind: "var", detail: "property" },
|
|
2117
|
+
{ label: "row-gap", kind: "var", detail: "property" },
|
|
2118
|
+
{ label: "column-gap", kind: "var", detail: "property" },
|
|
2119
|
+
// ── Grid ──────────────────────────────────────────────────
|
|
2120
|
+
{ label: "grid", kind: "var", detail: "property" },
|
|
2121
|
+
{ label: "grid-template", kind: "var", detail: "property" },
|
|
2122
|
+
{ label: "grid-template-columns", kind: "var", detail: "property" },
|
|
2123
|
+
{ label: "grid-template-rows", kind: "var", detail: "property" },
|
|
2124
|
+
{ label: "grid-template-areas", kind: "var", detail: "property" },
|
|
2125
|
+
{ label: "grid-column", kind: "var", detail: "property" },
|
|
2126
|
+
{ label: "grid-row", kind: "var", detail: "property" },
|
|
2127
|
+
{ label: "grid-area", kind: "var", detail: "property" },
|
|
2128
|
+
{ label: "grid-auto-flow", kind: "var", detail: "property" },
|
|
2129
|
+
// ── Spacing ───────────────────────────────────────────────
|
|
2130
|
+
{ label: "margin", kind: "var", detail: "property" },
|
|
2131
|
+
{ label: "margin-top", kind: "var", detail: "property" },
|
|
2132
|
+
{ label: "margin-right", kind: "var", detail: "property" },
|
|
2133
|
+
{ label: "margin-bottom", kind: "var", detail: "property" },
|
|
2134
|
+
{ label: "margin-left", kind: "var", detail: "property" },
|
|
2135
|
+
{ label: "padding", kind: "var", detail: "property" },
|
|
2136
|
+
{ label: "padding-top", kind: "var", detail: "property" },
|
|
2137
|
+
{ label: "padding-right", kind: "var", detail: "property" },
|
|
2138
|
+
{ label: "padding-bottom", kind: "var", detail: "property" },
|
|
2139
|
+
{ label: "padding-left", kind: "var", detail: "property" },
|
|
2140
|
+
// ── Typography ────────────────────────────────────────────
|
|
2141
|
+
{ label: "color", kind: "var", detail: "property" },
|
|
2142
|
+
{ label: "font", kind: "var", detail: "property" },
|
|
2143
|
+
{ label: "font-family", kind: "var", detail: "property" },
|
|
2144
|
+
{ label: "font-size", kind: "var", detail: "property" },
|
|
2145
|
+
{ label: "font-weight", kind: "var", detail: "property" },
|
|
2146
|
+
{ label: "font-style", kind: "var", detail: "property" },
|
|
2147
|
+
{ label: "line-height", kind: "var", detail: "property" },
|
|
2148
|
+
{ label: "text-align", kind: "var", detail: "property" },
|
|
2149
|
+
{ label: "text-decoration", kind: "var", detail: "property" },
|
|
2150
|
+
{ label: "text-transform", kind: "var", detail: "property" },
|
|
2151
|
+
{ label: "letter-spacing", kind: "var", detail: "property" },
|
|
2152
|
+
{ label: "word-spacing", kind: "var", detail: "property" },
|
|
2153
|
+
{ label: "white-space", kind: "var", detail: "property" },
|
|
2154
|
+
{ label: "word-break", kind: "var", detail: "property" },
|
|
2155
|
+
{ label: "word-wrap", kind: "var", detail: "property" },
|
|
2156
|
+
{ label: "text-overflow", kind: "var", detail: "property" },
|
|
2157
|
+
// ── Background ────────────────────────────────────────────
|
|
2158
|
+
{ label: "background", kind: "var", detail: "property" },
|
|
2159
|
+
{ label: "background-color", kind: "var", detail: "property" },
|
|
2160
|
+
{ label: "background-image", kind: "var", detail: "property" },
|
|
2161
|
+
{ label: "background-size", kind: "var", detail: "property" },
|
|
2162
|
+
{ label: "background-position", kind: "var", detail: "property" },
|
|
2163
|
+
{ label: "background-repeat", kind: "var", detail: "property" },
|
|
2164
|
+
{ label: "background-clip", kind: "var", detail: "property" },
|
|
2165
|
+
{ label: "background-attachment", kind: "var", detail: "property" },
|
|
2166
|
+
// ── Border ────────────────────────────────────────────────
|
|
2167
|
+
{ label: "border", kind: "var", detail: "property" },
|
|
2168
|
+
{ label: "border-width", kind: "var", detail: "property" },
|
|
2169
|
+
{ label: "border-style", kind: "var", detail: "property" },
|
|
2170
|
+
{ label: "border-color", kind: "var", detail: "property" },
|
|
2171
|
+
{ label: "border-radius", kind: "var", detail: "property" },
|
|
2172
|
+
{ label: "border-top", kind: "var", detail: "property" },
|
|
2173
|
+
{ label: "border-right", kind: "var", detail: "property" },
|
|
2174
|
+
{ label: "border-bottom", kind: "var", detail: "property" },
|
|
2175
|
+
{ label: "border-left", kind: "var", detail: "property" },
|
|
2176
|
+
{ label: "outline", kind: "var", detail: "property" },
|
|
2177
|
+
{ label: "outline-width", kind: "var", detail: "property" },
|
|
2178
|
+
{ label: "outline-style", kind: "var", detail: "property" },
|
|
2179
|
+
{ label: "outline-color", kind: "var", detail: "property" },
|
|
2180
|
+
{ label: "outline-offset", kind: "var", detail: "property" },
|
|
2181
|
+
// ── Effects ───────────────────────────────────────────────
|
|
2182
|
+
{ label: "opacity", kind: "var", detail: "property" },
|
|
2183
|
+
{ label: "box-shadow", kind: "var", detail: "property" },
|
|
2184
|
+
{ label: "text-shadow", kind: "var", detail: "property" },
|
|
2185
|
+
{ label: "filter", kind: "var", detail: "property" },
|
|
2186
|
+
{ label: "backdrop-filter", kind: "var", detail: "property" },
|
|
2187
|
+
{ label: "transform", kind: "var", detail: "property" },
|
|
2188
|
+
{ label: "transform-origin", kind: "var", detail: "property" },
|
|
2189
|
+
{ label: "transition", kind: "var", detail: "property" },
|
|
2190
|
+
{ label: "animation", kind: "var", detail: "property" },
|
|
2191
|
+
{ label: "animation-name", kind: "var", detail: "property" },
|
|
2192
|
+
{ label: "animation-duration", kind: "var", detail: "property" },
|
|
2193
|
+
{ label: "animation-timing-function", kind: "var", detail: "property" },
|
|
2194
|
+
{ label: "animation-delay", kind: "var", detail: "property" },
|
|
2195
|
+
{ label: "animation-iteration-count", kind: "var", detail: "property" },
|
|
2196
|
+
{ label: "animation-fill-mode", kind: "var", detail: "property" },
|
|
2197
|
+
// ── Interaction ───────────────────────────────────────────
|
|
2198
|
+
{ label: "cursor", kind: "var", detail: "property" },
|
|
2199
|
+
{ label: "pointer-events", kind: "var", detail: "property" },
|
|
2200
|
+
{ label: "user-select", kind: "var", detail: "property" },
|
|
2201
|
+
{ label: "resize", kind: "var", detail: "property" },
|
|
2202
|
+
// ── Misc ──────────────────────────────────────────────────
|
|
2203
|
+
{ label: "visibility", kind: "var", detail: "property" },
|
|
2204
|
+
{ label: "content", kind: "var", detail: "property" },
|
|
2205
|
+
{ label: "list-style", kind: "var", detail: "property" },
|
|
2206
|
+
{ label: "will-change", kind: "var", detail: "property" },
|
|
2207
|
+
{ label: "appearance", kind: "var", detail: "property" },
|
|
2208
|
+
{ label: "clip-path", kind: "var", detail: "property" },
|
|
2209
|
+
{ label: "object-fit", kind: "var", detail: "property" },
|
|
2210
|
+
{ label: "object-position", kind: "var", detail: "property" },
|
|
2211
|
+
{ label: "scroll-behavior", kind: "var", detail: "property" },
|
|
2212
|
+
{ label: "aspect-ratio", kind: "var", detail: "property" },
|
|
2213
|
+
// ── CSS functions ─────────────────────────────────────────
|
|
2214
|
+
{ label: "var", kind: "fn", detail: "css fn" },
|
|
2215
|
+
{ label: "calc", kind: "fn", detail: "css fn" },
|
|
2216
|
+
{ label: "min", kind: "fn", detail: "css fn" },
|
|
2217
|
+
{ label: "max", kind: "fn", detail: "css fn" },
|
|
2218
|
+
{ label: "clamp", kind: "fn", detail: "css fn" },
|
|
2219
|
+
{ label: "rgb", kind: "fn", detail: "css fn" },
|
|
2220
|
+
{ label: "rgba", kind: "fn", detail: "css fn" },
|
|
2221
|
+
{ label: "hsl", kind: "fn", detail: "css fn" },
|
|
2222
|
+
{ label: "hsla", kind: "fn", detail: "css fn" },
|
|
2223
|
+
{ label: "oklch", kind: "fn", detail: "css fn" },
|
|
2224
|
+
{ label: "linear-gradient", kind: "fn", detail: "css fn" },
|
|
2225
|
+
{ label: "radial-gradient", kind: "fn", detail: "css fn" },
|
|
2226
|
+
{ label: "conic-gradient", kind: "fn", detail: "css fn" },
|
|
2227
|
+
{ label: "translate", kind: "fn", detail: "css fn" },
|
|
2228
|
+
{ label: "scale", kind: "fn", detail: "css fn" },
|
|
2229
|
+
{ label: "rotate", kind: "fn", detail: "css fn" },
|
|
2230
|
+
{ label: "skew", kind: "fn", detail: "css fn" },
|
|
2231
|
+
{ label: "matrix", kind: "fn", detail: "css fn" },
|
|
2232
|
+
{ label: "perspective", kind: "fn", detail: "css fn" },
|
|
2233
|
+
{ label: "url", kind: "fn", detail: "css fn" },
|
|
2234
|
+
{ label: "attr", kind: "fn", detail: "css fn" },
|
|
2235
|
+
{ label: "env", kind: "fn", detail: "css fn" },
|
|
2236
|
+
{ label: "repeat", kind: "fn", detail: "css fn" },
|
|
2237
|
+
{ label: "minmax", kind: "fn", detail: "css fn" },
|
|
2238
|
+
{ label: "fit-content", kind: "fn", detail: "css fn" }
|
|
2239
|
+
], Mt = {
|
|
2240
|
+
typescript: re,
|
|
2241
|
+
javascript: re,
|
|
2242
|
+
css: St,
|
|
2243
|
+
json: [],
|
|
2244
|
+
markdown: [],
|
|
2245
|
+
text: []
|
|
2246
|
+
};
|
|
2247
|
+
function Te(s, e, t) {
|
|
2248
|
+
const i = Me[s] ?? se, n = Ee[s] ?? oe, r = Mt[s] ?? re;
|
|
2249
|
+
return [
|
|
2250
|
+
...[...i, ...e].map((o) => ({ label: o, kind: "kw", detail: "keyword" })),
|
|
2251
|
+
...[...n, ...t].map((o) => ({ label: o, kind: "typ", detail: "type" })),
|
|
2252
|
+
...r
|
|
2253
|
+
];
|
|
2254
|
+
}
|
|
2255
|
+
function Et(s, e) {
|
|
2256
|
+
const t = /* @__PURE__ */ new Set();
|
|
2257
|
+
for (const i of s) {
|
|
2258
|
+
const n = i.match(/[a-zA-Z_$][\w$]*/g) ?? [];
|
|
2259
|
+
for (const r of n)
|
|
2260
|
+
r !== e && r.length > 2 && t.add(r);
|
|
2261
|
+
}
|
|
2262
|
+
return t;
|
|
2263
|
+
}
|
|
2264
|
+
function Ce(s, e) {
|
|
2265
|
+
return s.language ? Array.isArray(s.language) ? s.language.includes(e) : s.language === e : !0;
|
|
2266
|
+
}
|
|
2267
|
+
function Lt(s, e, t = {}, i = 0, n = 0) {
|
|
2268
|
+
if (e.length < 2) return [];
|
|
2269
|
+
const r = e.toLowerCase(), {
|
|
2270
|
+
language: o = "typescript",
|
|
2271
|
+
extraKeywords: l = [],
|
|
2272
|
+
extraTypes: a = [],
|
|
2273
|
+
completions: c = [],
|
|
2274
|
+
replaceBuiltins: d = !1,
|
|
2275
|
+
maxResults: h = 14
|
|
2276
|
+
} = t, p = c.filter((y) => y.kind === "snip" && !!y.body && Ce(y, o)), f = c.filter((y) => !(y.kind === "snip" && y.body) && Ce(y, o)), _ = p.filter((y) => y.label.toLowerCase().startsWith(r));
|
|
2277
|
+
let b;
|
|
2278
|
+
if (t.provideCompletions) {
|
|
2279
|
+
const y = {
|
|
2280
|
+
line: s[i] ?? "",
|
|
2281
|
+
col: n,
|
|
2282
|
+
prefix: e,
|
|
2283
|
+
language: o,
|
|
2284
|
+
doc: s
|
|
2285
|
+
};
|
|
2286
|
+
let D;
|
|
2287
|
+
try {
|
|
2288
|
+
D = t.provideCompletions(y);
|
|
2289
|
+
} catch (R) {
|
|
2290
|
+
console.error("[syncline-editor] provideCompletions threw an error:", R), D = null;
|
|
2291
|
+
}
|
|
2292
|
+
b = D != null ? [...D, ...f] : [...d ? [] : Te(o, l, a), ...f];
|
|
2293
|
+
} else
|
|
2294
|
+
b = d ? f : [...Te(o, l, a), ...f];
|
|
2295
|
+
const v = new Set(b.map((y) => y.label)), u = b.filter(
|
|
2296
|
+
(y) => y.label.toLowerCase().startsWith(r) && y.label !== e
|
|
2297
|
+
), T = new Set(_.map((y) => y.label)), w = [...Et(s, e)].filter((y) => y.toLowerCase().startsWith(r) && !v.has(y) && !T.has(y)).slice(0, 8).map((y) => ({ label: y, kind: "var", detail: "in file" }));
|
|
2298
|
+
return [
|
|
2299
|
+
..._,
|
|
2300
|
+
...u.filter((y) => !T.has(y.label)),
|
|
2301
|
+
...w
|
|
2302
|
+
].slice(0, h);
|
|
2303
|
+
}
|
|
2304
|
+
function It(s, e, t = !1) {
|
|
2305
|
+
let i = e;
|
|
2306
|
+
for (; i > 0 && (t ? /[\w$.\-]/ : /[\w$.]/).test(s[i - 1]); ) i--;
|
|
2307
|
+
return { prefix: s.slice(i, e), start: i };
|
|
2308
|
+
}
|
|
2309
|
+
function At(s, e) {
|
|
2310
|
+
const t = (r) => /[\w$]/.test(r);
|
|
2311
|
+
let i = e;
|
|
2312
|
+
for (; i < s.length && t(s[i]); ) i++;
|
|
2313
|
+
let n = e;
|
|
2314
|
+
for (; n > 0 && t(s[n - 1]); ) n--;
|
|
2315
|
+
if (n === i) return "";
|
|
2316
|
+
if (n > 0 && s[n - 1] === ".") {
|
|
2317
|
+
let r = n - 1, o = r;
|
|
2318
|
+
for (; o > 0 && t(s[o - 1]); ) o--;
|
|
2319
|
+
if (o < r)
|
|
2320
|
+
return s.slice(o, i);
|
|
2321
|
+
}
|
|
2322
|
+
return s.slice(n, i);
|
|
2323
|
+
}
|
|
2324
|
+
const Dt = {
|
|
2325
|
+
// ── console ───────────────────────────────────────────────
|
|
2326
|
+
console: {
|
|
2327
|
+
title: "console",
|
|
2328
|
+
type: "Console",
|
|
2329
|
+
body: "Provides access to the browser's debugging console. Useful for logging, timing, profiling, and inspecting values during development.",
|
|
2330
|
+
language: ["typescript", "javascript"]
|
|
2331
|
+
},
|
|
2332
|
+
"console.log": {
|
|
2333
|
+
title: "console.log()",
|
|
2334
|
+
type: "(...data: any[]) => void",
|
|
2335
|
+
body: "Outputs a message to the web console. Accepts any number of arguments — objects are logged as expandable trees, primitives as their string form.",
|
|
2336
|
+
language: ["typescript", "javascript"]
|
|
2337
|
+
},
|
|
2338
|
+
"console.error": {
|
|
2339
|
+
title: "console.error()",
|
|
2340
|
+
type: "(...data: any[]) => void",
|
|
2341
|
+
body: "Logs an error message to the console, typically rendered in red with a stack trace. Use for unrecoverable failures.",
|
|
2342
|
+
language: ["typescript", "javascript"]
|
|
2343
|
+
},
|
|
2344
|
+
"console.warn": {
|
|
2345
|
+
title: "console.warn()",
|
|
2346
|
+
type: "(...data: any[]) => void",
|
|
2347
|
+
body: "Logs a warning message to the console, typically rendered in yellow. Use for non-fatal issues or deprecation notices.",
|
|
2348
|
+
language: ["typescript", "javascript"]
|
|
2349
|
+
},
|
|
2350
|
+
"console.info": {
|
|
2351
|
+
title: "console.info()",
|
|
2352
|
+
type: "(...data: any[]) => void",
|
|
2353
|
+
body: "Logs an informational message. Behaves identically to console.log in most environments.",
|
|
2354
|
+
language: ["typescript", "javascript"]
|
|
2355
|
+
},
|
|
2356
|
+
"console.table": {
|
|
2357
|
+
title: "console.table()",
|
|
2358
|
+
type: "(data: any, columns?: string[]) => void",
|
|
2359
|
+
body: "Displays an array or object as a formatted table in the console. Optionally restrict displayed columns.",
|
|
2360
|
+
language: ["typescript", "javascript"]
|
|
2361
|
+
},
|
|
2362
|
+
"console.time": {
|
|
2363
|
+
title: "console.time()",
|
|
2364
|
+
type: "(label?: string) => void",
|
|
2365
|
+
body: "Starts a timer with the given label. Call console.timeEnd() with the same label to log the elapsed time.",
|
|
2366
|
+
language: ["typescript", "javascript"]
|
|
2367
|
+
},
|
|
2368
|
+
"console.timeEnd": {
|
|
2369
|
+
title: "console.timeEnd()",
|
|
2370
|
+
type: "(label?: string) => void",
|
|
2371
|
+
body: "Stops the timer started by console.time() and logs the elapsed duration in milliseconds.",
|
|
2372
|
+
language: ["typescript", "javascript"]
|
|
2373
|
+
},
|
|
2374
|
+
"console.group": {
|
|
2375
|
+
title: "console.group()",
|
|
2376
|
+
type: "(...label: any[]) => void",
|
|
2377
|
+
body: "Creates a new inline group in the console output, indenting subsequent messages until console.groupEnd() is called.",
|
|
2378
|
+
language: ["typescript", "javascript"]
|
|
2379
|
+
},
|
|
2380
|
+
"console.groupEnd": {
|
|
2381
|
+
title: "console.groupEnd()",
|
|
2382
|
+
type: "() => void",
|
|
2383
|
+
body: "Closes the current inline group in the console, exiting the indented group created by console.group().",
|
|
2384
|
+
language: ["typescript", "javascript"]
|
|
2385
|
+
},
|
|
2386
|
+
// ── Math ──────────────────────────────────────────────────
|
|
2387
|
+
Math: {
|
|
2388
|
+
title: "Math",
|
|
2389
|
+
type: "namespace Math",
|
|
2390
|
+
body: "A built-in object with properties and methods for mathematical constants and functions. Not a constructor — all properties and methods are static.",
|
|
2391
|
+
language: ["typescript", "javascript"]
|
|
2392
|
+
},
|
|
2393
|
+
"Math.max": {
|
|
2394
|
+
title: "Math.max()",
|
|
2395
|
+
type: "(...values: number[]) => number",
|
|
2396
|
+
body: "Returns the largest of the given numbers. Returns -Infinity if no arguments, or NaN if any argument is not a number.",
|
|
2397
|
+
language: ["typescript", "javascript"]
|
|
2398
|
+
},
|
|
2399
|
+
"Math.min": {
|
|
2400
|
+
title: "Math.min()",
|
|
2401
|
+
type: "(...values: number[]) => number",
|
|
2402
|
+
body: "Returns the smallest of the given numbers. Returns Infinity if no arguments, or NaN if any argument is not a number.",
|
|
2403
|
+
language: ["typescript", "javascript"]
|
|
2404
|
+
},
|
|
2405
|
+
"Math.floor": {
|
|
2406
|
+
title: "Math.floor()",
|
|
2407
|
+
type: "(x: number) => number",
|
|
2408
|
+
body: "Returns the largest integer less than or equal to x. Rounds toward negative infinity.",
|
|
2409
|
+
language: ["typescript", "javascript"]
|
|
2410
|
+
},
|
|
2411
|
+
"Math.ceil": {
|
|
2412
|
+
title: "Math.ceil()",
|
|
2413
|
+
type: "(x: number) => number",
|
|
2414
|
+
body: "Returns the smallest integer greater than or equal to x. Rounds toward positive infinity.",
|
|
2415
|
+
language: ["typescript", "javascript"]
|
|
2416
|
+
},
|
|
2417
|
+
"Math.round": {
|
|
2418
|
+
title: "Math.round()",
|
|
2419
|
+
type: "(x: number) => number",
|
|
2420
|
+
body: "Returns the value of x rounded to the nearest integer. Values with a fractional part of exactly 0.5 round up.",
|
|
2421
|
+
language: ["typescript", "javascript"]
|
|
2422
|
+
},
|
|
2423
|
+
"Math.abs": {
|
|
2424
|
+
title: "Math.abs()",
|
|
2425
|
+
type: "(x: number) => number",
|
|
2426
|
+
body: "Returns the absolute (non-negative) value of x.",
|
|
2427
|
+
language: ["typescript", "javascript"]
|
|
2428
|
+
},
|
|
2429
|
+
"Math.sqrt": {
|
|
2430
|
+
title: "Math.sqrt()",
|
|
2431
|
+
type: "(x: number) => number",
|
|
2432
|
+
body: "Returns the square root of x. Returns NaN if x is negative.",
|
|
2433
|
+
language: ["typescript", "javascript"]
|
|
2434
|
+
},
|
|
2435
|
+
"Math.pow": {
|
|
2436
|
+
title: "Math.pow()",
|
|
2437
|
+
type: "(base: number, exponent: number) => number",
|
|
2438
|
+
body: "Returns base raised to the power of exponent. Equivalent to the ** operator.",
|
|
2439
|
+
language: ["typescript", "javascript"]
|
|
2440
|
+
},
|
|
2441
|
+
"Math.random": {
|
|
2442
|
+
title: "Math.random()",
|
|
2443
|
+
type: "() => number",
|
|
2444
|
+
body: "Returns a pseudo-random floating-point number in the range [0, 1). Not cryptographically secure — use crypto.getRandomValues() for security-sensitive code.",
|
|
2445
|
+
language: ["typescript", "javascript"]
|
|
2446
|
+
},
|
|
2447
|
+
"Math.PI": {
|
|
2448
|
+
title: "Math.PI",
|
|
2449
|
+
type: "number",
|
|
2450
|
+
body: "The ratio of a circle's circumference to its diameter: approximately 3.14159265358979.",
|
|
2451
|
+
language: ["typescript", "javascript"]
|
|
2452
|
+
},
|
|
2453
|
+
"Math.trunc": {
|
|
2454
|
+
title: "Math.trunc()",
|
|
2455
|
+
type: "(x: number) => number",
|
|
2456
|
+
body: "Returns the integer part of x by removing any fractional digits. Does not round — simply truncates toward zero.",
|
|
2457
|
+
language: ["typescript", "javascript"]
|
|
2458
|
+
},
|
|
2459
|
+
"Math.sign": {
|
|
2460
|
+
title: "Math.sign()",
|
|
2461
|
+
type: "(x: number) => number",
|
|
2462
|
+
body: "Returns 1 if x is positive, -1 if x is negative, 0 if x is zero, or NaN if x is not a number.",
|
|
2463
|
+
language: ["typescript", "javascript"]
|
|
2464
|
+
},
|
|
2465
|
+
"Math.clamp": {
|
|
2466
|
+
title: "Math.clamp()",
|
|
2467
|
+
type: "(value: number, min: number, max: number) => number",
|
|
2468
|
+
body: "Clamps value between min and max. Note: not yet standard — use Math.min(Math.max(value, min), max) for compatibility.",
|
|
2469
|
+
language: ["typescript", "javascript"]
|
|
2470
|
+
},
|
|
2471
|
+
// ── JSON ──────────────────────────────────────────────────
|
|
2472
|
+
JSON: {
|
|
2473
|
+
title: "JSON",
|
|
2474
|
+
type: "namespace JSON",
|
|
2475
|
+
body: "Provides methods for parsing and serializing JSON (JavaScript Object Notation). All methods are static.",
|
|
2476
|
+
language: ["typescript", "javascript"]
|
|
2477
|
+
},
|
|
2478
|
+
"JSON.stringify": {
|
|
2479
|
+
title: "JSON.stringify()",
|
|
2480
|
+
type: "(value: any, replacer?: any, space?: string | number) => string",
|
|
2481
|
+
body: "Converts a JavaScript value to a JSON string. Pass a number or string as the third argument to pretty-print with indentation. Throws on circular references.",
|
|
2482
|
+
language: ["typescript", "javascript"]
|
|
2483
|
+
},
|
|
2484
|
+
"JSON.parse": {
|
|
2485
|
+
title: "JSON.parse()",
|
|
2486
|
+
type: "(text: string, reviver?: (key: string, value: any) => any) => any",
|
|
2487
|
+
body: "Parses a JSON string and returns the corresponding JavaScript value. Throws SyntaxError if the string is not valid JSON.",
|
|
2488
|
+
language: ["typescript", "javascript"]
|
|
2489
|
+
},
|
|
2490
|
+
// ── Array ─────────────────────────────────────────────────
|
|
2491
|
+
Array: {
|
|
2492
|
+
title: "Array",
|
|
2493
|
+
type: "interface Array<T>",
|
|
2494
|
+
body: "Represents an ordered list of values. Provides methods for traversal, mutation, searching, and transformation.",
|
|
2495
|
+
language: ["typescript", "javascript"]
|
|
2496
|
+
},
|
|
2497
|
+
"Array.from": {
|
|
2498
|
+
title: "Array.from()",
|
|
2499
|
+
type: "<T>(arrayLike: Iterable<T> | ArrayLike<T>, mapFn?: (v: T, i: number) => T) => T[]",
|
|
2500
|
+
body: "Creates a new Array from an array-like or iterable object (e.g. NodeList, Set, Map, string). Optionally applies a mapping function.",
|
|
2501
|
+
language: ["typescript", "javascript"]
|
|
2502
|
+
},
|
|
2503
|
+
"Array.isArray": {
|
|
2504
|
+
title: "Array.isArray()",
|
|
2505
|
+
type: "(value: unknown) => value is any[]",
|
|
2506
|
+
body: "Returns true if the given value is an Array. More reliable than instanceof Array across iframe boundaries.",
|
|
2507
|
+
language: ["typescript", "javascript"]
|
|
2508
|
+
},
|
|
2509
|
+
// ── Object ────────────────────────────────────────────────
|
|
2510
|
+
Object: {
|
|
2511
|
+
title: "Object",
|
|
2512
|
+
type: "interface Object",
|
|
2513
|
+
body: "The base class of all JavaScript objects. Provides static methods for working with object properties, prototypes, and descriptors.",
|
|
2514
|
+
language: ["typescript", "javascript"]
|
|
2515
|
+
},
|
|
2516
|
+
"Object.keys": {
|
|
2517
|
+
title: "Object.keys()",
|
|
2518
|
+
type: "(obj: object) => string[]",
|
|
2519
|
+
body: "Returns an array of an object's own enumerable string-keyed property names, in insertion order.",
|
|
2520
|
+
language: ["typescript", "javascript"]
|
|
2521
|
+
},
|
|
2522
|
+
"Object.values": {
|
|
2523
|
+
title: "Object.values()",
|
|
2524
|
+
type: "(obj: object) => any[]",
|
|
2525
|
+
body: "Returns an array of an object's own enumerable string-keyed property values, in insertion order.",
|
|
2526
|
+
language: ["typescript", "javascript"]
|
|
2527
|
+
},
|
|
2528
|
+
"Object.entries": {
|
|
2529
|
+
title: "Object.entries()",
|
|
2530
|
+
type: "(obj: object) => [string, any][]",
|
|
2531
|
+
body: "Returns an array of [key, value] pairs for all own enumerable string-keyed properties of an object.",
|
|
2532
|
+
language: ["typescript", "javascript"]
|
|
2533
|
+
},
|
|
2534
|
+
"Object.assign": {
|
|
2535
|
+
title: "Object.assign()",
|
|
2536
|
+
type: "<T, U>(target: T, source: U) => T & U",
|
|
2537
|
+
body: "Copies own enumerable properties from one or more source objects into a target object. Returns the modified target. Does a shallow copy.",
|
|
2538
|
+
language: ["typescript", "javascript"]
|
|
2539
|
+
},
|
|
2540
|
+
"Object.freeze": {
|
|
2541
|
+
title: "Object.freeze()",
|
|
2542
|
+
type: "<T>(obj: T) => Readonly<T>",
|
|
2543
|
+
body: "Freezes an object — prevents adding, removing, or changing its properties. Returns the same object. Shallow — nested objects are not frozen.",
|
|
2544
|
+
language: ["typescript", "javascript"]
|
|
2545
|
+
},
|
|
2546
|
+
"Object.create": {
|
|
2547
|
+
title: "Object.create()",
|
|
2548
|
+
type: "(proto: object | null, propertiesObject?: PropertyDescriptorMap) => any",
|
|
2549
|
+
body: "Creates a new object with the specified prototype object and optional property descriptors.",
|
|
2550
|
+
language: ["typescript", "javascript"]
|
|
2551
|
+
},
|
|
2552
|
+
"Object.fromEntries": {
|
|
2553
|
+
title: "Object.fromEntries()",
|
|
2554
|
+
type: "<T>(entries: Iterable<[string, T]>) => Record<string, T>",
|
|
2555
|
+
body: "Creates an object from an array of [key, value] pairs or any iterable of key-value entries. The inverse of Object.entries().",
|
|
2556
|
+
language: ["typescript", "javascript"]
|
|
2557
|
+
},
|
|
2558
|
+
// ── Promise ───────────────────────────────────────────────
|
|
2559
|
+
Promise: {
|
|
2560
|
+
title: "Promise",
|
|
2561
|
+
type: "interface Promise<T>",
|
|
2562
|
+
body: "Represents an asynchronous operation that will eventually complete (or fail) and produce a value. Use .then(), .catch(), and .finally() to handle outcomes.",
|
|
2563
|
+
language: ["typescript", "javascript"]
|
|
2564
|
+
},
|
|
2565
|
+
"Promise.all": {
|
|
2566
|
+
title: "Promise.all()",
|
|
2567
|
+
type: "<T>(promises: Iterable<Promise<T>>) => Promise<T[]>",
|
|
2568
|
+
body: "Waits for all promises to resolve and returns an array of results. If any promise rejects, the entire result rejects immediately (fail-fast).",
|
|
2569
|
+
language: ["typescript", "javascript"]
|
|
2570
|
+
},
|
|
2571
|
+
"Promise.allSettled": {
|
|
2572
|
+
title: "Promise.allSettled()",
|
|
2573
|
+
type: "<T>(promises: Iterable<Promise<T>>) => Promise<PromiseSettledResult<T>[]>",
|
|
2574
|
+
body: 'Waits for all promises to settle (resolve or reject) and returns an array of result objects, each with a status of "fulfilled" or "rejected". Never rejects.',
|
|
2575
|
+
language: ["typescript", "javascript"]
|
|
2576
|
+
},
|
|
2577
|
+
"Promise.race": {
|
|
2578
|
+
title: "Promise.race()",
|
|
2579
|
+
type: "<T>(promises: Iterable<Promise<T>>) => Promise<T>",
|
|
2580
|
+
body: "Returns a promise that resolves or rejects as soon as one of the given promises resolves or rejects, with that value or reason.",
|
|
2581
|
+
language: ["typescript", "javascript"]
|
|
2582
|
+
},
|
|
2583
|
+
"Promise.resolve": {
|
|
2584
|
+
title: "Promise.resolve()",
|
|
2585
|
+
type: "<T>(value: T | PromiseLike<T>) => Promise<T>",
|
|
2586
|
+
body: "Returns a Promise object that is resolved with the given value. If the value is a thenable, the returned promise follows it.",
|
|
2587
|
+
language: ["typescript", "javascript"]
|
|
2588
|
+
},
|
|
2589
|
+
"Promise.reject": {
|
|
2590
|
+
title: "Promise.reject()",
|
|
2591
|
+
type: "(reason?: any) => Promise<never>",
|
|
2592
|
+
body: "Returns a Promise that is rejected with the given reason. Useful for creating pre-rejected promises in control flow.",
|
|
2593
|
+
language: ["typescript", "javascript"]
|
|
2594
|
+
},
|
|
2595
|
+
// ── Timers ────────────────────────────────────────────────
|
|
2596
|
+
setTimeout: {
|
|
2597
|
+
title: "setTimeout()",
|
|
2598
|
+
type: "(callback: () => void, delay?: number, ...args: any[]) => number",
|
|
2599
|
+
body: "Executes a function after a specified delay in milliseconds. Returns a timer ID that can be passed to clearTimeout() to cancel.",
|
|
2600
|
+
language: ["typescript", "javascript"]
|
|
2601
|
+
},
|
|
2602
|
+
clearTimeout: {
|
|
2603
|
+
title: "clearTimeout()",
|
|
2604
|
+
type: "(id: number) => void",
|
|
2605
|
+
body: "Cancels a timeout previously established by setTimeout(), preventing its callback from running.",
|
|
2606
|
+
language: ["typescript", "javascript"]
|
|
2607
|
+
},
|
|
2608
|
+
setInterval: {
|
|
2609
|
+
title: "setInterval()",
|
|
2610
|
+
type: "(callback: () => void, delay?: number, ...args: any[]) => number",
|
|
2611
|
+
body: "Repeatedly executes a function with a fixed time delay between each call. Returns a timer ID for cancellation via clearInterval().",
|
|
2612
|
+
language: ["typescript", "javascript"]
|
|
2613
|
+
},
|
|
2614
|
+
clearInterval: {
|
|
2615
|
+
title: "clearInterval()",
|
|
2616
|
+
type: "(id: number) => void",
|
|
2617
|
+
body: "Cancels a repeating timer established by setInterval().",
|
|
2618
|
+
language: ["typescript", "javascript"]
|
|
2619
|
+
},
|
|
2620
|
+
requestAnimationFrame: {
|
|
2621
|
+
title: "requestAnimationFrame()",
|
|
2622
|
+
type: "(callback: (timestamp: DOMHighResTimeStamp) => void) => number",
|
|
2623
|
+
body: "Schedules a callback to run before the next browser repaint. Ideal for animations — the browser can batch and throttle calls to 60fps or the display refresh rate.",
|
|
2624
|
+
language: ["typescript", "javascript"]
|
|
2625
|
+
},
|
|
2626
|
+
cancelAnimationFrame: {
|
|
2627
|
+
title: "cancelAnimationFrame()",
|
|
2628
|
+
type: "(id: number) => void",
|
|
2629
|
+
body: "Cancels an animation frame request previously scheduled with requestAnimationFrame().",
|
|
2630
|
+
language: ["typescript", "javascript"]
|
|
2631
|
+
},
|
|
2632
|
+
queueMicrotask: {
|
|
2633
|
+
title: "queueMicrotask()",
|
|
2634
|
+
type: "(callback: () => void) => void",
|
|
2635
|
+
body: "Queues a microtask to be executed before the next task in the event loop. Runs after the current JavaScript execution but before any setTimeout callbacks.",
|
|
2636
|
+
language: ["typescript", "javascript"]
|
|
2637
|
+
},
|
|
2638
|
+
// ── Network ───────────────────────────────────────────────
|
|
2639
|
+
fetch: {
|
|
2640
|
+
title: "fetch()",
|
|
2641
|
+
type: "(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>",
|
|
2642
|
+
body: "Fetches a resource from the network. Returns a Promise that resolves to a Response. Use .json(), .text(), or .blob() on the response to read the body.",
|
|
2643
|
+
language: ["typescript", "javascript"]
|
|
2644
|
+
},
|
|
2645
|
+
// ── Global utils ──────────────────────────────────────────
|
|
2646
|
+
parseInt: {
|
|
2647
|
+
title: "parseInt()",
|
|
2648
|
+
type: "(string: string, radix?: number) => number",
|
|
2649
|
+
body: "Parses a string and returns an integer in the specified radix (base). Always provide the radix (typically 10) to avoid unexpected behavior with leading zeros.",
|
|
2650
|
+
language: ["typescript", "javascript"]
|
|
2651
|
+
},
|
|
2652
|
+
parseFloat: {
|
|
2653
|
+
title: "parseFloat()",
|
|
2654
|
+
type: "(string: string) => number",
|
|
2655
|
+
body: "Parses a string and returns a floating-point number. Returns NaN if the string cannot be converted.",
|
|
2656
|
+
language: ["typescript", "javascript"]
|
|
2657
|
+
},
|
|
2658
|
+
isNaN: {
|
|
2659
|
+
title: "isNaN()",
|
|
2660
|
+
type: "(value: number) => boolean",
|
|
2661
|
+
body: "Returns true if the value is NaN (Not a Number). Note: coerces the argument to number first — use Number.isNaN() for strict checking without coercion.",
|
|
2662
|
+
language: ["typescript", "javascript"]
|
|
2663
|
+
},
|
|
2664
|
+
isFinite: {
|
|
2665
|
+
title: "isFinite()",
|
|
2666
|
+
type: "(value: number) => boolean",
|
|
2667
|
+
body: "Returns true if the value is a finite number. Returns false for ±Infinity and NaN. Coerces the argument to number first.",
|
|
2668
|
+
language: ["typescript", "javascript"]
|
|
2669
|
+
},
|
|
2670
|
+
encodeURIComponent: {
|
|
2671
|
+
title: "encodeURIComponent()",
|
|
2672
|
+
type: "(uriComponent: string | number | boolean) => string",
|
|
2673
|
+
body: "Encodes a URI component by replacing special characters with their UTF-8 escape sequences. Use for encoding query string values before appending to a URL.",
|
|
2674
|
+
language: ["typescript", "javascript"]
|
|
2675
|
+
},
|
|
2676
|
+
decodeURIComponent: {
|
|
2677
|
+
title: "decodeURIComponent()",
|
|
2678
|
+
type: "(encodedURIComponent: string) => string",
|
|
2679
|
+
body: "Decodes a URI component that was previously encoded with encodeURIComponent(). Throws URIError on malformed sequences.",
|
|
2680
|
+
language: ["typescript", "javascript"]
|
|
2681
|
+
},
|
|
2682
|
+
structuredClone: {
|
|
2683
|
+
title: "structuredClone()",
|
|
2684
|
+
type: "<T>(value: T, options?: StructuredSerializeOptions) => T",
|
|
2685
|
+
body: "Creates a deep clone of the given value using the structured clone algorithm. Handles cycles, Maps, Sets, Dates, and typed arrays. Does not clone functions or class instances.",
|
|
2686
|
+
language: ["typescript", "javascript"]
|
|
2687
|
+
},
|
|
2688
|
+
// ── DOM ───────────────────────────────────────────────────
|
|
2689
|
+
"document.getElementById": {
|
|
2690
|
+
title: "document.getElementById()",
|
|
2691
|
+
type: "(elementId: string) => HTMLElement | null",
|
|
2692
|
+
body: "Returns the first element in the document with the specified ID, or null if not found. IDs must be unique per document.",
|
|
2693
|
+
language: ["typescript", "javascript"]
|
|
2694
|
+
},
|
|
2695
|
+
"document.querySelector": {
|
|
2696
|
+
title: "document.querySelector()",
|
|
2697
|
+
type: "(selectors: string) => Element | null",
|
|
2698
|
+
body: "Returns the first Element matching the given CSS selector string, or null if no match. Use querySelectorAll() for all matches.",
|
|
2699
|
+
language: ["typescript", "javascript"]
|
|
2700
|
+
},
|
|
2701
|
+
"document.querySelectorAll": {
|
|
2702
|
+
title: "document.querySelectorAll()",
|
|
2703
|
+
type: "(selectors: string) => NodeListOf<Element>",
|
|
2704
|
+
body: "Returns a static NodeList of all Elements matching the given CSS selector string. Does not update as the document changes.",
|
|
2705
|
+
language: ["typescript", "javascript"]
|
|
2706
|
+
},
|
|
2707
|
+
"document.createElement": {
|
|
2708
|
+
title: "document.createElement()",
|
|
2709
|
+
type: "<K extends keyof HTMLElementTagNameMap>(tagName: K) => HTMLElementTagNameMap[K]",
|
|
2710
|
+
body: "Creates a new HTML element with the specified tag name. The element is not attached to the DOM until you call appendChild() or similar.",
|
|
2711
|
+
language: ["typescript", "javascript"]
|
|
2712
|
+
},
|
|
2713
|
+
addEventListener: {
|
|
2714
|
+
title: "addEventListener()",
|
|
2715
|
+
type: "(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void",
|
|
2716
|
+
body: "Registers an event listener on the target element. The listener is called whenever the specified event fires. Remember to call removeEventListener() to clean up.",
|
|
2717
|
+
language: ["typescript", "javascript"]
|
|
2718
|
+
},
|
|
2719
|
+
removeEventListener: {
|
|
2720
|
+
title: "removeEventListener()",
|
|
2721
|
+
type: "(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions) => void",
|
|
2722
|
+
body: "Removes an event listener previously added with addEventListener(). The listener reference must be the same function object.",
|
|
2723
|
+
language: ["typescript", "javascript"]
|
|
2724
|
+
},
|
|
2725
|
+
// ── TypeScript keywords ────────────────────────────────────
|
|
2726
|
+
const: {
|
|
2727
|
+
title: "const",
|
|
2728
|
+
type: "keyword",
|
|
2729
|
+
body: "Declares a block-scoped variable that cannot be reassigned. The binding is immutable — but for objects and arrays, their contents can still be mutated.",
|
|
2730
|
+
language: ["typescript", "javascript"]
|
|
2731
|
+
},
|
|
2732
|
+
let: {
|
|
2733
|
+
title: "let",
|
|
2734
|
+
type: "keyword",
|
|
2735
|
+
body: "Declares a block-scoped variable that can be reassigned. Prefer const for bindings that never change.",
|
|
2736
|
+
language: ["typescript", "javascript"]
|
|
2737
|
+
},
|
|
2738
|
+
var: {
|
|
2739
|
+
title: "var",
|
|
2740
|
+
type: "keyword",
|
|
2741
|
+
body: "Declares a function-scoped (or globally-scoped) variable. Hoisted to the top of its scope. Prefer const or let in modern code.",
|
|
2742
|
+
language: ["typescript", "javascript"]
|
|
2743
|
+
},
|
|
2744
|
+
function: {
|
|
2745
|
+
title: "function",
|
|
2746
|
+
type: "keyword",
|
|
2747
|
+
body: "Defines a named function declaration, or introduces a function expression. Function declarations are hoisted; expressions are not.",
|
|
2748
|
+
language: ["typescript", "javascript"]
|
|
2749
|
+
},
|
|
2750
|
+
class: {
|
|
2751
|
+
title: "class",
|
|
2752
|
+
type: "keyword",
|
|
2753
|
+
body: "Declares a class — a blueprint for creating objects with shared methods and properties. Classes support extends, implements, constructors, getters, setters, and static members.",
|
|
2754
|
+
language: ["typescript", "javascript"]
|
|
2755
|
+
},
|
|
2756
|
+
async: {
|
|
2757
|
+
title: "async",
|
|
2758
|
+
type: "keyword",
|
|
2759
|
+
body: "Marks a function as asynchronous, making it return a Promise implicitly. Enables the use of the await keyword inside the function body.",
|
|
2760
|
+
language: ["typescript", "javascript"]
|
|
2761
|
+
},
|
|
2762
|
+
await: {
|
|
2763
|
+
title: "await",
|
|
2764
|
+
type: "keyword",
|
|
2765
|
+
body: "Pauses execution of an async function until the Promise settles, then returns the resolved value. Must be used inside an async function.",
|
|
2766
|
+
language: ["typescript", "javascript"]
|
|
2767
|
+
},
|
|
2768
|
+
return: {
|
|
2769
|
+
title: "return",
|
|
2770
|
+
type: "keyword",
|
|
2771
|
+
body: "Exits the current function and optionally returns a value to the caller. In an async function, the value is wrapped in a resolved Promise.",
|
|
2772
|
+
language: ["typescript", "javascript"]
|
|
2773
|
+
},
|
|
2774
|
+
interface: {
|
|
2775
|
+
title: "interface",
|
|
2776
|
+
type: "keyword",
|
|
2777
|
+
body: "Defines a TypeScript interface — a named contract describing the shape of an object. Interfaces can be extended, merged (declaration merging), and implemented by classes.",
|
|
2778
|
+
language: ["typescript"]
|
|
2779
|
+
},
|
|
2780
|
+
type: {
|
|
2781
|
+
title: "type",
|
|
2782
|
+
type: "keyword",
|
|
2783
|
+
body: "Declares a TypeScript type alias — a name for any type expression including unions, intersections, tuples, mapped types, and conditional types.",
|
|
2784
|
+
language: ["typescript"]
|
|
2785
|
+
},
|
|
2786
|
+
extends: {
|
|
2787
|
+
title: "extends",
|
|
2788
|
+
type: "keyword",
|
|
2789
|
+
body: "Establishes inheritance (class extends Base) or constrains a generic type parameter (T extends object). Also used in conditional types (T extends U ? X : Y).",
|
|
2790
|
+
language: ["typescript", "javascript"]
|
|
2791
|
+
},
|
|
2792
|
+
implements: {
|
|
2793
|
+
title: "implements",
|
|
2794
|
+
type: "keyword",
|
|
2795
|
+
body: "Declares that a class satisfies the shape of one or more interfaces. TypeScript verifies at compile time that all required members are present.",
|
|
2796
|
+
language: ["typescript"]
|
|
2797
|
+
},
|
|
2798
|
+
export: {
|
|
2799
|
+
title: "export",
|
|
2800
|
+
type: "keyword",
|
|
2801
|
+
body: "Makes a declaration (variable, function, class, type, interface) available for import in other modules. Use export default for a single primary export.",
|
|
2802
|
+
language: ["typescript", "javascript"]
|
|
2803
|
+
},
|
|
2804
|
+
import: {
|
|
2805
|
+
title: "import",
|
|
2806
|
+
type: "keyword",
|
|
2807
|
+
body: "Imports bindings from another module. Supports named imports ({ foo, bar }), default imports (Foo), namespace imports (* as Foo), and side-effect imports.",
|
|
2808
|
+
language: ["typescript", "javascript"]
|
|
2809
|
+
},
|
|
2810
|
+
typeof: {
|
|
2811
|
+
title: "typeof",
|
|
2812
|
+
type: "keyword",
|
|
2813
|
+
body: 'Returns a string describing the type of its operand at runtime ("string", "number", "boolean", "object", "function", "undefined", "symbol", "bigint"). In TypeScript, also used as a type operator to capture the type of a value.',
|
|
2814
|
+
language: ["typescript", "javascript"]
|
|
2815
|
+
},
|
|
2816
|
+
instanceof: {
|
|
2817
|
+
title: "instanceof",
|
|
2818
|
+
type: "keyword",
|
|
2819
|
+
body: "Tests whether an object has a given constructor in its prototype chain. Returns true if the object is an instance of the constructor.",
|
|
2820
|
+
language: ["typescript", "javascript"]
|
|
2821
|
+
},
|
|
2822
|
+
new: {
|
|
2823
|
+
title: "new",
|
|
2824
|
+
type: "keyword",
|
|
2825
|
+
body: "Creates a new instance of a class or constructor function. Allocates memory, sets the prototype, calls the constructor with `this` bound to the new object, and returns it.",
|
|
2826
|
+
language: ["typescript", "javascript"]
|
|
2827
|
+
},
|
|
2828
|
+
throw: {
|
|
2829
|
+
title: "throw",
|
|
2830
|
+
type: "keyword",
|
|
2831
|
+
body: "Throws a user-defined exception, stopping execution of the current function and propagating up the call stack until caught by a try...catch block.",
|
|
2832
|
+
language: ["typescript", "javascript"]
|
|
2833
|
+
},
|
|
2834
|
+
try: {
|
|
2835
|
+
title: "try...catch...finally",
|
|
2836
|
+
type: "keyword",
|
|
2837
|
+
body: "Wraps code that might throw an exception. The catch block handles errors; the finally block always runs whether or not an error occurred.",
|
|
2838
|
+
language: ["typescript", "javascript"]
|
|
2839
|
+
},
|
|
2840
|
+
// ── TypeScript built-in types ──────────────────────────────
|
|
2841
|
+
string: {
|
|
2842
|
+
title: "string",
|
|
2843
|
+
type: "primitive type",
|
|
2844
|
+
body: 'Represents a sequence of UTF-16 code units. In TypeScript, the string type accepts any text value. Literal types like "hello" narrow to specific string values.',
|
|
2845
|
+
language: ["typescript"]
|
|
2846
|
+
},
|
|
2847
|
+
number: {
|
|
2848
|
+
title: "number",
|
|
2849
|
+
type: "primitive type",
|
|
2850
|
+
body: "Represents a double-precision 64-bit IEEE 754 floating-point value. Includes integers, decimals, NaN, and Infinity. TypeScript does not have a separate int type.",
|
|
2851
|
+
language: ["typescript"]
|
|
2852
|
+
},
|
|
2853
|
+
boolean: {
|
|
2854
|
+
title: "boolean",
|
|
2855
|
+
type: "primitive type",
|
|
2856
|
+
body: "Represents a logical true or false value. Literal types true and false narrow to specific boolean values.",
|
|
2857
|
+
language: ["typescript"]
|
|
2858
|
+
},
|
|
2859
|
+
any: {
|
|
2860
|
+
title: "any",
|
|
2861
|
+
type: "TypeScript type",
|
|
2862
|
+
body: "Disables type checking for a value — allows any operation without compile errors. Avoid using any; prefer unknown when the type is genuinely uncertain.",
|
|
2863
|
+
language: ["typescript"]
|
|
2864
|
+
},
|
|
2865
|
+
unknown: {
|
|
2866
|
+
title: "unknown",
|
|
2867
|
+
type: "TypeScript type",
|
|
2868
|
+
body: "The type-safe alternative to any. You cannot perform operations on an unknown value without first narrowing its type with typeof, instanceof, or a type guard.",
|
|
2869
|
+
language: ["typescript"]
|
|
2870
|
+
},
|
|
2871
|
+
void: {
|
|
2872
|
+
title: "void",
|
|
2873
|
+
type: "TypeScript type",
|
|
2874
|
+
body: "Represents the absence of a value, typically used as the return type of functions that do not return anything meaningful.",
|
|
2875
|
+
language: ["typescript"]
|
|
2876
|
+
},
|
|
2877
|
+
never: {
|
|
2878
|
+
title: "never",
|
|
2879
|
+
type: "TypeScript type",
|
|
2880
|
+
body: "A type with no values — used for functions that never return (throw or infinite loop) and for exhaustive checks in union type switches.",
|
|
2881
|
+
language: ["typescript"]
|
|
2882
|
+
},
|
|
2883
|
+
Record: {
|
|
2884
|
+
title: "Record<K, V>",
|
|
2885
|
+
type: "type Record<K extends keyof any, T> = { [P in K]: T }",
|
|
2886
|
+
body: "A utility type that constructs an object type whose keys are of type K and values are of type V. Useful for dictionaries and lookup tables.",
|
|
2887
|
+
language: ["typescript"]
|
|
2888
|
+
},
|
|
2889
|
+
Partial: {
|
|
2890
|
+
title: "Partial<T>",
|
|
2891
|
+
type: "type Partial<T> = { [P in keyof T]?: T[P] }",
|
|
2892
|
+
body: "A utility type that makes all properties of T optional. Useful for update payloads, patches, and configuration objects with defaults.",
|
|
2893
|
+
language: ["typescript"]
|
|
2894
|
+
},
|
|
2895
|
+
Required: {
|
|
2896
|
+
title: "Required<T>",
|
|
2897
|
+
type: "type Required<T> = { [P in keyof T]-?: T[P] }",
|
|
2898
|
+
body: "A utility type that makes all properties of T required (removes optionality). The inverse of Partial<T>.",
|
|
2899
|
+
language: ["typescript"]
|
|
2900
|
+
},
|
|
2901
|
+
Readonly: {
|
|
2902
|
+
title: "Readonly<T>",
|
|
2903
|
+
type: "type Readonly<T> = { readonly [P in keyof T]: T[P] }",
|
|
2904
|
+
body: "A utility type that makes all properties of T readonly. Prevents property reassignment at the type level.",
|
|
2905
|
+
language: ["typescript"]
|
|
2906
|
+
},
|
|
2907
|
+
ReturnType: {
|
|
2908
|
+
title: "ReturnType<T>",
|
|
2909
|
+
type: "type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any",
|
|
2910
|
+
body: "A utility type that extracts the return type of a function type T.",
|
|
2911
|
+
language: ["typescript"]
|
|
2912
|
+
},
|
|
2913
|
+
Omit: {
|
|
2914
|
+
title: "Omit<T, K>",
|
|
2915
|
+
type: "type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>",
|
|
2916
|
+
body: "A utility type that constructs a type by picking all properties from T then removing those in K.",
|
|
2917
|
+
language: ["typescript"]
|
|
2918
|
+
},
|
|
2919
|
+
Pick: {
|
|
2920
|
+
title: "Pick<T, K>",
|
|
2921
|
+
type: "type Pick<T, K extends keyof T> = { [P in K]: T[P] }",
|
|
2922
|
+
body: "A utility type that constructs a type by picking the set of properties K from T.",
|
|
2923
|
+
language: ["typescript"]
|
|
2924
|
+
},
|
|
2925
|
+
NonNullable: {
|
|
2926
|
+
title: "NonNullable<T>",
|
|
2927
|
+
type: "type NonNullable<T> = T extends null | undefined ? never : T",
|
|
2928
|
+
body: "A utility type that removes null and undefined from the type T.",
|
|
2929
|
+
language: ["typescript"]
|
|
2930
|
+
},
|
|
2931
|
+
keyof: {
|
|
2932
|
+
title: "keyof",
|
|
2933
|
+
type: "TypeScript type operator",
|
|
2934
|
+
body: 'Produces a union type of all property keys of an object type. keyof { a: string; b: number } is "a" | "b".',
|
|
2935
|
+
language: ["typescript"]
|
|
2936
|
+
}
|
|
2937
|
+
};
|
|
2938
|
+
function Ht(s, e) {
|
|
2939
|
+
const t = Dt[s];
|
|
2940
|
+
return !t || t.language && !(Array.isArray(t.language) ? t.language : [t.language]).includes(e) ? null : t;
|
|
2941
|
+
}
|
|
2942
|
+
function Rt(s) {
|
|
2943
|
+
var q, K, M, B;
|
|
2944
|
+
const { vr: e, visIdx: t, curVisRow: i, wm: n, foldedLines: r, isFoldable: o, opts: l } = s, { docLine: a, segIdx: c, text: d } = e, h = t === i, p = a === ((q = n.visualRows[i]) == null ? void 0 : q.docLine), f = c > 0, _ = ((K = n.segments[a]) == null ? void 0 : K.slice(0, c).reduce((k, x) => k + x.length, 0)) ?? 0, b = s.docSel ? fe(s.docSel, a, ((M = (n.segments[a] ?? [""])[c]) == null ? void 0 : M.length) ?? 0) : null;
|
|
2945
|
+
let v = null;
|
|
2946
|
+
if (b) {
|
|
2947
|
+
const k = ((B = (n.segments[a] ?? [""])[c]) == null ? void 0 : B.length) ?? 0, x = fe(s.docSel, a, k + _);
|
|
2948
|
+
if (x) {
|
|
2949
|
+
const E = x.start - _, H = x.end - _;
|
|
2950
|
+
H > 0 && E < d.length && (v = { start: Math.max(0, E), end: Math.min(d.length, H) });
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
const u = s.findMatches.filter((k) => k.row === a).map((k) => {
|
|
2954
|
+
var W, j;
|
|
2955
|
+
const x = k.col - _, E = k.col + k.len - _;
|
|
2956
|
+
if (E <= 0 || x >= d.length) return null;
|
|
2957
|
+
const H = s.findIdx >= 0 && ((W = s.findMatches[s.findIdx]) == null ? void 0 : W.row) === k.row && ((j = s.findMatches[s.findIdx]) == null ? void 0 : j.col) === k.col;
|
|
2958
|
+
return { start: Math.max(0, x), end: Math.min(d.length, E), isCur: H };
|
|
2959
|
+
}).filter(Boolean), T = s.wordHighlights.filter((k) => k.row === a).map((k) => {
|
|
2960
|
+
const x = k.col - _, E = k.col + k.len - _;
|
|
2961
|
+
return E <= 0 || x >= d.length ? null : { start: Math.max(0, x), end: Math.min(d.length, E) };
|
|
2962
|
+
}).filter(Boolean), m = [];
|
|
2963
|
+
if (s.bracketMatch) {
|
|
2964
|
+
for (const k of [s.bracketMatch.open, s.bracketMatch.close])
|
|
2965
|
+
if (k.row === a) {
|
|
2966
|
+
const x = k.col - _;
|
|
2967
|
+
x >= 0 && x < d.length && m.push({ start: x, end: x + 1 });
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
const w = [], y = [];
|
|
2971
|
+
for (const k of s.extraCursors) {
|
|
2972
|
+
const x = F(n, k.row, k.col);
|
|
2973
|
+
if (x.visRow === t && w.push(x.colInSeg), k.sel) {
|
|
2974
|
+
const E = jt(k.sel);
|
|
2975
|
+
if (a >= E.ar && a <= E.fr) {
|
|
2976
|
+
const H = a === E.ar ? E.ac - _ : -_, W = a === E.fr ? E.fc - _ : d.length + 999;
|
|
2977
|
+
W > 0 && H < d.length && y.push({ start: Math.max(0, H), end: Math.min(d.length, W) });
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
const D = Bt(d, l.renderWhitespace), R = h || v || u.length || w.length || T.length || m.length || y.length || s.snippetStopCols.length > 0;
|
|
2982
|
+
let C;
|
|
2983
|
+
if (R)
|
|
2984
|
+
C = $t(
|
|
2985
|
+
D,
|
|
2986
|
+
h ? s.curColInSeg : -1,
|
|
2987
|
+
v,
|
|
2988
|
+
u,
|
|
2989
|
+
w,
|
|
2990
|
+
s.snippetStopCols,
|
|
2991
|
+
T,
|
|
2992
|
+
m,
|
|
2993
|
+
y,
|
|
2994
|
+
l.tokeniserOpts
|
|
2995
|
+
);
|
|
2996
|
+
else {
|
|
2997
|
+
const k = `${a}:${c}:${l.renderWhitespace}`;
|
|
2998
|
+
let x = s.tokenCache.get(k, D);
|
|
2999
|
+
x || (x = ae(D, l.tokeniserOpts), s.tokenCache.set(k, D, x)), C = Pt(D, x) || "​";
|
|
3000
|
+
}
|
|
3001
|
+
let U = "";
|
|
3002
|
+
if (c === 0 && l.showIndentGuides) {
|
|
3003
|
+
const k = (d.match(/^(\s*)/) ?? ["", ""])[1].length, x = Math.floor(k / l.tabSize);
|
|
3004
|
+
for (let E = 1; E < x; E++) {
|
|
3005
|
+
const H = l.codePaddingLeft + E * l.tabSize * l.charWidth;
|
|
3006
|
+
U += `<span class="sl-ig" style="left:${H}px"></span>`;
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
let P = "";
|
|
3010
|
+
if (c === 0 && o) {
|
|
3011
|
+
const k = r.has(a);
|
|
3012
|
+
P = `<span class="sl-fold-btn" data-row="${a}">${k ? "▸" : "▾"}</span>`;
|
|
3013
|
+
}
|
|
3014
|
+
const N = r.has(a) && c === 0, O = c === 0 ? String(a + 1) : "";
|
|
3015
|
+
return `<div class="${[
|
|
3016
|
+
"sl-er",
|
|
3017
|
+
l.highlightActiveLine && p ? "sl-cur-row" : "",
|
|
3018
|
+
f ? "sl-wrap-cont" : "",
|
|
3019
|
+
N ? "sl-folded" : ""
|
|
3020
|
+
].filter(Boolean).join(" ")}" style="height:${l.lineHeight}px" data-v="${t}" data-doc="${a}"><div class="sl-eg" style="position:relative">${P}<span class="sl-egn">${O}</span></div><div class="sl-el"><span class="sl-cl">${U}${C}</span></div></div>`;
|
|
3021
|
+
}
|
|
3022
|
+
function Bt(s, e) {
|
|
3023
|
+
if (e === "none") return s;
|
|
3024
|
+
if (e === "all")
|
|
3025
|
+
return s.replace(/ /g, "·").replace(/\t/g, "→");
|
|
3026
|
+
const t = (s.match(/^ +/) ?? [""])[0].length, i = (s.match(/ +$/) ?? [""])[0].length;
|
|
3027
|
+
let n = s;
|
|
3028
|
+
return t && (n = "·".repeat(t) + n.slice(t)), i && (n = n.slice(0, n.length - i) + "·".repeat(i)), n.replace(/\t/g, "→");
|
|
3029
|
+
}
|
|
3030
|
+
function jt(s) {
|
|
3031
|
+
return s.ar < s.fr || s.ar === s.fr && s.ac <= s.fc ? s : { ar: s.fr, ac: s.fc, fr: s.ar, fc: s.ac };
|
|
3032
|
+
}
|
|
3033
|
+
function Pt(s, e) {
|
|
3034
|
+
if (!s) return "";
|
|
3035
|
+
const t = Le(s, e);
|
|
3036
|
+
let i = "", n = 0, r = t[0];
|
|
3037
|
+
const o = (l) => {
|
|
3038
|
+
if (l <= n) return;
|
|
3039
|
+
const a = V(s.slice(n, l));
|
|
3040
|
+
i += r ? `<span class="${r}">${a}</span>` : a;
|
|
3041
|
+
};
|
|
3042
|
+
for (let l = 1; l <= s.length; l++) {
|
|
3043
|
+
const a = l < s.length ? t[l] : null;
|
|
3044
|
+
a !== r && (o(l), n = l, r = a ?? "");
|
|
3045
|
+
}
|
|
3046
|
+
return i;
|
|
3047
|
+
}
|
|
3048
|
+
function $t(s, e, t, i, n, r, o, l, a, c) {
|
|
3049
|
+
if (s.length === 0) {
|
|
3050
|
+
let u = e >= 0 ? '<span class="sl-cur"></span>' : "";
|
|
3051
|
+
for (const T of n) u += '<span class="sl-cur-extra"></span>';
|
|
3052
|
+
for (const T of r) u += '<span class="sl-snip-stop"></span>';
|
|
3053
|
+
return u || "​";
|
|
3054
|
+
}
|
|
3055
|
+
const d = ae(s, c), h = Le(s, d);
|
|
3056
|
+
let p = "", f = 0, _ = "", b = "";
|
|
3057
|
+
const v = (u) => {
|
|
3058
|
+
if (u <= f) return;
|
|
3059
|
+
const T = V(s.slice(f, u)), m = [_, b].filter(Boolean).join(" ");
|
|
3060
|
+
p += m ? `<span class="${m}">${T}</span>` : T;
|
|
3061
|
+
};
|
|
3062
|
+
for (let u = 0; u <= s.length; u++) {
|
|
3063
|
+
e === u && (v(u), f = u, p += '<span class="sl-cur"></span>');
|
|
3064
|
+
for (const C of n)
|
|
3065
|
+
C === u && (v(u), f = u, p += '<span class="sl-cur-extra"></span>');
|
|
3066
|
+
for (const C of r)
|
|
3067
|
+
C === u && (v(u), f = u, p += '<span class="sl-snip-stop"></span>');
|
|
3068
|
+
if (u === s.length) {
|
|
3069
|
+
v(u);
|
|
3070
|
+
break;
|
|
3071
|
+
}
|
|
3072
|
+
const T = h[u], m = i.find((C) => u >= C.start && u < C.end), w = t && u >= t.start && u < t.end || a.some((C) => u >= C.start && u < C.end), y = !w && !m && o.some((C) => u >= C.start && u < C.end), D = !w && !m && l.some((C) => u >= C.start && u < C.end);
|
|
3073
|
+
let R = "";
|
|
3074
|
+
w ? R = "sl-sh" : m ? R = "sl-fh" + (m.isCur ? " sl-fh-cur" : "") : D ? R = "sl-bm" : y && (R = "sl-wh"), (R !== _ || T !== b) && (v(u), f = u, _ = R, b = T);
|
|
3075
|
+
}
|
|
3076
|
+
return p || "​";
|
|
3077
|
+
}
|
|
3078
|
+
function ie(s, e, t, i, n) {
|
|
3079
|
+
const r = Math.max(0, s * n - t), o = Math.max(0, s * 2 - i), a = (r > 0 ? e / r : 0) * o, c = Math.max(20, t / n * 2), d = e / n * 2 - a;
|
|
3080
|
+
return { mmScroll: a, sliderTop: d, sliderHeight: c };
|
|
3081
|
+
}
|
|
3082
|
+
function Wt(s, e, t, i, n) {
|
|
3083
|
+
const r = Math.max(0, e * n - t), o = Math.max(0, e * 2 - i);
|
|
3084
|
+
if (r <= 0) return 0;
|
|
3085
|
+
const l = 2 / n - o / r;
|
|
3086
|
+
if (Math.abs(l) < 1e-9) {
|
|
3087
|
+
const a = Math.max(20, t / n * 2);
|
|
3088
|
+
return Math.max(0, Math.min(r, s / Math.max(1, i - a) * r));
|
|
3089
|
+
}
|
|
3090
|
+
return Math.max(0, Math.min(r, s / l));
|
|
3091
|
+
}
|
|
3092
|
+
function Nt(s, e, t, i, n, r) {
|
|
3093
|
+
const o = Math.max(0, e * r - i), l = Math.max(0, e * 2 - n);
|
|
3094
|
+
if (o <= 0) return 0;
|
|
3095
|
+
const a = t / o * l, c = (s + a) / 2;
|
|
3096
|
+
return Math.max(0, Math.min(o, c * r - i / 2));
|
|
3097
|
+
}
|
|
3098
|
+
function Se(s) {
|
|
3099
|
+
const e = (t) => {
|
|
3100
|
+
const i = s(t);
|
|
3101
|
+
return i.startsWith("#") && i.length === 7 ? be(i, 0.85) : i;
|
|
3102
|
+
};
|
|
3103
|
+
return {
|
|
3104
|
+
kw: e("--tok-kw"),
|
|
3105
|
+
fn: e("--tok-fn"),
|
|
3106
|
+
cls: e("--tok-cls"),
|
|
3107
|
+
typ: e("--tok-typ"),
|
|
3108
|
+
str: e("--tok-str"),
|
|
3109
|
+
num: e("--tok-num"),
|
|
3110
|
+
cmt: e("--tok-cmt"),
|
|
3111
|
+
dec: e("--tok-dec"),
|
|
3112
|
+
op: e("--tok-op"),
|
|
3113
|
+
txt: (() => {
|
|
3114
|
+
const t = s("--text2");
|
|
3115
|
+
return t.startsWith("#") && t.length === 7 ? be(t, 0.28) : "rgba(150,148,140,0.28)";
|
|
3116
|
+
})()
|
|
3117
|
+
};
|
|
3118
|
+
}
|
|
3119
|
+
function Ot(s) {
|
|
3120
|
+
var q, K;
|
|
3121
|
+
const {
|
|
3122
|
+
canvas: e,
|
|
3123
|
+
doc: t,
|
|
3124
|
+
firstLine: i,
|
|
3125
|
+
lastLine: n,
|
|
3126
|
+
subPx: r,
|
|
3127
|
+
wrapperWidth: o,
|
|
3128
|
+
canvasHeight: l,
|
|
3129
|
+
cursorRow: a,
|
|
3130
|
+
sel: c,
|
|
3131
|
+
findMatches: d,
|
|
3132
|
+
findIdx: h,
|
|
3133
|
+
sliderTop: p,
|
|
3134
|
+
sliderHeight: f,
|
|
3135
|
+
colors: _,
|
|
3136
|
+
getCssVar: b,
|
|
3137
|
+
dpr: v
|
|
3138
|
+
} = s, u = e.getContext("2d");
|
|
3139
|
+
if (!u) return;
|
|
3140
|
+
u.setTransform(v, 0, 0, v, 0, 0);
|
|
3141
|
+
const T = b("--mm-bg") || "#0d0d0f", m = b("--mm-dim") || "rgba(0,0,0,.30)", w = b("--mm-edge") || "rgba(255,255,255,.18)", y = b("--mm-slider") || "rgba(255,255,255,.07)", D = b("--sel-bg") || "rgba(110,159,255,.22)", R = b("--cur-line-bg") || "rgba(255,255,255,.05)", C = b("--find-border") || "rgba(234,180,86,.50)", U = b("--find-cur-bg") || "rgba(234,180,86,.80)", P = (M) => (M - i) * 2;
|
|
3142
|
+
if (u.fillStyle = T, u.fillRect(0, 0, o, l), a >= i && a < n && (u.fillStyle = R, u.fillRect(0, P(a), o, 2)), c) {
|
|
3143
|
+
const M = Math.max(i, c.ar), B = Math.min(n - 1, c.fr);
|
|
3144
|
+
B >= M && (u.fillStyle = D, u.fillRect(0, P(M), o, (B - M + 1) * 2));
|
|
3145
|
+
}
|
|
3146
|
+
for (const M of d) {
|
|
3147
|
+
if (M.row < i || M.row >= n) continue;
|
|
3148
|
+
const B = h >= 0 && ((q = d[h]) == null ? void 0 : q.row) === M.row && ((K = d[h]) == null ? void 0 : K.col) === M.col;
|
|
3149
|
+
u.fillStyle = B ? U : C, u.fillRect(
|
|
3150
|
+
3 + M.col * 1.1,
|
|
3151
|
+
P(M.row),
|
|
3152
|
+
Math.max(3, M.len * 1.1),
|
|
3153
|
+
2
|
|
3154
|
+
);
|
|
3155
|
+
}
|
|
3156
|
+
const N = Math.floor((o - 3) / 1.1);
|
|
3157
|
+
for (let M = i; M < n; M++) {
|
|
3158
|
+
const B = t[M] ?? "";
|
|
3159
|
+
if (!B.trim()) continue;
|
|
3160
|
+
const k = P(M), x = 1.5, E = ae(B);
|
|
3161
|
+
let H = 0;
|
|
3162
|
+
for (const j of E) {
|
|
3163
|
+
if (j.start >= N) break;
|
|
3164
|
+
j.start > H && (u.fillStyle = _.txt, u.fillRect(3 + H * 1.1, k, (Math.min(j.start, N) - H) * 1.1, x));
|
|
3165
|
+
const Ae = _[j.cls] ?? _.txt, de = Math.min(j.end, N) - j.start;
|
|
3166
|
+
de > 0 && (u.fillStyle = Ae, u.fillRect(3 + j.start * 1.1, k, de * 1.1, x)), H = Math.max(H, Math.min(j.end, N));
|
|
3167
|
+
}
|
|
3168
|
+
const W = Math.min(B.length, N);
|
|
3169
|
+
H < W && (u.fillStyle = _.txt, u.fillRect(3 + H * 1.1, k, (W - H) * 1.1, x));
|
|
3170
|
+
}
|
|
3171
|
+
const O = p + r, z = O + f;
|
|
3172
|
+
u.fillStyle = m, O > 0 && u.fillRect(0, 0, o, O), z < l && u.fillRect(0, z, o, l - z), u.fillStyle = y, u.fillRect(0, O, o, f), u.fillStyle = w, u.fillRect(0, Math.max(0, O), o, 1), u.fillRect(0, Math.max(0, z - 1), o, 1);
|
|
3173
|
+
}
|
|
3174
|
+
const Ft = {
|
|
3175
|
+
value: "",
|
|
3176
|
+
language: "typescript",
|
|
3177
|
+
theme: "",
|
|
3178
|
+
showGutter: !0,
|
|
3179
|
+
showMinimap: !0,
|
|
3180
|
+
showStatusBar: !0,
|
|
3181
|
+
wordWrap: !1,
|
|
3182
|
+
wrapColumn: 80,
|
|
3183
|
+
fontFamily: "'JetBrains Mono', monospace",
|
|
3184
|
+
fontSize: 13,
|
|
3185
|
+
lineHeight: 22,
|
|
3186
|
+
tabSize: 2,
|
|
3187
|
+
insertSpaces: !0,
|
|
3188
|
+
maxUndoHistory: 300,
|
|
3189
|
+
showIndentGuides: !0,
|
|
3190
|
+
bracketMatching: !0,
|
|
3191
|
+
codeFolding: !0,
|
|
3192
|
+
emmet: !0,
|
|
3193
|
+
snippetExpansion: !0,
|
|
3194
|
+
autocomplete: !0,
|
|
3195
|
+
multiCursor: !0,
|
|
3196
|
+
find: !0,
|
|
3197
|
+
findReplace: !0,
|
|
3198
|
+
wordSelection: !0,
|
|
3199
|
+
wordHighlight: !0,
|
|
3200
|
+
highlightActiveLine: !0,
|
|
3201
|
+
autocompletePrefixLength: 2,
|
|
3202
|
+
readOnly: !1,
|
|
3203
|
+
extraKeywords: [],
|
|
3204
|
+
extraTypes: [],
|
|
3205
|
+
completions: [],
|
|
3206
|
+
replaceBuiltins: !1,
|
|
3207
|
+
maxCompletions: 14,
|
|
3208
|
+
autoClosePairs: { "(": ")", "[": "]", "{": "}", '"': '"', "'": "'", "`": "`" },
|
|
3209
|
+
lineCommentToken: "",
|
|
3210
|
+
wordSeparators: "",
|
|
3211
|
+
undoBatchMs: 700,
|
|
3212
|
+
gutterWidth: 60,
|
|
3213
|
+
minimapWidth: 120,
|
|
3214
|
+
cursorBlinkRate: 1050,
|
|
3215
|
+
cursorStyle: "line",
|
|
3216
|
+
renderWhitespace: "none",
|
|
3217
|
+
tokenColors: {},
|
|
3218
|
+
hover: !0,
|
|
3219
|
+
placeholder: "",
|
|
3220
|
+
goToLine: !1
|
|
3221
|
+
};
|
|
3222
|
+
class Ut {
|
|
3223
|
+
// ── Constructor ───────────────────────────────────────────
|
|
3224
|
+
constructor(e, t = {}) {
|
|
3225
|
+
// ── DOM ───────────────────────────────────────────────────
|
|
3226
|
+
g(this, "_host");
|
|
3227
|
+
g(this, "_shadow");
|
|
3228
|
+
g(this, "_editorEl");
|
|
3229
|
+
g(this, "_spacerEl");
|
|
3230
|
+
g(this, "_vpEl");
|
|
3231
|
+
g(this, "_inputEl");
|
|
3232
|
+
g(this, "_minimapWrap");
|
|
3233
|
+
g(this, "_mmCanvas");
|
|
3234
|
+
g(this, "_mmSlider");
|
|
3235
|
+
g(this, "_statusBar");
|
|
3236
|
+
g(this, "_findBar");
|
|
3237
|
+
g(this, "_findInput");
|
|
3238
|
+
g(this, "_replaceInput");
|
|
3239
|
+
g(this, "_findCount");
|
|
3240
|
+
g(this, "_replaceRow");
|
|
3241
|
+
g(this, "_acPopup");
|
|
3242
|
+
g(this, "_emmetTip");
|
|
3243
|
+
g(this, "_snippetTip");
|
|
3244
|
+
g(this, "_hoverTip");
|
|
3245
|
+
g(this, "_themeOverlay");
|
|
3246
|
+
g(this, "_themePanel");
|
|
3247
|
+
g(this, "_placeholderEl");
|
|
3248
|
+
g(this, "_goToLineBar");
|
|
3249
|
+
g(this, "_goToLineInput");
|
|
3250
|
+
g(this, "_goToLineHint");
|
|
3251
|
+
// ── State ─────────────────────────────────────────────────
|
|
3252
|
+
g(this, "_config");
|
|
3253
|
+
g(this, "_tab", ue(1, [""]));
|
|
3254
|
+
g(this, "_wm", { segments: [[""]], visualRows: [{ docLine: 0, segIdx: 0, text: "" }], docToVisArr: [0] });
|
|
3255
|
+
g(this, "_foldedLines", /* @__PURE__ */ new Map());
|
|
3256
|
+
g(this, "_tokenCache", new qe());
|
|
3257
|
+
g(this, "_themeManager");
|
|
3258
|
+
// Find
|
|
3259
|
+
g(this, "_findMatches", []);
|
|
3260
|
+
g(this, "_findIdx", -1);
|
|
3261
|
+
g(this, "_findCaseSensitive", !1);
|
|
3262
|
+
g(this, "_findRegex", !1);
|
|
3263
|
+
// Highlights
|
|
3264
|
+
g(this, "_wordHighlights", []);
|
|
3265
|
+
g(this, "_bracketMatch", null);
|
|
3266
|
+
// Autocomplete
|
|
3267
|
+
g(this, "_acItems", []);
|
|
3268
|
+
g(this, "_acSel", 0);
|
|
3269
|
+
g(this, "_acPrefix", "");
|
|
3270
|
+
g(this, "_acStartCol", 0);
|
|
3271
|
+
g(this, "_emmetAcStartCol", 0);
|
|
3272
|
+
// start col of the emmet abbreviation (may differ from _acStartCol)
|
|
3273
|
+
// Multi-cursor
|
|
3274
|
+
g(this, "_mc", mt());
|
|
3275
|
+
g(this, "_extraCursors", []);
|
|
3276
|
+
// Mouse drag
|
|
3277
|
+
g(this, "_isDragging", !1);
|
|
3278
|
+
g(this, "_dragAnchor", null);
|
|
3279
|
+
// Hover
|
|
3280
|
+
g(this, "_hoverTimer", null);
|
|
3281
|
+
g(this, "_hoverPinned", !1);
|
|
3282
|
+
// Minimap drag
|
|
3283
|
+
g(this, "_mmDragMode", "none");
|
|
3284
|
+
g(this, "_mmDragStartY", 0);
|
|
3285
|
+
g(this, "_mmDragStartScroll", 0);
|
|
3286
|
+
g(this, "_mmSliderOffset", 0);
|
|
3287
|
+
g(this, "_mmColors");
|
|
3288
|
+
// Undo batching
|
|
3289
|
+
g(this, "_lastInputTime", 0);
|
|
3290
|
+
// Dynamic styles
|
|
3291
|
+
g(this, "_dynamicStyleEl");
|
|
3292
|
+
// Emmet
|
|
3293
|
+
g(this, "_emmetExpanded", null);
|
|
3294
|
+
// Snippets
|
|
3295
|
+
g(this, "_snippetExpanded", null);
|
|
3296
|
+
/** Active snippet tab-stop session. Cleared on click, Escape, or structural edit. */
|
|
3297
|
+
g(this, "_snippetSession", null);
|
|
3298
|
+
// ── Lifecycle / performance ───────────────────────────────
|
|
3299
|
+
/** Pending debounce timer ID for autocomplete re-computation. */
|
|
3300
|
+
g(this, "_acDebounceTimer", null);
|
|
3301
|
+
/** Pending requestAnimationFrame ID for coalesced renders. */
|
|
3302
|
+
g(this, "_rafId", null);
|
|
3303
|
+
// ── Bound window listener refs ────────────────────────────
|
|
3304
|
+
// Stored as named references so they can be removed precisely in destroy().
|
|
3305
|
+
g(this, "_onWinMouseUp");
|
|
3306
|
+
g(this, "_onWinResize");
|
|
3307
|
+
g(this, "_onEditorScroll");
|
|
3308
|
+
g(this, "_onWinMmMouseMove");
|
|
3309
|
+
g(this, "_onWinMmMouseUp");
|
|
3310
|
+
// ── ResizeObserver — tracks container size changes ────────
|
|
3311
|
+
g(this, "_ro", null);
|
|
3312
|
+
g(this, "_onFoldBtnClick", (e) => {
|
|
3313
|
+
const t = e.target.closest(".sl-fold-btn");
|
|
3314
|
+
if (!t) return;
|
|
3315
|
+
e.preventDefault(), e.stopPropagation();
|
|
3316
|
+
const i = parseInt(t.dataset.row ?? "0", 10);
|
|
3317
|
+
this._foldedLines = dt(this._foldedLines, this._tab.doc, i), this._tokenCache.clear(), this._rebuildWrapMap(), this._render();
|
|
3318
|
+
});
|
|
3319
|
+
this._config = { ...Ft, ...ye(t) }, this._onWinMouseUp = () => {
|
|
3320
|
+
this._isDragging = !1, this._dragAnchor = null;
|
|
3321
|
+
}, this._onEditorScroll = Z(() => {
|
|
3322
|
+
this._hideHover(), this._scheduleRender(), this._updateMinimap();
|
|
3323
|
+
}, 16), this._onWinResize = Z(() => {
|
|
3324
|
+
this._config.wordWrap && this._rebuildWrapMap(), this._scheduleRender();
|
|
3325
|
+
}, 100), this._onWinMmMouseMove = (a) => {
|
|
3326
|
+
if (this._mmDragMode === "none") return;
|
|
3327
|
+
const c = this._minimapWrap.clientHeight;
|
|
3328
|
+
if (this._mmDragMode === "slider") {
|
|
3329
|
+
const d = a.clientY - this._minimapWrap.getBoundingClientRect().top;
|
|
3330
|
+
this._editorEl.scrollTop = Wt(
|
|
3331
|
+
d - this._mmSliderOffset,
|
|
3332
|
+
this._tab.doc.length,
|
|
3333
|
+
this._editorEl.clientHeight,
|
|
3334
|
+
c,
|
|
3335
|
+
this._config.lineHeight
|
|
3336
|
+
);
|
|
3337
|
+
} else {
|
|
3338
|
+
const d = a.clientY - this._mmDragStartY, h = Math.max(0, this._tab.doc.length * this._config.lineHeight - this._editorEl.clientHeight);
|
|
3339
|
+
this._editorEl.scrollTop = Math.max(0, Math.min(h, this._mmDragStartScroll + d / 2 * this._config.lineHeight));
|
|
3340
|
+
}
|
|
3341
|
+
this._render();
|
|
3342
|
+
}, this._onWinMmMouseUp = () => {
|
|
3343
|
+
this._mmDragMode !== "none" && (this._mmDragMode = "none", this._minimapWrap.style.cursor = "pointer");
|
|
3344
|
+
}, this._host = e, this._host.classList.add("sl-host"), this._shadow = this._host.attachShadow({ mode: "open" });
|
|
3345
|
+
const i = I("style");
|
|
3346
|
+
i.textContent = rt, this._shadow.appendChild(i), this._dynamicStyleEl = I("style"), this._shadow.appendChild(this._dynamicStyleEl), this._themeManager = new nt(this._host);
|
|
3347
|
+
const n = typeof this._config.theme == "string" ? this._config.theme : this._config.theme;
|
|
3348
|
+
this._themeManager.apply(n);
|
|
3349
|
+
const r = I("div", "sl-layout"), o = I("div", "sl-ed-pane");
|
|
3350
|
+
this._inputEl = I("textarea", "sl-input"), this._inputEl.setAttribute("autocomplete", "off"), this._inputEl.setAttribute("autocorrect", "off"), this._inputEl.setAttribute("autocapitalize", "off"), this._inputEl.setAttribute("spellcheck", "false"), this._inputEl.setAttribute("role", "textbox"), this._inputEl.setAttribute("aria-multiline", "true"), this._inputEl.setAttribute("aria-label", "Code editor"), this._inputEl.setAttribute("aria-readonly", String(!!this._config.readOnly)), this._inputEl.setAttribute("aria-haspopup", "listbox"), this._editorEl = I("div", "sl-editor"), this._spacerEl = I("div", "sl-spacer"), this._vpEl = I("div", "sl-vp"), this._editorEl.appendChild(this._spacerEl), this._editorEl.appendChild(this._vpEl), this._findBar = this._buildFindBar(), this._findInput = this._findBar.querySelector(".sl-find-input"), this._replaceInput = this._findBar.querySelector(".sl-find-replace-input"), this._findCount = this._findBar.querySelector(".sl-find-count"), this._replaceRow = this._findBar.querySelector(".sl-replace-row"), this._goToLineBar = this._buildGoToLineBar(), this._goToLineInput = this._goToLineBar.querySelector(".sl-gtl-input"), this._goToLineHint = this._goToLineBar.querySelector(".sl-gtl-hint"), this._placeholderEl = I("div", "sl-placeholder"), this._placeholderEl.textContent = this._config.placeholder, this._placeholderEl.style.display = "none", o.appendChild(this._inputEl), o.appendChild(this._findBar), o.appendChild(this._goToLineBar), o.appendChild(this._placeholderEl), o.appendChild(this._editorEl), this._minimapWrap = I("div", "sl-minimap"), this._minimapWrap.style.width = `${this._config.minimapWidth}px`, this._mmCanvas = I("canvas", ""), this._mmSlider = I("div", "sl-mm-slider"), this._minimapWrap.appendChild(this._mmCanvas), this._minimapWrap.appendChild(this._mmSlider), r.appendChild(o), this._config.showMinimap && r.appendChild(this._minimapWrap), this._statusBar = this._buildStatusBar(), this._acPopup = I("div", "sl-ac-popup"), this._acPopup.setAttribute("role", "listbox"), this._acPopup.setAttribute("aria-label", "Code suggestions"), this._acPopup.style.display = "none", this._emmetTip = I("div", "sl-emmet-tip"), this._emmetTip.style.display = "none", this._snippetTip = I("div", "sl-emmet-tip"), this._snippetTip.style.display = "none", this._hoverTip = I("div", "sl-hover-tip"), this._hoverTip.style.display = "none", this._hoverTip.addEventListener("mouseenter", () => {
|
|
3351
|
+
this._hoverPinned = !0;
|
|
3352
|
+
}), this._hoverTip.addEventListener("mouseleave", () => {
|
|
3353
|
+
this._hoverPinned = !1, this._hideHover();
|
|
3354
|
+
}), this._themeOverlay = I("div", "sl-theme-overlay"), this._themeOverlay.style.display = "none", this._themePanel = I("div", "sl-theme-panel"), this._themeOverlay.appendChild(this._themePanel), this._shadow.appendChild(r), this._config.showStatusBar && this._shadow.appendChild(this._statusBar), this._shadow.appendChild(this._acPopup), this._shadow.appendChild(this._emmetTip), this._shadow.appendChild(this._snippetTip), this._shadow.appendChild(this._hoverTip), this._shadow.appendChild(this._themeOverlay);
|
|
3355
|
+
const l = typeof this._config.value == "string" ? me(this._config.value) : this._config.value;
|
|
3356
|
+
this._tab = ue(1, l.length ? l : [""]), this._mmColors = Se((a) => X(a, this._host)), this._bindEditorEvents(), this._bindMinimapEvents(), this._bindFindEvents(), this._applyDynamicStyles(), typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(Z(() => {
|
|
3357
|
+
this._config.wordWrap && (this._rebuildWrapMap(), this._scheduleRender());
|
|
3358
|
+
}, 60)), this._ro.observe(this._host)), this._rebuildWrapMap(), this._render();
|
|
3359
|
+
}
|
|
3360
|
+
// ── Public API ────────────────────────────────────────────
|
|
3361
|
+
getValue() {
|
|
3362
|
+
return A(this._tab.doc);
|
|
3363
|
+
}
|
|
3364
|
+
setValue(e) {
|
|
3365
|
+
var t, i;
|
|
3366
|
+
L(this._tab, this._config.maxUndoHistory), this._tab.doc = me(e), this._tab.cur = { row: 0, col: 0 }, this._tab.sel = null, this._tokenCache.clear(), this._foldedLines.clear(), this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, e);
|
|
3367
|
+
}
|
|
3368
|
+
getCursor() {
|
|
3369
|
+
return { ...this._tab.cur };
|
|
3370
|
+
}
|
|
3371
|
+
setCursor(e) {
|
|
3372
|
+
this._tab.cur = { ...e }, S(this._tab), this._scrollIntoView(), this._render();
|
|
3373
|
+
}
|
|
3374
|
+
getSelection() {
|
|
3375
|
+
return this._tab.sel ? { ...this._tab.sel } : null;
|
|
3376
|
+
}
|
|
3377
|
+
setSelection(e) {
|
|
3378
|
+
this._tab.sel = e, this._render();
|
|
3379
|
+
}
|
|
3380
|
+
insertText(e) {
|
|
3381
|
+
this._config.readOnly || (this._insertStr(e, !1), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render());
|
|
3382
|
+
}
|
|
3383
|
+
setTheme(e) {
|
|
3384
|
+
this._themeManager.apply(e), this._applyTokenOverrides(), this._mmColors = Se((t) => X(t, this._host)), this._tokenCache.clear(), this._render();
|
|
3385
|
+
}
|
|
3386
|
+
updateConfig(e) {
|
|
3387
|
+
const t = ye(e);
|
|
3388
|
+
if (t.autoClosePairs !== void 0) {
|
|
3389
|
+
const i = t.autoClosePairs;
|
|
3390
|
+
this._config.autoClosePairs = Object.keys(i).length === 0 ? {} : { ...this._config.autoClosePairs, ...i };
|
|
3391
|
+
const { autoClosePairs: n, ...r } = t;
|
|
3392
|
+
Object.assign(this._config, r);
|
|
3393
|
+
} else
|
|
3394
|
+
Object.assign(this._config, t);
|
|
3395
|
+
if (t.readOnly !== void 0 && this._inputEl.setAttribute("aria-readonly", String(!!t.readOnly)), e.theme !== void 0 && this.setTheme(e.theme), (e.wordWrap !== void 0 || e.wrapColumn !== void 0) && this._rebuildWrapMap(), e.showMinimap !== void 0) {
|
|
3396
|
+
const i = this._shadow.querySelector(".sl-layout");
|
|
3397
|
+
e.showMinimap ? i.contains(this._minimapWrap) || i.appendChild(this._minimapWrap) : this._minimapWrap.remove();
|
|
3398
|
+
}
|
|
3399
|
+
e.showStatusBar !== void 0 && (e.showStatusBar ? this._shadow.contains(this._statusBar) || this._shadow.appendChild(this._statusBar) : this._statusBar.remove()), (e.fontFamily !== void 0 || e.fontSize !== void 0 || e.lineHeight !== void 0 || e.cursorBlinkRate !== void 0 || e.cursorStyle !== void 0 || e.gutterWidth !== void 0 || e.minimapWidth !== void 0 || e.showGutter !== void 0 || e.tokenColors !== void 0) && this._applyDynamicStyles(), (e.language !== void 0 || e.extraKeywords !== void 0 || e.extraTypes !== void 0 || e.renderWhitespace !== void 0 || e.completions !== void 0) && this._tokenCache.clear(), e.find === !1 ? this._closeFind() : e.findReplace === !1 && (this._replaceRow.style.display = "none"), e.goToLine === !1 && this._closeGoToLine(), e.placeholder !== void 0 && (this._placeholderEl.textContent = e.placeholder), this._render();
|
|
3400
|
+
}
|
|
3401
|
+
focus() {
|
|
3402
|
+
this._focusInput();
|
|
3403
|
+
}
|
|
3404
|
+
getThemes() {
|
|
3405
|
+
return this._themeManager.allIds;
|
|
3406
|
+
}
|
|
3407
|
+
registerTheme(e) {
|
|
3408
|
+
this._themeManager.register(e);
|
|
3409
|
+
}
|
|
3410
|
+
undo() {
|
|
3411
|
+
var e, t;
|
|
3412
|
+
Oe(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, A(this._tab.doc)));
|
|
3413
|
+
}
|
|
3414
|
+
redo() {
|
|
3415
|
+
var e, t;
|
|
3416
|
+
Fe(this._tab) && (this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (t = (e = this._config).onChange) == null || t.call(e, A(this._tab.doc)));
|
|
3417
|
+
}
|
|
3418
|
+
executeCommand(e) {
|
|
3419
|
+
const t = this._config.readOnly;
|
|
3420
|
+
switch (e) {
|
|
3421
|
+
case "undo":
|
|
3422
|
+
t || this.undo();
|
|
3423
|
+
break;
|
|
3424
|
+
case "redo":
|
|
3425
|
+
t || this.redo();
|
|
3426
|
+
break;
|
|
3427
|
+
case "selectAll":
|
|
3428
|
+
this._selectAll();
|
|
3429
|
+
break;
|
|
3430
|
+
case "copy":
|
|
3431
|
+
this._doCopy();
|
|
3432
|
+
break;
|
|
3433
|
+
case "cut":
|
|
3434
|
+
t || this._doCut();
|
|
3435
|
+
break;
|
|
3436
|
+
case "toggleComment":
|
|
3437
|
+
t || this._toggleComment();
|
|
3438
|
+
break;
|
|
3439
|
+
case "duplicateLine":
|
|
3440
|
+
t || this._duplicateLine();
|
|
3441
|
+
break;
|
|
3442
|
+
case "deleteLine":
|
|
3443
|
+
t || this._deleteLine();
|
|
3444
|
+
break;
|
|
3445
|
+
case "toggleWordWrap":
|
|
3446
|
+
this._toggleWrap();
|
|
3447
|
+
break;
|
|
3448
|
+
case "find":
|
|
3449
|
+
this._config.find && this._openFind(!1);
|
|
3450
|
+
break;
|
|
3451
|
+
case "findReplace":
|
|
3452
|
+
this._config.find && this._config.findReplace && this._openFind(!0);
|
|
3453
|
+
break;
|
|
3454
|
+
case "indentLine":
|
|
3455
|
+
t || this._indentSel();
|
|
3456
|
+
break;
|
|
3457
|
+
case "outdentLine":
|
|
3458
|
+
t || this._unindentSel();
|
|
3459
|
+
break;
|
|
3460
|
+
default:
|
|
3461
|
+
console.warn(`[syncline-editor] executeCommand: unknown command "${e}"`);
|
|
3462
|
+
break;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
destroy() {
|
|
3466
|
+
var t;
|
|
3467
|
+
this._acDebounceTimer !== null && (clearTimeout(this._acDebounceTimer), this._acDebounceTimer = null), this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null), this._rafId !== null && (cancelAnimationFrame(this._rafId), this._rafId = null), window.removeEventListener("mouseup", this._onWinMouseUp), window.removeEventListener("resize", this._onWinResize), window.removeEventListener("mousemove", this._onWinMmMouseMove), window.removeEventListener("mouseup", this._onWinMmMouseUp), (t = this._ro) == null || t.disconnect();
|
|
3468
|
+
const e = this._mmCanvas.getContext("2d");
|
|
3469
|
+
e && e.clearRect(0, 0, this._mmCanvas.width, this._mmCanvas.height), this._shadow.innerHTML = "", this._host.classList.remove("sl-host");
|
|
3470
|
+
}
|
|
3471
|
+
// ── DOM builders ──────────────────────────────────────────
|
|
3472
|
+
_buildFindBar() {
|
|
3473
|
+
const e = I("div", "sl-find-bar");
|
|
3474
|
+
return e.innerHTML = `
|
|
3475
|
+
<div class="sl-find-row">
|
|
3476
|
+
<input class="sl-find-input" placeholder="Find…" autocomplete="off" spellcheck="false">
|
|
3477
|
+
<span class="sl-find-count">–</span>
|
|
3478
|
+
<button class="sl-find-btn sl-find-prev" title="Previous">↑</button>
|
|
3479
|
+
<button class="sl-find-btn sl-find-next" title="Next">↓</button>
|
|
3480
|
+
<button class="sl-find-btn sl-find-case" title="Match case">Aa</button>
|
|
3481
|
+
<button class="sl-find-btn sl-find-regex" title="Regex">.*</button>
|
|
3482
|
+
<span class="sl-find-x sl-find-close">✕</span>
|
|
3483
|
+
</div>
|
|
3484
|
+
<div class="sl-find-row sl-replace-row" style="display:none">
|
|
3485
|
+
<input class="sl-find-replace-input" placeholder="Replace…" autocomplete="off" spellcheck="false">
|
|
3486
|
+
<button class="sl-find-btn sl-replace-one">Replace</button>
|
|
3487
|
+
<button class="sl-find-btn sl-replace-all">All</button>
|
|
3488
|
+
</div>
|
|
3489
|
+
`, e;
|
|
3490
|
+
}
|
|
3491
|
+
_buildGoToLineBar() {
|
|
3492
|
+
const e = I("div", "sl-gtl-bar");
|
|
3493
|
+
e.innerHTML = `
|
|
3494
|
+
<span class="sl-gtl-label">Go to line</span>
|
|
3495
|
+
<input class="sl-gtl-input" type="text" inputmode="numeric" autocomplete="off" spellcheck="false" placeholder="…">
|
|
3496
|
+
<span class="sl-gtl-hint"></span>
|
|
3497
|
+
<span class="sl-find-x sl-gtl-close" title="Close">✕</span>
|
|
3498
|
+
`;
|
|
3499
|
+
const t = e.querySelector(".sl-gtl-input"), i = e.querySelector(".sl-gtl-hint");
|
|
3500
|
+
return t.addEventListener("input", () => {
|
|
3501
|
+
const n = parseInt(t.value, 10), r = !isNaN(n) && n >= 1 && n <= this._tab.doc.length;
|
|
3502
|
+
t.classList.toggle("sl-gtl-err", t.value !== "" && !r), i.textContent = `(1–${this._tab.doc.length})`;
|
|
3503
|
+
}), t.addEventListener("keydown", (n) => {
|
|
3504
|
+
var r, o;
|
|
3505
|
+
if (n.key === "Enter") {
|
|
3506
|
+
n.preventDefault();
|
|
3507
|
+
const l = parseInt(t.value, 10);
|
|
3508
|
+
!isNaN(l) && l >= 1 && l <= this._tab.doc.length && (this._tab.cur.row = l - 1, this._tab.cur.col = Math.min(this._tab.cur.col, (this._tab.doc[l - 1] ?? "").length), S(this._tab), this._tab.sel = null, this._closeGoToLine(), this._scrollIntoView(), this._render(), (o = (r = this._config).onCursorChange) == null || o.call(r, { ...this._tab.cur }));
|
|
3509
|
+
} else n.key === "Escape" && (n.preventDefault(), this._closeGoToLine());
|
|
3510
|
+
n.stopPropagation();
|
|
3511
|
+
}), e.querySelector(".sl-gtl-close").addEventListener("click", () => this._closeGoToLine()), e;
|
|
3512
|
+
}
|
|
3513
|
+
_openGoToLine() {
|
|
3514
|
+
if (this._goToLineBar.classList.contains("sl-open")) {
|
|
3515
|
+
this._closeGoToLine();
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
this._goToLineHint.textContent = `(1–${this._tab.doc.length})`, this._goToLineInput.value = String(this._tab.cur.row + 1), this._goToLineInput.classList.remove("sl-gtl-err"), this._goToLineBar.classList.add("sl-open"), this._goToLineInput.focus(), this._goToLineInput.select();
|
|
3519
|
+
}
|
|
3520
|
+
_closeGoToLine() {
|
|
3521
|
+
this._goToLineBar.classList.remove("sl-open"), this._focusInput();
|
|
3522
|
+
}
|
|
3523
|
+
_buildStatusBar() {
|
|
3524
|
+
const e = I("div", "sl-statusbar");
|
|
3525
|
+
return e.innerHTML = `
|
|
3526
|
+
<div class="sl-sb-item sl-no-click sl-sb-lang">⬡ TypeScript</div>
|
|
3527
|
+
<div class="sl-sb-sep"></div>
|
|
3528
|
+
<div class="sl-sb-item sl-no-click sl-sb-pos">Ln 1, Col 1</div>
|
|
3529
|
+
<div class="sl-sb-sep"></div>
|
|
3530
|
+
<div class="sl-sb-item sl-no-click sl-sb-sel"></div>
|
|
3531
|
+
<div class="sl-sb-sep sl-sb-sel-sep" style="display:none"></div>
|
|
3532
|
+
<div class="sl-sb-item sl-no-click sl-sb-lines">1 line</div>
|
|
3533
|
+
<div class="sl-sb-sep"></div>
|
|
3534
|
+
<div class="sl-sb-item sl-no-click">UTF-8 LF</div>
|
|
3535
|
+
<div class="sl-sb-right">
|
|
3536
|
+
<div class="sl-sb-item sl-no-click sl-sb-mc" style="display:none">⊕ <span class="sl-sb-mc-count">1</span> cursors</div>
|
|
3537
|
+
<div class="sl-sb-item sl-sb-wrap sl-sb-wrap-btn">⇥ Wrap: OFF</div>
|
|
3538
|
+
<div class="sl-sb-sep"></div>
|
|
3539
|
+
<div class="sl-sb-item sl-sb-theme-btn">🎨 Theme</div>
|
|
3540
|
+
<div class="sl-sb-sep"></div>
|
|
3541
|
+
<div class="sl-sb-item sl-no-click sl-sb-undo">↩0 ↪0</div>
|
|
3542
|
+
</div>
|
|
3543
|
+
`, e.querySelector(".sl-sb-wrap-btn").addEventListener("click", () => this._toggleWrap()), e.querySelector(".sl-sb-theme-btn").addEventListener("click", () => this._openThemePicker()), e;
|
|
3544
|
+
}
|
|
3545
|
+
// ── Dynamic styles ────────────────────────────────────────
|
|
3546
|
+
_applyDynamicStyles() {
|
|
3547
|
+
const {
|
|
3548
|
+
fontFamily: e,
|
|
3549
|
+
fontSize: t,
|
|
3550
|
+
lineHeight: i,
|
|
3551
|
+
cursorBlinkRate: n,
|
|
3552
|
+
cursorStyle: r,
|
|
3553
|
+
gutterWidth: o,
|
|
3554
|
+
minimapWidth: l,
|
|
3555
|
+
showGutter: a
|
|
3556
|
+
} = this._config, c = Math.max(2, i - 4), d = Math.floor((i - c) / 2);
|
|
3557
|
+
let h = "";
|
|
3558
|
+
r === "block" ? h = `width:${7.82}px;opacity:.5;border-radius:1px;` : r === "underline" && (h = `width:${7.82}px;height:2px;top:${i - 2}px;border-radius:0;`);
|
|
3559
|
+
const p = a ? o : 0;
|
|
3560
|
+
this._dynamicStyleEl.textContent = `
|
|
3561
|
+
.sl-el{font-family:${e};font-size:${t}px;line-height:${i}px}
|
|
3562
|
+
.sl-cl{height:${i}px;line-height:${i}px}
|
|
3563
|
+
.sl-egn{height:${i}px;line-height:${i}px}
|
|
3564
|
+
.sl-eg{min-width:${p}px;width:${p}px;${a ? "" : "display:none"}}
|
|
3565
|
+
.sl-cur::after{height:${c}px;top:${d}px;animation-duration:${n}ms;${h}}
|
|
3566
|
+
.sl-cur-extra::after{height:${c}px;top:${d}px;animation-duration:${n}ms;${h}}
|
|
3567
|
+
`, this._applyTokenOverrides(), this._minimapWrap.style.width = `${l}px`, this._placeholderEl.style.left = `${p + 14}px`, this._placeholderEl.style.fontFamily = e, this._placeholderEl.style.fontSize = `${t}px`, this._placeholderEl.style.lineHeight = `${i}px`;
|
|
3568
|
+
}
|
|
3569
|
+
/**
|
|
3570
|
+
* Apply tokenColors overrides as inline styles on the host element.
|
|
3571
|
+
* Must be called AFTER the theme has applied its own inline styles so
|
|
3572
|
+
* our values win (last writer wins for element.style.setProperty).
|
|
3573
|
+
* When a token field is empty/absent, restore the active theme's value.
|
|
3574
|
+
*/
|
|
3575
|
+
_applyTokenOverrides() {
|
|
3576
|
+
const e = this._config.tokenColors ?? {}, t = this._themeManager.activeTheme, i = this._host.style, n = (o, l, a) => {
|
|
3577
|
+
i.setProperty(o, l || a);
|
|
3578
|
+
}, r = t == null ? void 0 : t.tokens;
|
|
3579
|
+
n("--tok-kw", e.keyword, (r == null ? void 0 : r.tokKw) ?? ""), n("--tok-str", e.string, (r == null ? void 0 : r.tokStr) ?? ""), n("--tok-cmt", e.comment, (r == null ? void 0 : r.tokCmt) ?? ""), n("--tok-fn", e.function, (r == null ? void 0 : r.tokFn) ?? ""), n("--tok-num", e.number, (r == null ? void 0 : r.tokNum) ?? ""), n("--tok-cls", e.class, (r == null ? void 0 : r.tokCls) ?? ""), n("--tok-op", e.operator, (r == null ? void 0 : r.tokOp) ?? ""), n("--tok-typ", e.type, (r == null ? void 0 : r.tokTyp) ?? ""), n("--tok-dec", e.decorator, (r == null ? void 0 : r.tokDec) ?? "");
|
|
3580
|
+
}
|
|
3581
|
+
// ── Core render ───────────────────────────────────────────
|
|
3582
|
+
/**
|
|
3583
|
+
* Schedule a render on the next animation frame.
|
|
3584
|
+
* Multiple calls within a single frame are coalesced into one render —
|
|
3585
|
+
* ideal for scroll and resize handlers which can fire at 60+ Hz.
|
|
3586
|
+
*/
|
|
3587
|
+
_scheduleRender() {
|
|
3588
|
+
this._rafId === null && (this._rafId = requestAnimationFrame(() => {
|
|
3589
|
+
this._rafId = null, this._render();
|
|
3590
|
+
}));
|
|
3591
|
+
}
|
|
3592
|
+
_render() {
|
|
3593
|
+
const { doc: e, cur: t, sel: i } = this._tab, { lineHeight: n } = this._config;
|
|
3594
|
+
this._wordHighlights = this._config.wordHighlight ? Ct(e, t.row, t.col, i) : [], this._bracketMatch = this._config.bracketMatching ? at(e, t) : null;
|
|
3595
|
+
const r = this._wm.visualRows.length;
|
|
3596
|
+
if (this._spacerEl.style.height = `${r * n}px`, this._config.wordWrap)
|
|
3597
|
+
this._spacerEl.style.width = "", this._vpEl.style.width = "";
|
|
3598
|
+
else {
|
|
3599
|
+
const f = e.reduce((v, u) => Math.max(v, u.length), 0), _ = this._config.showGutter ? this._config.gutterWidth : 0, b = Math.max(
|
|
3600
|
+
this._editorEl.clientWidth,
|
|
3601
|
+
_ + 14 + Math.ceil(f * 7.82) + 20 + 64
|
|
3602
|
+
);
|
|
3603
|
+
this._spacerEl.style.width = `${b}px`, this._vpEl.style.width = `${b}px`;
|
|
3604
|
+
}
|
|
3605
|
+
const o = this._editorEl.scrollTop, l = this._editorEl.clientHeight, a = Math.max(0, Math.floor(o / n) - 6), c = Math.min(r - 1, Math.ceil((o + l) / n) + 6);
|
|
3606
|
+
this._vpEl.style.transform = `translateY(${a * n}px)`;
|
|
3607
|
+
const d = F(this._wm, t.row, t.col), h = /* @__PURE__ */ new Map();
|
|
3608
|
+
if (this._snippetSession)
|
|
3609
|
+
for (let f = this._snippetSession.idx + 1; f < this._snippetSession.stops.length; f++) {
|
|
3610
|
+
const _ = this._snippetSession.stops[f], b = F(this._wm, _.row, _.col), v = h.get(b.visRow) ?? [];
|
|
3611
|
+
v.push(b.colInSeg), h.set(b.visRow, v);
|
|
3612
|
+
}
|
|
3613
|
+
let p = "";
|
|
3614
|
+
for (let f = a; f <= c; f++) {
|
|
3615
|
+
const _ = this._wm.visualRows[f];
|
|
3616
|
+
_ && (p += Rt({
|
|
3617
|
+
vr: _,
|
|
3618
|
+
visIdx: f,
|
|
3619
|
+
curVisRow: d.visRow,
|
|
3620
|
+
curColInSeg: d.colInSeg,
|
|
3621
|
+
docSel: i,
|
|
3622
|
+
findMatches: this._findMatches,
|
|
3623
|
+
findIdx: this._findIdx,
|
|
3624
|
+
wordHighlights: this._wordHighlights,
|
|
3625
|
+
bracketMatch: this._bracketMatch,
|
|
3626
|
+
extraCursors: this._extraCursors,
|
|
3627
|
+
snippetStopCols: h.get(f) ?? [],
|
|
3628
|
+
foldedLines: this._foldedLines,
|
|
3629
|
+
isFoldable: this._config.codeFolding && lt(e, _.docLine),
|
|
3630
|
+
wm: this._wm,
|
|
3631
|
+
tokenCache: this._tokenCache,
|
|
3632
|
+
opts: {
|
|
3633
|
+
tokeniserOpts: {
|
|
3634
|
+
language: this._config.language,
|
|
3635
|
+
extraKeywords: new Set(this._config.extraKeywords),
|
|
3636
|
+
extraTypes: new Set(this._config.extraTypes)
|
|
3637
|
+
},
|
|
3638
|
+
showIndentGuides: this._config.showIndentGuides,
|
|
3639
|
+
highlightActiveLine: this._config.highlightActiveLine,
|
|
3640
|
+
charWidth: 7.82,
|
|
3641
|
+
codePaddingLeft: 14,
|
|
3642
|
+
tabSize: this._config.tabSize,
|
|
3643
|
+
lineHeight: n,
|
|
3644
|
+
renderWhitespace: this._config.renderWhitespace
|
|
3645
|
+
}
|
|
3646
|
+
}));
|
|
3647
|
+
}
|
|
3648
|
+
if (this._vpEl.innerHTML = p, this._updateStatusBar(), this._updateMinimap(), this._config.placeholder) {
|
|
3649
|
+
const f = this._tab.doc.length === 1 && this._tab.doc[0] === "";
|
|
3650
|
+
this._placeholderEl.style.display = f ? "" : "none";
|
|
3651
|
+
} else
|
|
3652
|
+
this._placeholderEl.style.display = "none";
|
|
3653
|
+
}
|
|
3654
|
+
// ── Status bar ────────────────────────────────────────────
|
|
3655
|
+
_updateStatusBar() {
|
|
3656
|
+
if (!this._config.showStatusBar) return;
|
|
3657
|
+
const { cur: e, doc: t, undoStack: i, redoStack: n } = this._tab, r = this._config.language, o = {
|
|
3658
|
+
typescript: "TypeScript",
|
|
3659
|
+
javascript: "JavaScript",
|
|
3660
|
+
css: "CSS",
|
|
3661
|
+
json: "JSON",
|
|
3662
|
+
markdown: "Markdown",
|
|
3663
|
+
text: "Text"
|
|
3664
|
+
}, l = (p) => this._statusBar.querySelector(p);
|
|
3665
|
+
l(".sl-sb-lang").textContent = `⬡ ${o[r] ?? r}`, l(".sl-sb-pos").textContent = `Ln ${e.row + 1}, Col ${e.col + 1}`, l(".sl-sb-lines").textContent = `${t.length.toLocaleString()} lines`;
|
|
3666
|
+
const a = Ue(this._tab), c = l(".sl-sb-sel"), d = l(".sl-sb-sel-sep");
|
|
3667
|
+
c.textContent = a ? `${a.toLocaleString()} selected` : "", d.style.display = a ? "" : "none", l(".sl-sb-undo").textContent = `↩${i.length} ↪${n.length}`;
|
|
3668
|
+
const h = l(".sl-sb-mc");
|
|
3669
|
+
this._extraCursors.length ? (h.style.display = "", l(".sl-sb-mc-count").textContent = String(this._extraCursors.length + 1)) : h.style.display = "none";
|
|
3670
|
+
}
|
|
3671
|
+
// ── Minimap ───────────────────────────────────────────────
|
|
3672
|
+
_updateMinimap() {
|
|
3673
|
+
if (!this._config.showMinimap) return;
|
|
3674
|
+
const e = this._minimapWrap.clientWidth, t = this._minimapWrap.clientHeight;
|
|
3675
|
+
if (!e || !t) return;
|
|
3676
|
+
const i = this._tab.doc, n = i.length, r = Math.min(window.devicePixelRatio || 1, 2), o = this._config.lineHeight, { mmScroll: l, sliderTop: a, sliderHeight: c } = ie(
|
|
3677
|
+
n,
|
|
3678
|
+
this._editorEl.scrollTop,
|
|
3679
|
+
this._editorEl.clientHeight,
|
|
3680
|
+
t,
|
|
3681
|
+
o
|
|
3682
|
+
), d = l / 2, h = Math.floor(d), p = Math.ceil(t / 2) + 2, f = Math.min(n, h + p), _ = (f - h) * 2, b = (d - h) * 2, v = Math.round(e * r), u = Math.round(_ * r);
|
|
3683
|
+
(this._mmCanvas.width !== v || this._mmCanvas.height !== u) && (this._mmCanvas.width = v, this._mmCanvas.height = u, this._mmCanvas.style.width = `${e}px`, this._mmCanvas.style.height = `${_}px`), this._mmCanvas.style.transform = `translateY(${-b}px)`, Ot({
|
|
3684
|
+
canvas: this._mmCanvas,
|
|
3685
|
+
doc: i,
|
|
3686
|
+
firstLine: h,
|
|
3687
|
+
lastLine: f,
|
|
3688
|
+
subPx: b,
|
|
3689
|
+
wrapperWidth: e,
|
|
3690
|
+
canvasHeight: _,
|
|
3691
|
+
cursorRow: this._tab.cur.row,
|
|
3692
|
+
sel: this._tab.sel,
|
|
3693
|
+
findMatches: this._findMatches,
|
|
3694
|
+
findIdx: this._findIdx,
|
|
3695
|
+
sliderTop: a,
|
|
3696
|
+
sliderHeight: c,
|
|
3697
|
+
colors: this._mmColors,
|
|
3698
|
+
getCssVar: (T) => X(T, this._host),
|
|
3699
|
+
dpr: r
|
|
3700
|
+
}), this._mmSlider.style.top = `${Math.max(0, Math.min(t - c, a))}px`, this._mmSlider.style.height = `${c}px`;
|
|
3701
|
+
}
|
|
3702
|
+
// ── WrapMap ───────────────────────────────────────────────
|
|
3703
|
+
_rebuildWrapMap() {
|
|
3704
|
+
let e;
|
|
3705
|
+
if (this._config.wordWrap) {
|
|
3706
|
+
const t = this._config.showGutter ? this._config.gutterWidth : 0, i = this._editorEl.clientWidth;
|
|
3707
|
+
if (i > 0) {
|
|
3708
|
+
const n = i - t - 14 - 20;
|
|
3709
|
+
e = Math.max(20, Math.floor(n / 7.82));
|
|
3710
|
+
} else
|
|
3711
|
+
e = this._config.wrapColumn;
|
|
3712
|
+
} else
|
|
3713
|
+
e = 9999;
|
|
3714
|
+
this._wm = ze(
|
|
3715
|
+
this._tab.doc,
|
|
3716
|
+
e,
|
|
3717
|
+
this._config.wordWrap,
|
|
3718
|
+
this._foldedLines
|
|
3719
|
+
);
|
|
3720
|
+
}
|
|
3721
|
+
// ── Scroll ────────────────────────────────────────────────
|
|
3722
|
+
_scrollIntoView() {
|
|
3723
|
+
const e = this._tab.cur, i = F(this._wm, e.row, e.col).visRow * this._config.lineHeight, n = i + this._config.lineHeight, r = this._editorEl.scrollTop, o = this._editorEl.clientHeight, l = this._config.lineHeight * 3;
|
|
3724
|
+
i < r + l ? this._editorEl.scrollTop = Math.max(0, i - l) : n > r + o - l && (this._editorEl.scrollTop = n - o + l);
|
|
3725
|
+
}
|
|
3726
|
+
// ── Input helpers ─────────────────────────────────────────
|
|
3727
|
+
_focusInput() {
|
|
3728
|
+
this._inputEl.style.pointerEvents = "auto", this._inputEl.focus(), this._inputEl.style.pointerEvents = "none";
|
|
3729
|
+
}
|
|
3730
|
+
_insertStr(e, t) {
|
|
3731
|
+
var d, h;
|
|
3732
|
+
const i = Date.now();
|
|
3733
|
+
(!t || i - this._lastInputTime > this._config.undoBatchMs) && L(this._tab, this._config.maxUndoHistory), this._lastInputTime = i, this._tab.sel && (this._tab.cur = G(this._tab));
|
|
3734
|
+
const { doc: n, cur: r } = this._tab, o = e.split(`
|
|
3735
|
+
`), l = n[r.row] ?? "", a = l.slice(0, r.col), c = l.slice(r.col);
|
|
3736
|
+
if (o.length === 1)
|
|
3737
|
+
n[r.row] = a + e + c, r.col += e.length;
|
|
3738
|
+
else {
|
|
3739
|
+
const p = [a + o[0]];
|
|
3740
|
+
for (let f = 1; f < o.length - 1; f++) p.push(o[f]);
|
|
3741
|
+
p.push(o[o.length - 1] + c), n.splice(r.row, 1, ...p), r.row += o.length - 1, r.col = o[o.length - 1].length;
|
|
3742
|
+
}
|
|
3743
|
+
this._tokenCache.invalidateLine(r.row, (this._wm.segments[r.row] ?? [""]).length), this._tab.dirty = !0, (h = (d = this._config).onChange) == null || h.call(d, A(n));
|
|
3744
|
+
}
|
|
3745
|
+
_doBackspace() {
|
|
3746
|
+
var i;
|
|
3747
|
+
if (L(this._tab, this._config.maxUndoHistory), this._tab.sel) {
|
|
3748
|
+
this._tab.cur = G(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
|
|
3749
|
+
return;
|
|
3750
|
+
}
|
|
3751
|
+
const { doc: e, cur: t } = this._tab;
|
|
3752
|
+
if (t.col > 0) {
|
|
3753
|
+
const n = e[t.row] ?? "", r = n.slice(0, t.col), o = r.length >= 2 && r.endsWith(" ") && !r.trim() ? 2 : 1;
|
|
3754
|
+
e[t.row] = n.slice(0, t.col - o) + n.slice(t.col), t.col -= o, this._tokenCache.invalidateLine(t.row, ((i = this._wm.segments[t.row]) == null ? void 0 : i.length) ?? 1);
|
|
3755
|
+
} else if (t.row > 0) {
|
|
3756
|
+
const n = (e[t.row - 1] ?? "").length;
|
|
3757
|
+
e[t.row - 1] += e[t.row] ?? "", e.splice(t.row, 1), t.row--, t.col = n, this._tokenCache.clear();
|
|
3758
|
+
}
|
|
3759
|
+
this._tab.dirty = !0;
|
|
3760
|
+
}
|
|
3761
|
+
_doEnter() {
|
|
3762
|
+
L(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = G(this._tab));
|
|
3763
|
+
const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "", n = i.slice(0, t.col), r = i.slice(t.col), o = _e(i), l = n.trimEnd().endsWith("{") ? J(this._config.tabSize) : "";
|
|
3764
|
+
e[t.row] = n, n.trimEnd().endsWith("{") && r.trimStart() === "}" ? e.splice(t.row + 1, 0, o + l, o + r) : e.splice(t.row + 1, 0, o + l + r), t.row++, t.col = o.length + l.length, this._tokenCache.clear(), this._tab.dirty = !0;
|
|
3765
|
+
}
|
|
3766
|
+
_doDelete() {
|
|
3767
|
+
var n;
|
|
3768
|
+
if (L(this._tab, this._config.maxUndoHistory), this._tab.sel) {
|
|
3769
|
+
this._tab.cur = G(this._tab), this._tokenCache.clear(), this._tab.dirty = !0;
|
|
3770
|
+
return;
|
|
3771
|
+
}
|
|
3772
|
+
const { doc: e, cur: t } = this._tab, i = e[t.row] ?? "";
|
|
3773
|
+
t.col < i.length ? (e[t.row] = i.slice(0, t.col) + i.slice(t.col + 1), this._tokenCache.invalidateLine(t.row, ((n = this._wm.segments[t.row]) == null ? void 0 : n.length) ?? 1)) : t.row < e.length - 1 && (e[t.row] = i + (e[t.row + 1] ?? ""), e.splice(t.row + 1, 1), this._tokenCache.clear()), this._tab.dirty = !0;
|
|
3774
|
+
}
|
|
3775
|
+
// ── Editing commands ──────────────────────────────────────
|
|
3776
|
+
_selectAll() {
|
|
3777
|
+
const e = this._tab.doc, t = e.length - 1;
|
|
3778
|
+
this._tab.sel = { ar: 0, ac: 0, fr: t, fc: (e[t] ?? "").length }, this._tab.cur = { row: t, col: (e[t] ?? "").length }, this._render();
|
|
3779
|
+
}
|
|
3780
|
+
_doCopy() {
|
|
3781
|
+
var t;
|
|
3782
|
+
const e = ge(this._tab);
|
|
3783
|
+
e && ((t = navigator.clipboard) == null || t.writeText(e).catch(() => {
|
|
3784
|
+
}));
|
|
3785
|
+
}
|
|
3786
|
+
_doCut() {
|
|
3787
|
+
var t, i, n;
|
|
3788
|
+
const e = ge(this._tab);
|
|
3789
|
+
e && ((t = navigator.clipboard) == null || t.writeText(e).catch(() => {
|
|
3790
|
+
}), L(this._tab, this._config.maxUndoHistory), this._tab.cur = G(this._tab), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (n = (i = this._config).onChange) == null || n.call(i, A(this._tab.doc)));
|
|
3791
|
+
}
|
|
3792
|
+
_toggleComment() {
|
|
3793
|
+
var r, o;
|
|
3794
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
3795
|
+
const e = this._getSelRows(), t = this._config.lineCommentToken || Re[this._config.language] || "";
|
|
3796
|
+
if (!t) return;
|
|
3797
|
+
const i = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), n = e.every((l) => (this._tab.doc[l] ?? "").trimStart().startsWith(t));
|
|
3798
|
+
e.forEach((l) => {
|
|
3799
|
+
var c;
|
|
3800
|
+
const a = this._tab.doc[l] ?? "";
|
|
3801
|
+
this._tab.doc[l] = n ? a.replace(new RegExp(`^(\\s*)${i}\\s?`), "$1") : a.replace(/^(\s*)/, `$1${t} `), this._tokenCache.invalidateLine(l, ((c = this._wm.segments[l]) == null ? void 0 : c.length) ?? 1);
|
|
3802
|
+
}), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (o = (r = this._config).onChange) == null || o.call(r, A(this._tab.doc));
|
|
3803
|
+
}
|
|
3804
|
+
_duplicateLine() {
|
|
3805
|
+
var t, i;
|
|
3806
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
3807
|
+
const e = this._tab.cur.row;
|
|
3808
|
+
this._tab.doc.splice(e + 1, 0, this._tab.doc[e] ?? ""), this._tab.cur.row++, this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
|
|
3809
|
+
}
|
|
3810
|
+
_deleteLine() {
|
|
3811
|
+
var i, n;
|
|
3812
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
3813
|
+
const { doc: e, cur: t } = this._tab;
|
|
3814
|
+
e.length > 1 ? e.splice(t.row, 1) : (e[0] = "", t.col = 0), this._tokenCache.clear(), this._tab.dirty = !0, S(this._tab), this._rebuildWrapMap(), this._render(), (n = (i = this._config).onChange) == null || n.call(i, A(this._tab.doc));
|
|
3815
|
+
}
|
|
3816
|
+
_indentSel() {
|
|
3817
|
+
var t, i;
|
|
3818
|
+
if (!this._tab.sel) {
|
|
3819
|
+
this._insertStr(J(this._config.tabSize), !1);
|
|
3820
|
+
return;
|
|
3821
|
+
}
|
|
3822
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
3823
|
+
const e = J(this._config.tabSize);
|
|
3824
|
+
this._getSelRows().forEach((n) => {
|
|
3825
|
+
var r;
|
|
3826
|
+
this._tab.doc[n] = e + (this._tab.doc[n] ?? ""), this._tokenCache.invalidateLine(n, ((r = this._wm.segments[n]) == null ? void 0 : r.length) ?? 1);
|
|
3827
|
+
}), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
|
|
3828
|
+
}
|
|
3829
|
+
_unindentSel() {
|
|
3830
|
+
var t, i;
|
|
3831
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
3832
|
+
const e = this._config.tabSize;
|
|
3833
|
+
this._getSelRows().forEach((n) => {
|
|
3834
|
+
var o;
|
|
3835
|
+
const r = this._tab.doc[n] ?? "";
|
|
3836
|
+
r.startsWith(J(e)) ? this._tab.doc[n] = r.slice(e) : r.startsWith(" ") && (this._tab.doc[n] = r.slice(1)), this._tokenCache.invalidateLine(n, ((o = this._wm.segments[n]) == null ? void 0 : o.length) ?? 1);
|
|
3837
|
+
}), this._tab.dirty = !0, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
|
|
3838
|
+
}
|
|
3839
|
+
_toggleWrap() {
|
|
3840
|
+
this._config.wordWrap = !this._config.wordWrap, this._vpEl.classList.toggle("sl-wrap-mode", this._config.wordWrap);
|
|
3841
|
+
const e = this._statusBar.querySelector(".sl-sb-wrap-btn");
|
|
3842
|
+
e && (e.textContent = `⇥ Wrap: ${this._config.wordWrap ? "ON" : "OFF"}`, e.classList.toggle("sl-on", this._config.wordWrap)), this._tokenCache.clear(), this._rebuildWrapMap(), this._render();
|
|
3843
|
+
}
|
|
3844
|
+
_getSelRows() {
|
|
3845
|
+
if (!this._tab.sel) return [this._tab.cur.row];
|
|
3846
|
+
const e = $(this._tab.sel), t = [];
|
|
3847
|
+
for (let i = e.ar; i <= e.fr; i++) t.push(i);
|
|
3848
|
+
return t;
|
|
3849
|
+
}
|
|
3850
|
+
// ── Mouse position helper ─────────────────────────────────
|
|
3851
|
+
_posFromMouse(e) {
|
|
3852
|
+
var c;
|
|
3853
|
+
const t = this._editorEl.getBoundingClientRect(), i = e.clientY - t.top + this._editorEl.scrollTop, n = this._config.showGutter ? this._config.gutterWidth : 0, r = e.clientX - t.left - n - 14, o = this._config.lineHeight, l = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(i / o))), a = Math.max(0, Math.min(
|
|
3854
|
+
(((c = this._wm.visualRows[l]) == null ? void 0 : c.text) ?? "").length,
|
|
3855
|
+
Math.round(r / 7.82)
|
|
3856
|
+
));
|
|
3857
|
+
return Y(this._wm, l, a);
|
|
3858
|
+
}
|
|
3859
|
+
// ── Find ──────────────────────────────────────────────────
|
|
3860
|
+
_openFind(e) {
|
|
3861
|
+
this._findBar.classList.add("sl-open"), this._replaceRow.style.display = e && this._config.findReplace ? "" : "none", this._findInput.focus(), this._findInput.select(), this._runFind(this._findInput.value), this._findMatches.length ? (this._findIdx = -1, this._navFind(1)) : this._render();
|
|
3862
|
+
}
|
|
3863
|
+
_closeFind() {
|
|
3864
|
+
this._findBar.classList.remove("sl-open"), this._findMatches = [], this._findIdx = -1, this._findCount.textContent = "–", this._focusInput(), this._render();
|
|
3865
|
+
}
|
|
3866
|
+
_runFind(e) {
|
|
3867
|
+
this._findMatches = wt(this._tab.doc, e, {
|
|
3868
|
+
caseSensitive: this._findCaseSensitive,
|
|
3869
|
+
useRegex: this._findRegex
|
|
3870
|
+
});
|
|
3871
|
+
}
|
|
3872
|
+
_navFind(e) {
|
|
3873
|
+
if (!this._findMatches.length) {
|
|
3874
|
+
this._findCount.textContent = "0/0";
|
|
3875
|
+
return;
|
|
3876
|
+
}
|
|
3877
|
+
this._findIdx = Tt(this._findMatches, this._findIdx, e);
|
|
3878
|
+
const t = this._findMatches[this._findIdx];
|
|
3879
|
+
this._tab.cur = { row: t.row, col: t.col }, this._tab.sel = { ar: t.row, ac: t.col, fr: t.row, fc: t.col + t.len }, this._scrollIntoView(), this._render(), this._findCount.textContent = `${this._findIdx + 1}/${this._findMatches.length}`;
|
|
3880
|
+
}
|
|
3881
|
+
// ── Autocomplete ──────────────────────────────────────────
|
|
3882
|
+
_acVisible() {
|
|
3883
|
+
return this._acPopup.style.display !== "none";
|
|
3884
|
+
}
|
|
3885
|
+
_acHide() {
|
|
3886
|
+
this._acPopup.style.display = "none", this._acItems = [];
|
|
3887
|
+
}
|
|
3888
|
+
/**
|
|
3889
|
+
* Schedule an autocomplete refresh after a brief debounce pause.
|
|
3890
|
+
* Prevents the suggestion engine running on every single keystroke —
|
|
3891
|
+
* only fires when the user pauses for `AC_DEBOUNCE_MS` milliseconds.
|
|
3892
|
+
* Call `_acTriggerNow()` directly when an immediate refresh is required
|
|
3893
|
+
* (e.g., on explicit Ctrl+Space or arrow-key navigation).
|
|
3894
|
+
*/
|
|
3895
|
+
_acTrigger() {
|
|
3896
|
+
if (!this._config.autocomplete) {
|
|
3897
|
+
this._acHide();
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
this._acDebounceTimer !== null && clearTimeout(this._acDebounceTimer), this._acDebounceTimer = setTimeout(() => {
|
|
3901
|
+
this._acDebounceTimer = null, this._acTriggerNow();
|
|
3902
|
+
}, 120);
|
|
3903
|
+
}
|
|
3904
|
+
/** Run an autocomplete refresh immediately (no debounce). */
|
|
3905
|
+
_acTriggerNow() {
|
|
3906
|
+
if (!this._config.autocomplete) {
|
|
3907
|
+
this._acHide();
|
|
3908
|
+
return;
|
|
3909
|
+
}
|
|
3910
|
+
const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", n = this._config.language === "css", { prefix: r, start: o } = It(i, e.col, n);
|
|
3911
|
+
this._acPrefix = r, this._acStartCol = o;
|
|
3912
|
+
const l = [];
|
|
3913
|
+
if (this._config.emmet) {
|
|
3914
|
+
const c = we(i, e.col);
|
|
3915
|
+
if (c) {
|
|
3916
|
+
const d = ve(c.abbr);
|
|
3917
|
+
if (d) {
|
|
3918
|
+
this._emmetAcStartCol = c.start;
|
|
3919
|
+
const h = d.replace(/\n/g, "↵ ").slice(0, 60);
|
|
3920
|
+
l.push({ label: c.abbr, kind: "emmet", detail: h, body: d });
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
const a = r.length >= this._config.autocompletePrefixLength ? Lt(t, r, {
|
|
3925
|
+
language: this._config.language,
|
|
3926
|
+
extraKeywords: this._config.extraKeywords,
|
|
3927
|
+
extraTypes: this._config.extraTypes,
|
|
3928
|
+
completions: this._allCompletions(),
|
|
3929
|
+
replaceBuiltins: this._config.replaceBuiltins,
|
|
3930
|
+
maxResults: this._config.maxCompletions,
|
|
3931
|
+
provideCompletions: this._config.provideCompletions
|
|
3932
|
+
}, e.row, e.col) : [];
|
|
3933
|
+
if (this._acItems = [...l, ...a], !this._acItems.length) {
|
|
3934
|
+
this._acHide();
|
|
3935
|
+
return;
|
|
3936
|
+
}
|
|
3937
|
+
this._acSel = 0, this._renderAcPopup();
|
|
3938
|
+
}
|
|
3939
|
+
_renderAcPopup() {
|
|
3940
|
+
const e = (a) => {
|
|
3941
|
+
switch (a) {
|
|
3942
|
+
case "kw":
|
|
3943
|
+
return "K";
|
|
3944
|
+
case "fn":
|
|
3945
|
+
return "f";
|
|
3946
|
+
case "typ":
|
|
3947
|
+
return "T";
|
|
3948
|
+
case "cls":
|
|
3949
|
+
return "C";
|
|
3950
|
+
case "snip":
|
|
3951
|
+
return "S";
|
|
3952
|
+
case "emmet":
|
|
3953
|
+
return "E";
|
|
3954
|
+
default:
|
|
3955
|
+
return "·";
|
|
3956
|
+
}
|
|
3957
|
+
}, t = this._acItems[this._acSel];
|
|
3958
|
+
let i = "";
|
|
3959
|
+
t != null && t.description ? i = t.description : (t == null ? void 0 : t.kind) === "snip" && t.body ? i = t.body.replace(/\$\d/g, "▌") : (t == null ? void 0 : t.kind) === "emmet" && t.body && (i = t.body);
|
|
3960
|
+
const n = this._acItems.map((a, c) => {
|
|
3961
|
+
const d = c === this._acSel;
|
|
3962
|
+
return `<div class="sl-ac-item${d ? " sl-sel" : ""}" data-i="${c}" role="option" aria-selected="${d}"><span class="sl-ac-badge ${a.kind}">${e(a.kind)}</span><span class="sl-ac-label">${a.label}</span><span class="sl-ac-detail">${a.detail ?? ""}</span></div>`;
|
|
3963
|
+
}).join(""), r = i ? `<div class="sl-ac-desc"><pre class="sl-ac-desc-body">${i.replace(/</g, "<")}</pre></div>` : "";
|
|
3964
|
+
this._acPopup.innerHTML = `<div class="sl-ac-list">${n}</div>` + r, this._acPopup.style.display = "flex", this._posAcPopup();
|
|
3965
|
+
const o = this._acPopup.querySelector(".sl-ac-list"), l = this._acPopup.querySelector(".sl-ac-item.sl-sel");
|
|
3966
|
+
if (o && l) {
|
|
3967
|
+
const a = l.offsetTop, c = a + l.offsetHeight;
|
|
3968
|
+
c > o.scrollTop + o.clientHeight ? o.scrollTop = c - o.clientHeight : a < o.scrollTop && (o.scrollTop = a);
|
|
3969
|
+
}
|
|
3970
|
+
this._acPopup.querySelectorAll(".sl-ac-item").forEach((a) => {
|
|
3971
|
+
a.addEventListener("mousedown", (c) => {
|
|
3972
|
+
c.preventDefault(), this._acSel = parseInt(a.dataset.i ?? "0", 10), this._acAccept();
|
|
3973
|
+
});
|
|
3974
|
+
});
|
|
3975
|
+
}
|
|
3976
|
+
_posAcPopup() {
|
|
3977
|
+
const e = this._editorEl.getBoundingClientRect(), t = F(this._wm, this._tab.cur.row, this._tab.cur.col), i = this._config.showGutter ? this._config.gutterWidth : 0, n = e.left + i + 14 + this._acStartCol * 7.82, r = e.top + (t.visRow * this._config.lineHeight - this._editorEl.scrollTop) + this._config.lineHeight + 2, l = !!this._acPopup.querySelector(".sl-ac-desc") ? 620 : 300, a = Math.min(this._acItems.length * 28 + 8, 320), c = r + a > window.innerHeight - 16;
|
|
3978
|
+
this._acPopup.style.left = `${Math.min(n, window.innerWidth - l - 16)}px`, this._acPopup.style.top = `${c ? r - this._config.lineHeight - 2 - a : r}px`;
|
|
3979
|
+
}
|
|
3980
|
+
_acAccept() {
|
|
3981
|
+
const e = this._acItems[this._acSel];
|
|
3982
|
+
if (!e) return;
|
|
3983
|
+
if (this._acHide(), e.kind === "emmet" && e.body) {
|
|
3984
|
+
L(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._emmetAcStartCol);
|
|
3985
|
+
return;
|
|
3986
|
+
}
|
|
3987
|
+
if (e.body) {
|
|
3988
|
+
L(this._tab, this._config.maxUndoHistory), this._expandBodyAt(e.body, this._acStartCol);
|
|
3989
|
+
return;
|
|
3990
|
+
}
|
|
3991
|
+
const t = e.label.slice(this._acPrefix.length);
|
|
3992
|
+
this._insertStr(t, !1), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render();
|
|
3993
|
+
}
|
|
3994
|
+
// ── Emmet ─────────────────────────────────────────────────
|
|
3995
|
+
_emmetCheck() {
|
|
3996
|
+
if (this._emmetTip.style.display = "none", !this._config.emmet) {
|
|
3997
|
+
this._emmetExpanded = null;
|
|
3998
|
+
return;
|
|
3999
|
+
}
|
|
4000
|
+
const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", n = we(i, e.col);
|
|
4001
|
+
if (!n) {
|
|
4002
|
+
this._emmetExpanded = null;
|
|
4003
|
+
return;
|
|
4004
|
+
}
|
|
4005
|
+
const r = ve(n.abbr);
|
|
4006
|
+
if (!r) {
|
|
4007
|
+
this._emmetExpanded = null;
|
|
4008
|
+
return;
|
|
4009
|
+
}
|
|
4010
|
+
this._emmetExpanded = { abbr: n.abbr, result: r, start: n.start };
|
|
4011
|
+
}
|
|
4012
|
+
_emmetAccept() {
|
|
4013
|
+
if (!this._emmetExpanded || this._emmetTip.style.display === "none") return !1;
|
|
4014
|
+
const { abbr: e, result: t, start: i } = this._emmetExpanded;
|
|
4015
|
+
return L(this._tab, this._config.maxUndoHistory), this._emmetExpanded = null, this._emmetTip.style.display = "none", this._expandBodyAt(t, i), !0;
|
|
4016
|
+
}
|
|
4017
|
+
// ── Snippets / Completions ────────────────────────────────
|
|
4018
|
+
/** Returns built-in snippets for the current language merged with user completions.
|
|
4019
|
+
* When `replaceBuiltins` is true the language built-ins are suppressed so only
|
|
4020
|
+
* the caller-supplied completions (e.g. MDX_SNIPPETS) are active. */
|
|
4021
|
+
_allCompletions() {
|
|
4022
|
+
return [...this._config.replaceBuiltins ? [] : gt(this._config.language), ...this._config.completions];
|
|
4023
|
+
}
|
|
4024
|
+
_snippetCheck() {
|
|
4025
|
+
if (this._snippetTip.style.display = "none", !this._config.snippetExpansion) {
|
|
4026
|
+
this._snippetExpanded = null;
|
|
4027
|
+
return;
|
|
4028
|
+
}
|
|
4029
|
+
const { cur: e, doc: t } = this._tab, i = t[e.row] ?? "", n = bt(i, e.col, this._allCompletions());
|
|
4030
|
+
if (!n) {
|
|
4031
|
+
this._snippetExpanded = null;
|
|
4032
|
+
return;
|
|
4033
|
+
}
|
|
4034
|
+
this._snippetExpanded = { snippet: n.snippet, start: n.start };
|
|
4035
|
+
}
|
|
4036
|
+
_snippetAccept() {
|
|
4037
|
+
if (!this._snippetExpanded || this._snippetTip.style.display === "none") return !1;
|
|
4038
|
+
const { snippet: e, start: t } = this._snippetExpanded;
|
|
4039
|
+
return e.body ? (L(this._tab, this._config.maxUndoHistory), this._snippetExpanded = null, this._snippetTip.style.display = "none", this._expandBodyAt(e.body, t), !0) : !1;
|
|
4040
|
+
}
|
|
4041
|
+
/**
|
|
4042
|
+
* Expand a snippet/emmet body template at the current cursor position.
|
|
4043
|
+
* `triggerStart` is the column where the trigger word begins.
|
|
4044
|
+
* `cur.col` must be at the end of the trigger (emmet) or at `triggerStart`
|
|
4045
|
+
* when the prefix was already stripped (snippet accepted from popup).
|
|
4046
|
+
* Everything between `triggerStart` and `cur.col` is replaced by `body`.
|
|
4047
|
+
*/
|
|
4048
|
+
_expandBodyAt(e, t) {
|
|
4049
|
+
var u, T;
|
|
4050
|
+
const { doc: i, cur: n } = this._tab, r = n.row, o = i[n.row] ?? "", l = o.slice(0, t), a = o.slice(n.col), c = _e(o), d = e.split(`
|
|
4051
|
+
`).map((m, w) => w === 0 ? m : c + m), h = d.join(`
|
|
4052
|
+
`), p = [], f = /\$(\d+)/g;
|
|
4053
|
+
let _;
|
|
4054
|
+
for (; (_ = f.exec(h)) !== null; ) {
|
|
4055
|
+
const m = parseInt(_[1], 10), y = h.slice(0, _.index).split(`
|
|
4056
|
+
`), D = y.length - 1, R = y[D].length, C = (y[D].match(/\$\d+/g) ?? []).join("").length, U = r + D, P = (D === 0 ? t : c.length) + (R - C);
|
|
4057
|
+
p.push({ n: m, row: U, col: P });
|
|
4058
|
+
}
|
|
4059
|
+
p.sort((m, w) => m.n === 0 ? 1 : w.n === 0 ? -1 : m.n - w.n);
|
|
4060
|
+
const b = d.map((m) => m.replace(/\$\d+/g, "")), v = b.length === 1 ? [l + b[0] + a] : [l + b[0], ...b.slice(1, -1), b[b.length - 1] + a];
|
|
4061
|
+
i.splice(n.row, 1, ...v), p.length > 0 ? (this._snippetSession = { stops: p.map((m) => ({ row: m.row, col: m.col })), idx: 0 }, n.row = p[0].row, n.col = p[0].col) : (this._snippetSession = null, n.row += v.length - 1, n.col = (v[v.length - 1] ?? "").length - a.length), this._tokenCache.clear(), this._tab.dirty = !0, this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (T = (u = this._config).onChange) == null || T.call(u, A(this._tab.doc));
|
|
4062
|
+
}
|
|
4063
|
+
// ── Theme picker ──────────────────────────────────────────
|
|
4064
|
+
_openThemePicker() {
|
|
4065
|
+
var t;
|
|
4066
|
+
const e = this._themeManager.all;
|
|
4067
|
+
this._themePanel.innerHTML = `
|
|
4068
|
+
<div class="sl-theme-header">
|
|
4069
|
+
<div class="sl-theme-title">Color Theme</div>
|
|
4070
|
+
<div class="sl-theme-close">✕</div>
|
|
4071
|
+
</div>
|
|
4072
|
+
<div class="sl-theme-list">
|
|
4073
|
+
${e.map((i) => `
|
|
4074
|
+
<div class="sl-theme-item${i.id === this._themeManager.activeId ? " sl-active" : ""}" data-id="${i.id}">
|
|
4075
|
+
<div class="sl-theme-swatch">
|
|
4076
|
+
${i.tokens.bg0 ? `<span style="background:${i.tokens.bg0}"></span>` : ""}
|
|
4077
|
+
<span style="background:${i.tokens.accent}"></span>
|
|
4078
|
+
<span style="background:${i.tokens.tokStr}"></span>
|
|
4079
|
+
<span style="background:${i.tokens.tokFn}"></span>
|
|
4080
|
+
</div>
|
|
4081
|
+
<div>
|
|
4082
|
+
<div class="sl-theme-name">${i.name}<span class="sl-theme-tag${i.light ? " sl-light" : ""}">${i.light ? "Light" : "Dark"}</span></div>
|
|
4083
|
+
<div class="sl-theme-desc">${i.description}</div>
|
|
4084
|
+
</div>
|
|
4085
|
+
<div class="sl-theme-check">✓</div>
|
|
4086
|
+
</div>
|
|
4087
|
+
`).join("")}
|
|
4088
|
+
</div>
|
|
4089
|
+
`, this._themeOverlay.style.display = "block", (t = this._themePanel.querySelector(".sl-theme-close")) == null || t.addEventListener("click", () => {
|
|
4090
|
+
this._themeOverlay.style.display = "none";
|
|
4091
|
+
}), this._themeOverlay.addEventListener("click", (i) => {
|
|
4092
|
+
i.target === this._themeOverlay && (this._themeOverlay.style.display = "none");
|
|
4093
|
+
}, { once: !0 }), this._themePanel.querySelectorAll(".sl-theme-item").forEach((i) => {
|
|
4094
|
+
i.addEventListener("click", () => {
|
|
4095
|
+
const n = i.dataset.id ?? "";
|
|
4096
|
+
this.setTheme(n), this._themePanel.querySelectorAll(".sl-theme-item").forEach((r) => r.classList.remove("sl-active")), i.classList.add("sl-active");
|
|
4097
|
+
});
|
|
4098
|
+
});
|
|
4099
|
+
}
|
|
4100
|
+
// ── Event binding ─────────────────────────────────────────
|
|
4101
|
+
_bindEditorEvents() {
|
|
4102
|
+
this._vpEl.addEventListener("mousedown", this._onFoldBtnClick), this._editorEl.addEventListener("mousedown", (e) => {
|
|
4103
|
+
if (e.button !== 0) return;
|
|
4104
|
+
e.preventDefault(), this._focusInput(), this._acHide(), this._snippetSession = null, this._emmetTip.style.display = "none", e.altKey || (xe(this._mc), this._extraCursors = []);
|
|
4105
|
+
const t = this._posFromMouse(e);
|
|
4106
|
+
if (this._tab.cur = { ...t }, e.detail === 3)
|
|
4107
|
+
this._tab.sel = { ar: t.row, ac: 0, fr: t.row, fc: (this._tab.doc[t.row] ?? "").length }, this._tab.cur.col = this._tab.sel.fc;
|
|
4108
|
+
else if (e.detail === 2 && this._config.wordSelection) {
|
|
4109
|
+
const i = this._tab.doc[t.row] ?? "", n = le(i, t.col, this._isWordChar.bind(this)), r = ce(i, t.col, this._isWordChar.bind(this));
|
|
4110
|
+
n !== r ? (this._tab.sel = { ar: t.row, ac: n, fr: t.row, fc: r }, this._tab.cur.col = r) : this._tab.sel = null;
|
|
4111
|
+
} else {
|
|
4112
|
+
if (e.altKey && this._config.multiCursor) {
|
|
4113
|
+
ke(this._mc, t.row, t.col, null), this._extraCursors = [...this._mc.cursors], this._render();
|
|
4114
|
+
return;
|
|
4115
|
+
}
|
|
4116
|
+
this._tab.sel = null, this._isDragging = !0, this._dragAnchor = { ...t };
|
|
4117
|
+
}
|
|
4118
|
+
S(this._tab), this._render();
|
|
4119
|
+
}), this._editorEl.addEventListener("mousemove", (e) => {
|
|
4120
|
+
if (this._config.hover && !this._hoverPinned && !this._isDragging && this._scheduleHover(e), !this._isDragging || !this._dragAnchor) return;
|
|
4121
|
+
const t = this._posFromMouse(e);
|
|
4122
|
+
this._tab.cur = { ...t }, t.row !== this._dragAnchor.row || t.col !== this._dragAnchor.col ? this._tab.sel = { ar: this._dragAnchor.row, ac: this._dragAnchor.col, fr: t.row, fc: t.col } : this._tab.sel = null, S(this._tab), this._render();
|
|
4123
|
+
}), this._editorEl.addEventListener("mouseleave", () => {
|
|
4124
|
+
this._hoverPinned || this._hideHover();
|
|
4125
|
+
}), window.addEventListener("mouseup", this._onWinMouseUp), this._editorEl.addEventListener("scroll", this._onEditorScroll, { passive: !0 }), window.addEventListener("resize", this._onWinResize), this._inputEl.addEventListener("keydown", (e) => this._onKeyDown(e)), this._inputEl.addEventListener("input", (e) => this._onInput(e)), this._inputEl.addEventListener("paste", (e) => {
|
|
4126
|
+
var i;
|
|
4127
|
+
if (e.preventDefault(), this._config.readOnly) return;
|
|
4128
|
+
const t = (i = e.clipboardData ?? window.clipboardData) == null ? void 0 : i.getData("text/plain");
|
|
4129
|
+
t && (this._insertStr(t, !1), this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render());
|
|
4130
|
+
}), this._editorEl.addEventListener("mousedown", () => setTimeout(() => this._focusInput(), 0)), this._inputEl.addEventListener("focus", () => {
|
|
4131
|
+
var e, t;
|
|
4132
|
+
return (t = (e = this._config).onFocus) == null ? void 0 : t.call(e);
|
|
4133
|
+
}), this._inputEl.addEventListener("blur", () => {
|
|
4134
|
+
var e, t;
|
|
4135
|
+
return (t = (e = this._config).onBlur) == null ? void 0 : t.call(e);
|
|
4136
|
+
});
|
|
4137
|
+
}
|
|
4138
|
+
_onKeyDown(e) {
|
|
4139
|
+
var o, l, a, c, d, h, p, f, _;
|
|
4140
|
+
const t = e.ctrlKey || e.metaKey, i = e.shiftKey, n = e.altKey, r = this._config.readOnly;
|
|
4141
|
+
if (this._hideHover(), this._acVisible()) {
|
|
4142
|
+
if (e.key === "ArrowDown") {
|
|
4143
|
+
e.preventDefault(), this._acSel = Math.min(this._acItems.length - 1, this._acSel + 1), this._renderAcPopup();
|
|
4144
|
+
return;
|
|
4145
|
+
}
|
|
4146
|
+
if (e.key === "ArrowUp") {
|
|
4147
|
+
e.preventDefault(), this._acSel = Math.max(0, this._acSel - 1), this._renderAcPopup();
|
|
4148
|
+
return;
|
|
4149
|
+
}
|
|
4150
|
+
if (e.key === "Tab" || e.key === "Enter") {
|
|
4151
|
+
e.preventDefault(), this._acAccept();
|
|
4152
|
+
return;
|
|
4153
|
+
}
|
|
4154
|
+
if (e.key === "Escape") {
|
|
4155
|
+
this._acHide();
|
|
4156
|
+
return;
|
|
4157
|
+
}
|
|
4158
|
+
}
|
|
4159
|
+
if (n && (e.key === "z" || e.key === "Z" || e.key === "Ω")) {
|
|
4160
|
+
e.preventDefault(), this._toggleWrap();
|
|
4161
|
+
return;
|
|
4162
|
+
}
|
|
4163
|
+
if (t && e.key === "z" && !i) {
|
|
4164
|
+
e.preventDefault(), r || this.undo();
|
|
4165
|
+
return;
|
|
4166
|
+
}
|
|
4167
|
+
if (t && (e.key === "y" || i && e.key === "z")) {
|
|
4168
|
+
e.preventDefault(), r || this.redo();
|
|
4169
|
+
return;
|
|
4170
|
+
}
|
|
4171
|
+
if (t && e.key === "a") {
|
|
4172
|
+
e.preventDefault(), this._selectAll();
|
|
4173
|
+
return;
|
|
4174
|
+
}
|
|
4175
|
+
if (t && e.key === "c") {
|
|
4176
|
+
e.preventDefault(), this._doCopy();
|
|
4177
|
+
return;
|
|
4178
|
+
}
|
|
4179
|
+
if (t && e.key === "x") {
|
|
4180
|
+
e.preventDefault(), r || this._doCut();
|
|
4181
|
+
return;
|
|
4182
|
+
}
|
|
4183
|
+
if (t && e.key === "f") {
|
|
4184
|
+
e.preventDefault(), this._config.find && this._openFind(!1);
|
|
4185
|
+
return;
|
|
4186
|
+
}
|
|
4187
|
+
if (t && e.key === "h") {
|
|
4188
|
+
e.preventDefault(), this._config.find && this._config.findReplace && this._openFind(!0);
|
|
4189
|
+
return;
|
|
4190
|
+
}
|
|
4191
|
+
if (t && e.key === "g") {
|
|
4192
|
+
e.preventDefault(), this._config.goToLine && this._openGoToLine();
|
|
4193
|
+
return;
|
|
4194
|
+
}
|
|
4195
|
+
if (t && e.key === "d") {
|
|
4196
|
+
e.preventDefault(), !r && this._config.multiCursor && this._ctrlD();
|
|
4197
|
+
return;
|
|
4198
|
+
}
|
|
4199
|
+
if (t && i && e.key === "d") {
|
|
4200
|
+
e.preventDefault(), r || this._duplicateLine();
|
|
4201
|
+
return;
|
|
4202
|
+
}
|
|
4203
|
+
if (t && e.key === "/") {
|
|
4204
|
+
e.preventDefault(), r || this._toggleComment();
|
|
4205
|
+
return;
|
|
4206
|
+
}
|
|
4207
|
+
if (t && e.key === "k") {
|
|
4208
|
+
e.preventDefault(), r || this._deleteLine();
|
|
4209
|
+
return;
|
|
4210
|
+
}
|
|
4211
|
+
if (e.key === "Escape") {
|
|
4212
|
+
this._tab.sel = null, this._acHide(), this._closeFind(), this._closeGoToLine(), this._emmetTip.style.display = "none", this._snippetTip.style.display = "none", this._snippetExpanded = null, this._snippetSession = null, xe(this._mc), this._extraCursors = [], this._mc.searchWord = "", this._render();
|
|
4213
|
+
return;
|
|
4214
|
+
}
|
|
4215
|
+
if (r) {
|
|
4216
|
+
this._handleArrowKeys(e, t, i);
|
|
4217
|
+
return;
|
|
4218
|
+
}
|
|
4219
|
+
if (e.key === "Tab") {
|
|
4220
|
+
if (e.preventDefault(), this._snippetSession) {
|
|
4221
|
+
if (i) {
|
|
4222
|
+
if (this._snippetSession.idx > 0) {
|
|
4223
|
+
this._snippetSession.idx--;
|
|
4224
|
+
const b = this._snippetSession.stops[this._snippetSession.idx];
|
|
4225
|
+
this._tab.cur.row = b.row, this._tab.cur.col = b.col, this._tab.sel = null, S(this._tab), this._scrollIntoView(), this._render();
|
|
4226
|
+
}
|
|
4227
|
+
} else if (this._snippetSession.idx++, this._snippetSession.idx >= this._snippetSession.stops.length)
|
|
4228
|
+
this._snippetSession = null;
|
|
4229
|
+
else {
|
|
4230
|
+
const b = this._snippetSession.stops[this._snippetSession.idx];
|
|
4231
|
+
this._tab.cur.row = b.row, this._tab.cur.col = b.col, this._tab.sel = null, S(this._tab), this._scrollIntoView(), this._render();
|
|
4232
|
+
}
|
|
4233
|
+
return;
|
|
4234
|
+
}
|
|
4235
|
+
if (!i && this._emmetAccept() || !i && this._snippetAccept()) return;
|
|
4236
|
+
i ? this._unindentSel() : this._indentSel(), S(this._tab), this._scrollIntoView(), this._rebuildWrapMap(), this._render();
|
|
4237
|
+
return;
|
|
4238
|
+
}
|
|
4239
|
+
if (e.key === "Backspace") {
|
|
4240
|
+
if (e.preventDefault(), this._extraCursors.length) {
|
|
4241
|
+
this._snippetSession = null;
|
|
4242
|
+
const b = yt(
|
|
4243
|
+
this._tab.doc,
|
|
4244
|
+
this._tab.cur.row,
|
|
4245
|
+
this._tab.cur.col,
|
|
4246
|
+
this._extraCursors
|
|
4247
|
+
);
|
|
4248
|
+
this._tab.doc = b.doc, this._tab.cur.row = b.primaryRow, this._tab.cur.col = b.primaryCol, this._extraCursors = b.extraCursors, this._mc.cursors = b.extraCursors;
|
|
4249
|
+
} else {
|
|
4250
|
+
if (this._snippetSession) {
|
|
4251
|
+
const b = this._snippetSession.stops[this._snippetSession.idx];
|
|
4252
|
+
if (this._tab.cur.row === b.row && this._tab.cur.col > b.col) {
|
|
4253
|
+
for (let v = this._snippetSession.idx + 1; v < this._snippetSession.stops.length; v++) {
|
|
4254
|
+
const u = this._snippetSession.stops[v];
|
|
4255
|
+
u.row === b.row && u.col >= this._tab.cur.col && u.col--;
|
|
4256
|
+
}
|
|
4257
|
+
b.col--;
|
|
4258
|
+
} else
|
|
4259
|
+
this._snippetSession = null;
|
|
4260
|
+
}
|
|
4261
|
+
this._doBackspace();
|
|
4262
|
+
}
|
|
4263
|
+
this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (l = (o = this._config).onChange) == null || l.call(o, A(this._tab.doc));
|
|
4264
|
+
return;
|
|
4265
|
+
}
|
|
4266
|
+
if (e.key === "Delete") {
|
|
4267
|
+
e.preventDefault(), this._snippetSession = null, this._doDelete(), this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (c = (a = this._config).onChange) == null || c.call(a, A(this._tab.doc));
|
|
4268
|
+
return;
|
|
4269
|
+
}
|
|
4270
|
+
if (e.key === "Enter") {
|
|
4271
|
+
e.preventDefault(), this._snippetSession = null, this._doEnter(), this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (h = (d = this._config).onChange) == null || h.call(d, A(this._tab.doc));
|
|
4272
|
+
return;
|
|
4273
|
+
}
|
|
4274
|
+
if (!t && !n && this._config.autoClosePairs[e.key]) {
|
|
4275
|
+
e.preventDefault(), L(this._tab, this._config.maxUndoHistory), this._tab.sel && (this._tab.cur = G(this._tab));
|
|
4276
|
+
const { doc: b, cur: v } = this._tab, u = b[v.row] ?? "";
|
|
4277
|
+
b[v.row] = u.slice(0, v.col) + e.key + this._config.autoClosePairs[e.key] + u.slice(v.col), v.col++, this._tokenCache.invalidateLine(v.row, ((p = this._wm.segments[v.row]) == null ? void 0 : p.length) ?? 1), this._tab.dirty = !0, this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (_ = (f = this._config).onChange) == null || _.call(f, A(this._tab.doc));
|
|
4278
|
+
return;
|
|
4279
|
+
}
|
|
4280
|
+
if (!t && !n && Object.values(this._config.autoClosePairs).includes(e.key)) {
|
|
4281
|
+
const { doc: b, cur: v } = this._tab;
|
|
4282
|
+
if ((b[v.row] ?? "")[v.col] === e.key) {
|
|
4283
|
+
e.preventDefault(), v.col++, S(this._tab), this._scrollIntoView(), this._render();
|
|
4284
|
+
return;
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
if (i && n && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
|
|
4288
|
+
e.preventDefault(), this._duplicateLines(e.key === "ArrowDown");
|
|
4289
|
+
return;
|
|
4290
|
+
}
|
|
4291
|
+
if (n && !t && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
|
|
4292
|
+
e.preventDefault(), this._moveLines(e.key === "ArrowUp");
|
|
4293
|
+
return;
|
|
4294
|
+
}
|
|
4295
|
+
this._handleArrowKeys(e, t, i);
|
|
4296
|
+
}
|
|
4297
|
+
_handleArrowKeys(e, t, i) {
|
|
4298
|
+
var f, _, b, v, u, T;
|
|
4299
|
+
const { doc: n, cur: r } = this._tab, o = this._config.lineHeight, l = e.metaKey, a = e.ctrlKey, c = e.altKey, d = (m, w) => {
|
|
4300
|
+
if (i) {
|
|
4301
|
+
this._tab.sel || (this._tab.sel = { ar: r.row, ac: r.col, fr: r.row, fc: r.col }), r.row = m, r.col = w;
|
|
4302
|
+
const y = this._tab.sel;
|
|
4303
|
+
y.fr = m, y.fc = w, y.ar === y.fr && y.ac === y.fc && (this._tab.sel = null);
|
|
4304
|
+
} else
|
|
4305
|
+
this._tab.sel = null, r.row = m, r.col = w;
|
|
4306
|
+
}, h = (m) => {
|
|
4307
|
+
const y = (n[m] ?? "").search(/\S/);
|
|
4308
|
+
return y === -1 || r.col === y ? 0 : y;
|
|
4309
|
+
}, p = () => ({ row: n.length - 1, col: (n[n.length - 1] ?? "").length });
|
|
4310
|
+
switch (e.key) {
|
|
4311
|
+
case "ArrowRight":
|
|
4312
|
+
if (e.preventDefault(), this._tab.sel && !i) {
|
|
4313
|
+
const m = $(this._tab.sel);
|
|
4314
|
+
r.row = m.fr, r.col = m.fc, this._tab.sel = null;
|
|
4315
|
+
break;
|
|
4316
|
+
}
|
|
4317
|
+
if (l)
|
|
4318
|
+
d(r.row, (n[r.row] ?? "").length);
|
|
4319
|
+
else if (a || c) {
|
|
4320
|
+
const m = n[r.row] ?? "";
|
|
4321
|
+
if (r.col >= m.length)
|
|
4322
|
+
r.row < n.length - 1 && d(r.row + 1, 0);
|
|
4323
|
+
else {
|
|
4324
|
+
const w = this._wordSkipRight(m, r.col);
|
|
4325
|
+
d(r.row, w);
|
|
4326
|
+
}
|
|
4327
|
+
} else r.col < (n[r.row] ?? "").length ? d(r.row, r.col + 1) : r.row < n.length - 1 && d(r.row + 1, 0);
|
|
4328
|
+
break;
|
|
4329
|
+
case "ArrowLeft":
|
|
4330
|
+
if (e.preventDefault(), this._tab.sel && !i) {
|
|
4331
|
+
const m = $(this._tab.sel);
|
|
4332
|
+
r.row = m.ar, r.col = m.ac, this._tab.sel = null;
|
|
4333
|
+
break;
|
|
4334
|
+
}
|
|
4335
|
+
if (l)
|
|
4336
|
+
d(r.row, h(r.row));
|
|
4337
|
+
else if (a || c)
|
|
4338
|
+
if (r.col === 0)
|
|
4339
|
+
r.row > 0 && d(r.row - 1, (n[r.row - 1] ?? "").length);
|
|
4340
|
+
else {
|
|
4341
|
+
const m = this._wordSkipLeft(n[r.row] ?? "", r.col);
|
|
4342
|
+
d(r.row, m);
|
|
4343
|
+
}
|
|
4344
|
+
else r.col > 0 ? d(r.row, r.col - 1) : r.row > 0 && d(r.row - 1, (n[r.row - 1] ?? "").length);
|
|
4345
|
+
break;
|
|
4346
|
+
case "ArrowDown":
|
|
4347
|
+
if (e.preventDefault(), l) {
|
|
4348
|
+
const m = p();
|
|
4349
|
+
d(m.row, m.col);
|
|
4350
|
+
} else if (this._config.wordWrap) {
|
|
4351
|
+
const m = F(this._wm, r.row, r.col), w = Math.min(this._wm.visualRows.length - 1, m.visRow + 1), y = Y(this._wm, w, Math.min(m.colInSeg, (((f = this._wm.visualRows[w]) == null ? void 0 : f.text) ?? "").length));
|
|
4352
|
+
d(y.row, y.col);
|
|
4353
|
+
} else {
|
|
4354
|
+
const m = Math.min(n.length - 1, r.row + 1);
|
|
4355
|
+
d(m, Math.min(r.col, (n[m] ?? "").length));
|
|
4356
|
+
}
|
|
4357
|
+
break;
|
|
4358
|
+
case "ArrowUp":
|
|
4359
|
+
if (e.preventDefault(), l)
|
|
4360
|
+
d(0, 0);
|
|
4361
|
+
else if (this._config.wordWrap) {
|
|
4362
|
+
const m = F(this._wm, r.row, r.col), w = Math.max(0, m.visRow - 1), y = Y(this._wm, w, Math.min(m.colInSeg, (((_ = this._wm.visualRows[w]) == null ? void 0 : _.text) ?? "").length));
|
|
4363
|
+
d(y.row, y.col);
|
|
4364
|
+
} else {
|
|
4365
|
+
const m = Math.max(0, r.row - 1);
|
|
4366
|
+
d(m, Math.min(r.col, (n[m] ?? "").length));
|
|
4367
|
+
}
|
|
4368
|
+
break;
|
|
4369
|
+
case "Home":
|
|
4370
|
+
e.preventDefault(), a ? d(0, 0) : d(r.row, h(r.row));
|
|
4371
|
+
break;
|
|
4372
|
+
case "End":
|
|
4373
|
+
if (e.preventDefault(), a) {
|
|
4374
|
+
const m = p();
|
|
4375
|
+
d(m.row, m.col);
|
|
4376
|
+
} else
|
|
4377
|
+
d(r.row, (n[r.row] ?? "").length);
|
|
4378
|
+
break;
|
|
4379
|
+
case "PageDown":
|
|
4380
|
+
e.preventDefault();
|
|
4381
|
+
{
|
|
4382
|
+
const m = Math.max(1, Math.floor(this._editorEl.clientHeight / o) - 1), w = Math.min(n.length - 1, r.row + m);
|
|
4383
|
+
d(w, Math.min(r.col, (n[w] ?? "").length)), this._editorEl.scrollTop += this._editorEl.clientHeight - o;
|
|
4384
|
+
break;
|
|
4385
|
+
}
|
|
4386
|
+
case "PageUp":
|
|
4387
|
+
e.preventDefault();
|
|
4388
|
+
{
|
|
4389
|
+
const m = Math.max(1, Math.floor(this._editorEl.clientHeight / o) - 1), w = Math.max(0, r.row - m);
|
|
4390
|
+
d(w, Math.min(r.col, (n[w] ?? "").length)), this._editorEl.scrollTop -= this._editorEl.clientHeight - o;
|
|
4391
|
+
break;
|
|
4392
|
+
}
|
|
4393
|
+
default:
|
|
4394
|
+
return;
|
|
4395
|
+
}
|
|
4396
|
+
S(this._tab), this._scrollIntoView(), this._acHide(), (v = (b = this._config).onCursorChange) == null || v.call(b, { ...this._tab.cur }), (T = (u = this._config).onSelectionChange) == null || T.call(u, this._tab.sel ? { ...this._tab.sel } : null), this._render();
|
|
4397
|
+
}
|
|
4398
|
+
_isWordChar(e) {
|
|
4399
|
+
const t = this._config.wordSeparators;
|
|
4400
|
+
return t ? e.trim() !== "" && !t.includes(e) : /[\w$]/.test(e);
|
|
4401
|
+
}
|
|
4402
|
+
_wordSkipRight(e, t) {
|
|
4403
|
+
let i = t;
|
|
4404
|
+
const n = e.length;
|
|
4405
|
+
for (; i < n && /\s/.test(e[i]); ) i++;
|
|
4406
|
+
if (i >= n) return i;
|
|
4407
|
+
if (/\w/.test(e[i]))
|
|
4408
|
+
for (; i < n && /\w/.test(e[i]); ) i++;
|
|
4409
|
+
else
|
|
4410
|
+
for (; i < n && /[^\w\s]/.test(e[i]); ) i++;
|
|
4411
|
+
return i;
|
|
4412
|
+
}
|
|
4413
|
+
_wordSkipLeft(e, t) {
|
|
4414
|
+
let i = t;
|
|
4415
|
+
for (; i > 0 && /\s/.test(e[i - 1]); ) i--;
|
|
4416
|
+
if (i <= 0) return i;
|
|
4417
|
+
if (/\w/.test(e[i - 1]))
|
|
4418
|
+
for (; i > 0 && /\w/.test(e[i - 1]); ) i--;
|
|
4419
|
+
else
|
|
4420
|
+
for (; i > 0 && /[^\w\s]/.test(e[i - 1]); ) i--;
|
|
4421
|
+
return i;
|
|
4422
|
+
}
|
|
4423
|
+
// ── Move lines ────────────────────────────────────────────
|
|
4424
|
+
_duplicateLines(e) {
|
|
4425
|
+
var a, c, d, h;
|
|
4426
|
+
const { doc: t, cur: i } = this._tab, n = this._tab.sel;
|
|
4427
|
+
let r = i.row, o = i.row;
|
|
4428
|
+
if (n) {
|
|
4429
|
+
const p = $(n);
|
|
4430
|
+
r = p.ar, o = p.fr, p.fc === 0 && p.fr > p.ar && o--;
|
|
4431
|
+
}
|
|
4432
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
4433
|
+
const l = t.slice(r, o + 1);
|
|
4434
|
+
e ? (t.splice(o + 1, 0, ...l), i.row += l.length, n && (n.ar += l.length, n.fr += l.length)) : t.splice(r, 0, ...l), this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (c = (a = this._config).onChange) == null || c.call(a, A(this._tab.doc)), (h = (d = this._config).onCursorChange) == null || h.call(d, { ...this._tab.cur });
|
|
4435
|
+
}
|
|
4436
|
+
_moveLines(e) {
|
|
4437
|
+
var l, a, c, d;
|
|
4438
|
+
const { doc: t, cur: i } = this._tab, n = this._tab.sel;
|
|
4439
|
+
let r = i.row, o = i.row;
|
|
4440
|
+
if (n) {
|
|
4441
|
+
const h = $(n);
|
|
4442
|
+
r = h.ar, o = h.fr, h.fc === 0 && h.fr > h.ar && o--;
|
|
4443
|
+
}
|
|
4444
|
+
if (e) {
|
|
4445
|
+
if (r === 0) return;
|
|
4446
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
4447
|
+
const h = t.splice(r, o - r + 1);
|
|
4448
|
+
t.splice(r - 1, 0, ...h), i.row--, n && (n.ar--, n.fr--);
|
|
4449
|
+
} else {
|
|
4450
|
+
if (o >= t.length - 1) return;
|
|
4451
|
+
L(this._tab, this._config.maxUndoHistory);
|
|
4452
|
+
const h = t.splice(r, o - r + 1);
|
|
4453
|
+
t.splice(r + 1, 0, ...h), i.row++, n && (n.ar++, n.fr++);
|
|
4454
|
+
}
|
|
4455
|
+
this._tab.dirty = !0, this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), (a = (l = this._config).onChange) == null || a.call(l, A(this._tab.doc)), (d = (c = this._config).onCursorChange) == null || d.call(c, { ...this._tab.cur });
|
|
4456
|
+
}
|
|
4457
|
+
// ── Hover documentation ────────────────────────────────────
|
|
4458
|
+
_scheduleHover(e) {
|
|
4459
|
+
this._hoverTip.style.display !== "none" && (this._hoverTip.style.display = "none"), this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null);
|
|
4460
|
+
const { clientX: t, clientY: i } = e;
|
|
4461
|
+
this._hoverTimer = setTimeout(() => {
|
|
4462
|
+
this._hoverTimer = null, this._doHover(t, i);
|
|
4463
|
+
}, 500);
|
|
4464
|
+
}
|
|
4465
|
+
_doHover(e, t) {
|
|
4466
|
+
var _, b, v;
|
|
4467
|
+
if (!this._config.hover) return;
|
|
4468
|
+
const i = this._editorEl.getBoundingClientRect(), n = t - i.top + this._editorEl.scrollTop, r = this._config.showGutter ? this._config.gutterWidth : 0, o = e - i.left - r - 14, l = this._config.lineHeight, a = Math.max(0, Math.min(this._wm.visualRows.length - 1, Math.floor(n / l))), c = Math.max(0, Math.min(
|
|
4469
|
+
(((_ = this._wm.visualRows[a]) == null ? void 0 : _.text) ?? "").length,
|
|
4470
|
+
Math.round(o / 7.82)
|
|
4471
|
+
)), d = Y(this._wm, a, c), h = this._tab.doc[d.row] ?? "", p = At(h, d.col);
|
|
4472
|
+
if (!p) return;
|
|
4473
|
+
let f = Ht(p, this._config.language);
|
|
4474
|
+
if (!f) {
|
|
4475
|
+
const u = this._config.completions.find((T) => T.label === p);
|
|
4476
|
+
u && (u.description || u.detail) && (f = {
|
|
4477
|
+
title: u.label,
|
|
4478
|
+
type: u.detail,
|
|
4479
|
+
body: u.description ?? ""
|
|
4480
|
+
});
|
|
4481
|
+
}
|
|
4482
|
+
if (!f) {
|
|
4483
|
+
const u = (v = (b = this._config).provideHover) == null ? void 0 : v.call(b, {
|
|
4484
|
+
word: p,
|
|
4485
|
+
row: d.row,
|
|
4486
|
+
col: d.col,
|
|
4487
|
+
line: h,
|
|
4488
|
+
language: this._config.language,
|
|
4489
|
+
doc: this._tab.doc
|
|
4490
|
+
});
|
|
4491
|
+
u && (f = u);
|
|
4492
|
+
}
|
|
4493
|
+
f && this._showHoverTip(f, e, t);
|
|
4494
|
+
}
|
|
4495
|
+
_showHoverTip(e, t, i) {
|
|
4496
|
+
const n = this._hoverTip;
|
|
4497
|
+
let r = '<div class="sl-ht-sig">';
|
|
4498
|
+
r += `<span class="sl-ht-title">${V(e.title)}</span>`, e.type && (r += `<code class="sl-ht-type">${V(e.type)}</code>`), r += "</div>", e.title && e.body && (r += '<div class="sl-ht-divider"></div>'), e.body && (r += `<div class="sl-ht-body">${V(e.body)}</div>`), n.innerHTML = r, n.style.display = "block";
|
|
4499
|
+
const o = 12, l = 18, a = n.offsetWidth || 300, c = n.offsetHeight || 80;
|
|
4500
|
+
let d = t, h = i + l;
|
|
4501
|
+
h + c > window.innerHeight - o && (h = i - c - 8), d + a > window.innerWidth - o && (d = window.innerWidth - a - o), d < o && (d = o), n.style.left = `${d}px`, n.style.top = `${Math.max(o, h)}px`;
|
|
4502
|
+
}
|
|
4503
|
+
_hideHover() {
|
|
4504
|
+
this._hoverTimer !== null && (clearTimeout(this._hoverTimer), this._hoverTimer = null), this._hoverPinned = !1, this._hoverTip.style.display = "none";
|
|
4505
|
+
}
|
|
4506
|
+
_onInput(e) {
|
|
4507
|
+
var r, o, l, a;
|
|
4508
|
+
if (this._config.readOnly) {
|
|
4509
|
+
e.target.value = "";
|
|
4510
|
+
return;
|
|
4511
|
+
}
|
|
4512
|
+
const t = e.target, i = t.value;
|
|
4513
|
+
if (t.value = "", !i || i === "Ω") return;
|
|
4514
|
+
const n = i.replace(/[\x00-\x08\x0a-\x1f\x7f]/g, "");
|
|
4515
|
+
if (n) {
|
|
4516
|
+
if (this._extraCursors.length) {
|
|
4517
|
+
this._snippetSession = null;
|
|
4518
|
+
const c = _t(
|
|
4519
|
+
this._tab.doc,
|
|
4520
|
+
this._tab.cur.row,
|
|
4521
|
+
this._tab.cur.col,
|
|
4522
|
+
this._extraCursors,
|
|
4523
|
+
n
|
|
4524
|
+
);
|
|
4525
|
+
this._tab.doc = c.doc, this._tab.cur.row = c.primaryRow, this._tab.cur.col = c.primaryCol, this._extraCursors = c.extraCursors, this._mc.cursors = c.extraCursors, this._tab.dirty = !0, (o = (r = this._config).onChange) == null || o.call(r, A(this._tab.doc));
|
|
4526
|
+
} else {
|
|
4527
|
+
const c = this._tab.cur.row, d = this._tab.cur.col;
|
|
4528
|
+
if (this._insertStr(n, !0), this._snippetSession) {
|
|
4529
|
+
const h = this._snippetSession, p = h.stops[h.idx];
|
|
4530
|
+
if (this._tab.cur.row === p.row) {
|
|
4531
|
+
const f = this._tab.cur.col - d;
|
|
4532
|
+
for (let _ = h.idx + 1; _ < h.stops.length; _++) {
|
|
4533
|
+
const b = h.stops[_];
|
|
4534
|
+
b.row === c && b.col >= d && (b.col += f);
|
|
4535
|
+
}
|
|
4536
|
+
p.col = this._tab.cur.col;
|
|
4537
|
+
} else
|
|
4538
|
+
this._snippetSession = null;
|
|
4539
|
+
}
|
|
4540
|
+
}
|
|
4541
|
+
this._tokenCache.clear(), this._rebuildWrapMap(), S(this._tab), this._scrollIntoView(), this._render(), this._acTrigger(), this._emmetCheck(), this._snippetCheck(), (a = (l = this._config).onCursorChange) == null || a.call(l, { ...this._tab.cur });
|
|
4542
|
+
}
|
|
4543
|
+
}
|
|
4544
|
+
_ctrlD() {
|
|
4545
|
+
if (!this._config.multiCursor) return;
|
|
4546
|
+
const e = vt(
|
|
4547
|
+
this._mc,
|
|
4548
|
+
this._tab.doc,
|
|
4549
|
+
this._tab.cur.row,
|
|
4550
|
+
this._tab.cur.col,
|
|
4551
|
+
this._tab.sel
|
|
4552
|
+
);
|
|
4553
|
+
e && (!this._mc.cursors.length || e.word !== this._mc.searchWord ? (this._tab.sel = e.sel, this._tab.cur.col = e.col) : (ke(this._mc, e.row, e.col, e.sel), this._extraCursors = [...this._mc.cursors]), this._mc.searchWord = e.word, this._mc.lastMatchRow = e.row, this._mc.lastMatchCol = e.col, this._scrollIntoView(), this._render());
|
|
4554
|
+
}
|
|
4555
|
+
// ── Find event binding ────────────────────────────────────
|
|
4556
|
+
_bindFindEvents() {
|
|
4557
|
+
var e, t, i, n, r, o, l;
|
|
4558
|
+
this._findInput.addEventListener("input", () => {
|
|
4559
|
+
this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
|
|
4560
|
+
}), this._findInput.addEventListener("keydown", (a) => {
|
|
4561
|
+
a.key === "Enter" ? a.shiftKey ? this._navFind(-1) : this._navFind(1) : a.key === "Escape" && this._closeFind(), a.stopPropagation();
|
|
4562
|
+
}), this._replaceInput.addEventListener("keydown", (a) => {
|
|
4563
|
+
a.key === "Enter" ? this._doReplaceOne() : a.key === "Escape" && this._closeFind(), a.stopPropagation();
|
|
4564
|
+
}), (e = this._findBar.querySelector(".sl-find-prev")) == null || e.addEventListener("click", () => this._navFind(-1)), (t = this._findBar.querySelector(".sl-find-next")) == null || t.addEventListener("click", () => this._navFind(1)), (i = this._findBar.querySelector(".sl-find-close")) == null || i.addEventListener("click", () => this._closeFind()), (n = this._findBar.querySelector(".sl-find-case")) == null || n.addEventListener("click", (a) => {
|
|
4565
|
+
this._findCaseSensitive = !this._findCaseSensitive, a.target.classList.toggle("sl-active", this._findCaseSensitive), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
|
|
4566
|
+
}), (r = this._findBar.querySelector(".sl-find-regex")) == null || r.addEventListener("click", (a) => {
|
|
4567
|
+
this._findRegex = !this._findRegex, a.target.classList.toggle("sl-active", this._findRegex), this._runFind(this._findInput.value), this._findIdx = -1, this._findMatches.length ? this._navFind(1) : (this._findCount.textContent = "0/0", this._render());
|
|
4568
|
+
}), (o = this._findBar.querySelector(".sl-replace-one")) == null || o.addEventListener("click", () => this._doReplaceOne()), (l = this._findBar.querySelector(".sl-replace-all")) == null || l.addEventListener("click", () => this._doReplaceAll());
|
|
4569
|
+
}
|
|
4570
|
+
_doReplaceOne() {
|
|
4571
|
+
var e, t;
|
|
4572
|
+
this._findIdx < 0 || !this._findMatches.length || (L(this._tab, this._config.maxUndoHistory), this._tab.doc = kt(this._tab.doc, this._findMatches, this._findIdx, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._runFind(this._findInput.value), this._findMatches.length ? (this._findIdx >= this._findMatches.length && (this._findIdx = 0), this._navFind(0)) : (this._findCount.textContent = "0/0", this._rebuildWrapMap(), this._render()), (t = (e = this._config).onChange) == null || t.call(e, A(this._tab.doc)));
|
|
4573
|
+
}
|
|
4574
|
+
_doReplaceAll() {
|
|
4575
|
+
var t, i;
|
|
4576
|
+
if (!this._findMatches.length) return;
|
|
4577
|
+
const e = this._findMatches.length;
|
|
4578
|
+
L(this._tab, this._config.maxUndoHistory), this._tab.doc = xt(this._tab.doc, this._findMatches, this._replaceInput.value), this._tokenCache.clear(), this._tab.dirty = !0, this._findMatches = [], this._findIdx = -1, this._findCount.textContent = `0/0 (${e} replaced)`, this._rebuildWrapMap(), this._render(), (i = (t = this._config).onChange) == null || i.call(t, A(this._tab.doc));
|
|
4579
|
+
}
|
|
4580
|
+
// ── Minimap events ────────────────────────────────────────
|
|
4581
|
+
_bindMinimapEvents() {
|
|
4582
|
+
const e = this._minimapWrap;
|
|
4583
|
+
e.addEventListener("mousemove", (t) => {
|
|
4584
|
+
if (this._mmDragMode !== "none") return;
|
|
4585
|
+
const i = t.clientY - e.getBoundingClientRect().top, { sliderTop: n, sliderHeight: r } = ie(
|
|
4586
|
+
this._tab.doc.length,
|
|
4587
|
+
this._editorEl.scrollTop,
|
|
4588
|
+
this._editorEl.clientHeight,
|
|
4589
|
+
e.clientHeight,
|
|
4590
|
+
this._config.lineHeight
|
|
4591
|
+
);
|
|
4592
|
+
e.style.cursor = i >= n && i <= n + r ? "grab" : "pointer";
|
|
4593
|
+
}), e.addEventListener("mousedown", (t) => {
|
|
4594
|
+
t.preventDefault();
|
|
4595
|
+
const i = e.clientHeight, n = t.clientY - e.getBoundingClientRect().top, { sliderTop: r, sliderHeight: o } = ie(
|
|
4596
|
+
this._tab.doc.length,
|
|
4597
|
+
this._editorEl.scrollTop,
|
|
4598
|
+
this._editorEl.clientHeight,
|
|
4599
|
+
i,
|
|
4600
|
+
this._config.lineHeight
|
|
4601
|
+
);
|
|
4602
|
+
if (n >= r && n <= r + o)
|
|
4603
|
+
this._mmDragMode = "slider", this._mmSliderOffset = n - r, this._mmDragStartY = t.clientY, this._mmDragStartScroll = this._editorEl.scrollTop, e.style.cursor = "grabbing";
|
|
4604
|
+
else {
|
|
4605
|
+
this._mmDragMode = "jump";
|
|
4606
|
+
const l = Nt(
|
|
4607
|
+
n,
|
|
4608
|
+
this._tab.doc.length,
|
|
4609
|
+
this._editorEl.scrollTop,
|
|
4610
|
+
this._editorEl.clientHeight,
|
|
4611
|
+
i,
|
|
4612
|
+
this._config.lineHeight
|
|
4613
|
+
);
|
|
4614
|
+
this._editorEl.scrollTop = l, this._mmDragStartY = t.clientY, this._mmDragStartScroll = l, this._render();
|
|
4615
|
+
}
|
|
4616
|
+
}), window.addEventListener("mousemove", this._onWinMmMouseMove), window.addEventListener("mouseup", this._onWinMmMouseUp);
|
|
4617
|
+
}
|
|
4618
|
+
}
|
|
4619
|
+
function zt(s, e) {
|
|
4620
|
+
return new Ut(s, e);
|
|
4621
|
+
}
|
|
4622
|
+
export {
|
|
4623
|
+
tt as BUILT_IN_THEMES,
|
|
4624
|
+
Ut as SynclineEditor,
|
|
4625
|
+
Je as THEME_DRACULA,
|
|
4626
|
+
Xe as THEME_GITHUB_LIGHT,
|
|
4627
|
+
Qe as THEME_MDX_DARK,
|
|
4628
|
+
et as THEME_MDX_LIGHT,
|
|
4629
|
+
Ye as THEME_MONOKAI,
|
|
4630
|
+
Ze as THEME_SOLARIZED_LIGHT,
|
|
4631
|
+
Ke as THEME_VR_DARK,
|
|
4632
|
+
Ve as THEME_VSCODE_DARK,
|
|
4633
|
+
zt as createEditor
|
|
4634
|
+
};
|
|
4635
|
+
//# sourceMappingURL=syncline-editor.es.js.map
|