eff-u-code 2.0.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/LICENSE +21 -0
- package/README.md +256 -0
- package/bin/fuck-u-code-mcp.js +2 -0
- package/bin/fuck-u-code.js +2 -0
- package/bin/postinstall.js +53 -0
- package/dist/ai/index.d.ts +34 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +227 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts/code-review.d.ts +9 -0
- package/dist/ai/prompts/code-review.d.ts.map +1 -0
- package/dist/ai/prompts/code-review.js +61 -0
- package/dist/ai/prompts/code-review.js.map +1 -0
- package/dist/ai/providers/anthropic.d.ts +11 -0
- package/dist/ai/providers/anthropic.d.ts.map +1 -0
- package/dist/ai/providers/anthropic.js +60 -0
- package/dist/ai/providers/anthropic.js.map +1 -0
- package/dist/ai/providers/fetch.d.ts +10 -0
- package/dist/ai/providers/fetch.d.ts.map +1 -0
- package/dist/ai/providers/fetch.js +50 -0
- package/dist/ai/providers/fetch.js.map +1 -0
- package/dist/ai/providers/gemini.d.ts +12 -0
- package/dist/ai/providers/gemini.d.ts.map +1 -0
- package/dist/ai/providers/gemini.js +66 -0
- package/dist/ai/providers/gemini.js.map +1 -0
- package/dist/ai/providers/ollama.d.ts +11 -0
- package/dist/ai/providers/ollama.d.ts.map +1 -0
- package/dist/ai/providers/ollama.js +54 -0
- package/dist/ai/providers/ollama.js.map +1 -0
- package/dist/ai/providers/openai.d.ts +11 -0
- package/dist/ai/providers/openai.d.ts.map +1 -0
- package/dist/ai/providers/openai.js +52 -0
- package/dist/ai/providers/openai.js.map +1 -0
- package/dist/ai/selector.d.ts +19 -0
- package/dist/ai/selector.d.ts.map +1 -0
- package/dist/ai/selector.js +145 -0
- package/dist/ai/selector.js.map +1 -0
- package/dist/ai/types.d.ts +120 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +6 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/analyzer/concurrent-analyzer.d.ts +11 -0
- package/dist/analyzer/concurrent-analyzer.d.ts.map +1 -0
- package/dist/analyzer/concurrent-analyzer.js +67 -0
- package/dist/analyzer/concurrent-analyzer.js.map +1 -0
- package/dist/analyzer/file-discovery.d.ts +23 -0
- package/dist/analyzer/file-discovery.d.ts.map +1 -0
- package/dist/analyzer/file-discovery.js +64 -0
- package/dist/analyzer/file-discovery.js.map +1 -0
- package/dist/analyzer/index.d.ts +27 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +64 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/cli/commands/ai-review.d.ts +6 -0
- package/dist/cli/commands/ai-review.d.ts.map +1 -0
- package/dist/cli/commands/ai-review.js +213 -0
- package/dist/cli/commands/ai-review.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +6 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +145 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/config.d.ts +6 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +147 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/mcp-install.d.ts +9 -0
- package/dist/cli/commands/mcp-install.d.ts.map +1 -0
- package/dist/cli/commands/mcp-install.js +102 -0
- package/dist/cli/commands/mcp-install.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +69 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output/ai-review-output.d.ts +20 -0
- package/dist/cli/output/ai-review-output.d.ts.map +1 -0
- package/dist/cli/output/ai-review-output.js +324 -0
- package/dist/cli/output/ai-review-output.js.map +1 -0
- package/dist/cli/output/console.d.ts +31 -0
- package/dist/cli/output/console.d.ts.map +1 -0
- package/dist/cli/output/console.js +571 -0
- package/dist/cli/output/console.js.map +1 -0
- package/dist/cli/output/html.d.ts +20 -0
- package/dist/cli/output/html.d.ts.map +1 -0
- package/dist/cli/output/html.js +339 -0
- package/dist/cli/output/html.js.map +1 -0
- package/dist/cli/output/json.d.ts +8 -0
- package/dist/cli/output/json.d.ts.map +1 -0
- package/dist/cli/output/json.js +46 -0
- package/dist/cli/output/json.js.map +1 -0
- package/dist/cli/output/markdown.d.ts +17 -0
- package/dist/cli/output/markdown.d.ts.map +1 -0
- package/dist/cli/output/markdown.js +323 -0
- package/dist/cli/output/markdown.js.map +1 -0
- package/dist/cli/output/stats.d.ts +35 -0
- package/dist/cli/output/stats.d.ts.map +1 -0
- package/dist/cli/output/stats.js +63 -0
- package/dist/cli/output/stats.js.map +1 -0
- package/dist/cli/output/terminal-markdown.d.ts +23 -0
- package/dist/cli/output/terminal-markdown.d.ts.map +1 -0
- package/dist/cli/output/terminal-markdown.js +159 -0
- package/dist/cli/output/terminal-markdown.js.map +1 -0
- package/dist/config/index.d.ts +27 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +266 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +179 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +85 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/gitignore/index.d.ts +5 -0
- package/dist/gitignore/index.d.ts.map +1 -0
- package/dist/gitignore/index.js +5 -0
- package/dist/gitignore/index.js.map +1 -0
- package/dist/gitignore/parser.d.ts +32 -0
- package/dist/gitignore/parser.d.ts.map +1 -0
- package/dist/gitignore/parser.js +110 -0
- package/dist/gitignore/parser.js.map +1 -0
- package/dist/gitignore/parser.test.d.ts +2 -0
- package/dist/gitignore/parser.test.d.ts.map +1 -0
- package/dist/gitignore/parser.test.js +217 -0
- package/dist/gitignore/parser.test.js.map +1 -0
- package/dist/i18n/index.d.ts +19 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +43 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locales/en.json +320 -0
- package/dist/i18n/locales/ru.json +320 -0
- package/dist/i18n/locales/zh.json +320 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +156 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/metrics/complexity/cognitive.d.ts +25 -0
- package/dist/metrics/complexity/cognitive.d.ts.map +1 -0
- package/dist/metrics/complexity/cognitive.js +109 -0
- package/dist/metrics/complexity/cognitive.js.map +1 -0
- package/dist/metrics/complexity/cyclomatic.d.ts +21 -0
- package/dist/metrics/complexity/cyclomatic.d.ts.map +1 -0
- package/dist/metrics/complexity/cyclomatic.js +111 -0
- package/dist/metrics/complexity/cyclomatic.js.map +1 -0
- package/dist/metrics/complexity/nesting-depth.d.ts +19 -0
- package/dist/metrics/complexity/nesting-depth.d.ts.map +1 -0
- package/dist/metrics/complexity/nesting-depth.js +97 -0
- package/dist/metrics/complexity/nesting-depth.js.map +1 -0
- package/dist/metrics/documentation/comment-ratio.d.ts +21 -0
- package/dist/metrics/documentation/comment-ratio.d.ts.map +1 -0
- package/dist/metrics/documentation/comment-ratio.js +91 -0
- package/dist/metrics/documentation/comment-ratio.js.map +1 -0
- package/dist/metrics/duplication/code-duplication.d.ts +24 -0
- package/dist/metrics/duplication/code-duplication.d.ts.map +1 -0
- package/dist/metrics/duplication/code-duplication.js +167 -0
- package/dist/metrics/duplication/code-duplication.js.map +1 -0
- package/dist/metrics/duplication/code-duplication.test.d.ts +2 -0
- package/dist/metrics/duplication/code-duplication.test.d.ts.map +1 -0
- package/dist/metrics/duplication/code-duplication.test.js +612 -0
- package/dist/metrics/duplication/code-duplication.test.js.map +1 -0
- package/dist/metrics/error/error-handling.d.ts +23 -0
- package/dist/metrics/error/error-handling.d.ts.map +1 -0
- package/dist/metrics/error/error-handling.js +164 -0
- package/dist/metrics/error/error-handling.js.map +1 -0
- package/dist/metrics/error/error-handling.test.d.ts +2 -0
- package/dist/metrics/error/error-handling.test.d.ts.map +1 -0
- package/dist/metrics/error/error-handling.test.js +349 -0
- package/dist/metrics/error/error-handling.test.js.map +1 -0
- package/dist/metrics/index.d.ts +21 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +50 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/naming/convention.d.ts +22 -0
- package/dist/metrics/naming/convention.d.ts.map +1 -0
- package/dist/metrics/naming/convention.js +117 -0
- package/dist/metrics/naming/convention.js.map +1 -0
- package/dist/metrics/size/file-length.d.ts +19 -0
- package/dist/metrics/size/file-length.d.ts.map +1 -0
- package/dist/metrics/size/file-length.js +68 -0
- package/dist/metrics/size/file-length.js.map +1 -0
- package/dist/metrics/size/function-length.d.ts +20 -0
- package/dist/metrics/size/function-length.d.ts.map +1 -0
- package/dist/metrics/size/function-length.js +101 -0
- package/dist/metrics/size/function-length.js.map +1 -0
- package/dist/metrics/size/parameter-count.d.ts +19 -0
- package/dist/metrics/size/parameter-count.d.ts.map +1 -0
- package/dist/metrics/size/parameter-count.js +97 -0
- package/dist/metrics/size/parameter-count.js.map +1 -0
- package/dist/metrics/structure/structure-analysis.d.ts +24 -0
- package/dist/metrics/structure/structure-analysis.d.ts.map +1 -0
- package/dist/metrics/structure/structure-analysis.js +223 -0
- package/dist/metrics/structure/structure-analysis.js.map +1 -0
- package/dist/metrics/structure/structure-analysis.test.d.ts +2 -0
- package/dist/metrics/structure/structure-analysis.test.d.ts.map +1 -0
- package/dist/metrics/structure/structure-analysis.test.js +342 -0
- package/dist/metrics/structure/structure-analysis.test.js.map +1 -0
- package/dist/metrics/types.d.ts +71 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +5 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/parser/generic-parser.d.ts +28 -0
- package/dist/parser/generic-parser.d.ts.map +1 -0
- package/dist/parser/generic-parser.js +218 -0
- package/dist/parser/generic-parser.js.map +1 -0
- package/dist/parser/index.d.ts +19 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +52 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/regex-parser.d.ts +46 -0
- package/dist/parser/regex-parser.d.ts.map +1 -0
- package/dist/parser/regex-parser.js +560 -0
- package/dist/parser/regex-parser.js.map +1 -0
- package/dist/parser/tree-sitter-parser.d.ts +50 -0
- package/dist/parser/tree-sitter-parser.d.ts.map +1 -0
- package/dist/parser/tree-sitter-parser.js +707 -0
- package/dist/parser/tree-sitter-parser.js.map +1 -0
- package/dist/parser/types.d.ts +52 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +49 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/scoring/index.d.ts +14 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +80 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/utils/fs.d.ts +24 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +61 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +16 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +303 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/progress.d.ts +24 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +79 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/terminal.d.ts +62 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +207 -0
- package/dist/utils/terminal.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naming convention metric
|
|
3
|
+
*
|
|
4
|
+
* Checks if identifiers follow language-specific naming conventions.
|
|
5
|
+
* Based on official style guides:
|
|
6
|
+
* - Go: Effective Go
|
|
7
|
+
* - JavaScript/TypeScript: Airbnb Style Guide
|
|
8
|
+
* - Python: PEP 8
|
|
9
|
+
* - Java: Oracle Code Conventions
|
|
10
|
+
* - Rust: Rust API Guidelines
|
|
11
|
+
* - C#: Microsoft Naming Guidelines
|
|
12
|
+
*/
|
|
13
|
+
import { t } from '../../i18n/index.js';
|
|
14
|
+
// Naming patterns
|
|
15
|
+
const PATTERNS = {
|
|
16
|
+
camelCase: /^[a-z][a-zA-Z0-9]*$/,
|
|
17
|
+
PascalCase: /^[A-Z][a-zA-Z0-9]*$/,
|
|
18
|
+
snake_case: /^[a-z][a-z0-9_]*$/,
|
|
19
|
+
UPPER_SNAKE_CASE: /^[A-Z][A-Z0-9_]*$/,
|
|
20
|
+
};
|
|
21
|
+
// Language-specific function naming rules
|
|
22
|
+
const FUNCTION_RULES = {
|
|
23
|
+
go: ['PascalCase', 'camelCase'],
|
|
24
|
+
javascript: ['camelCase', 'PascalCase'],
|
|
25
|
+
typescript: ['camelCase', 'PascalCase'],
|
|
26
|
+
python: ['snake_case'],
|
|
27
|
+
java: ['camelCase'],
|
|
28
|
+
c: ['snake_case', 'camelCase'],
|
|
29
|
+
cpp: ['camelCase', 'snake_case', 'PascalCase'],
|
|
30
|
+
rust: ['snake_case'],
|
|
31
|
+
csharp: ['PascalCase'],
|
|
32
|
+
lua: ['camelCase', 'snake_case'],
|
|
33
|
+
unknown: ['camelCase', 'snake_case', 'PascalCase'],
|
|
34
|
+
};
|
|
35
|
+
export class NamingConventionMetric {
|
|
36
|
+
name = 'naming_convention';
|
|
37
|
+
category = 'naming';
|
|
38
|
+
weight;
|
|
39
|
+
constructor(weight) {
|
|
40
|
+
this.weight = weight;
|
|
41
|
+
}
|
|
42
|
+
calculate(parseResult) {
|
|
43
|
+
const { functions, classes, language, filePath } = parseResult;
|
|
44
|
+
const allowedRules = FUNCTION_RULES[language];
|
|
45
|
+
let violations = 0;
|
|
46
|
+
let total = 0;
|
|
47
|
+
const locations = [];
|
|
48
|
+
// Check function names
|
|
49
|
+
for (const func of functions) {
|
|
50
|
+
total++;
|
|
51
|
+
let matches = false;
|
|
52
|
+
for (const ruleName of allowedRules) {
|
|
53
|
+
if (PATTERNS[ruleName].test(func.name)) {
|
|
54
|
+
matches = true;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!matches) {
|
|
59
|
+
violations++;
|
|
60
|
+
locations.push({
|
|
61
|
+
filePath,
|
|
62
|
+
line: func.startLine,
|
|
63
|
+
functionName: func.name,
|
|
64
|
+
message: `"${func.name}" - ${allowedRules.join('/')}`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Check class names
|
|
69
|
+
for (const cls of classes) {
|
|
70
|
+
total++;
|
|
71
|
+
if (!PATTERNS.PascalCase.test(cls.name)) {
|
|
72
|
+
violations++;
|
|
73
|
+
locations.push({
|
|
74
|
+
filePath,
|
|
75
|
+
line: cls.startLine,
|
|
76
|
+
message: `"${cls.name}" - PascalCase`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (total === 0) {
|
|
81
|
+
return {
|
|
82
|
+
name: this.name,
|
|
83
|
+
category: this.category,
|
|
84
|
+
value: 100,
|
|
85
|
+
normalizedScore: 100,
|
|
86
|
+
severity: 'info',
|
|
87
|
+
details: t('detail_no_violations'),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const complianceRate = ((total - violations) / total) * 100;
|
|
91
|
+
let severity;
|
|
92
|
+
if (complianceRate >= 90) {
|
|
93
|
+
severity = 'info';
|
|
94
|
+
}
|
|
95
|
+
else if (complianceRate >= 70) {
|
|
96
|
+
severity = 'warning';
|
|
97
|
+
}
|
|
98
|
+
else if (complianceRate >= 50) {
|
|
99
|
+
severity = 'error';
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
severity = 'critical';
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
name: this.name,
|
|
106
|
+
category: this.category,
|
|
107
|
+
value: complianceRate,
|
|
108
|
+
normalizedScore: Math.round(complianceRate * 10) / 10,
|
|
109
|
+
severity,
|
|
110
|
+
details: violations > 0
|
|
111
|
+
? t('detail_violations', { count: String(violations) })
|
|
112
|
+
: t('detail_no_violations'),
|
|
113
|
+
locations: locations.length > 0 ? locations.slice(0, 10) : undefined,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=convention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convention.js","sourceRoot":"","sources":["../../../src/metrics/naming/convention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File length metric
|
|
3
|
+
*
|
|
4
|
+
* Industry thresholds (based on Clean Code, SonarQube):
|
|
5
|
+
* - 1-200 lines: Excellent, focused file
|
|
6
|
+
* - 201-400 lines: Good, manageable
|
|
7
|
+
* - 401-800 lines: Moderate, consider splitting
|
|
8
|
+
* - 800+ lines: Poor, should be split
|
|
9
|
+
*/
|
|
10
|
+
import type { Metric, MetricResult, MetricCategory } from '../types.js';
|
|
11
|
+
import type { ParseResult } from '../../parser/types.js';
|
|
12
|
+
export declare class FileLengthMetric implements Metric {
|
|
13
|
+
readonly name = "file_length";
|
|
14
|
+
readonly category: MetricCategory;
|
|
15
|
+
readonly weight: number;
|
|
16
|
+
constructor(weight: number);
|
|
17
|
+
calculate(parseResult: ParseResult): MetricResult;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=file-length.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-length.d.ts","sourceRoot":"","sources":["../../../src/metrics/size/file-length.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAY,MAAM,aAAa,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAUzD,qBAAa,gBAAiB,YAAW,MAAM;IAC7C,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAU;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;IAI1B,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,YAAY;CAuClD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File length metric
|
|
3
|
+
*
|
|
4
|
+
* Industry thresholds (based on Clean Code, SonarQube):
|
|
5
|
+
* - 1-200 lines: Excellent, focused file
|
|
6
|
+
* - 201-400 lines: Good, manageable
|
|
7
|
+
* - 401-800 lines: Moderate, consider splitting
|
|
8
|
+
* - 800+ lines: Poor, should be split
|
|
9
|
+
*/
|
|
10
|
+
import { t } from '../../i18n/index.js';
|
|
11
|
+
const THRESHOLDS = {
|
|
12
|
+
EXCELLENT: 200,
|
|
13
|
+
GOOD: 400,
|
|
14
|
+
ACCEPTABLE: 800,
|
|
15
|
+
POOR: 1500,
|
|
16
|
+
};
|
|
17
|
+
export class FileLengthMetric {
|
|
18
|
+
name = 'file_length';
|
|
19
|
+
category = 'size';
|
|
20
|
+
weight;
|
|
21
|
+
constructor(weight) {
|
|
22
|
+
this.weight = weight;
|
|
23
|
+
}
|
|
24
|
+
calculate(parseResult) {
|
|
25
|
+
const { totalLines, codeLines } = parseResult;
|
|
26
|
+
let normalizedScore;
|
|
27
|
+
if (codeLines <= THRESHOLDS.EXCELLENT) {
|
|
28
|
+
normalizedScore = 100;
|
|
29
|
+
}
|
|
30
|
+
else if (codeLines <= THRESHOLDS.GOOD) {
|
|
31
|
+
normalizedScore =
|
|
32
|
+
100 - ((codeLines - THRESHOLDS.EXCELLENT) / (THRESHOLDS.GOOD - THRESHOLDS.EXCELLENT)) * 15;
|
|
33
|
+
}
|
|
34
|
+
else if (codeLines <= THRESHOLDS.ACCEPTABLE) {
|
|
35
|
+
normalizedScore =
|
|
36
|
+
85 - ((codeLines - THRESHOLDS.GOOD) / (THRESHOLDS.ACCEPTABLE - THRESHOLDS.GOOD)) * 35;
|
|
37
|
+
}
|
|
38
|
+
else if (codeLines <= THRESHOLDS.POOR) {
|
|
39
|
+
normalizedScore =
|
|
40
|
+
50 - ((codeLines - THRESHOLDS.ACCEPTABLE) / (THRESHOLDS.POOR - THRESHOLDS.ACCEPTABLE)) * 35;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
normalizedScore = Math.max(0, 15 * Math.exp(-(codeLines - THRESHOLDS.POOR) / 500));
|
|
44
|
+
}
|
|
45
|
+
let severity;
|
|
46
|
+
if (codeLines <= THRESHOLDS.EXCELLENT) {
|
|
47
|
+
severity = 'info';
|
|
48
|
+
}
|
|
49
|
+
else if (codeLines <= THRESHOLDS.GOOD) {
|
|
50
|
+
severity = 'warning';
|
|
51
|
+
}
|
|
52
|
+
else if (codeLines <= THRESHOLDS.ACCEPTABLE) {
|
|
53
|
+
severity = 'error';
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
severity = 'critical';
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
name: this.name,
|
|
60
|
+
category: this.category,
|
|
61
|
+
value: codeLines,
|
|
62
|
+
normalizedScore: Math.round(normalizedScore * 10) / 10,
|
|
63
|
+
severity,
|
|
64
|
+
details: t('detail_file_length', { code: codeLines, total: totalLines }),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=file-length.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-length.js","sourceRoot":"","sources":["../../../src/metrics/size/file-length.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;AAExC,MAAM,UAAU,GAAG;IACjB,SAAS,EAAE,GAAG;IACd,IAAI,EAAE,GAAG;IACT,UAAU,EAAE,GAAG;IACf,IAAI,EAAE,IAAI;CACF,CAAC;AAEX,MAAM,OAAO,gBAAgB;IAClB,IAAI,GAAG,aAAa,CAAC;IACrB,QAAQ,GAAmB,MAAM,CAAC;IAClC,MAAM,CAAS;IAExB,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,SAAS,CAAC,WAAwB;QAChC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC;QAE9C,IAAI,eAAuB,CAAC;QAC5B,IAAI,SAAS,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACtC,eAAe,GAAG,GAAG,CAAC;QACxB,CAAC;aAAM,IAAI,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACxC,eAAe;gBACb,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/F,CAAC;aAAM,IAAI,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC9C,eAAe;gBACb,EAAE,GAAG,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1F,CAAC;aAAM,IAAI,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACxC,eAAe;gBACb,EAAE,GAAG,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC;QAChG,CAAC;aAAM,CAAC;YACN,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,QAAkB,CAAC;QACvB,IAAI,SAAS,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,GAAG,MAAM,CAAC;QACpB,CAAC;aAAM,IAAI,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACxC,QAAQ,GAAG,SAAS,CAAC;QACvB,CAAC;aAAM,IAAI,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC9C,QAAQ,GAAG,OAAO,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,UAAU,CAAC;QACxB,CAAC;QAED,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,SAAS;YAChB,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC,GAAG,EAAE;YACtD,QAAQ;YACR,OAAO,EAAE,CAAC,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;SACzE,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function length metric
|
|
3
|
+
*
|
|
4
|
+
* Industry thresholds (based on SonarQube, real-world projects):
|
|
5
|
+
* - 1-50 lines: Excellent, concise and clear
|
|
6
|
+
* - 51-150 lines: Good, typical business logic
|
|
7
|
+
* - 151-300 lines: Acceptable, complex but manageable
|
|
8
|
+
* - 301-500 lines: Poor, consider refactoring
|
|
9
|
+
* - 500+ lines: Critical, needs refactoring
|
|
10
|
+
*/
|
|
11
|
+
import type { Metric, MetricResult, MetricCategory } from '../types.js';
|
|
12
|
+
import type { ParseResult } from '../../parser/types.js';
|
|
13
|
+
export declare class FunctionLengthMetric implements Metric {
|
|
14
|
+
readonly name = "function_length";
|
|
15
|
+
readonly category: MetricCategory;
|
|
16
|
+
readonly weight: number;
|
|
17
|
+
constructor(weight: number);
|
|
18
|
+
calculate(parseResult: ParseResult): MetricResult;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=function-length.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-length.d.ts","sourceRoot":"","sources":["../../../src/metrics/size/function-length.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAUzD,qBAAa,oBAAqB,YAAW,MAAM;IACjD,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAU;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;IAI1B,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,YAAY;CA2ElD"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function length metric
|
|
3
|
+
*
|
|
4
|
+
* Industry thresholds (based on SonarQube, real-world projects):
|
|
5
|
+
* - 1-50 lines: Excellent, concise and clear
|
|
6
|
+
* - 51-150 lines: Good, typical business logic
|
|
7
|
+
* - 151-300 lines: Acceptable, complex but manageable
|
|
8
|
+
* - 301-500 lines: Poor, consider refactoring
|
|
9
|
+
* - 500+ lines: Critical, needs refactoring
|
|
10
|
+
*/
|
|
11
|
+
import { t } from '../../i18n/index.js';
|
|
12
|
+
const THRESHOLDS = {
|
|
13
|
+
EXCELLENT: 50,
|
|
14
|
+
GOOD: 150,
|
|
15
|
+
ACCEPTABLE: 300,
|
|
16
|
+
POOR: 500,
|
|
17
|
+
};
|
|
18
|
+
export class FunctionLengthMetric {
|
|
19
|
+
name = 'function_length';
|
|
20
|
+
category = 'size';
|
|
21
|
+
weight;
|
|
22
|
+
constructor(weight) {
|
|
23
|
+
this.weight = weight;
|
|
24
|
+
}
|
|
25
|
+
calculate(parseResult) {
|
|
26
|
+
const { functions, filePath } = parseResult;
|
|
27
|
+
if (functions.length === 0) {
|
|
28
|
+
return {
|
|
29
|
+
name: this.name,
|
|
30
|
+
category: this.category,
|
|
31
|
+
value: 0,
|
|
32
|
+
normalizedScore: 100,
|
|
33
|
+
severity: 'info',
|
|
34
|
+
details: t('detail_no_functions'),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
let totalLength = 0;
|
|
38
|
+
let maxLength = 0;
|
|
39
|
+
const locations = [];
|
|
40
|
+
for (const func of functions) {
|
|
41
|
+
totalLength += func.lineCount;
|
|
42
|
+
if (func.lineCount > maxLength) {
|
|
43
|
+
maxLength = func.lineCount;
|
|
44
|
+
}
|
|
45
|
+
if (func.lineCount > THRESHOLDS.GOOD) {
|
|
46
|
+
locations.push({
|
|
47
|
+
filePath,
|
|
48
|
+
line: func.startLine,
|
|
49
|
+
functionName: func.name,
|
|
50
|
+
message: `${func.lineCount} ${t('size')}`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const avgLength = totalLength / functions.length;
|
|
55
|
+
let normalizedScore;
|
|
56
|
+
if (avgLength <= THRESHOLDS.EXCELLENT) {
|
|
57
|
+
normalizedScore = 100;
|
|
58
|
+
}
|
|
59
|
+
else if (avgLength <= THRESHOLDS.GOOD) {
|
|
60
|
+
normalizedScore =
|
|
61
|
+
100 - ((avgLength - THRESHOLDS.EXCELLENT) / (THRESHOLDS.GOOD - THRESHOLDS.EXCELLENT)) * 15;
|
|
62
|
+
}
|
|
63
|
+
else if (avgLength <= THRESHOLDS.ACCEPTABLE) {
|
|
64
|
+
normalizedScore =
|
|
65
|
+
85 - ((avgLength - THRESHOLDS.GOOD) / (THRESHOLDS.ACCEPTABLE - THRESHOLDS.GOOD)) * 35;
|
|
66
|
+
}
|
|
67
|
+
else if (avgLength <= THRESHOLDS.POOR) {
|
|
68
|
+
normalizedScore =
|
|
69
|
+
50 - ((avgLength - THRESHOLDS.ACCEPTABLE) / (THRESHOLDS.POOR - THRESHOLDS.ACCEPTABLE)) * 35;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
normalizedScore = Math.max(0, 15 * Math.exp(-(avgLength - THRESHOLDS.POOR) / 50));
|
|
73
|
+
}
|
|
74
|
+
let severity;
|
|
75
|
+
if (maxLength <= THRESHOLDS.GOOD) {
|
|
76
|
+
severity = 'info';
|
|
77
|
+
}
|
|
78
|
+
else if (maxLength <= THRESHOLDS.ACCEPTABLE) {
|
|
79
|
+
severity = 'warning';
|
|
80
|
+
}
|
|
81
|
+
else if (maxLength <= THRESHOLDS.POOR) {
|
|
82
|
+
severity = 'error';
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
severity = 'critical';
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
name: this.name,
|
|
89
|
+
category: this.category,
|
|
90
|
+
value: avgLength,
|
|
91
|
+
normalizedScore: Math.round(normalizedScore * 10) / 10,
|
|
92
|
+
severity,
|
|
93
|
+
details: t('detail_avg_lines_max_lines', {
|
|
94
|
+
avg: avgLength.toFixed(1),
|
|
95
|
+
max: String(maxLength),
|
|
96
|
+
}),
|
|
97
|
+
locations: locations.length > 0 ? locations : undefined,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=function-length.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-length.js","sourceRoot":"","sources":["../../../src/metrics/size/function-length.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter count metric
|
|
3
|
+
*
|
|
4
|
+
* Industry thresholds (based on Clean Code, SonarQube):
|
|
5
|
+
* - 0-3: Excellent, easy to understand and test
|
|
6
|
+
* - 4-5: Good, acceptable
|
|
7
|
+
* - 6-7: Moderate, consider using object parameter
|
|
8
|
+
* - 8+: Poor, should be refactored
|
|
9
|
+
*/
|
|
10
|
+
import type { Metric, MetricResult, MetricCategory } from '../types.js';
|
|
11
|
+
import type { ParseResult } from '../../parser/types.js';
|
|
12
|
+
export declare class ParameterCountMetric implements Metric {
|
|
13
|
+
readonly name = "parameter_count";
|
|
14
|
+
readonly category: MetricCategory;
|
|
15
|
+
readonly weight: number;
|
|
16
|
+
constructor(weight: number);
|
|
17
|
+
calculate(parseResult: ParseResult): MetricResult;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=parameter-count.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-count.d.ts","sourceRoot":"","sources":["../../../src/metrics/size/parameter-count.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAUzD,qBAAa,oBAAqB,YAAW,MAAM;IACjD,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAU;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;IAI1B,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,YAAY;CAwElD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter count metric
|
|
3
|
+
*
|
|
4
|
+
* Industry thresholds (based on Clean Code, SonarQube):
|
|
5
|
+
* - 0-3: Excellent, easy to understand and test
|
|
6
|
+
* - 4-5: Good, acceptable
|
|
7
|
+
* - 6-7: Moderate, consider using object parameter
|
|
8
|
+
* - 8+: Poor, should be refactored
|
|
9
|
+
*/
|
|
10
|
+
import { t } from '../../i18n/index.js';
|
|
11
|
+
const THRESHOLDS = {
|
|
12
|
+
EXCELLENT: 3,
|
|
13
|
+
GOOD: 5,
|
|
14
|
+
ACCEPTABLE: 7,
|
|
15
|
+
POOR: 10,
|
|
16
|
+
};
|
|
17
|
+
export class ParameterCountMetric {
|
|
18
|
+
name = 'parameter_count';
|
|
19
|
+
category = 'size';
|
|
20
|
+
weight;
|
|
21
|
+
constructor(weight) {
|
|
22
|
+
this.weight = weight;
|
|
23
|
+
}
|
|
24
|
+
calculate(parseResult) {
|
|
25
|
+
const { functions, filePath } = parseResult;
|
|
26
|
+
if (functions.length === 0) {
|
|
27
|
+
return {
|
|
28
|
+
name: this.name,
|
|
29
|
+
category: this.category,
|
|
30
|
+
value: 0,
|
|
31
|
+
normalizedScore: 100,
|
|
32
|
+
severity: 'info',
|
|
33
|
+
details: t('detail_no_functions'),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let totalParams = 0;
|
|
37
|
+
let maxParams = 0;
|
|
38
|
+
const locations = [];
|
|
39
|
+
for (const func of functions) {
|
|
40
|
+
totalParams += func.parameterCount;
|
|
41
|
+
if (func.parameterCount > maxParams) {
|
|
42
|
+
maxParams = func.parameterCount;
|
|
43
|
+
}
|
|
44
|
+
if (func.parameterCount > THRESHOLDS.GOOD) {
|
|
45
|
+
locations.push({
|
|
46
|
+
filePath,
|
|
47
|
+
line: func.startLine,
|
|
48
|
+
functionName: func.name,
|
|
49
|
+
message: `${func.parameterCount} ${t('metric_parameter_count')}`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const avgParams = totalParams / functions.length;
|
|
54
|
+
let normalizedScore;
|
|
55
|
+
if (maxParams <= THRESHOLDS.EXCELLENT) {
|
|
56
|
+
normalizedScore = 100;
|
|
57
|
+
}
|
|
58
|
+
else if (maxParams <= THRESHOLDS.GOOD) {
|
|
59
|
+
normalizedScore =
|
|
60
|
+
100 - ((maxParams - THRESHOLDS.EXCELLENT) / (THRESHOLDS.GOOD - THRESHOLDS.EXCELLENT)) * 15;
|
|
61
|
+
}
|
|
62
|
+
else if (maxParams <= THRESHOLDS.ACCEPTABLE) {
|
|
63
|
+
normalizedScore =
|
|
64
|
+
85 - ((maxParams - THRESHOLDS.GOOD) / (THRESHOLDS.ACCEPTABLE - THRESHOLDS.GOOD)) * 35;
|
|
65
|
+
}
|
|
66
|
+
else if (maxParams <= THRESHOLDS.POOR) {
|
|
67
|
+
normalizedScore =
|
|
68
|
+
50 - ((maxParams - THRESHOLDS.ACCEPTABLE) / (THRESHOLDS.POOR - THRESHOLDS.ACCEPTABLE)) * 35;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
normalizedScore = Math.max(0, 15 * Math.exp(-(maxParams - THRESHOLDS.POOR) / 3));
|
|
72
|
+
}
|
|
73
|
+
let severity;
|
|
74
|
+
if (maxParams <= THRESHOLDS.EXCELLENT) {
|
|
75
|
+
severity = 'info';
|
|
76
|
+
}
|
|
77
|
+
else if (maxParams <= THRESHOLDS.GOOD) {
|
|
78
|
+
severity = 'warning';
|
|
79
|
+
}
|
|
80
|
+
else if (maxParams <= THRESHOLDS.ACCEPTABLE) {
|
|
81
|
+
severity = 'error';
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
severity = 'critical';
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
name: this.name,
|
|
88
|
+
category: this.category,
|
|
89
|
+
value: maxParams,
|
|
90
|
+
normalizedScore: Math.round(normalizedScore * 10) / 10,
|
|
91
|
+
severity,
|
|
92
|
+
details: t('detail_avg_max', { avg: avgParams.toFixed(1), max: String(maxParams) }),
|
|
93
|
+
locations: locations.length > 0 ? locations : undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=parameter-count.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-count.js","sourceRoot":"","sources":["../../../src/metrics/size/parameter-count.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structure analysis metric
|
|
3
|
+
*
|
|
4
|
+
* Analyzes code structure quality across multiple dimensions.
|
|
5
|
+
*
|
|
6
|
+
* Industry thresholds (SonarQube, Clean Code):
|
|
7
|
+
* - Nesting: >=5 problematic, >=3 needs attention
|
|
8
|
+
* - File size: >1000 lines large, >500 needs review
|
|
9
|
+
* - Functions: >50 per file too many, >30 needs attention
|
|
10
|
+
* - Imports: >20 high coupling, >15 needs attention
|
|
11
|
+
*/
|
|
12
|
+
import type { Metric, MetricResult, MetricCategory } from '../types.js';
|
|
13
|
+
import type { ParseResult } from '../../parser/types.js';
|
|
14
|
+
export declare class StructureAnalysisMetric implements Metric {
|
|
15
|
+
readonly name = "structure_analysis";
|
|
16
|
+
readonly category: MetricCategory;
|
|
17
|
+
readonly weight: number;
|
|
18
|
+
constructor(weight: number);
|
|
19
|
+
calculate(parseResult: ParseResult): MetricResult;
|
|
20
|
+
private calculateSimplified;
|
|
21
|
+
private countImports;
|
|
22
|
+
private detectCircular;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=structure-analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure-analysis.d.ts","sourceRoot":"","sources":["../../../src/metrics/structure/structure-analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAA4B,MAAM,aAAa,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAczD,qBAAa,uBAAwB,YAAW,MAAM;IACpD,QAAQ,CAAC,IAAI,wBAAwB;IACrC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAe;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;IAI1B,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,YAAY;IAmIjD,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,cAAc;CAqCvB"}
|