@trebired/code-discipline 4.4.2 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +48 -3
- package/dist/checks/apply-fixes.d.ts +27 -0
- package/dist/checks/apply-fixes.d.ts.map +1 -0
- package/dist/checks/apply-fixes.js +129 -0
- package/dist/checks/apply-fixes.js.map +1 -0
- package/dist/checks/index.d.ts.map +1 -1
- package/dist/checks/index.js +17 -127
- package/dist/checks/index.js.map +1 -1
- package/dist/checks/rule-slugs.d.ts +2 -0
- package/dist/checks/rule-slugs.d.ts.map +1 -1
- package/dist/checks/rule-slugs.js +6 -0
- package/dist/checks/rule-slugs.js.map +1 -1
- package/dist/checks/rules/blank-lines/classify.d.ts +6 -0
- package/dist/checks/rules/blank-lines/classify.d.ts.map +1 -0
- package/dist/checks/rules/blank-lines/classify.js +80 -0
- package/dist/checks/rules/blank-lines/classify.js.map +1 -0
- package/dist/checks/rules/blank-lines/comments.d.ts +7 -0
- package/dist/checks/rules/blank-lines/comments.d.ts.map +1 -0
- package/dist/checks/rules/blank-lines/comments.js +68 -0
- package/dist/checks/rules/blank-lines/comments.js.map +1 -0
- package/dist/checks/rules/blank-lines/index.d.ts +7 -0
- package/dist/checks/rules/blank-lines/index.d.ts.map +1 -0
- package/dist/checks/rules/blank-lines/index.js +89 -0
- package/dist/checks/rules/blank-lines/index.js.map +1 -0
- package/dist/checks/rules/blank-lines/rewrite.d.ts +14 -0
- package/dist/checks/rules/blank-lines/rewrite.d.ts.map +1 -0
- package/dist/checks/rules/blank-lines/rewrite.js +122 -0
- package/dist/checks/rules/blank-lines/rewrite.js.map +1 -0
- package/dist/checks/rules/blank-lines/types.d.ts +21 -0
- package/dist/checks/rules/blank-lines/types.d.ts.map +1 -0
- package/dist/checks/rules/blank-lines/types.js +2 -0
- package/dist/checks/rules/blank-lines/types.js.map +1 -0
- package/dist/checks/rules/ts-nocheck-audit/index.d.ts +7 -0
- package/dist/checks/rules/ts-nocheck-audit/index.d.ts.map +1 -0
- package/dist/checks/rules/ts-nocheck-audit/index.js +76 -0
- package/dist/checks/rules/ts-nocheck-audit/index.js.map +1 -0
- package/dist/checks/rules/ts-nocheck-audit/pragma.d.ts +12 -0
- package/dist/checks/rules/ts-nocheck-audit/pragma.d.ts.map +1 -0
- package/dist/checks/rules/ts-nocheck-audit/pragma.js +33 -0
- package/dist/checks/rules/ts-nocheck-audit/pragma.js.map +1 -0
- package/dist/checks/rules/ts-nocheck-audit/program.d.ts +14 -0
- package/dist/checks/rules/ts-nocheck-audit/program.d.ts.map +1 -0
- package/dist/checks/rules/ts-nocheck-audit/program.js +50 -0
- package/dist/checks/rules/ts-nocheck-audit/program.js.map +1 -0
- package/dist/checks/severity.d.ts +5 -0
- package/dist/checks/severity.d.ts.map +1 -0
- package/dist/checks/severity.js +29 -0
- package/dist/checks/severity.js.map +1 -0
- package/dist/checks/types.d.ts +24 -2
- package/dist/checks/types.d.ts.map +1 -1
- package/dist/config/normalize/check-options.d.ts.map +1 -1
- package/dist/config/normalize/check-options.js +3 -1
- package/dist/config/normalize/check-options.js.map +1 -1
- package/dist/config/normalize/rule-options.d.ts +11 -2
- package/dist/config/normalize/rule-options.d.ts.map +1 -1
- package/dist/config/normalize/rule-options.js +42 -1
- package/dist/config/normalize/rule-options.js.map +1 -1
- package/dist/imports/module-specifiers.d.ts +2 -1
- package/dist/imports/module-specifiers.d.ts.map +1 -1
- package/dist/imports/module-specifiers.js +1 -1
- package/dist/imports/module-specifiers.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/shared/discipline-types.d.ts +1 -1
- package/dist/shared/discipline-types.d.ts.map +1 -1
- package/dist/shared/languages.d.ts +3 -1
- package/dist/shared/languages.d.ts.map +1 -1
- package/dist/shared/languages.js +13 -1
- package/dist/shared/languages.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { getLine, resolveAttachedStartLine } from "./comments.js";
|
|
3
|
+
function resolveDeclarationName(node) {
|
|
4
|
+
if (ts.isFunctionDeclaration(node)
|
|
5
|
+
|| ts.isMethodDeclaration(node)
|
|
6
|
+
|| ts.isGetAccessorDeclaration(node)
|
|
7
|
+
|| ts.isSetAccessorDeclaration(node)) {
|
|
8
|
+
return node.name?.getText();
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
function classifyStatement(node, isDirectiveCandidate) {
|
|
13
|
+
if (ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node))
|
|
14
|
+
return "import";
|
|
15
|
+
if (ts.isExportDeclaration(node) || ts.isExportAssignment(node))
|
|
16
|
+
return "export";
|
|
17
|
+
if (isDirectiveCandidate)
|
|
18
|
+
return "directive";
|
|
19
|
+
if (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node))
|
|
20
|
+
return "type";
|
|
21
|
+
if (ts.isVariableStatement(node))
|
|
22
|
+
return "variable";
|
|
23
|
+
if (ts.isFunctionDeclaration(node))
|
|
24
|
+
return "function";
|
|
25
|
+
if (ts.isClassDeclaration(node))
|
|
26
|
+
return "class";
|
|
27
|
+
if (ts.isEnumDeclaration(node))
|
|
28
|
+
return "enum";
|
|
29
|
+
if (ts.isModuleDeclaration(node))
|
|
30
|
+
return "namespace";
|
|
31
|
+
return "execution";
|
|
32
|
+
}
|
|
33
|
+
function classifyMember(node) {
|
|
34
|
+
if (ts.isPropertyDeclaration(node) || ts.isIndexSignatureDeclaration(node))
|
|
35
|
+
return "class-field";
|
|
36
|
+
if (ts.isConstructorDeclaration(node))
|
|
37
|
+
return "class-constructor";
|
|
38
|
+
if (ts.isMethodDeclaration(node))
|
|
39
|
+
return "class-method";
|
|
40
|
+
if (ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node))
|
|
41
|
+
return "class-accessor";
|
|
42
|
+
if (ts.isClassStaticBlockDeclaration(node))
|
|
43
|
+
return "class-static-block";
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
function buildStatementUnits(sourceFile, fullText, statements, notBeforePos) {
|
|
47
|
+
const units = [];
|
|
48
|
+
let inDirectivePrologue = true;
|
|
49
|
+
statements.forEach((node, index) => {
|
|
50
|
+
const isDirectiveCandidate = inDirectivePrologue && ts.isExpressionStatement(node) && ts.isStringLiteralLike(node.expression);
|
|
51
|
+
if (inDirectivePrologue && !isDirectiveCandidate)
|
|
52
|
+
inDirectivePrologue = false;
|
|
53
|
+
units.push({
|
|
54
|
+
group: classifyStatement(node, isDirectiveCandidate),
|
|
55
|
+
name: resolveDeclarationName(node),
|
|
56
|
+
startLine: resolveAttachedStartLine(sourceFile, fullText, node, index === 0 ? notBeforePos : 0),
|
|
57
|
+
endLine: getLine(sourceFile, node.getEnd()),
|
|
58
|
+
node,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
return units;
|
|
62
|
+
}
|
|
63
|
+
function buildMemberUnits(sourceFile, fullText, members) {
|
|
64
|
+
const units = [];
|
|
65
|
+
for (const node of members) {
|
|
66
|
+
const group = classifyMember(node);
|
|
67
|
+
if (!group)
|
|
68
|
+
continue;
|
|
69
|
+
units.push({
|
|
70
|
+
group,
|
|
71
|
+
name: resolveDeclarationName(node),
|
|
72
|
+
startLine: resolveAttachedStartLine(sourceFile, fullText, node, 0),
|
|
73
|
+
endLine: getLine(sourceFile, node.getEnd()),
|
|
74
|
+
node,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return units;
|
|
78
|
+
}
|
|
79
|
+
export { buildMemberUnits, buildStatementUnits };
|
|
80
|
+
//# sourceMappingURL=classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/classify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { HeaderSegment } from "./types.js";
|
|
3
|
+
declare function getLine(sourceFile: ts.SourceFile, pos: number): number;
|
|
4
|
+
declare function resolveFileHeaderSegments(sourceFile: ts.SourceFile, fullText: string): HeaderSegment[];
|
|
5
|
+
declare function resolveAttachedStartLine(sourceFile: ts.SourceFile, fullText: string, node: ts.Node, notBeforePos: number): number;
|
|
6
|
+
export { getLine, resolveAttachedStartLine, resolveFileHeaderSegments };
|
|
7
|
+
//# sourceMappingURL=comments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAmBhD,iBAAS,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/D;AAQD,iBAAS,yBAAyB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAyB/F;AAED,iBAAS,wBAAwB,CAC/B,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,YAAY,EAAE,MAAM,GACnB,MAAM,CAqBR;AAED,OAAO,EAAE,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
const HEADER_COMMENT_MARKERS = [
|
|
3
|
+
"@ts-nocheck",
|
|
4
|
+
"@ts-check",
|
|
5
|
+
"eslint-disable",
|
|
6
|
+
"prettier-ignore",
|
|
7
|
+
"generated by",
|
|
8
|
+
"auto-generated",
|
|
9
|
+
"do not edit",
|
|
10
|
+
"@license",
|
|
11
|
+
"spdx-license-identifier",
|
|
12
|
+
];
|
|
13
|
+
function isHeaderCommentText(text) {
|
|
14
|
+
const normalized = text.toLowerCase();
|
|
15
|
+
return HEADER_COMMENT_MARKERS.some((marker) => normalized.includes(marker));
|
|
16
|
+
}
|
|
17
|
+
function getLine(sourceFile, pos) {
|
|
18
|
+
return sourceFile.getLineAndCharacterOfPosition(pos).line + 1;
|
|
19
|
+
}
|
|
20
|
+
function resolveShebangEnd(fullText) {
|
|
21
|
+
if (!fullText.startsWith("#!"))
|
|
22
|
+
return 0;
|
|
23
|
+
const newlineIndex = fullText.indexOf("\n");
|
|
24
|
+
return newlineIndex === -1 ? fullText.length : newlineIndex + 1;
|
|
25
|
+
}
|
|
26
|
+
function resolveFileHeaderSegments(sourceFile, fullText) {
|
|
27
|
+
const segments = [];
|
|
28
|
+
const shebangEnd = resolveShebangEnd(fullText);
|
|
29
|
+
if (shebangEnd > 0) {
|
|
30
|
+
segments.push({
|
|
31
|
+
startLine: 1,
|
|
32
|
+
endLine: getLine(sourceFile, Math.max(0, shebangEnd - 1)),
|
|
33
|
+
endPos: shebangEnd,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const commentRanges = ts.getLeadingCommentRanges(fullText, shebangEnd) ?? [];
|
|
37
|
+
for (const range of commentRanges) {
|
|
38
|
+
if (!isHeaderCommentText(fullText.slice(range.pos, range.end)))
|
|
39
|
+
break;
|
|
40
|
+
segments.push({
|
|
41
|
+
startLine: getLine(sourceFile, range.pos),
|
|
42
|
+
endLine: getLine(sourceFile, range.end),
|
|
43
|
+
endPos: range.end,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return segments;
|
|
47
|
+
}
|
|
48
|
+
function resolveAttachedStartLine(sourceFile, fullText, node, notBeforePos) {
|
|
49
|
+
const nodeStart = node.getStart(sourceFile);
|
|
50
|
+
const searchStart = Math.max(node.getFullStart(), notBeforePos);
|
|
51
|
+
const commentRanges = (ts.getLeadingCommentRanges(fullText, searchStart) ?? [])
|
|
52
|
+
.filter((range) => range.pos >= notBeforePos && range.end <= nodeStart);
|
|
53
|
+
if (commentRanges.length === 0)
|
|
54
|
+
return getLine(sourceFile, nodeStart);
|
|
55
|
+
let cursorPos = nodeStart;
|
|
56
|
+
let attachedStart = nodeStart;
|
|
57
|
+
for (let index = commentRanges.length - 1; index >= 0; index -= 1) {
|
|
58
|
+
const range = commentRanges[index];
|
|
59
|
+
const gap = getLine(sourceFile, cursorPos) - getLine(sourceFile, range.end);
|
|
60
|
+
if (gap > 1)
|
|
61
|
+
break;
|
|
62
|
+
attachedStart = range.pos;
|
|
63
|
+
cursorPos = range.pos;
|
|
64
|
+
}
|
|
65
|
+
return getLine(sourceFile, attachedStart);
|
|
66
|
+
}
|
|
67
|
+
export { getLine, resolveAttachedStartLine, resolveFileHeaderSegments };
|
|
68
|
+
//# sourceMappingURL=comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/comments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScannedSourceFile } from "../../../imports/types.js";
|
|
2
|
+
import type { CodeDisciplineViolation } from "../../../shared/discipline-types.js";
|
|
3
|
+
import type { FixCodeDisciplineRuleResult, NormalizedCheckCodeDisciplineOptions } from "../../types.js";
|
|
4
|
+
declare function collectStructuralBlankLinesViolations(sourceFiles: ScannedSourceFile[], options: NormalizedCheckCodeDisciplineOptions): Promise<CodeDisciplineViolation[]>;
|
|
5
|
+
declare function fixStructuralBlankLinesRule(sourceFiles: ScannedSourceFile[], options: NormalizedCheckCodeDisciplineOptions): Promise<FixCodeDisciplineRuleResult>;
|
|
6
|
+
export { collectStructuralBlankLinesViolations, fixStructuralBlankLinesRule };
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAGnF,OAAO,KAAK,EAAE,2BAA2B,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;AAsBxG,iBAAe,qCAAqC,CAClD,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAiCpC;AAED,iBAAe,2BAA2B,CACxC,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,2BAA2B,CAAC,CA4CtC;AAED,OAAO,EAAE,qCAAqC,EAAE,2BAA2B,EAAE,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseSource } from "../../../imports/module-specifiers.js";
|
|
4
|
+
import { isTypeScriptFamilyExtension } from "../../../shared/languages.js";
|
|
5
|
+
import { createRuleProgress, emitRuleChunk, emitRuleCompleted } from "../../progress.js";
|
|
6
|
+
import { rewriteStructuralBlankLines } from "./rewrite.js";
|
|
7
|
+
function createStructuralBlankLinesViolation(args) {
|
|
8
|
+
return {
|
|
9
|
+
rule: "structural-blank-lines",
|
|
10
|
+
fix: true,
|
|
11
|
+
filePath: args.filePath,
|
|
12
|
+
message: `file has ${args.boundaryCount} structural boundar${args.boundaryCount === 1 ? "y" : "ies"} with incorrect blank line spacing`,
|
|
13
|
+
details: {
|
|
14
|
+
boundaryCount: args.boundaryCount,
|
|
15
|
+
insertedBlankLines: args.insertedBlankLines,
|
|
16
|
+
removedBlankLines: args.removedBlankLines,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async function collectStructuralBlankLinesViolations(sourceFiles, options) {
|
|
21
|
+
const violations = [];
|
|
22
|
+
const progress = createRuleProgress({
|
|
23
|
+
observer: options.progressObserver,
|
|
24
|
+
rule: "structural-blank-lines",
|
|
25
|
+
totalItems: sourceFiles.length,
|
|
26
|
+
});
|
|
27
|
+
for (let index = 0; index < sourceFiles.length; index += 1) {
|
|
28
|
+
const file = sourceFiles[index];
|
|
29
|
+
if (!isTypeScriptFamilyExtension(path.extname(file.absolutePath).toLowerCase())) {
|
|
30
|
+
emitRuleChunk(progress, index + 1, violations.length);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const sourceText = await fs.readFile(file.absolutePath, "utf8");
|
|
34
|
+
const sourceFile = parseSource(sourceText, file.absolutePath);
|
|
35
|
+
const result = rewriteStructuralBlankLines(sourceFile, sourceText);
|
|
36
|
+
if (result.changed) {
|
|
37
|
+
violations.push(createStructuralBlankLinesViolation({
|
|
38
|
+
filePath: file.relativeFromProjectRoot,
|
|
39
|
+
boundaryCount: result.boundaryCount,
|
|
40
|
+
insertedBlankLines: result.insertedBlankLines,
|
|
41
|
+
removedBlankLines: result.removedBlankLines,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
emitRuleChunk(progress, index + 1, violations.length);
|
|
45
|
+
}
|
|
46
|
+
emitRuleCompleted(progress, violations.length);
|
|
47
|
+
return violations;
|
|
48
|
+
}
|
|
49
|
+
async function fixStructuralBlankLinesRule(sourceFiles, options) {
|
|
50
|
+
const progress = createRuleProgress({
|
|
51
|
+
observer: options.progressObserver,
|
|
52
|
+
rule: "structural-blank-lines",
|
|
53
|
+
stage: "fix",
|
|
54
|
+
totalItems: sourceFiles.length,
|
|
55
|
+
});
|
|
56
|
+
let rewrittenFiles = 0;
|
|
57
|
+
let insertedBlankLines = 0;
|
|
58
|
+
let removedBlankLines = 0;
|
|
59
|
+
for (let index = 0; index < sourceFiles.length; index += 1) {
|
|
60
|
+
const file = sourceFiles[index];
|
|
61
|
+
if (!isTypeScriptFamilyExtension(path.extname(file.absolutePath).toLowerCase())) {
|
|
62
|
+
emitRuleChunk(progress, index + 1, 0, { rewrittenFiles });
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const sourceText = await fs.readFile(file.absolutePath, "utf8");
|
|
66
|
+
const sourceFile = parseSource(sourceText, file.absolutePath);
|
|
67
|
+
const result = rewriteStructuralBlankLines(sourceFile, sourceText);
|
|
68
|
+
if (!result.changed) {
|
|
69
|
+
emitRuleChunk(progress, index + 1, 0, { rewrittenFiles });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
await fs.writeFile(file.absolutePath, result.text, "utf8");
|
|
73
|
+
rewrittenFiles += 1;
|
|
74
|
+
insertedBlankLines += result.insertedBlankLines;
|
|
75
|
+
removedBlankLines += result.removedBlankLines;
|
|
76
|
+
emitRuleChunk(progress, index + 1, 0, { rewrittenFiles });
|
|
77
|
+
}
|
|
78
|
+
emitRuleCompleted(progress, 0, { rewrittenFiles });
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
violationCount: 0,
|
|
82
|
+
violations: [],
|
|
83
|
+
rewritten_files: rewrittenFiles,
|
|
84
|
+
inserted_blank_lines: insertedBlankLines,
|
|
85
|
+
removed_blank_lines: removedBlankLines,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export { collectStructuralBlankLinesViolations, fixStructuralBlankLinesRule };
|
|
89
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { BoundaryEdit } from "./types.js";
|
|
3
|
+
declare function collectBoundaryEdits(sourceFile: ts.SourceFile, fullText: string): BoundaryEdit[];
|
|
4
|
+
type ApplyBoundaryEditsResult = {
|
|
5
|
+
text: string;
|
|
6
|
+
changed: boolean;
|
|
7
|
+
boundaryCount: number;
|
|
8
|
+
insertedBlankLines: number;
|
|
9
|
+
removedBlankLines: number;
|
|
10
|
+
};
|
|
11
|
+
declare function rewriteStructuralBlankLines(sourceFile: ts.SourceFile, fullText: string): ApplyBoundaryEditsResult;
|
|
12
|
+
export { collectBoundaryEdits, rewriteStructuralBlankLines };
|
|
13
|
+
export type { ApplyBoundaryEditsResult };
|
|
14
|
+
//# sourceMappingURL=rewrite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/rewrite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAI5B,OAAO,KAAK,EAAE,YAAY,EAAkD,MAAM,YAAY,CAAC;AAkG/F,iBAAS,oBAAoB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAUzF;AAED,KAAK,wBAAwB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AA6BF,iBAAS,2BAA2B,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,wBAAwB,CAG1G;AAED,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,CAAC;AAC7D,YAAY,EAAE,wBAAwB,EAAE,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { buildMemberUnits, buildStatementUnits } from "./classify.js";
|
|
3
|
+
import { resolveFileHeaderSegments } from "./comments.js";
|
|
4
|
+
const COMPACT_GROUPS = new Set([
|
|
5
|
+
"directive",
|
|
6
|
+
"import",
|
|
7
|
+
"export",
|
|
8
|
+
"type",
|
|
9
|
+
"variable",
|
|
10
|
+
"execution",
|
|
11
|
+
"class-field",
|
|
12
|
+
]);
|
|
13
|
+
const OVERLOAD_LIKE_GROUPS = new Set([
|
|
14
|
+
"function",
|
|
15
|
+
"class-method",
|
|
16
|
+
"class-accessor",
|
|
17
|
+
]);
|
|
18
|
+
function isCompactPair(previous, next) {
|
|
19
|
+
if (previous.group !== next.group)
|
|
20
|
+
return false;
|
|
21
|
+
if (COMPACT_GROUPS.has(previous.group))
|
|
22
|
+
return true;
|
|
23
|
+
return OVERLOAD_LIKE_GROUPS.has(previous.group) && Boolean(previous.name) && previous.name === next.name;
|
|
24
|
+
}
|
|
25
|
+
function computePairwiseEdits(units) {
|
|
26
|
+
const edits = [];
|
|
27
|
+
for (let index = 1; index < units.length; index += 1) {
|
|
28
|
+
const previous = units[index - 1];
|
|
29
|
+
const next = units[index];
|
|
30
|
+
const gap = next.startLine - previous.endLine - 1;
|
|
31
|
+
const target = isCompactPair(previous, next) ? Math.min(gap, 1) : 1;
|
|
32
|
+
if (target === gap)
|
|
33
|
+
continue;
|
|
34
|
+
edits.push({
|
|
35
|
+
atLine: previous.endLine + 1,
|
|
36
|
+
removeCount: Math.max(0, gap - target),
|
|
37
|
+
insertCount: Math.max(0, target - gap),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return edits;
|
|
41
|
+
}
|
|
42
|
+
function computeHeaderEdits(headerSegments, firstUnit) {
|
|
43
|
+
if (headerSegments.length === 0 || !firstUnit)
|
|
44
|
+
return [];
|
|
45
|
+
const edits = [];
|
|
46
|
+
for (let index = 1; index < headerSegments.length; index += 1) {
|
|
47
|
+
const previous = headerSegments[index - 1];
|
|
48
|
+
const next = headerSegments[index];
|
|
49
|
+
const gap = next.startLine - previous.endLine - 1;
|
|
50
|
+
const target = Math.min(gap, 1);
|
|
51
|
+
if (target === gap)
|
|
52
|
+
continue;
|
|
53
|
+
edits.push({ atLine: previous.endLine + 1, removeCount: gap - target, insertCount: 0 });
|
|
54
|
+
}
|
|
55
|
+
const lastHeader = headerSegments[headerSegments.length - 1];
|
|
56
|
+
const gap = firstUnit.startLine - lastHeader.endLine - 1;
|
|
57
|
+
if (gap !== 1) {
|
|
58
|
+
edits.push({
|
|
59
|
+
atLine: lastHeader.endLine + 1,
|
|
60
|
+
removeCount: Math.max(0, gap - 1),
|
|
61
|
+
insertCount: Math.max(0, 1 - gap),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return edits;
|
|
65
|
+
}
|
|
66
|
+
function isClassLikeDeclaration(node) {
|
|
67
|
+
return ts.isClassDeclaration(node) || ts.isClassExpression(node);
|
|
68
|
+
}
|
|
69
|
+
function collectNestedEdits(sourceFile, fullText, units) {
|
|
70
|
+
const edits = [];
|
|
71
|
+
for (const unit of units) {
|
|
72
|
+
if (isClassLikeDeclaration(unit.node)) {
|
|
73
|
+
const memberUnits = buildMemberUnits(sourceFile, fullText, unit.node.members);
|
|
74
|
+
edits.push(...computePairwiseEdits(memberUnits));
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (ts.isModuleDeclaration(unit.node) && unit.node.body && ts.isModuleBlock(unit.node.body)) {
|
|
78
|
+
const nestedUnits = buildStatementUnits(sourceFile, fullText, unit.node.body.statements, 0);
|
|
79
|
+
edits.push(...computePairwiseEdits(nestedUnits));
|
|
80
|
+
edits.push(...collectNestedEdits(sourceFile, fullText, nestedUnits));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return edits;
|
|
84
|
+
}
|
|
85
|
+
function collectBoundaryEdits(sourceFile, fullText) {
|
|
86
|
+
const headerSegments = resolveFileHeaderSegments(sourceFile, fullText);
|
|
87
|
+
const notBeforePos = headerSegments.length > 0 ? headerSegments[headerSegments.length - 1].endPos : 0;
|
|
88
|
+
const topUnits = buildStatementUnits(sourceFile, fullText, sourceFile.statements, notBeforePos);
|
|
89
|
+
return [
|
|
90
|
+
...computeHeaderEdits(headerSegments, topUnits[0]),
|
|
91
|
+
...computePairwiseEdits(topUnits),
|
|
92
|
+
...collectNestedEdits(sourceFile, fullText, topUnits),
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
function applyBoundaryEdits(text, edits) {
|
|
96
|
+
if (edits.length === 0) {
|
|
97
|
+
return { text, changed: false, boundaryCount: 0, insertedBlankLines: 0, removedBlankLines: 0 };
|
|
98
|
+
}
|
|
99
|
+
const newline = text.includes("\r\n") ? "\r\n" : "\n";
|
|
100
|
+
const lines = text.split(/\r\n|\n/);
|
|
101
|
+
const sorted = [...edits].sort((left, right) => right.atLine - left.atLine);
|
|
102
|
+
let insertedBlankLines = 0;
|
|
103
|
+
let removedBlankLines = 0;
|
|
104
|
+
for (const edit of sorted) {
|
|
105
|
+
lines.splice(edit.atLine - 1, edit.removeCount, ...Array.from({ length: edit.insertCount }, () => ""));
|
|
106
|
+
insertedBlankLines += edit.insertCount;
|
|
107
|
+
removedBlankLines += edit.removeCount;
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
text: lines.join(newline),
|
|
111
|
+
changed: true,
|
|
112
|
+
boundaryCount: edits.length,
|
|
113
|
+
insertedBlankLines,
|
|
114
|
+
removedBlankLines,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function rewriteStructuralBlankLines(sourceFile, fullText) {
|
|
118
|
+
const edits = collectBoundaryEdits(sourceFile, fullText);
|
|
119
|
+
return applyBoundaryEdits(fullText, edits);
|
|
120
|
+
}
|
|
121
|
+
export { collectBoundaryEdits, rewriteStructuralBlankLines };
|
|
122
|
+
//# sourceMappingURL=rewrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewrite.js","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/rewrite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type ts from "typescript";
|
|
2
|
+
type StructuralGroup = "directive" | "import" | "type" | "variable" | "function" | "class" | "enum" | "namespace" | "export" | "execution" | "class-field" | "class-method" | "class-accessor" | "class-constructor" | "class-static-block";
|
|
3
|
+
type StructuralUnit = {
|
|
4
|
+
group: StructuralGroup;
|
|
5
|
+
name?: string;
|
|
6
|
+
startLine: number;
|
|
7
|
+
endLine: number;
|
|
8
|
+
node: ts.Node;
|
|
9
|
+
};
|
|
10
|
+
type HeaderSegment = {
|
|
11
|
+
startLine: number;
|
|
12
|
+
endLine: number;
|
|
13
|
+
endPos: number;
|
|
14
|
+
};
|
|
15
|
+
type BoundaryEdit = {
|
|
16
|
+
atLine: number;
|
|
17
|
+
removeCount: number;
|
|
18
|
+
insertCount: number;
|
|
19
|
+
};
|
|
20
|
+
export type { BoundaryEdit, HeaderSegment, StructuralGroup, StructuralUnit };
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,KAAK,eAAe,GAChB,WAAW,GACX,QAAQ,GACR,MAAM,GACN,UAAU,GACV,UAAU,GACV,OAAO,GACP,MAAM,GACN,WAAW,GACX,QAAQ,GACR,WAAW,GACX,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,CAAC;AAEzB,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;CACf,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/checks/rules/blank-lines/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScannedSourceFile } from "../../../imports/types.js";
|
|
2
|
+
import type { CodeDisciplineViolation } from "../../../shared/discipline-types.js";
|
|
3
|
+
import type { FixCodeDisciplineRuleResult, NormalizedCheckCodeDisciplineOptions } from "../../types.js";
|
|
4
|
+
declare function collectTsNocheckAuditViolations(sourceFiles: ScannedSourceFile[], options: NormalizedCheckCodeDisciplineOptions): Promise<CodeDisciplineViolation[]>;
|
|
5
|
+
declare function fixTsNocheckAuditRule(sourceFiles: ScannedSourceFile[], options: NormalizedCheckCodeDisciplineOptions): Promise<FixCodeDisciplineRuleResult>;
|
|
6
|
+
export { collectTsNocheckAuditViolations, fixTsNocheckAuditRule };
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/checks/rules/ts-nocheck-audit/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAGnF,OAAO,KAAK,EAAE,2BAA2B,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;AA6ExG,iBAAe,+BAA+B,CAC5C,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAGpC;AAED,iBAAe,qBAAqB,CAClC,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,2BAA2B,CAAC,CAatC;AAED,OAAO,EAAE,+BAA+B,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { supportsTsNocheckAudit } from "../../../shared/languages.js";
|
|
3
|
+
import { createRuleProgress, emitRuleChunk, emitRuleCompleted } from "../../progress.js";
|
|
4
|
+
import { buildStrippedProgram, getSemanticDiagnosticCount, resolveTsconfigPath } from "./program.js";
|
|
5
|
+
import { findLeadingTsNocheckLine, removeLeadingTsNocheckLine } from "./pragma.js";
|
|
6
|
+
async function findUnnecessaryPragmaFiles(sourceFiles, options, stage) {
|
|
7
|
+
const progress = createRuleProgress({
|
|
8
|
+
observer: options.progressObserver,
|
|
9
|
+
rule: "ts-nocheck-audit",
|
|
10
|
+
stage,
|
|
11
|
+
totalItems: sourceFiles.length,
|
|
12
|
+
});
|
|
13
|
+
const candidates = [];
|
|
14
|
+
for (let index = 0; index < sourceFiles.length; index += 1) {
|
|
15
|
+
const file = sourceFiles[index];
|
|
16
|
+
if (!supportsTsNocheckAudit(file.extension)) {
|
|
17
|
+
emitRuleChunk(progress, index + 1, candidates.length);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const text = await fs.readFile(file.absolutePath, "utf8");
|
|
21
|
+
if (findLeadingTsNocheckLine(text)) {
|
|
22
|
+
candidates.push({ file, text });
|
|
23
|
+
}
|
|
24
|
+
emitRuleChunk(progress, index + 1, candidates.length);
|
|
25
|
+
}
|
|
26
|
+
if (candidates.length === 0) {
|
|
27
|
+
emitRuleCompleted(progress, 0);
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const tsconfigPath = resolveTsconfigPath(options.projectRoot, options.rules.tsNocheckAudit?.tsconfigPath);
|
|
31
|
+
const program = await buildStrippedProgram({
|
|
32
|
+
tsconfigPath,
|
|
33
|
+
candidates: candidates.map(({ file, text }) => ({ absolutePath: file.absolutePath, text })),
|
|
34
|
+
});
|
|
35
|
+
const unnecessary = [];
|
|
36
|
+
for (const candidate of candidates) {
|
|
37
|
+
const diagnosticCount = getSemanticDiagnosticCount(program, candidate.file.absolutePath);
|
|
38
|
+
if (diagnosticCount !== 0)
|
|
39
|
+
continue;
|
|
40
|
+
const { text: strippedText, removed } = removeLeadingTsNocheckLine(candidate.text);
|
|
41
|
+
if (!removed)
|
|
42
|
+
continue;
|
|
43
|
+
unnecessary.push({ file: candidate.file, strippedText });
|
|
44
|
+
}
|
|
45
|
+
emitRuleCompleted(progress, unnecessary.length);
|
|
46
|
+
return unnecessary;
|
|
47
|
+
}
|
|
48
|
+
function createTsNocheckAuditViolation(file) {
|
|
49
|
+
return {
|
|
50
|
+
rule: "ts-nocheck-audit",
|
|
51
|
+
fix: true,
|
|
52
|
+
filePath: file.relativeFromProjectRoot,
|
|
53
|
+
message: "@ts-nocheck is unnecessary — no diagnostics are reported without it",
|
|
54
|
+
details: {
|
|
55
|
+
diagnosticCount: 0,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function collectTsNocheckAuditViolations(sourceFiles, options) {
|
|
60
|
+
const unnecessary = await findUnnecessaryPragmaFiles(sourceFiles, options, "scan");
|
|
61
|
+
return unnecessary.map(({ file }) => createTsNocheckAuditViolation(file));
|
|
62
|
+
}
|
|
63
|
+
async function fixTsNocheckAuditRule(sourceFiles, options) {
|
|
64
|
+
const unnecessary = await findUnnecessaryPragmaFiles(sourceFiles, options, "fix");
|
|
65
|
+
for (const { file, strippedText } of unnecessary) {
|
|
66
|
+
await fs.writeFile(file.absolutePath, strippedText, "utf8");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
ok: true,
|
|
70
|
+
violationCount: 0,
|
|
71
|
+
violations: [],
|
|
72
|
+
rewritten_files: unnecessary.length,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export { collectTsNocheckAuditViolations, fixTsNocheckAuditRule };
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/checks/rules/ts-nocheck-audit/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type PragmaLineRange = {
|
|
2
|
+
start: number;
|
|
3
|
+
end: number;
|
|
4
|
+
};
|
|
5
|
+
declare function findLeadingTsNocheckLine(text: string): PragmaLineRange | null;
|
|
6
|
+
declare function removeLeadingTsNocheckLine(text: string): {
|
|
7
|
+
text: string;
|
|
8
|
+
removed: boolean;
|
|
9
|
+
};
|
|
10
|
+
export { findLeadingTsNocheckLine, removeLeadingTsNocheckLine };
|
|
11
|
+
export type { PragmaLineRange };
|
|
12
|
+
//# sourceMappingURL=pragma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pragma.d.ts","sourceRoot":"","sources":["../../../../src/checks/rules/ts-nocheck-audit/pragma.ts"],"names":[],"mappings":"AAEA,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,iBAAS,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA0BtE;AAED,iBAAS,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAQpF;AAED,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const TS_NOCHECK_LINE_PATTERN = /^\/\/\s*@ts-nocheck(?:\s.*)?$/;
|
|
2
|
+
function findLeadingTsNocheckLine(text) {
|
|
3
|
+
let cursor = 0;
|
|
4
|
+
if (text.startsWith("#!")) {
|
|
5
|
+
const shebangEnd = text.indexOf("\n");
|
|
6
|
+
cursor = shebangEnd === -1 ? text.length : shebangEnd + 1;
|
|
7
|
+
}
|
|
8
|
+
while (cursor < text.length) {
|
|
9
|
+
const newlineIndex = text.indexOf("\n", cursor);
|
|
10
|
+
const lineEnd = newlineIndex === -1 ? text.length : newlineIndex;
|
|
11
|
+
const line = text.slice(cursor, lineEnd);
|
|
12
|
+
if (line.trim() === "") {
|
|
13
|
+
cursor = newlineIndex === -1 ? text.length : newlineIndex + 1;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (TS_NOCHECK_LINE_PATTERN.test(line.trim())) {
|
|
17
|
+
return { start: cursor, end: newlineIndex === -1 ? text.length : newlineIndex + 1 };
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function removeLeadingTsNocheckLine(text) {
|
|
24
|
+
const range = findLeadingTsNocheckLine(text);
|
|
25
|
+
if (!range)
|
|
26
|
+
return { text, removed: false };
|
|
27
|
+
return {
|
|
28
|
+
text: text.slice(0, range.start) + text.slice(range.end),
|
|
29
|
+
removed: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export { findLeadingTsNocheckLine, removeLeadingTsNocheckLine };
|
|
33
|
+
//# sourceMappingURL=pragma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pragma.js","sourceRoot":"","sources":["../../../../src/checks/rules/ts-nocheck-audit/pragma.ts"],"names":[],"mappings":"AAAA,MAAM,uBAAuB,GAAG,+BAA+B,CAAC;AAOhE,SAAS,wBAAwB,CAAC,IAAY;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEzC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC;YAC9D,SAAS;QACX,CAAC;QAED,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QACtF,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC9C,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;QACxD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,CAAC"}
|