@libs-ui/components-preview-text-data 0.2.357-1 → 0.2.357-10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,65 @@
1
+ import { syntaxTree } from '@codemirror/language';
2
+ import { linter } from '@codemirror/lint';
3
+ import { EditorState, Transaction } from '@codemirror/state';
4
+ const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
5
+ const toGlobalRegex = (pattern) => {
6
+ if (pattern instanceof RegExp) {
7
+ const flags = pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`;
8
+ return new RegExp(pattern.source, flags);
9
+ }
10
+ return new RegExp(escapeRegex(pattern), 'gi');
11
+ };
12
+ /**
13
+ * Extension bảo mật gồm 2 layer:
14
+ * 1. Linter: highlight đỏ tại đúng vị trí match (bỏ qua match trong comment) + gọi `emitViolations`.
15
+ * 2. Transaction filter: chặn paste nếu nội dung paste chứa pattern cấm.
16
+ */
17
+ export const buildForbiddenExtension = (patterns, emitViolations) => {
18
+ const forbiddenLinter = linter((view) => {
19
+ const diagnostics = [];
20
+ const violations = [];
21
+ const text = view.state.doc.toString();
22
+ const commentRanges = [];
23
+ syntaxTree(view.state).iterate({
24
+ enter: (node) => {
25
+ if (node.type.name.toLowerCase().includes('comment')) {
26
+ commentRanges.push({ from: node.from, to: node.to });
27
+ }
28
+ },
29
+ });
30
+ const isInComment = (from, to) => commentRanges.some((r) => from >= r.from && to <= r.to);
31
+ for (const pattern of patterns) {
32
+ const re = toGlobalRegex(pattern);
33
+ re.lastIndex = 0;
34
+ let match;
35
+ while ((match = re.exec(text)) !== null) {
36
+ const from = match.index;
37
+ const to = from + match[0].length;
38
+ if (isInComment(from, to))
39
+ continue;
40
+ const line = view.state.doc.lineAt(from).number;
41
+ const patternLabel = pattern instanceof RegExp ? pattern.source : pattern;
42
+ diagnostics.push({ from, to, severity: 'error', message: `Mã bị cấm: "${match[0]}" — vi phạm chính sách bảo mật` });
43
+ violations.push({ from, to, line, pattern: patternLabel, matched: match[0] });
44
+ }
45
+ }
46
+ emitViolations(violations);
47
+ return diagnostics;
48
+ });
49
+ const pasteFilter = EditorState.transactionFilter.of((tr) => {
50
+ if (!tr.docChanged)
51
+ return tr;
52
+ if (!tr.annotation(Transaction.userEvent)?.startsWith('input.paste'))
53
+ return tr;
54
+ const newText = tr.newDoc.toString();
55
+ for (const pattern of patterns) {
56
+ const re = toGlobalRegex(pattern);
57
+ re.lastIndex = 0;
58
+ if (re.test(newText))
59
+ return [];
60
+ }
61
+ return tr;
62
+ });
63
+ return [forbiddenLinter, pasteFilter];
64
+ };
65
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLWZvcmJpZGRlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvZWRpdG9yL2VkaXRvci1mb3JiaWRkZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBYyxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFhLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBSXhFLE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBVyxFQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBRXhGLE1BQU0sYUFBYSxHQUFHLENBQUMsT0FBMkIsRUFBVSxFQUFFO0lBQzVELElBQUksT0FBTyxZQUFZLE1BQU0sRUFBRSxDQUFDO1FBQzlCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQztRQUNoRixPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUNELE9BQU8sSUFBSSxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2hELENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLFFBQThCLEVBQUUsY0FBaUUsRUFBYSxFQUFFO0lBQ3RKLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ3RDLE1BQU0sV0FBVyxHQUFpQixFQUFFLENBQUM7UUFDckMsTUFBTSxVQUFVLEdBQWdDLEVBQUUsQ0FBQztRQUNuRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUV2QyxNQUFNLGFBQWEsR0FBbUMsRUFBRSxDQUFDO1FBQ3pELFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzdCLEtBQUssRUFBRSxDQUFDLElBQW1CLEVBQUUsRUFBRTtnQkFDN0IsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztvQkFDckQsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDdkQsQ0FBQztZQUNILENBQUM7U0FDRixDQUFDLENBQUM7UUFDSCxNQUFNLFdBQVcsR0FBRyxDQUFDLElBQVksRUFBRSxFQUFVLEVBQVcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFbkgsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEMsRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7WUFDakIsSUFBSSxLQUE2QixDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUN4QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO2dCQUN6QixNQUFNLEVBQUUsR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDbEMsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztvQkFBRSxTQUFTO2dCQUNwQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUNoRCxNQUFNLFlBQVksR0FBRyxPQUFPLFlBQVksTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQzFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGVBQWUsS0FBSyxDQUFDLENBQUMsQ0FBQyxnQ0FBZ0MsRUFBRSxDQUFDLENBQUM7Z0JBQ3BILFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7UUFDSCxDQUFDO1FBRUQsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNCLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQWUsRUFBRSxFQUFFO1FBQ3ZFLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsRUFBRSxVQUFVLENBQUMsYUFBYSxDQUFDO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDaEYsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNyQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQy9CLE1BQU0sRUFBRSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNsQyxFQUFFLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztZQUNqQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ2xDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxDQUFDLGVBQWUsRUFBRSxXQUFXLENBQUMsQ0FBQztBQUN4QyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzeW50YXhUcmVlIH0gZnJvbSAnQGNvZGVtaXJyb3IvbGFuZ3VhZ2UnO1xuaW1wb3J0IHsgRGlhZ25vc3RpYywgbGludGVyIH0gZnJvbSAnQGNvZGVtaXJyb3IvbGludCc7XG5pbXBvcnQgeyBFZGl0b3JTdGF0ZSwgRXh0ZW5zaW9uLCBUcmFuc2FjdGlvbiB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcbmltcG9ydCB0eXBlIHsgU3ludGF4Tm9kZVJlZiB9IGZyb20gJ0BsZXplci9jb21tb24nO1xuaW1wb3J0IHsgSVByZXZpZXdUZXh0RGF0YVZpb2xhdGlvbiwgVF9Gb3JiaWRkZW5QYXR0ZXJuIH0gZnJvbSAnLi4vcHJldmlldy10ZXh0LWRhdGEuaW50ZXJmYWNlcyc7XG5cbmNvbnN0IGVzY2FwZVJlZ2V4ID0gKHN0cjogc3RyaW5nKTogc3RyaW5nID0+IHN0ci5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpO1xuXG5jb25zdCB0b0dsb2JhbFJlZ2V4ID0gKHBhdHRlcm46IFRfRm9yYmlkZGVuUGF0dGVybik6IFJlZ0V4cCA9PiB7XG4gIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgY29uc3QgZmxhZ3MgPSBwYXR0ZXJuLmZsYWdzLmluY2x1ZGVzKCdnJykgPyBwYXR0ZXJuLmZsYWdzIDogYCR7cGF0dGVybi5mbGFnc31nYDtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChwYXR0ZXJuLnNvdXJjZSwgZmxhZ3MpO1xuICB9XG4gIHJldHVybiBuZXcgUmVnRXhwKGVzY2FwZVJlZ2V4KHBhdHRlcm4pLCAnZ2knKTtcbn07XG5cbi8qKlxuICogRXh0ZW5zaW9uIGLhuqNvIG3huq10IGfhu5NtIDIgbGF5ZXI6XG4gKiAxLiBMaW50ZXI6IGhpZ2hsaWdodCDEkeG7jyB04bqhaSDEkcO6bmcgduG7iyB0csOtIG1hdGNoIChi4buPIHF1YSBtYXRjaCB0cm9uZyBjb21tZW50KSArIGfhu41pIGBlbWl0VmlvbGF0aW9uc2AuXG4gKiAyLiBUcmFuc2FjdGlvbiBmaWx0ZXI6IGNo4bq3biBwYXN0ZSBu4bq/dSBu4buZaSBkdW5nIHBhc3RlIGNo4bupYSBwYXR0ZXJuIGPhuqVtLlxuICovXG5leHBvcnQgY29uc3QgYnVpbGRGb3JiaWRkZW5FeHRlbnNpb24gPSAocGF0dGVybnM6IFRfRm9yYmlkZGVuUGF0dGVybltdLCBlbWl0VmlvbGF0aW9uczogKHZpb2xhdGlvbnM6IElQcmV2aWV3VGV4dERhdGFWaW9sYXRpb25bXSkgPT4gdm9pZCk6IEV4dGVuc2lvbiA9PiB7XG4gIGNvbnN0IGZvcmJpZGRlbkxpbnRlciA9IGxpbnRlcigodmlldykgPT4ge1xuICAgIGNvbnN0IGRpYWdub3N0aWNzOiBEaWFnbm9zdGljW10gPSBbXTtcbiAgICBjb25zdCB2aW9sYXRpb25zOiBJUHJldmlld1RleHREYXRhVmlvbGF0aW9uW10gPSBbXTtcbiAgICBjb25zdCB0ZXh0ID0gdmlldy5zdGF0ZS5kb2MudG9TdHJpbmcoKTtcblxuICAgIGNvbnN0IGNvbW1lbnRSYW5nZXM6IHsgZnJvbTogbnVtYmVyOyB0bzogbnVtYmVyIH1bXSA9IFtdO1xuICAgIHN5bnRheFRyZWUodmlldy5zdGF0ZSkuaXRlcmF0ZSh7XG4gICAgICBlbnRlcjogKG5vZGU6IFN5bnRheE5vZGVSZWYpID0+IHtcbiAgICAgICAgaWYgKG5vZGUudHlwZS5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2NvbW1lbnQnKSkge1xuICAgICAgICAgIGNvbW1lbnRSYW5nZXMucHVzaCh7IGZyb206IG5vZGUuZnJvbSwgdG86IG5vZGUudG8gfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY29uc3QgaXNJbkNvbW1lbnQgPSAoZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyKTogYm9vbGVhbiA9PiBjb21tZW50UmFuZ2VzLnNvbWUoKHIpID0+IGZyb20gPj0gci5mcm9tICYmIHRvIDw9IHIudG8pO1xuXG4gICAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIHBhdHRlcm5zKSB7XG4gICAgICBjb25zdCByZSA9IHRvR2xvYmFsUmVnZXgocGF0dGVybik7XG4gICAgICByZS5sYXN0SW5kZXggPSAwO1xuICAgICAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICAgICAgd2hpbGUgKChtYXRjaCA9IHJlLmV4ZWModGV4dCkpICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGZyb20gPSBtYXRjaC5pbmRleDtcbiAgICAgICAgY29uc3QgdG8gPSBmcm9tICsgbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICBpZiAoaXNJbkNvbW1lbnQoZnJvbSwgdG8pKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgbGluZSA9IHZpZXcuc3RhdGUuZG9jLmxpbmVBdChmcm9tKS5udW1iZXI7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5MYWJlbCA9IHBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHAgPyBwYXR0ZXJuLnNvdXJjZSA6IHBhdHRlcm47XG4gICAgICAgIGRpYWdub3N0aWNzLnB1c2goeyBmcm9tLCB0bywgc2V2ZXJpdHk6ICdlcnJvcicsIG1lc3NhZ2U6IGBNw6MgYuG7iyBj4bqlbTogXCIke21hdGNoWzBdfVwiIOKAlCB2aSBwaOG6oW0gY2jDrW5oIHPDoWNoIGLhuqNvIG3huq10YCB9KTtcbiAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHsgZnJvbSwgdG8sIGxpbmUsIHBhdHRlcm46IHBhdHRlcm5MYWJlbCwgbWF0Y2hlZDogbWF0Y2hbMF0gfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZW1pdFZpb2xhdGlvbnModmlvbGF0aW9ucyk7XG4gICAgcmV0dXJuIGRpYWdub3N0aWNzO1xuICB9KTtcblxuICBjb25zdCBwYXN0ZUZpbHRlciA9IEVkaXRvclN0YXRlLnRyYW5zYWN0aW9uRmlsdGVyLm9mKCh0cjogVHJhbnNhY3Rpb24pID0+IHtcbiAgICBpZiAoIXRyLmRvY0NoYW5nZWQpIHJldHVybiB0cjtcbiAgICBpZiAoIXRyLmFubm90YXRpb24oVHJhbnNhY3Rpb24udXNlckV2ZW50KT8uc3RhcnRzV2l0aCgnaW5wdXQucGFzdGUnKSkgcmV0dXJuIHRyO1xuICAgIGNvbnN0IG5ld1RleHQgPSB0ci5uZXdEb2MudG9TdHJpbmcoKTtcbiAgICBmb3IgKGNvbnN0IHBhdHRlcm4gb2YgcGF0dGVybnMpIHtcbiAgICAgIGNvbnN0IHJlID0gdG9HbG9iYWxSZWdleChwYXR0ZXJuKTtcbiAgICAgIHJlLmxhc3RJbmRleCA9IDA7XG4gICAgICBpZiAocmUudGVzdChuZXdUZXh0KSkgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gdHI7XG4gIH0pO1xuXG4gIHJldHVybiBbZm9yYmlkZGVuTGludGVyLCBwYXN0ZUZpbHRlcl07XG59O1xuIl19
@@ -0,0 +1,87 @@
1
+ /** Parse giá trị CSS px → number. Trả về undefined nếu không phải px hợp lệ (vd `none`, `0`). */
2
+ export const parsePx = (raw) => {
3
+ if (!raw || !raw.endsWith('px')) {
4
+ return undefined;
5
+ }
6
+ const value = parseFloat(raw);
7
+ return Number.isFinite(value) && value > 0 ? value : undefined;
8
+ };
9
+ /** Bù dòng trống cho đủ `minLines` (xử lý 1 lần khi khởi tạo). Đủ rồi giữ nguyên, không cắt bớt. */
10
+ export const applyMinLines = (content, minLines) => {
11
+ const value = content ?? '';
12
+ if (!minLines || minLines <= 0) {
13
+ return value;
14
+ }
15
+ const currentLines = value === '' ? 1 : value.split('\n').length;
16
+ if (currentLines >= minLines) {
17
+ return value;
18
+ }
19
+ return value + '\n'.repeat(minLines - currentLines);
20
+ };
21
+ /**
22
+ * Tính min/max-height vùng cuộn theo CSS của container ngoài, snap về bội số dòng.
23
+ * Trừ offset phần header/toolbar (giữa đỉnh container và đỉnh vùng cuộn) để vừa khít container.
24
+ */
25
+ export const applyContainerHeight = (view, container) => {
26
+ const style = getComputedStyle(container);
27
+ const minPx = parsePx(style.minHeight);
28
+ const maxPx = parsePx(style.maxHeight);
29
+ if (minPx === undefined && maxPx === undefined) {
30
+ return;
31
+ }
32
+ view.requestMeasure({
33
+ read: (measureView) => {
34
+ const line = measureView.contentDOM.querySelector('.cm-line');
35
+ const lineHeight = (line ? line.getBoundingClientRect().height : measureView.defaultLineHeight) || 20;
36
+ const offsetTop = Math.max(measureView.scrollDOM.getBoundingClientRect().top - container.getBoundingClientRect().top, 0);
37
+ const toLines = (px) => Math.max(1, Math.floor((px - offsetTop - 8) / lineHeight));
38
+ return { lineHeight, minLines: minPx === undefined ? undefined : toLines(minPx), maxLines: maxPx === undefined ? undefined : toLines(maxPx) };
39
+ },
40
+ write: ({ lineHeight, minLines, maxLines }, writeView) => {
41
+ if (maxLines !== undefined) {
42
+ writeView.scrollDOM.style.maxHeight = `${maxLines * lineHeight + 8}px`;
43
+ writeView.scrollDOM.style.overflowY = 'auto';
44
+ }
45
+ // min-height: bù dòng trống vào content (hiện đủ line-number 1..N), giống cơ chế minLines.
46
+ if (minLines !== undefined) {
47
+ const currentLines = writeView.state.doc.lines;
48
+ if (currentLines < minLines) {
49
+ queueMicrotask(() => writeView.dispatch({ changes: { from: writeView.state.doc.length, insert: '\n'.repeat(minLines - currentLines) } }));
50
+ }
51
+ }
52
+ },
53
+ });
54
+ };
55
+ /**
56
+ * Giới hạn chiều cao editor (xử lý 1 lần). 2 chế độ loại trừ nhau:
57
+ * - `maxLines`: cap theo số dòng truyền vào.
58
+ * - `container`: tự tính số dòng theo `min-height`/`max-height` (CSS) của container, snap bội số dòng.
59
+ * Cấu hình đồng thời `container` + `minLines`/`maxLines` → throw.
60
+ */
61
+ export const applyMaxHeight = (view, options) => {
62
+ const { minLines, maxLines, container } = options;
63
+ if (container && (minLines || maxLines)) {
64
+ throw new Error('[preview-text-data] CẤM cấu hình [containerElement] cùng [minLines]/[maxLines]. Container tự quản lý min/max height.');
65
+ }
66
+ if (!view) {
67
+ return;
68
+ }
69
+ if (container) {
70
+ applyContainerHeight(view, container);
71
+ return;
72
+ }
73
+ if (!maxLines || maxLines <= 0) {
74
+ return;
75
+ }
76
+ view.requestMeasure({
77
+ read: (measureView) => {
78
+ const line = measureView.contentDOM.querySelector('.cm-line');
79
+ return (line ? line.getBoundingClientRect().height : measureView.defaultLineHeight) || 20;
80
+ },
81
+ write: (lineHeight, writeView) => {
82
+ writeView.scrollDOM.style.maxHeight = `${maxLines * lineHeight + 8}px`;
83
+ writeView.scrollDOM.style.overflowY = 'auto';
84
+ },
85
+ });
86
+ };
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLWhlaWdodC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvZWRpdG9yL2VkaXRvci1oZWlnaHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsaUdBQWlHO0FBQ2pHLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQVcsRUFBc0IsRUFBRTtJQUN6RCxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2hDLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDOUIsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ2pFLENBQUMsQ0FBQztBQUVGLG9HQUFvRztBQUNwRyxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxPQUFlLEVBQUUsUUFBaUIsRUFBVSxFQUFFO0lBQzFFLE1BQU0sS0FBSyxHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFDNUIsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDL0IsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxZQUFZLEdBQUcsS0FBSyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNqRSxJQUFJLFlBQVksSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUM3QixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxPQUFPLEtB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U0FBUyxHQUFHLE1BQU0sQ0FBQztRQUMvQyxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuXG4vKiogUGFyc2UgZ2nDoSB0cuG7iyBDU1MgcHgg4oaSIG51bWJlci4gVHLhuqMgduG7gSB1bmRlZmluZWQgbuG6v3Uga2jDtG5nIHBo4bqjaSBweCBo4bujcCBs4buHICh2ZCBgbm9uZWAsIGAwYCkuICovXG5leHBvcnQgY29uc3QgcGFyc2VQeCA9IChyYXc6IHN0cmluZyk6IG51bWJlciB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmICghcmF3IHx8ICFyYXcuZW5kc1dpdGgoJ3B4JykpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHZhbHVlID0gcGFyc2VGbG9hdChyYXcpO1xuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+IDAgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn07XG5cbi8qKiBCw7kgZMOybmcgdHLhu5FuZyBjaG8gxJHhu6cgYG1pbkxpbmVzYCAoeOG7rSBsw70gMSBs4bqnbiBraGkga2jhu59pIHThuqFvKS4gxJDhu6cgcuG7k2kgZ2nhu68gbmd1ecOqbiwga2jDtG5nIGPhuq90IGLhu5t0LiAqL1xuZXhwb3J0IGNvbnN0IGFwcGx5TWluTGluZXMgPSAoY29udGVudDogc3RyaW5nLCBtaW5MaW5lcz86IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHZhbHVlID0gY29udGVudCA/PyAnJztcbiAgaWYgKCFtaW5MaW5lcyB8fCBtaW5MaW5lcyA8PSAwKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGNvbnN0IGN1cnJlbnRMaW5lcyA9IHZhbHVlID09PSAnJyA/IDEgOiB2YWx1ZS5zcGxpdCgnXFxuJykubGVuZ3RoO1xuICBpZiAoY3VycmVudExpbmVzID49IG1pbkxpbmVzKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJldHVybiB2YWx1ZSArICdcXG4nLnJlcGVhdChtaW5MaW5lcyAtIGN1cnJlbnRMaW5lcyk7XG59O1xuXG4vKipcbiAqIFTDrW5oIG1pbi9tYXgtaGVpZ2h0IHbDuW5nIGN14buZbiB0aGVvIENTUyBj4bunYSBjb250YWluZXIgbmdvw6BpLCBzbmFwIHbhu4EgYuG7mWkgc+G7kSBkw7JuZy5cbiAqIFRy4burIG9mZnNldCBwaOG6p24gaGVhZGVyL3Rvb2xiYXIgKGdp4buvYSDEkeG7iW5oIGNvbnRhaW5lciB2w6AgxJHhu4luaCB2w7luZyBjdeG7mW4pIMSR4buDIHbhu6thIGtow610IGNvbnRhaW5lci5cbiAqL1xuZXhwb3J0IGNvbnN0IGFwcGx5Q29udGFpbmVySGVpZ2h0ID0gKHZpZXc6IEVkaXRvclZpZXcsIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQpOiB2b2lkID0+IHtcbiAgY29uc3Qgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGNvbnRhaW5lcik7XG4gIGNvbnN0IG1pblB4ID0gcGFyc2VQeChzdHlsZS5taW5IZWlnaHQpO1xuICBjb25zdCBtYXhQeCA9IHBhcnNlUHgoc3R5bGUubWF4SGVpZ2h0KTtcbiAgaWYgKG1pblB4ID09PSB1bmRlZmluZWQgJiYgbWF4UHggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybjtcbiAgfVxuICB2aWV3LnJlcXVlc3RNZWFzdXJlKHtcbiAgICByZWFkOiAobWVhc3VyZVZpZXcpID0+IHtcbiAgICAgIGNvbnN0IGxpbmUgPSBtZWFzdXJlVmlldy5jb250ZW50RE9NLnF1ZXJ5U2VsZWN0b3IoJy5jbS1saW5lJyk7XG4gICAgICBjb25zdCBsaW5lSGVpZ2h0ID0gKGxpbmUgPyBsaW5lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCA6IG1lYXN1cmVWaWV3LmRlZmF1bHRMaW5lSGVpZ2h0KSB8fCAyMDtcbiAgICAgIGNvbnN0IG9mZnNldFRvcCA9IE1hdGgubWF4KG1lYXN1cmVWaWV3LnNjcm9sbERPTS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgLSBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wLCAwKTtcbiAgICAgIGNvbnN0IHRvTGluZXMgPSAocHg6IG51bWJlcikgPT4gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcigocHggLSBvZmZzZXRUb3AgLSA4KSAvIGxpbmVIZWlnaHQpKTtcbiAgICAgIHJldHVybiB7IGxpbmVIZWlnaHQsIG1pbkxpbmVzOiBtaW5QeCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdG9MaW5lcyhtaW5QeCksIG1heExpbmVzOiBtYXhQeCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogdG9MaW5lcyhtYXhQeCkgfTtcbiAgICB9LFxuICAgIHdyaXRlOiAoeyBsaW5lSGVpZ2h0LCBtaW5MaW5lcywgbWF4TGluZXMgfSwgd3JpdGVWaWV3KSA9PiB7XG4gICAgICBpZiAobWF4TGluZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB3cml0ZVZpZXcuc2Nyb2xsRE9NLnN0eWxlLm1heEhlaWdodCA9IGAke21heExpbmVzICogbGluZUhlaWdodCArIDh9cHhgO1xuICAgICAgICB3cml0ZVZpZXcuc2Nyb2xsRE9NLnN0eWxlLm92ZXJmbG93WSA9ICdhdXRvJztcbiAgICAgIH1cbiAgICAgIC8vIG1pbi1oZWlnaHQ6IGLDuSBkw7JuZyB0cuG7kW5nIHbDoG8gY29udGVudCAoaGnhu4duIMSR4bunIGxpbmUtbnVtYmVyIDEuLk4pLCBnaeG7kW5nIGPGoSBjaOG6vyBtaW5MaW5lcy5cbiAgICAgIGlmIChtaW5MaW5lcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRMaW5lcyA9IHdyaXRlVmlldy5zdGF0ZS5kb2MubGluZXM7XG4gICAgICAgIGlmIChjdXJyZW50TGluZXMgPCBtaW5MaW5lcykge1xuICAgICAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHdyaXRlVmlldy5kaXNwYXRjaCh7IGNoYW5nZXM6IHsgZnJvbTogd3JpdGVWaWV3LnN0YXRlLmRvYy5sZW5ndGgsIGluc2VydDogJ1xcbicucmVwZWF0KG1pbkxpbmVzIC0gY3VycmVudExpbmVzKSB9IH0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufTtcblxuLyoqXG4gKiBHaeG7m2kgaOG6oW4gY2hp4buBdSBjYW8gZWRpdG9yICh44butIGzDvSAxIGzhuqduKS4gMiBjaOG6vyDEkeG7mSBsb+G6oWkgdHLhu6sgbmhhdTpcbiAqIC0gYG1heExpbmVzYDogY2FwIHRoZW8gc+G7kSBkw7JuZyB0cnV54buBbiB2w6BvLlxuICogLSBgY29udGFpbmVyYDogdOG7sSB0w61uaCBz4buRIGTDsm5nIHRoZW8gYG1pbi1oZWlnaHRgL2BtYXgtaGVpZ2h0YCAoQ1NTKSBj4bunYSBjb250YWluZXIsIHNuYXAgYuG7mWkgc+G7kSBkw7JuZy5cbiAqIEPhuqV1IGjDrG5oIMSR4buTbmcgdGjhu51pIGBjb250YWluZXJgICsgYG1pbkxpbmVzYC9gbWF4TGluZXNgIOKGkiB0aHJvdy5cbiAqL1xuZXhwb3J0IGNvbnN0IGFwcGx5TWF4SGVpZ2h0ID0gKHZpZXc6IEVkaXRvclZpZXcgfCB1bmRlZmluZWQsIG9wdGlvbnM6IHsgbWluTGluZXM/OiBudW1iZXI7IG1heExpbmVzPzogbnVtYmVyOyBjb250YWluZXI/OiBIVE1MRWxlbWVudCB9KTogdm9pZCA9PiB7XG4gIGNvbnN0IHsgbWluTGluZXMsIG1heExpbmVzLCBjb250YWluZXIgfSA9IG9wdGlvbnM7XG4gIGlmIChjb250YWluZXIgJiYgKG1pbkxpbmVzIHx8IG1heExpbmVzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignW3ByZXZpZXctdGV4dC1kYXRhXSBD4bqkTSBj4bqldSBow6xuaCBbY29udGFpbmVyRWxlbWVudF0gY8O5bmcgW21pbkxpbmVzXS9bbWF4TGluZXNdLiBDb250YWluZXIgdOG7sSBxdeG6o24gbMO9IG1pbi9tYXggaGVpZ2h0LicpO1xuICB9XG4gIGlmICghdmlldykge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoY29udGFpbmVyKSB7XG4gICAgYXBwbHlDb250YWluZXJIZWlnaHQodmlldywgY29udGFpbmVyKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKCFtYXhMaW5lcyB8fCBtYXhMaW5lcyA8PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZpZXcucmVxdWVzdE1lYXN1cmUoe1xuICAgIHJlYWQ6IChtZWFzdXJlVmlldykgPT4ge1xuICAgICAgY29uc3QgbGluZSA9IG1lYXN1cmVWaWV3LmNvbnRlbnRET00ucXVlcnlTZWxlY3RvcignLmNtLWxpbmUnKTtcbiAgICAgIHJldHVybiAobGluZSA/IGxpbmUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0IDogbWVhc3VyZVZpZXcuZGVmYXVsdExpbmVIZWlnaHQpIHx8IDIwO1xuICAgIH0sXG4gICAgd3JpdGU6IChsaW5lSGVpZ2h0LCB3cml0ZVZpZXcpID0+IHtcbiAgICAgIHdyaXRlVmlldy5zY3JvbGxET00uc3R5bGUubWF4SGVpZ2h0ID0gYCR7bWF4TGluZXMgKiBsaW5lSGVpZ2h0ICsgOH1weGA7XG4gICAgICB3cml0ZVZpZXcuc2Nyb2xsRE9NLnN0eWxlLm92ZXJmbG93WSA9ICdhdXRvJztcbiAgICB9LFxuICB9KTtcbn07XG4iXX0=
@@ -0,0 +1,348 @@
1
+ import { get } from '@libs-ui/utils';
2
+ import { astSkipKeys, astTypeKeys, tsValueNodes } from '../preview-text-data.define';
3
+ import { getTokenBefore } from './linter-shared';
4
+ // Cache module-level (chia sẻ giữa các instance editor) — đều immutable, lazy-load 1 lần.
5
+ let babelParserModule;
6
+ let knownGlobalsSet;
7
+ /** Lazy-load + cache module @babel/parser (chỉ tải lần đầu khi lint JS/TS). */
8
+ const getBabelParser = async () => {
9
+ if (!babelParserModule) {
10
+ babelParserModule = await import('@babel/parser');
11
+ }
12
+ return babelParserModule;
13
+ };
14
+ /** Lazy-load + cache tập biến toàn cục JS/DOM hợp lệ từ package `globals` (JSON thuần, browser-safe). */
15
+ const getKnownGlobals = async () => {
16
+ if (!knownGlobalsSet) {
17
+ const globalsModule = (await import('globals'));
18
+ const globalsData = (globalsModule.default ?? globalsModule);
19
+ knownGlobalsSet = new Set([...Object.keys(globalsData['builtin'] ?? {}), ...Object.keys(globalsData['browser'] ?? {}), ...Object.keys(globalsData['es2021'] ?? {})]);
20
+ }
21
+ return knownGlobalsSet;
22
+ };
23
+ /**
24
+ * Parse code, trả về vừa danh sách lỗi cú pháp vừa AST (nếu parse sạch).
25
+ * `errorRecovery` gom nhiều lỗi vào `result.errors`; lỗi nặng vẫn `throw` → bắt thêm ở catch.
26
+ */
27
+ export const parseJs = (parser, code) => {
28
+ try {
29
+ const result = parser.parse(code, {
30
+ sourceType: 'module',
31
+ errorRecovery: true,
32
+ plugins: ['typescript', 'jsx'],
33
+ allowReturnOutsideFunction: true,
34
+ allowAwaitOutsideFunction: true,
35
+ allowImportExportEverywhere: true,
36
+ allowSuperOutsideMethod: true,
37
+ allowNewTargetOutsideFunction: true,
38
+ allowUndeclaredExports: true,
39
+ });
40
+ return { errors: result.errors, ast: result };
41
+ }
42
+ catch (error) {
43
+ const loc = get(error, 'loc');
44
+ const message = get(error, 'message') || 'JavaScript syntax error';
45
+ return { errors: [{ loc, message }] };
46
+ }
47
+ };
48
+ /** Giữ cho test/back-compat: chỉ lấy danh sách lỗi cú pháp. */
49
+ export const collectBabelErrors = (parser, code) => parseJs(parser, code).errors;
50
+ /**
51
+ * Quét text từng dòng, flag dấu "." cuối dòng (incomplete property access) tại ĐÚNG vị trí dấu chấm.
52
+ * Thu thập `taintedLines` (dòng có trailing dot) + `dotPositions` (offset dấu chấm để vá khi parse).
53
+ */
54
+ export const collectTrailingDotDiagnostics = (doc, diagnostics, taintedLines, dotPositions) => {
55
+ for (let lineNumber = 1; lineNumber <= doc.lines; lineNumber++) {
56
+ const line = doc.line(lineNumber);
57
+ const trimmed = line.text.trimEnd();
58
+ const match = /(\w+)\.\s*$/.exec(trimmed);
59
+ if (!match) {
60
+ continue;
61
+ }
62
+ taintedLines.add(lineNumber);
63
+ const dotPosition = line.from + trimmed.lastIndexOf('.');
64
+ dotPositions.push(dotPosition);
65
+ diagnostics.push({ from: dotPosition, to: dotPosition + 1, severity: 'error', message: `Incomplete property access on "${match[1]}"` });
66
+ }
67
+ };
68
+ /** Thay các ký tự tại `positions` bằng space, giữ nguyên độ dài chuỗi (để offset không đổi). */
69
+ const replaceCharsWithSpace = (code, positions) => {
70
+ if (!positions.length) {
71
+ return code;
72
+ }
73
+ const chars = code.split('');
74
+ for (const position of positions) {
75
+ if (position >= 0 && position < chars.length) {
76
+ chars[position] = ' ';
77
+ }
78
+ }
79
+ return chars.join('');
80
+ };
81
+ /** VariableDeclaration ở `for(let i=0;...)` / `for..in` / `for..of` KHÔNG cần `;` cuối. */
82
+ const requiresSemicolon = (nodeType, parentType, keyInParent) => {
83
+ if (nodeType === 'VariableDeclaration') {
84
+ if (parentType === 'ForStatement' && keyInParent === 'init')
85
+ return false;
86
+ if ((parentType === 'ForInStatement' || parentType === 'ForOfStatement') && keyInParent === 'left')
87
+ return false;
88
+ }
89
+ return true;
90
+ };
91
+ /**
92
+ * Rule custom "require semicolon": câu lệnh (const/let/return/expression...) không kết thúc bằng `;` → báo lỗi.
93
+ * Dùng vị trí `node.end` của AST babel; bỏ qua dòng tainted (trailing dot) để không chồng lỗi.
94
+ */
95
+ export const collectMissingSemicolonDiagnostics = (ast, code, diagnostics, taintedLines) => {
96
+ const semiNodes = new Set(['ExpressionStatement', 'VariableDeclaration', 'ReturnStatement', 'ThrowStatement', 'BreakStatement', 'ContinueStatement', 'DoWhileStatement', 'DebuggerStatement']);
97
+ const seen = new Set();
98
+ const lineOf = (offset) => code.slice(0, offset).split('\n').length;
99
+ const walk = (node, parentType, keyInParent) => {
100
+ if (Array.isArray(node)) {
101
+ for (const item of node)
102
+ walk(item, parentType, keyInParent);
103
+ return;
104
+ }
105
+ if (!node || typeof node !== 'object')
106
+ return;
107
+ const current = node;
108
+ if (typeof current.type !== 'string')
109
+ return;
110
+ if (semiNodes.has(current.type) && requiresSemicolon(current.type, parentType, keyInParent) && typeof current.end === 'number') {
111
+ const end = Math.min(current.end, code.length);
112
+ if (end > 0 && code.charAt(end - 1) !== ';' && !seen.has(end) && !taintedLines.has(lineOf(end - 1))) {
113
+ seen.add(end);
114
+ diagnostics.push({ from: end - 1, to: end, severity: 'error', message: 'Missing semicolon' });
115
+ }
116
+ }
117
+ for (const childKey of Object.keys(current)) {
118
+ if (astSkipKeys.has(childKey))
119
+ continue;
120
+ walk(current[childKey], current.type, childKey);
121
+ }
122
+ };
123
+ walk(ast.program ?? ast, '', '');
124
+ };
125
+ /** Chuẩn hóa message: thân thiện cho trailing dot + heuristic kiểu cũ cho "Unexpected token"; bỏ hậu tố "(line:col)". */
126
+ export const buildJsErrorMessage = (doc, from, rawMessage) => {
127
+ const charBefore = from > 0 ? doc.sliceString(from - 1, from) : '';
128
+ if (charBefore === '.') {
129
+ const owner = getTokenBefore(doc, from).replace(/\.$/, '');
130
+ return owner ? `Incomplete property access on "${owner}"` : 'Incomplete property access';
131
+ }
132
+ const cleaned = rawMessage.replace(/\s*\(\d+:\d+\)\s*$/, '').trim();
133
+ if (/missing semicolon/i.test(cleaned)) {
134
+ return 'Unexpected token — missing operator or separator between expressions';
135
+ }
136
+ if (/^unexpected token$/i.test(cleaned)) {
137
+ const prevToken = getTokenBefore(doc, from);
138
+ if (prevToken.endsWith('('))
139
+ return 'Missing closing ")"';
140
+ if (prevToken.endsWith('['))
141
+ return 'Missing closing "]"';
142
+ if (/^function$/i.test(prevToken))
143
+ return 'Expected function name or "("';
144
+ if (/^return$/i.test(prevToken))
145
+ return 'Invalid expression after "return"';
146
+ if (/^=>$/.test(prevToken))
147
+ return 'Expected function body after "=>"';
148
+ if (/^const$|^let$|^var$/i.test(prevToken))
149
+ return 'Expected variable name';
150
+ }
151
+ return `JavaScript syntax error: ${cleaned}`;
152
+ };
153
+ /** Lấy tên binding từ pattern (Identifier, destructuring object/array, default, rest). */
154
+ const collectPatternNames = (node, declared) => {
155
+ if (!node || typeof node.type !== 'string')
156
+ return;
157
+ switch (node.type) {
158
+ case 'Identifier':
159
+ if (node.name)
160
+ declared.add(node.name);
161
+ return;
162
+ case 'ObjectPattern':
163
+ if (node.properties)
164
+ for (const property of node.properties)
165
+ collectPatternNames(property.type === 'RestElement' ? property.argument : property.value, declared);
166
+ return;
167
+ case 'ArrayPattern':
168
+ if (node.elements)
169
+ for (const element of node.elements)
170
+ collectPatternNames(element, declared);
171
+ return;
172
+ case 'AssignmentPattern':
173
+ collectPatternNames(node.left, declared);
174
+ return;
175
+ case 'RestElement':
176
+ collectPatternNames(node.argument, declared);
177
+ return;
178
+ case 'TSParameterProperty':
179
+ collectPatternNames(node.parameter, declared);
180
+ return;
181
+ default:
182
+ return;
183
+ }
184
+ };
185
+ /** Thu thập tên binding (biến/hàm/class/param/import/enum...) từ 1 node vào tập `declared`. */
186
+ const collectBindingNames = (node, declared) => {
187
+ switch (node.type) {
188
+ case 'VariableDeclarator':
189
+ collectPatternNames(node.id, declared);
190
+ return;
191
+ case 'FunctionDeclaration':
192
+ case 'FunctionExpression':
193
+ case 'ClassDeclaration':
194
+ case 'ClassExpression':
195
+ if (node.id?.name)
196
+ declared.add(node.id.name);
197
+ if (node.params)
198
+ for (const param of node.params)
199
+ collectPatternNames(param, declared);
200
+ return;
201
+ case 'ArrowFunctionExpression':
202
+ if (node.params)
203
+ for (const param of node.params)
204
+ collectPatternNames(param, declared);
205
+ return;
206
+ case 'CatchClause':
207
+ collectPatternNames(node.param, declared);
208
+ return;
209
+ case 'ImportDefaultSpecifier':
210
+ case 'ImportNamespaceSpecifier':
211
+ case 'ImportSpecifier':
212
+ if (node.local?.name)
213
+ declared.add(node.local.name);
214
+ return;
215
+ case 'TSEnumDeclaration':
216
+ case 'TSModuleDeclaration':
217
+ if (node.id?.name)
218
+ declared.add(node.id.name);
219
+ return;
220
+ default:
221
+ return;
222
+ }
223
+ };
224
+ /** Xác định 1 Identifier có phải tham chiếu giá trị không (loại property access, key object, declaration id, label...). */
225
+ const isReferenceIdentifier = (parent, keyInParent) => {
226
+ if (!parent)
227
+ return true;
228
+ const parentType = parent.type;
229
+ if ((parentType === 'MemberExpression' || parentType === 'OptionalMemberExpression') && keyInParent === 'property' && !parent.computed)
230
+ return false;
231
+ if ((parentType === 'ObjectProperty' || parentType === 'ObjectMethod' || parentType === 'ClassMethod' || parentType === 'ClassProperty' || parentType === 'ClassPrivateProperty' || parentType === 'PropertyDefinition') && keyInParent === 'key' && !parent.computed)
232
+ return false;
233
+ if (keyInParent === 'label')
234
+ return false;
235
+ if (parentType === 'TSQualifiedName' && keyInParent === 'right')
236
+ return false;
237
+ if (parentType === 'VariableDeclarator' && keyInParent === 'id')
238
+ return false;
239
+ if ((parentType === 'FunctionDeclaration' || parentType === 'FunctionExpression' || parentType === 'ClassDeclaration' || parentType === 'ClassExpression') && keyInParent === 'id')
240
+ return false;
241
+ if (parentType === 'ImportSpecifier' || parentType === 'ImportDefaultSpecifier' || parentType === 'ImportNamespaceSpecifier' || parentType === 'ExportSpecifier')
242
+ return false;
243
+ if (parentType === 'MetaProperty')
244
+ return false;
245
+ if (parentType === 'TSEnumMember' && keyInParent === 'id')
246
+ return false;
247
+ return true;
248
+ };
249
+ /** Duyệt đệ quy AST: gom binding name vào `declared`, gom identifier tham chiếu vào `references`. */
250
+ const walkAstNode = (node, parent, keyInParent, inType, declared, references) => {
251
+ if (Array.isArray(node)) {
252
+ for (const item of node)
253
+ walkAstNode(item, parent, keyInParent, inType, declared, references);
254
+ return;
255
+ }
256
+ if (!node || typeof node !== 'object')
257
+ return;
258
+ const current = node;
259
+ if (typeof current.type !== 'string')
260
+ return;
261
+ collectBindingNames(current, declared);
262
+ if (current.type === 'Identifier' && !inType && isReferenceIdentifier(parent, keyInParent)) {
263
+ const start = current.loc?.start;
264
+ if (current.name && start)
265
+ references.push({ name: current.name, line: start.line, column: start.column });
266
+ }
267
+ const opensType = inType || (current.type.startsWith('TS') && !tsValueNodes.has(current.type));
268
+ for (const childKey of Object.keys(current)) {
269
+ if (astSkipKeys.has(childKey))
270
+ continue;
271
+ const child = current[childKey];
272
+ const childOpensType = typeof child === 'object' && child !== null && typeof child.type === 'string' && child.type.startsWith('TS') && !tsValueNodes.has(child.type);
273
+ const childInType = opensType || astTypeKeys.has(childKey) || childOpensType;
274
+ walkAstNode(child, current, childKey, childInType, declared, references);
275
+ }
276
+ };
277
+ /**
278
+ * Pass ngữ nghĩa: báo biến CHƯA KHAI BÁO. Tự duyệt AST (object thuần) — KHÔNG dùng `@babel/traverse`
279
+ * (cần `process` của Node → crash browser). Hợp lệ = binding trong code + global JS/DOM + `completionLabels`.
280
+ */
281
+ export const collectUndeclaredIdentifiers = async (ast, doc, completionLabels, taintedLines = new Set()) => {
282
+ const globalsSet = await getKnownGlobals();
283
+ const declared = new Set();
284
+ const references = [];
285
+ walkAstNode(ast, null, '', false, declared, references);
286
+ const diagnostics = [];
287
+ const seen = new Set();
288
+ for (const reference of references) {
289
+ const { name, line: startLine, column: startColumn } = reference;
290
+ if (declared.has(name) || globalsSet.has(name) || completionLabels.has(name))
291
+ continue;
292
+ if (taintedLines.has(startLine))
293
+ continue;
294
+ const dedupeKey = `${startLine}:${startColumn}:${name}`;
295
+ if (seen.has(dedupeKey))
296
+ continue;
297
+ seen.add(dedupeKey);
298
+ const line = doc.line(Math.min(Math.max(startLine, 1), doc.lines));
299
+ const from = Math.min(line.from + Math.max(startColumn, 0), doc.length);
300
+ const to = Math.min(from + name.length, doc.length);
301
+ diagnostics.push({ from, to: Math.max(from + 1, to), severity: 'error', message: `"${name}" is not defined` });
302
+ }
303
+ return diagnostics;
304
+ };
305
+ /**
306
+ * Toàn bộ pipeline validate JS/TS:
307
+ * - Pass 1: trailing dot (text) — flag đúng vị trí dấu `.` cuối dòng + đánh dấu dòng tainted.
308
+ * - Pass 2: lỗi cú pháp babel — bỏ lỗi trên dòng tainted (cascading).
309
+ * - Pass 3: rule cần AST (thiếu `;`, biến chưa khai báo). Trailing dot được "vá" (`.`→space) để babel
310
+ * vẫn parse được phần còn lại → rule vẫn chạy cho các dòng KHÁC.
311
+ */
312
+ export const computeJsDiagnostics = async (doc, code, completionLabels) => {
313
+ const diagnostics = [];
314
+ if (code.trim() === '') {
315
+ return diagnostics;
316
+ }
317
+ const taintedLines = new Set();
318
+ const dotPositions = [];
319
+ collectTrailingDotDiagnostics(doc, diagnostics, taintedLines, dotPositions);
320
+ const parseCode = replaceCharsWithSpace(code, dotPositions);
321
+ const parser = await getBabelParser();
322
+ const { errors, ast } = parseJs(parser, parseCode);
323
+ const seen = new Set();
324
+ for (const error of errors) {
325
+ const location = error.loc;
326
+ if (!location)
327
+ continue;
328
+ const lineNumber = Math.min(Math.max(location.line, 1), doc.lines);
329
+ if (taintedLines.has(lineNumber))
330
+ continue;
331
+ const line = doc.line(lineNumber);
332
+ const errorPos = Math.min(line.from + Math.max(location.column, 0), doc.length);
333
+ const to = Math.min(errorPos + 1, doc.length);
334
+ const from = errorPos >= to && errorPos > 0 ? errorPos - 1 : errorPos;
335
+ const message = buildJsErrorMessage(doc, errorPos, error.message);
336
+ const dedupeKey = `${from}:${message}`;
337
+ if (seen.has(dedupeKey))
338
+ continue;
339
+ seen.add(dedupeKey);
340
+ diagnostics.push({ from, to: Math.max(from + 1, to), severity: 'error', message });
341
+ }
342
+ if (errors.length === 0 && ast) {
343
+ collectMissingSemicolonDiagnostics(ast, code, diagnostics, taintedLines);
344
+ diagnostics.push(...(await collectUndeclaredIdentifiers(ast, doc, completionLabels, taintedLines)));
345
+ }
346
+ return diagnostics;
347
+ };
348
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianMtbGludGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3ByZXZpZXctdGV4dC1kYXRhL3NyYy9saW50ZXJzL2pzLWxpbnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFckYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBS2pELDBGQUEwRjtBQUMxRixJQUFJLGlCQUE2RCxDQUFDO0FBQ2xFLElBQUksZUFBd0MsQ0FBQztBQUU3QywrRUFBK0U7QUFDL0UsTUFBTSxjQUFjLEdBQUcsS0FBSyxJQUE2QyxFQUFFO0lBQ3pFLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3ZCLGlCQUFpQixHQUFHLE1BQU0sTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFDRCxPQUFPLGlCQUFpQixDQUFDO0FBQzNCLENBQUMsQ0FBQztBQUVGLHlHQUF5RztBQUN6RyxNQUFNLGVBQWUsR0FBRyxLQUFLLElBQTBCLEVBQUU7SUFDdkQsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3JCLE1BQU0sYUFBYSxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQXFFLENBQUM7UUFDcEgsTUFBTSxXQUFXLEdBQUcsQ0FBQyxhQUFhLENBQUMsT0FBTyxJQUFJLGFBQWEsQ0FBNEMsQ0FBQztRQUN4RyxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQVMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxD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QUFPLEVBQUUsQ0FBQztRQUN2QyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO1lBQUUsU0FBUztRQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BCLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDL0Isa0NBQWtDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDekUsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSw0QkFBNEIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RyxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlhZ25vc3RpYyB9IGZyb20gJ0Bjb2RlbWlycm9yL2xpbnQnO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IGFzdFNraXBLZXlzLCBhc3RUeXBlS2V5cywgdHNWYWx1ZU5vZGVzIH0gZnJvbSAnLi4vcHJldmlldy10ZXh0LWRhdGEuZGVmaW5lJztcbmltcG9ydCB7IFRfQXN0Tm9kZSB9IGZyb20gJy4uL3ByZXZpZXctdGV4dC1kYXRhLnR5cGUnO1xuaW1wb3J0IHsgZ2V0VG9rZW5CZWZvcmUgfSBmcm9tICcuL2xpbnRlci1zaGFyZWQnO1xuXG50eXBlIFRfQmFiZWxFcnJvciA9IHsgbG9jPzogeyBsaW5lOiBudW1iZXI7IGNvbHVtbjogbnVtYmVyIH07IG1lc3NhZ2U6IHN0cmluZyB9O1xudHlwZSBUX0FzdFJlZmVyZW5jZSA9IHsgbmFtZTogc3RyaW5nOyBsaW5lOiBudW1iZXI7IGNvbHVtbjogbnVtYmVyIH07XG5cbi8vIENhY2hlIG1vZHVsZS1sZXZlbCAoY2hpYSBz4bq7IGdp4buvYSBjw6FjIGluc3RhbmNlIGVkaXRvcikg4oCUIMSR4buBdSBpbW11dGFibGUsIGxhenktbG9hZCAxIGzhuqduLlxubGV0IGJhYmVsUGFyc2VyTW9kdWxlOiB0eXBlb2YgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJykgfCB1bmRlZmluZWQ7XG5sZXQga25vd25HbG9iYWxzU2V0OiBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZDtcblxuLyoqIExhenktbG9hZCArIGNhY2hlIG1vZHVsZSBAYmFiZWwvcGFyc2VyIChjaOG7iSB04bqjaSBs4bqnbiDEkeG6p3Uga2hpIGxpbnQgSlMvVFMpLiAqL1xuY29uc3QgZ2V0QmFiZWxQYXJzZXIgPSBhc3luYyAoKTogUHJvbWlzZTx0eXBlb2YgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJyk+ID0+IHtcbiAgaWYgKCFiYWJlbFBhcnNlck1vZHVsZSkge1xuICAgIGJhYmVsUGFyc2VyTW9kdWxlID0gYXdhaXQgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJyk7XG4gIH1cbiAgcmV0dXJuIGJhYmVsUGFyc2VyTW9kdWxlO1xufTtcblxuLyoqIExhenktbG9hZCArIGNhY2hlIHThuq1wIGJp4bq/biB0b8OgbiBj4bulYyBKUy9ET00gaOG7o3AgbOG7hyB04burIHBhY2thZ2UgYGdsb2JhbHNgIChKU09OIHRodeG6p24sIGJyb3dzZXItc2FmZSkuICovXG5jb25zdCBnZXRLbm93bkdsb2JhbHMgPSBhc3luYyAoKTogUHJvbWlzZTxTZXQ8c3RyaW5nPj4gPT4ge1xuICBpZiAoIWtub3duR2xvYmFsc1NldCkge1xuICAgIGNvbnN0IGdsb2JhbHNNb2R1bGUgPSAoYXdhaXQgaW1wb3J0KCdnbG9iYWxzJykpIGFzIHVua25vd24gYXMgeyBkZWZhdWx0PzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4+IH07XG4gICAgY29uc3QgZ2xvYmFsc0RhdGEgPSAoZ2xvYmFsc01vZHVsZS5kZWZhdWx0ID8/IGdsb2JhbHNNb2R1bGUpIGFzIFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+PjtcbiAgICBrbm93bkdsb2JhbHNTZXQgPSBuZXcgU2V0PHN0cmluZz4oWy4uLk9iamVjdC5rZXlzKGdsb2JhbHNEYXRhWydidWlsdGluJ10gPz8ge30pLCAuLi5PYmplY3Qua2V5cyhnbG9iYWxzRGF0YVsnYnJvd3NlciddID8/IHt9KSwgLi4uT2JqZWN0LmtleXMoZ2xvYmFsc0RhdGFbJ2VzMjAyMSddID8/IHt9KV0pO1xuICB9XG4gIHJldHVybiBrbm93bkdsb2JhbHNTZXQ7XG59O1xuXG4vKipcbiAqIFBhcnNlIGNvZGUsIHRy4bqjIHbhu4EgduG7q2EgZGFuaCBzw6FjaCBs4buXaSBjw7ogcGjDoXAgduG7q2EgQVNUIChu4bq/dSBwYXJzZSBz4bqhY2gpLlxuICogYGVycm9yUmVjb3ZlcnlgIGdvbSBuaGnhu4F1IGzhu5dpIHbDoG8gYHJlc3VsdC5lcnJvcnNgOyBs4buXaSBu4bq3bmcgduG6q24gYHRocm93YCDihpIgYuG6r3QgdGjDqm0g4bufIGNhdGNoLlxuICovXG5leHBvcnQgY29uc3QgcGFyc2VKcyA9IChwYXJzZXI6IHR5cGVvZiBpbXBvcnQoJ0BiYWJlbC9wYXJzZXInKSwgY29kZTogc3RyaW5nKTogeyBlcnJvcnM6IFRfQmFiZWxFcnJvcltdOyBhc3Q/OiBvYmplY3QgfSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gcGFyc2VyLnBhcnNlKGNvZGUsIHtcbiAgICAgIHNvdXJjZVR5cGU6ICdtb2R1bGUnLFxuICAgICAgZXJyb3JSZWNvdmVyeTogdHJ1ZSxcbiAgICAgIHBsdWdpbnM6IFsndHlwZXNjcmlwdCcsICdqc3gnXSxcbiAgICAgIGFsbG93UmV0dXJuT3V0c2lkZUZ1bmN0aW9uOiB0cnVlLFxuICAgICAgYWxsb3dBd2FpdE91dHNpZGVGdW5jdGlvbjogdHJ1ZSxcbiAgICAgIGFsbG93SW1wb3J0RXhwb3J0RXZlcnl3aGVyZTogdHJ1ZSxcbiAgICAgIGFsbG93U3VwZXJPdXRzaWRlTWV0aG9kOiB0cnVlLFxuICAgICAgYWxsb3dOZXdUYXJnZXRPdXRzaWRlRnVuY3Rpb246IHRydWUsXG4gICAgICBhbGxvd1VuZGVjbGFyZWRFeHBvcnRzOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiB7IGVycm9yczogcmVzdWx0LmVycm9ycyBhcyBUX0JhYmVsRXJyb3JbXSwgYXN0OiByZXN1bHQgfTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBjb25zdCBsb2MgPSBnZXQoZXJyb3IsICdsb2MnKSBhcyB7IGxpbmU6IG51bWJlcjsgY29sdW1uOiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtZXNzYWdlID0gKGdldChlcnJvciwgJ21lc3NhZ2UnKSBhcyBzdHJpbmcpIHx8ICdKYXZhU2NyaXB0IHN5bnRheCBlcnJvcic7XG4gICAgcmV0dXJuIHsgZXJyb3JzOiBbeyBsb2MsIG1lc3NhZ2UgfV0gfTtcbiAgfVxufTtcblxuLyoqIEdp4buvIGNobyB0ZXN0L2JhY2stY29tcGF0OiBjaOG7iSBs4bqleSBkYW5oIHPDoWNoIGzhu5dpIGPDuiBwaMOhcC4gKi9cbmV4cG9ydCBjb25zdCBjb2xsZWN0QmFiZWxFcnJvcnMgPSAocGFyc2VyOiB0eXBlb2YgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJyksIGNvZGU6IHN0cmluZyk6IFRfQmFiZWxFcnJvcltdID0+IHBhcnNlSnMocGFyc2VyLCBjb2RlKS5lcnJvcnM7XG5cbi8qKlxuICogUXXDqXQgdGV4dCB04burbmcgZMOybmcsIGZsYWcgZOG6pXUgXCIuXCIgY3Xhu5FpIGTDsm5nIChpbmNvbXBsZXRlIHByb3BlcnR5IGFjY2VzcykgdOG6oWkgxJDDmk5HIHbhu4sgdHLDrSBk4bqldSBjaOG6pW0uXG4gKiBUaHUgdGjhuq1wIGB0YWludGVkTGluZXNgIChkw7JuZyBjw7MgdHJhaWxpbmcgZG90KSArIGBkb3RQb3NpdGlvbnNgIChvZmZzZXQgZOG6pXUgY2jhuqVtIMSR4buDIHbDoSBraGkgcGFyc2UpLlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdFRyYWlsaW5nRG90RGlhZ25vc3RpY3MgPSAoZG9jOiBUZXh0LCBkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdLCB0YWludGVkTGluZXM6IFNldDxudW1iZXI+LCBkb3RQb3NpdGlvbnM6IG51bWJlcltdKTogdm9pZCA9PiB7XG4gIGZvciAobGV0IGxpbmVOdW1iZXIgPSAxOyBsaW5lTnVtYmVyIDw9IGRvYy5saW5lczsgbGluZU51bWJlcisrKSB7XG4gICAgY29uc3QgbGluZSA9IGRvYy5saW5lKGxpbmVOdW1iZXIpO1xuICAgIGNvbnN0IHRyaW1tZWQgPSBsaW5lLnRleHQudHJpbUVuZCgpO1xuICAgIGNvbnN0IG1hdGNoID0gLyhcXHcrKVxcLlxccyokLy5leGVjKHRyaW1tZWQpO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0YWludGVkTGluZXMuYWRkKGxpbmVOdW1iZXIpO1xuICAgIGNvbnN0IGRvdFBvc2l0aW9uID0gbGluZS5mcm9tICsgdHJpbW1lZC5sYXN0SW5kZXhPZignLicpO1xuICAgIGRvdFBvc2l0aW9ucy5wdXNoKGRvdFBvc2l0aW9uKTtcbiAgICBkaWFnbm9zdGljcy5wdXNoKHsgZnJvbTogZG90UG9zaXRpb24sIHRvOiBkb3RQb3NpdGlvbiArIDEsIHNldmVyaXR5OiAnZXJyb3InLCBtZXNzYWdlOiBgSW5jb21wbGV0ZSBwcm9wZXJ0eSBhY2Nlc3Mgb24gXCIke21hdGNoWzFdfVwiYCB9KTtcbiAgfVxufTtcblxuLyoqIFRoYXkgY8OhYyBrw70gdOG7sSB04bqhaSBgcG9zaXRpb25zYCBi4bqxbmcgc3BhY2UsIGdp4buvIG5ndXnDqm4gxJHhu5kgZMOgaSBjaHXhu5dpICjEkeG7gyBvZmZzZXQga2jDtG5nIMSR4buVaSkuICovXG5jb25zdCByZXBsYWNlQ2hhcnNXaXRoU3BhY2UgPSAoY29kZTogc3RyaW5nLCBwb3NpdGlvbnM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgaWYgKCFwb3NpdGlvbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNvZGU7XG4gIH1cbiAgY29uc3QgY2hhcnMgPSBjb2RlLnNwbGl0KCcnKTtcbiAgZm9yIChjb25zdCBwb3NpdGlvbiBvZiBwb3NpdGlvbnMpIHtcbiAgICBpZiAocG9zaXRpb24gPj0gMCAmJiBwb3NpdGlvbiA8IGNoYXJzLmxlbmd0aCkge1xuICAgICAgY2hhcnNbcG9zaXRpb25dID0gJyAnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY2hhcnMuam9pbignJyk7XG59O1xuXG4vKiogVmFyaWFibGVEZWNsYXJhdGlvbiDhu58gYGZvcihsZXQgaT0wOy4uLilgIC8gYGZvci4uaW5gIC8gYGZvci4ub2ZgIEtIw5RORyBj4bqnbiBgO2AgY3Xhu5FpLiAqL1xuY29uc3QgcmVxdWlyZXNTZW1pY29sb24gPSAobm9kZVR5cGU6IHN0cmluZywgcGFyZW50VHlwZTogc3RyaW5nLCBrZXlJblBhcmVudDogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIGlmIChub2RlVHlwZSA9PT0gJ1ZhcmlhYmxlRGVjbGFyYXRpb24nKSB7XG4gICAgaWYgKHBhcmVudFR5cGUgPT09ICdGb3JTdGF0ZW1lbnQnICYmIGtleUluUGFyZW50ID09PSAnaW5pdCcpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoKHBhcmVudFR5cGUgPT09ICdGb3JJblN0YXRlbWVudCcgfHwgcGFyZW50VHlwZSA9PT0gJ0Zvck9mU3RhdGVtZW50JykgJiYga2V5SW5QYXJlbnQgPT09ICdsZWZ0JykgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBSdWxlIGN1c3RvbSBcInJlcXVpcmUgc2VtaWNvbG9uXCI6IGPDonUgbOG7h25oIChjb25zdC9sZXQvcmV0dXJuL2V4cHJlc3Npb24uLi4pIGtow7RuZyBr4bq/dCB0aMO6YyBi4bqxbmcgYDtgIOKGkiBiw6FvIGzhu5dpLlxuICogRMO5bmcgduG7iyB0csOtIGBub2RlLmVuZGAgY+G7p2EgQVNUIGJhYmVsOyBi4buPIHF1YSBkw7JuZyB0YWludGVkICh0cmFpbGluZyBkb3QpIMSR4buDIGtow7RuZyBjaOG7k25nIGzhu5dpLlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdE1pc3NpbmdTZW1pY29sb25EaWFnbm9zdGljcyA9IChhc3Q6IG9iamVjdCwgY29kZTogc3RyaW5nLCBkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdLCB0YWludGVkTGluZXM6IFNldDxudW1iZXI+KTogdm9pZCA9PiB7XG4gIGNvbnN0IHNlbWlOb2RlcyA9IG5ldyBTZXQoWydFeHByZXNzaW9uU3RhdGVtZW50JywgJ1ZhcmlhYmxlRGVjbGFyYXRpb24nLCAnUmV0dXJuU3RhdGVtZW50JywgJ1Rocm93U3RhdGVtZW50JywgJ0JyZWFrU3RhdGVtZW50JywgJ0NvbnRpbnVlU3RhdGVtZW50JywgJ0RvV2hpbGVTdGF0ZW1lbnQnLCAnRGVidWdnZXJTdGF0ZW1lbnQnXSk7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgY29uc3QgbGluZU9mID0gKG9mZnNldDogbnVtYmVyKSA9PiBjb2RlLnNsaWNlKDAsIG9mZnNldCkuc3BsaXQoJ1xcbicpLmxlbmd0aDtcbiAgY29uc3Qgd2FsayA9IChub2RlOiB1bmtub3duLCBwYXJlbnRUeXBlOiBzdHJpbmcsIGtleUluUGFyZW50OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShub2RlKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIG5vZGUpIHdhbGsoaXRlbSwgcGFyZW50VHlwZSwga2V5SW5QYXJlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudCA9IG5vZGUgYXMgVF9Bc3ROb2RlO1xuICAgIGlmICh0eXBlb2YgY3VycmVudC50eXBlICE9PSAnc3RyaW5nJykgcmV0dXJuO1xuXG4gICAgaWYgKHNlbWlOb2Rlcy5oYXMoY3VycmVudC50eXBlKSAmJiByZXF1aXJlc1NlbWljb2xvbihjdXJyZW50LnR5cGUsIHBhcmVudFR5cGUsIGtleUluUGFyZW50KSAmJiB0eXBlb2YgY3VycmVudC5lbmQgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBlbmQgPSBNYXRoLm1pbihjdXJyZW50LmVuZCwgY29kZS5sZW5ndGgpO1xuICAgICAgaWYgKGVuZCA+IDAgJiYgY29kZS5jaGFyQXQoZW5kIC0gMSkgIT09ICc7JyAmJiAhc2Vlbi5oYXMoZW5kKSAmJiAhdGFpbnRlZExpbmVzLmhhcyhsaW5lT2YoZW5kIC0gMSkpKSB7XG4gICAgICAgIHNlZW4uYWRkKGVuZCk7XG4gICAgICAgIGRpYWdub3N0aWNzLnB1c2goeyBmcm9tOiBlbmQgLSAxLCB0bzogZW5kLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZTogJ01pc3Npbmcgc2VtaWNvbG9uJyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkS2V5IG9mIE9iamVjdC5rZXlzKGN1cnJlbnQpKSB7XG4gICAgICBpZiAoYXN0U2tpcEtleXMuaGFzKGNoaWxkS2V5KSkgY29udGludWU7XG4gICAgICB3YWxrKGN1cnJlbnRbY2hpbGRLZXldLCBjdXJyZW50LnR5cGUsIGNoaWxkS2V5KTtcbiAgICB9XG4gIH07XG4gIHdhbGsoKGFzdCBhcyB7IHByb2dyYW0/OiB1bmtub3duIH0pLnByb2dyYW0gPz8gYXN0LCAnJywgJycpO1xufTtcblxuLyoqIENodeG6qW4gaMOzYSBtZXNzYWdlOiB0aMOibiB0aGnhu4duIGNobyB0cmFpbGluZyBkb3QgKyBoZXVyaXN0aWMga2nhu4N1IGPFqSBjaG8gXCJVbmV4cGVjdGVkIHRva2VuXCI7IGLhu48gaOG6rXUgdOG7kSBcIihsaW5lOmNvbClcIi4gKi9cbmV4cG9ydCBjb25zdCBidWlsZEpzRXJyb3JNZXNzYWdlID0gKGRvYzogVGV4dCwgZnJvbTogbnVtYmVyLCByYXdNZXNzYWdlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjaGFyQmVmb3JlID0gZnJvbSA+IDAgPyBkb2Muc2xpY2VTdHJpbmcoZnJvbSAtIDEsIGZyb20pIDogJyc7XG4gIGlmIChjaGFyQmVmb3JlID09PSAnLicpIHtcbiAgICBjb25zdCBvd25lciA9IGdldFRva2VuQmVmb3JlKGRvYywgZnJvbSkucmVwbGFjZSgvXFwuJC8sICcnKTtcbiAgICByZXR1cm4gb3duZXIgPyBgSW5jb21wbGV0ZSBwcm9wZXJ0eSBhY2Nlc3Mgb24gXCIke293bmVyfVwiYCA6ICdJbmNvbXBsZXRlIHByb3BlcnR5IGFjY2Vzcyc7XG4gIH1cblxuICBjb25zdCBjbGVhbmVkID0gcmF3TWVzc2FnZS5yZXBsYWNlKC9cXHMqXFwoXFxkKzpcXGQrXFwpXFxzKiQvLCAnJykudHJpbSgpO1xuICBpZiAoL21pc3Npbmcgc2VtaWNvbG9uL2kudGVzdChjbGVhbmVkKSkge1xuICAgIHJldHVybiAnVW5leHBlY3RlZCB0b2tlbiDigJQgbWlzc2luZyBvcGVyYXRvciBvciBzZXBhcmF0b3IgYmV0d2VlbiBleHByZXNzaW9ucyc7XG4gIH1cbiAgaWYgKC9edW5leHBlY3RlZCB0b2tlbiQvaS50ZXN0KGNsZWFuZWQpKSB7XG4gICAgY29uc3QgcHJldlRva2VuID0gZ2V0VG9rZW5CZWZvcmUoZG9jLCBmcm9tKTtcbiAgICBpZiAocHJldlRva2VuLmVuZHNXaXRoKCcoJykpIHJldHVybiAnTWlzc2luZyBjbG9zaW5nIFwiKVwiJztcbiAgICBpZiAocHJldlRva2VuLmVuZHNXaXRoKCdbJykpIHJldHVybiAnTWlzc2luZyBjbG9zaW5nIFwiXVwiJztcbiAgICBpZiAoL15mdW5jdGlvbiQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgZnVuY3Rpb24gbmFtZSBvciBcIihcIic7XG4gICAgaWYgKC9ecmV0dXJuJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdJbnZhbGlkIGV4cHJlc3Npb24gYWZ0ZXIgXCJyZXR1cm5cIic7XG4gICAgaWYgKC9ePT4kLy50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgZnVuY3Rpb24gYm9keSBhZnRlciBcIj0+XCInO1xuICAgIGlmICgvXmNvbnN0JHxebGV0JHxedmFyJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCB2YXJpYWJsZSBuYW1lJztcbiAgfVxuICByZXR1cm4gYEphdmFTY3JpcHQgc3ludGF4IGVycm9yOiAke2NsZWFuZWR9YDtcbn07XG5cbi8qKiBM4bqleSB0w6puIGJpbmRpbmcgdOG7qyBwYXR0ZXJuIChJZGVudGlmaWVyLCBkZXN0cnVjdHVyaW5nIG9iamVjdC9hcnJheSwgZGVmYXVsdCwgcmVzdCkuICovXG5jb25zdCBjb2xsZWN0UGF0dGVybk5hbWVzID0gKG5vZGU6IFRfQXN0Tm9kZSB8IG51bGwgfCB1bmRlZmluZWQsIGRlY2xhcmVkOiBTZXQ8c3RyaW5nPik6IHZvaWQgPT4ge1xuICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUudHlwZSAhPT0gJ3N0cmluZycpIHJldHVybjtcbiAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICBjYXNlICdJZGVudGlmaWVyJzpcbiAgICAgIGlmIChub2RlLm5hbWUpIGRlY2xhcmVkLmFkZChub2RlLm5hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ09iamVjdFBhdHRlcm4nOlxuICAgICAgaWYgKG5vZGUucHJvcGVydGllcykgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBub2RlLnByb3BlcnRpZXMpIGNvbGxlY3RQYXR0ZXJuTmFtZXMocHJvcGVydHkudHlwZSA9PT0gJ1Jlc3RFbGVtZW50JyA/IHByb3BlcnR5LmFyZ3VtZW50IDogcHJvcGVydHkudmFsdWUsIGRlY2xhcmVkKTtcbiAgICAgIHJldHVybjtcbiAgICBjYXNlICdBcnJheVBhdHRlcm4nOlxuICAgICAgaWYgKG5vZGUuZWxlbWVudHMpIGZvciAoY29uc3QgZWxlbWVudCBvZiBub2RlLmVsZW1lbnRzKSBjb2xsZWN0UGF0dGVybk5hbWVzKGVsZW1lbnQsIGRlY2xhcmVkKTtcbiAgICAgIHJldHVybjtcbiAgICBjYXNlICdBc3NpZ25tZW50UGF0dGVybic6XG4gICAgICBjb2xsZWN0UGF0dGVybk5hbWVzKG5vZGUubGVmdCwgZGVjbGFyZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ1Jlc3RFbGVtZW50JzpcbiAgICAgIGNvbGxlY3RQYXR0ZXJuTmFtZXMobm9kZS5hcmd1bWVudCwgZGVjbGFyZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ1RTUGFyYW1ldGVyUHJvcGVydHknOlxuICAgICAgY29sbGVjdFBhdHRlcm5OYW1lcyhub2RlLnBhcmFtZXRlciwgZGVjbGFyZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm47XG4gIH1cbn07XG5cbi8qKiBUaHUgdGjhuq1wIHTDqm4gYmluZGluZyAoYmnhur9uL2jDoG0vY2xhc3MvcGFyYW0vaW1wb3J0L2VudW0uLi4pIHThu6sgMSBub2RlIHbDoG8gdOG6rXAgYGRlY2xhcmVkYC4gKi9cbmNvbnN0IGNvbGxlY3RCaW5kaW5nTmFtZXMgPSAobm9kZTogVF9Bc3ROb2RlLCBkZWNsYXJlZDogU2V0PHN0cmluZz4pOiB2b2lkID0+IHtcbiAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICBjYXNlICdWYXJpYWJsZURlY2xhcmF0b3InOlxuICAgICAgY29sbGVjdFBhdHRlcm5OYW1lcyhub2RlLmlkLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnRnVuY3Rpb25EZWNsYXJhdGlvbic6XG4gICAgY2FzZSAnRnVuY3Rpb25FeHByZXNzaW9uJzpcbiAgICBjYXNlICdDbGFzc0RlY2xhcmF0aW9uJzpcbiAgICBjYXNlICdDbGFzc0V4cHJlc3Npb24nOlxuICAgICAgaWYgKG5vZGUuaWQ/Lm5hbWUpIGRlY2xhcmVkLmFkZChub2RlLmlkLm5hbWUpO1xuICAgICAgaWYgKG5vZGUucGFyYW1zKSBmb3IgKGNvbnN0IHBhcmFtIG9mIG5vZGUucGFyYW1zKSBjb2xsZWN0UGF0dGVybk5hbWVzKHBhcmFtLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24nOlxuICAgICAgaWYgKG5vZGUucGFyYW1zKSBmb3IgKGNvbnN0IHBhcmFtIG9mIG5vZGUucGFyYW1zKSBjb2xsZWN0UGF0dGVybk5hbWVzKHBhcmFtLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnQ2F0Y2hDbGF1c2UnOlxuICAgICAgY29sbGVjdFBhdHRlcm5OYW1lcyhub2RlLnBhcmFtLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnSW1wb3J0RGVmYXVsdFNwZWNpZmllcic6XG4gICAgY2FzZSAnSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyJzpcbiAgICBjYXNlICdJbXBvcnRTcGVjaWZpZXInOlxuICAgICAgaWYgKG5vZGUubG9jYWw/Lm5hbWUpIGRlY2xhcmVkLmFkZChub2RlLmxvY2FsLm5hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ1RTRW51bURlY2xhcmF0aW9uJzpcbiAgICBjYXNlICdUU01vZHVsZURlY2xhcmF0aW9uJzpcbiAgICAgIGlmIChub2RlLmlkPy5uYW1lKSBkZWNsYXJlZC5hZGQobm9kZS5pZC5uYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuO1xuICB9XG59O1xuXG4vKiogWMOhYyDEkeG7i25oIDEgSWRlbnRpZmllciBjw7MgcGjhuqNpIHRoYW0gY2hp4bq/dSBnacOhIHRy4buLIGtow7RuZyAobG/huqFpIHByb3BlcnR5IGFjY2Vzcywga2V5IG9iamVjdCwgZGVjbGFyYXRpb24gaWQsIGxhYmVsLi4uKS4gKi9cbmNvbnN0IGlzUmVmZXJlbmNlSWRlbnRpZmllciA9IChwYXJlbnQ6IFRfQXN0Tm9kZSB8IG51bGwsIGtleUluUGFyZW50OiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgaWYgKCFwYXJlbnQpIHJldHVybiB0cnVlO1xuICBjb25zdCBwYXJlbnRUeXBlID0gcGFyZW50LnR5cGU7XG4gIGlmICgocGFyZW50VHlwZSA9PT0gJ01lbWJlckV4cHJlc3Npb24nIHx8IHBhcmVudFR5cGUgPT09ICdPcHRpb25hbE1lbWJlckV4cHJlc3Npb24nKSAmJiBrZXlJblBhcmVudCA9PT0gJ3Byb3BlcnR5JyAmJiAhcGFyZW50LmNvbXB1dGVkKSByZXR1cm4gZmFsc2U7XG4gIGlmICgocGFyZW50VHlwZSA9PT0gJ09iamVjdFByb3BlcnR5JyB8fCBwYXJlbnRUeXBlID09PSAnT2JqZWN0TWV0aG9kJyB8fCBwYXJlbnRUeXBlID09PSAnQ2xhc3NNZXRob2QnIHx8IHBhcmVudFR5cGUgPT09ICdDbGFzc1Byb3BlcnR5JyB8fCBwYXJlbnRUeXBlID09PSAnQ2xhc3NQcml2YXRlUHJvcGVydHknIHx8IHBhcmVudFR5cGUgPT09ICdQcm9wZXJ0eURlZmluaXRpb24nKSAmJiBrZXlJblBhcmVudCA9PT0gJ2tleScgJiYgIXBhcmVudC5jb21wdXRlZCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoa2V5SW5QYXJlbnQgPT09ICdsYWJlbCcpIHJldHVybiBmYWxzZTtcbiAgaWYgKHBhcmVudFR5cGUgPT09ICdUU1F1YWxpZmllZE5hbWUnICYmIGtleUluUGFyZW50ID09PSAncmlnaHQnKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnRUeXBlID09PSAnVmFyaWFibGVEZWNsYXJhdG9yJyAmJiBrZXlJblBhcmVudCA9PT0gJ2lkJykgcmV0dXJuIGZhbHNlO1xuICBpZiAoKHBhcmVudFR5cGUgPT09ICdGdW5jdGlvbkRlY2xhcmF0aW9uJyB8fCBwYXJlbnRUeXBlID09PSAnRnVuY3Rpb25FeHByZXNzaW9uJyB8fCBwYXJlbnRUeXBlID09PSAnQ2xhc3NEZWNsYXJhdGlvbicgfHwgcGFyZW50VHlwZSA9PT0gJ0NsYXNzRXhwcmVzc2lvbicpICYmIGtleUluUGFyZW50ID09PSAnaWQnKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnRUeXBlID09PSAnSW1wb3J0U3BlY2lmaWVyJyB8fCBwYXJlbnRUeXBlID09PSAnSW1wb3J0RGVmYXVsdFNwZWNpZmllcicgfHwgcGFyZW50VHlwZSA9PT0gJ0ltcG9ydE5hbWVzcGFjZVNwZWNpZmllcicgfHwgcGFyZW50VHlwZSA9PT0gJ0V4cG9ydFNwZWNpZmllcicpIHJldHVybiBmYWxzZTtcbiAgaWYgKHBhcmVudFR5cGUgPT09ICdNZXRhUHJvcGVydHknKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnRUeXBlID09PSAnVFNFbnVtTWVtYmVyJyAmJiBrZXlJblBhcmVudCA9PT0gJ2lkJykgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKiBEdXnhu4d0IMSR4buHIHF1eSBBU1Q6IGdvbSBiaW5kaW5nIG5hbWUgdsOgbyBgZGVjbGFyZWRgLCBnb20gaWRlbnRpZmllciB0aGFtIGNoaeG6v3UgdsOgbyBgcmVmZXJlbmNlc2AuICovXG5jb25zdCB3YWxrQXN0Tm9kZSA9IChub2RlOiB1bmtub3duLCBwYXJlbnQ6IFRfQXN0Tm9kZSB8IG51bGwsIGtleUluUGFyZW50OiBzdHJpbmcsIGluVHlwZTogYm9vbGVhbiwgZGVjbGFyZWQ6IFNldDxzdHJpbmc+LCByZWZlcmVuY2VzOiBUX0FzdFJlZmVyZW5jZVtdKTogdm9pZCA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KG5vZGUpKSB7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIG5vZGUpIHdhbGtBc3ROb2RlKGl0ZW0sIHBhcmVudCwga2V5SW5QYXJlbnQsIGluVHlwZSwgZGVjbGFyZWQsIHJlZmVyZW5jZXMpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSByZXR1cm47XG4gIGNvbnN0IGN1cnJlbnQgPSBub2RlIGFzIFRfQXN0Tm9kZTtcbiAgaWYgKHR5cGVvZiBjdXJyZW50LnR5cGUgIT09ICdzdHJpbmcnKSByZXR1cm47XG5cbiAgY29sbGVjdEJpbmRpbmdOYW1lcyhjdXJyZW50LCBkZWNsYXJlZCk7XG5cbiAgaWYgKGN1cnJlbnQudHlwZSA9PT0gJ0lkZW50aWZpZXInICYmICFpblR5cGUgJiYgaXNSZWZlcmVuY2VJZGVudGlmaWVyKHBhcmVudCwga2V5SW5QYXJlbnQpKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBjdXJyZW50LmxvYz8uc3RhcnQ7XG4gICAgaWYgKGN1cnJlbnQubmFtZSAmJiBzdGFydCkgcmVmZXJlbmNlcy5wdXNoKHsgbmFtZTogY3VycmVudC5uYW1lLCBsaW5lOiBzdGFydC5saW5lLCBjb2x1bW46IHN0YXJ0LmNvbHVtbiB9KTtcbiAgfVxuXG4gIGNvbnN0IG9wZW5zVHlwZSA9IGluVHlwZSB8fCAoY3VycmVudC50eXBlLnN0YXJ0c1dpdGgoJ1RTJykgJiYgIXRzVmFsdWVOb2Rlcy5oYXMoY3VycmVudC50eXBlKSk7XG4gIGZvciAoY29uc3QgY2hpbGRLZXkgb2YgT2JqZWN0LmtleXMoY3VycmVudCkpIHtcbiAgICBpZiAoYXN0U2tpcEtleXMuaGFzKGNoaWxkS2V5KSkgY29udGludWU7XG4gICAgY29uc3QgY2hpbGQgPSBjdXJyZW50W2NoaWxkS2V5XTtcbiAgICBjb25zdCBjaGlsZE9wZW5zVHlwZSA9IHR5cGVvZiBjaGlsZCA9PT0gJ29iamVjdCcgJiYgY2hpbGQgIT09IG51bGwgJiYgdHlwZW9mIChjaGlsZCBhcyBUX0FzdE5vZGUpLnR5cGUgPT09ICdzdHJpbmcnICYmIChjaGlsZCBhcyBUX0FzdE5vZGUpLnR5cGUuc3RhcnRzV2l0aCgnVFMnKSAmJiAhdHNWYWx1ZU5vZGVzLmhhcygoY2hpbGQgYXMgVF9Bc3ROb2RlKS50eXBlKTtcbiAgICBjb25zdCBjaGlsZEluVHlwZSA9IG9wZW5zVHlwZSB8fCBhc3RUeXBlS2V5cy5oYXMoY2hpbGRLZXkpIHx8IGNoaWxkT3BlbnNUeXBlO1xuICAgIHdhbGtBc3ROb2RlKGNoaWxkLCBjdXJyZW50LCBjaGlsZEtleSwgY2hpbGRJblR5cGUsIGRlY2xhcmVkLCByZWZlcmVuY2VzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQYXNzIG5n4buvIG5naMSpYTogYsOhbyBiaeG6v24gQ0jGr0EgS0hBSSBCw4FPLiBU4buxIGR1eeG7h3QgQVNUIChvYmplY3QgdGh14bqnbikg4oCUIEtIw5RORyBkw7luZyBgQGJhYmVsL3RyYXZlcnNlYFxuICogKGPhuqduIGBwcm9jZXNzYCBj4bunYSBOb2RlIOKGkiBjcmFzaCBicm93c2VyKS4gSOG7o3AgbOG7hyA9IGJpbmRpbmcgdHJvbmcgY29kZSArIGdsb2JhbCBKUy9ET00gKyBgY29tcGxldGlvbkxhYmVsc2AuXG4gKi9cbmV4cG9ydCBjb25zdCBjb2xsZWN0VW5kZWNsYXJlZElkZW50aWZpZXJzID0gYXN5bmMgKGFzdDogb2JqZWN0LCBkb2M6IFRleHQsIGNvbXBsZXRpb25MYWJlbHM6IFNldDxzdHJpbmc+LCB0YWludGVkTGluZXM6IFNldDxudW1iZXI+ID0gbmV3IFNldCgpKTogUHJvbWlzZTxEaWFnbm9zdGljW10+ID0+IHtcbiAgY29uc3QgZ2xvYmFsc1NldCA9IGF3YWl0IGdldEtub3duR2xvYmFscygpO1xuICBjb25zdCBkZWNsYXJlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCByZWZlcmVuY2VzOiBUX0FzdFJlZmVyZW5jZVtdID0gW107XG5cbiAgd2Fsa0FzdE5vZGUoYXN0IGFzIFRfQXN0Tm9kZSwgbnVsbCwgJycsIGZhbHNlLCBkZWNsYXJlZCwgcmVmZXJlbmNlcyk7XG5cbiAgY29uc3QgZGlhZ25vc3RpY3M6IERpYWdub3N0aWNbXSA9IFtdO1xuICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgcmVmZXJlbmNlIG9mIHJlZmVyZW5jZXMpIHtcbiAgICBjb25zdCB7IG5hbWUsIGxpbmU6IHN0YXJ0TGluZSwgY29sdW1uOiBzdGFydENvbHVtbiB9ID0gcmVmZXJlbmNlO1xuICAgIGlmIChkZWNsYXJlZC5oYXMobmFtZSkgfHwgZ2xvYmFsc1NldC5oYXMobmFtZSkgfHwgY29tcGxldGlvbkxhYmVscy5oYXMobmFtZSkpIGNvbnRpbnVlO1xuICAgIGlmICh0YWludGVkTGluZXMuaGFzKHN0YXJ0TGluZSkpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVkdXBlS2V5ID0gYCR7c3RhcnRMaW5lfToke3N0YXJ0Q29sdW1ufToke25hbWV9YDtcbiAgICBpZiAoc2Vlbi5oYXMoZGVkdXBlS2V5KSkgY29udGludWU7XG4gICAgc2Vlbi5hZGQoZGVkdXBlS2V5KTtcblxuICAgIGNvbnN0IGxpbmUgPSBkb2MubGluZShNYXRoLm1pbihNYXRoLm1heChzdGFydExpbmUsIDEpLCBkb2MubGluZXMpKTtcbiAgICBjb25zdCBmcm9tID0gTWF0aC5taW4obGluZS5mcm9tICsgTWF0aC5tYXgoc3RhcnRDb2x1bW4sIDApLCBkb2MubGVuZ3RoKTtcbiAgICBjb25zdCB0byA9IE1hdGgubWluKGZyb20gKyBuYW1lLmxlbmd0aCwgZG9jLmxlbmd0aCk7XG4gICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb20sIHRvOiBNYXRoLm1heChmcm9tICsgMSwgdG8pLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZTogYFwiJHtuYW1lfVwiIGlzIG5vdCBkZWZpbmVkYCB9KTtcbiAgfVxuICByZXR1cm4gZGlhZ25vc3RpY3M7XG59O1xuXG4vKipcbiAqIFRvw6BuIGLhu5kgcGlwZWxpbmUgdmFsaWRhdGUgSlMvVFM6XG4gKiAtIFBhc3MgMTogdHJhaWxpbmcgZG90ICh0ZXh0KSDigJQgZmxhZyDEkcO6bmcgduG7iyB0csOtIGThuqV1IGAuYCBjdeG7kWkgZMOybmcgKyDEkcOhbmggZOG6pXUgZMOybmcgdGFpbnRlZC5cbiAqIC0gUGFzcyAyOiBs4buXaSBjw7ogcGjDoXAgYmFiZWwg4oCUIGLhu48gbOG7l2kgdHLDqm4gZMOybmcgdGFpbnRlZCAoY2FzY2FkaW5nKS5cbiAqIC0gUGFzcyAzOiBydWxlIGPhuqduIEFTVCAodGhp4bq/dSBgO2AsIGJp4bq/biBjaMawYSBraGFpIGLDoW8pLiBUcmFpbGluZyBkb3QgxJHGsOG7o2MgXCJ2w6FcIiAoYC5g4oaSc3BhY2UpIMSR4buDIGJhYmVsXG4gKiAgIHbhuqtuIHBhcnNlIMSRxrDhu6NjIHBo4bqnbiBjw7JuIGzhuqFpIOKGkiBydWxlIHbhuqtuIGNo4bqheSBjaG8gY8OhYyBkw7JuZyBLSMOBQy5cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXB1dGVKc0RpYWdub3N0aWNzID0gYXN5bmMgKGRvYzogVGV4dCwgY29kZTogc3RyaW5nLCBjb21wbGV0aW9uTGFiZWxzOiBTZXQ8c3RyaW5nPik6IFByb21pc2U8RGlhZ25vc3RpY1tdPiA9PiB7XG4gIGNvbnN0IGRpYWdub3N0aWNzOiBEaWFnbm9zdGljW10gPSBbXTtcbiAgaWYgKGNvZGUudHJpbSgpID09PSAnJykge1xuICAgIHJldHVybiBkaWFnbm9zdGljcztcbiAgfVxuXG4gIGNvbnN0IHRhaW50ZWRMaW5lcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBjb25zdCBkb3RQb3NpdGlvbnM6IG51bWJlcltdID0gW107XG4gIGNvbGxlY3RUcmFpbGluZ0RvdERpYWdub3N0aWNzKGRvYywgZGlhZ25vc3RpY3MsIHRhaW50ZWRMaW5lcywgZG90UG9zaXRpb25zKTtcblxuICBjb25zdCBwYXJzZUNvZGUgPSByZXBsYWNlQ2hhcnNXaXRoU3BhY2UoY29kZSwgZG90UG9zaXRpb25zKTtcbiAgY29uc3QgcGFyc2VyID0gYXdhaXQgZ2V0QmFiZWxQYXJzZXIoKTtcbiAgY29uc3QgeyBlcnJvcnMsIGFzdCB9ID0gcGFyc2VKcyhwYXJzZXIsIHBhcnNlQ29kZSk7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBlcnJvciBvZiBlcnJvcnMpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IGVycm9yLmxvYztcbiAgICBpZiAoIWxvY2F0aW9uKSBjb250aW51ZTtcbiAgICBjb25zdCBsaW5lTnVtYmVyID0gTWF0aC5taW4oTWF0aC5tYXgobG9jYXRpb24ubGluZSwgMSksIGRvYy5saW5lcyk7XG4gICAgaWYgKHRhaW50ZWRMaW5lcy5oYXMobGluZU51bWJlcikpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGxpbmUgPSBkb2MubGluZShsaW5lTnVtYmVyKTtcbiAgICBjb25zdCBlcnJvclBvcyA9IE1hdGgubWluKGxpbmUuZnJvbSArIE1hdGgubWF4KGxvY2F0aW9uLmNvbHVtbiwgMCksIGRvYy5sZW5ndGgpO1xuICAgIGNvbnN0IHRvID0gTWF0aC5taW4oZXJyb3JQb3MgKyAxLCBkb2MubGVuZ3RoKTtcbiAgICBjb25zdCBmcm9tID0gZXJyb3JQb3MgPj0gdG8gJiYgZXJyb3JQb3MgPiAwID8gZXJyb3JQb3MgLSAxIDogZXJyb3JQb3M7XG4gICAgY29uc3QgbWVzc2FnZSA9IGJ1aWxkSnNFcnJvck1lc3NhZ2UoZG9jLCBlcnJvclBvcywgZXJyb3IubWVzc2FnZSk7XG4gICAgY29uc3QgZGVkdXBlS2V5ID0gYCR7ZnJvbX06JHttZXNzYWdlfWA7XG4gICAgaWYgKHNlZW4uaGFzKGRlZHVwZUtleSkpIGNvbnRpbnVlO1xuICAgIHNlZW4uYWRkKGRlZHVwZUtleSk7XG4gICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb20sIHRvOiBNYXRoLm1heChmcm9tICsgMSwgdG8pLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZSB9KTtcbiAgfVxuXG4gIGlmIChlcnJvcnMubGVuZ3RoID09PSAwICYmIGFzdCkge1xuICAgIGNvbGxlY3RNaXNzaW5nU2VtaWNvbG9uRGlhZ25vc3RpY3MoYXN0LCBjb2RlLCBkaWFnbm9zdGljcywgdGFpbnRlZExpbmVzKTtcbiAgICBkaWFnbm9zdGljcy5wdXNoKC4uLihhd2FpdCBjb2xsZWN0VW5kZWNsYXJlZElkZW50aWZpZXJzKGFzdCwgZG9jLCBjb21wbGV0aW9uTGFiZWxzLCB0YWludGVkTGluZXMpKSk7XG4gIH1cblxuICByZXR1cm4gZGlhZ25vc3RpY3M7XG59O1xuIl19
@@ -0,0 +1,14 @@
1
+ import { get } from '@libs-ui/utils';
2
+ /** Validate JSON bằng `JSON.parse`. Lỗi → 1 diagnostic phủ toàn bộ nội dung. */
3
+ export const computeJsonDiagnostics = (view) => {
4
+ const text = view.state.doc.toString();
5
+ const diagnostics = [];
6
+ try {
7
+ JSON.parse(text);
8
+ }
9
+ catch (error) {
10
+ diagnostics.push({ from: 0, to: text.length, severity: 'error', message: get(error, 'message', '') });
11
+ }
12
+ return diagnostics;
13
+ };
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1saW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvcHJldmlldy10ZXh0LWRhdGEvc3JjL2xpbnRlcnMvanNvbi1saW50ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXJDLGdGQUFnRjtBQUNoRixNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLElBQWdCLEVBQWdCLEVBQUU7SUFDdkUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdkMsTUFBTSxXQUFXLEdBQWlCLEVBQUUsQ0FBQztJQUNyQyxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25CLENBQUM7SUFBQyxPQUFPLEtBQWMsRUFBRSxDQUFDO1FBQ3hCLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4RyxDQUFDO0lBQ0QsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlhZ25vc3RpYyB9IGZyb20gJ0Bjb2RlbWlycm9yL2xpbnQnO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHsgZ2V0IH0gZnJvbSAnQGxpYnMtdWkvdXRpbHMnO1xuXG4vKiogVmFsaWRhdGUgSlNPTiBi4bqxbmcgYEpTT04ucGFyc2VgLiBM4buXaSDihpIgMSBkaWFnbm9zdGljIHBo4bunIHRvw6BuIGLhu5kgbuG7mWkgZHVuZy4gKi9cbmV4cG9ydCBjb25zdCBjb21wdXRlSnNvbkRpYWdub3N0aWNzID0gKHZpZXc6IEVkaXRvclZpZXcpOiBEaWFnbm9zdGljW10gPT4ge1xuICBjb25zdCB0ZXh0ID0gdmlldy5zdGF0ZS5kb2MudG9TdHJpbmcoKTtcbiAgY29uc3QgZGlhZ25vc3RpY3M6IERpYWdub3N0aWNbXSA9IFtdO1xuICB0cnkge1xuICAgIEpTT04ucGFyc2UodGV4dCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb206IDAsIHRvOiB0ZXh0Lmxlbmd0aCwgc2V2ZXJpdHk6ICdlcnJvcicsIG1lc3NhZ2U6IGdldChlcnJvciwgJ21lc3NhZ2UnLCAnJykgfSk7XG4gIH1cbiAgcmV0dXJuIGRpYWdub3N0aWNzO1xufTtcbiJdfQ==