@vyuhlabs/dxkit 2.4.4 → 2.4.6

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +339 -0
  2. package/README.md +33 -19
  3. package/dist/analyzers/tests/index.d.ts.map +1 -1
  4. package/dist/analyzers/tests/index.js +2 -0
  5. package/dist/analyzers/tests/index.js.map +1 -1
  6. package/dist/analyzers/tools/coverage.d.ts +1 -1
  7. package/dist/analyzers/tools/coverage.d.ts.map +1 -1
  8. package/dist/analyzers/tools/coverage.js.map +1 -1
  9. package/dist/analyzers/tools/jacoco.d.ts +76 -0
  10. package/dist/analyzers/tools/jacoco.d.ts.map +1 -0
  11. package/dist/analyzers/tools/jacoco.js +228 -0
  12. package/dist/analyzers/tools/jacoco.js.map +1 -0
  13. package/dist/analyzers/tools/osv-scanner-deps.d.ts +47 -0
  14. package/dist/analyzers/tools/osv-scanner-deps.d.ts.map +1 -0
  15. package/dist/analyzers/tools/osv-scanner-deps.js +175 -0
  16. package/dist/analyzers/tools/osv-scanner-deps.js.map +1 -0
  17. package/dist/analyzers/tools/osv-scanner-fix.d.ts +20 -0
  18. package/dist/analyzers/tools/osv-scanner-fix.d.ts.map +1 -1
  19. package/dist/analyzers/tools/osv-scanner-fix.js +45 -20
  20. package/dist/analyzers/tools/osv-scanner-fix.js.map +1 -1
  21. package/dist/analyzers/tools/runner.d.ts +47 -0
  22. package/dist/analyzers/tools/runner.d.ts.map +1 -1
  23. package/dist/analyzers/tools/runner.js +79 -0
  24. package/dist/analyzers/tools/runner.js.map +1 -1
  25. package/dist/analyzers/tools/tool-registry.d.ts +10 -0
  26. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
  27. package/dist/analyzers/tools/tool-registry.js +131 -0
  28. package/dist/analyzers/tools/tool-registry.js.map +1 -1
  29. package/dist/cli.d.ts.map +1 -1
  30. package/dist/cli.js +36 -2
  31. package/dist/cli.js.map +1 -1
  32. package/dist/constants.d.ts +2 -0
  33. package/dist/constants.d.ts.map +1 -1
  34. package/dist/languages/index.d.ts.map +1 -1
  35. package/dist/languages/index.js +12 -1
  36. package/dist/languages/index.js.map +1 -1
  37. package/dist/languages/java.d.ts +67 -0
  38. package/dist/languages/java.d.ts.map +1 -0
  39. package/dist/languages/java.js +421 -0
  40. package/dist/languages/java.js.map +1 -0
  41. package/dist/languages/kotlin.d.ts +1 -52
  42. package/dist/languages/kotlin.d.ts.map +1 -1
  43. package/dist/languages/kotlin.js +16 -286
  44. package/dist/languages/kotlin.js.map +1 -1
  45. package/dist/languages/ruby.d.ts +77 -0
  46. package/dist/languages/ruby.d.ts.map +1 -0
  47. package/dist/languages/ruby.js +531 -0
  48. package/dist/languages/ruby.js.map +1 -0
  49. package/dist/languages/types.d.ts +9 -1
  50. package/dist/languages/types.d.ts.map +1 -1
  51. package/dist/tools-cli.d.ts +16 -1
  52. package/dist/tools-cli.d.ts.map +1 -1
  53. package/dist/tools-cli.js +69 -6
  54. package/dist/tools-cli.js.map +1 -1
  55. package/dist/types.d.ts +1 -1
  56. package/dist/types.d.ts.map +1 -1
  57. package/package.json +2 -1
  58. package/templates/.claude/rules/java.md +11 -0
  59. package/templates/.claude/rules/ruby.md +11 -0
  60. package/templates/configs/java/README.md +6 -0
  61. package/templates/configs/ruby/README.md +6 -0
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parseJaCoCoXml = parseJaCoCoXml;
37
+ exports.findJaCoCoReport = findJaCoCoReport;
38
+ exports.gatherJaCoCoCoverageResult = gatherJaCoCoCoverageResult;
39
+ /**
40
+ * JaCoCo XML report parser + standard-location finder. Shared across
41
+ * JVM-language packs (kotlin, java) — single source of truth per
42
+ * CLAUDE.md rule #2 ("Each tool has ONE gather function … if another
43
+ * module needs that tool's output, it MUST call the existing
44
+ * function").
45
+ *
46
+ * Extracted from `src/languages/kotlin.ts` in 10k.1.2 (Phase 10k.1
47
+ * SSOT validation) — when the Java pack needed JaCoCo coverage, the
48
+ * parser was already generic (kotlin's own tests cover it against
49
+ * Java source, see test/languages-kotlin.test.ts). Forking would
50
+ * have been the architectural violation; relocating to a shared
51
+ * tool module is the correct outcome.
52
+ */
53
+ const fs = __importStar(require("fs"));
54
+ const path = __importStar(require("path"));
55
+ const coverage_1 = require("./coverage");
56
+ /**
57
+ * Pure parser for JaCoCo's XML report (DTD: `report.dtd`). The structure:
58
+ *
59
+ * <report name="...">
60
+ * <package name="com/example">
61
+ * <class name="com/example/Foo" sourcefilename="Foo.kt">...</class>
62
+ * <sourcefile name="Foo.kt">
63
+ * <line nr="N" mi="..." ci="..." mb="..." cb="..."/>
64
+ * <counter type="LINE" missed="X" covered="Y"/>
65
+ * </sourcefile>
66
+ * <counter type="LINE" missed="X" covered="Y"/>
67
+ * </package>
68
+ * <counter type="LINE" missed="X" covered="Y"/>
69
+ * </report>
70
+ *
71
+ * Per-file coverage comes from `<sourcefile>` blocks: their LINE counter
72
+ * holds the file's missed/covered totals. Project-level total comes from
73
+ * the top-level `<counter type="LINE">` (last in the document).
74
+ *
75
+ * Path attribution joins `<package name>` (forward-slashed, JVM-style)
76
+ * with `<sourcefile name>` to produce the canonical relative path the
77
+ * downstream consumers expect (`com/example/Foo.kt` or
78
+ * `com/example/Foo.java`). JVM bytecode namespacing isn't 1:1 with
79
+ * on-disk source paths in multi-module projects — accepted limitation
80
+ * (matches C#'s cobertura attribution).
81
+ *
82
+ * Returns null when no `<counter type="LINE">` exists at the top level
83
+ * — that's JaCoCo's "no coverage data" signal, distinct from "0%
84
+ * coverage" (where the counter exists with covered=0).
85
+ *
86
+ * Language-agnostic: works for Kotlin (.kt), Java (.java), and any
87
+ * other JVM language whose JaCoCo output respects the `<package>` /
88
+ * `<sourcefile>` shape — `<sourcefile name>` carries the on-disk
89
+ * filename verbatim so the parser doesn't need to know the language.
90
+ */
91
+ function parseJaCoCoXml(raw, sourceFile, _cwd) {
92
+ const files = new Map();
93
+ // Iterate <package> blocks. Each block contains <sourcefile> children
94
+ // we tally and aggregate counters we can ignore (they're sums of the
95
+ // children, redundant given we sum the children ourselves).
96
+ const packageRe = /<package\s+name="([^"]+)">([\s\S]*?)<\/package>/g;
97
+ let pm;
98
+ while ((pm = packageRe.exec(raw)) !== null) {
99
+ const pkgPath = pm[1].replace(/\\/g, '/'); // JVM uses forward-slashes already; defensive
100
+ const pkgInner = pm[2];
101
+ // Within a <package>, <sourcefile> blocks own per-file counters.
102
+ const sourceFileRe = /<sourcefile\s+name="([^"]+)">([\s\S]*?)<\/sourcefile>/g;
103
+ let sm;
104
+ while ((sm = sourceFileRe.exec(pkgInner)) !== null) {
105
+ const fileName = sm[1];
106
+ const sourceInner = sm[2];
107
+ // The LAST <counter type="LINE"> in <sourcefile> is the
108
+ // file-level aggregate; earlier ones are per-method. We pick the
109
+ // last to get the full-file roll-up.
110
+ const counterRe = /<counter\s+type="LINE"\s+missed="(\d+)"\s+covered="(\d+)"\s*\/>/g;
111
+ let lastMissed = 0;
112
+ let lastCovered = 0;
113
+ let cm;
114
+ while ((cm = counterRe.exec(sourceInner)) !== null) {
115
+ lastMissed = parseInt(cm[1], 10);
116
+ lastCovered = parseInt(cm[2], 10);
117
+ }
118
+ const total = lastMissed + lastCovered;
119
+ const rel = pkgPath ? `${pkgPath}/${fileName}` : fileName;
120
+ files.set(rel, {
121
+ path: rel,
122
+ covered: lastCovered,
123
+ total,
124
+ pct: (0, coverage_1.round1)(total > 0 ? (lastCovered / total) * 100 : 0),
125
+ });
126
+ }
127
+ }
128
+ // Top-level project-wide LINE counter — JaCoCo emits it after the
129
+ // last </package>. Use a non-greedy match against the document tail
130
+ // to avoid grabbing per-package counters as project-level.
131
+ const tailMatch = raw.match(/<\/package>\s*<counter\s+type="LINE"\s+missed="(\d+)"\s+covered="(\d+)"\s*\/>\s*<\/report>/);
132
+ let totalMissed = 0;
133
+ let totalCovered = 0;
134
+ if (tailMatch) {
135
+ totalMissed = parseInt(tailMatch[1], 10);
136
+ totalCovered = parseInt(tailMatch[2], 10);
137
+ }
138
+ else {
139
+ // No project-level counter (degenerate report — single package, no
140
+ // explicit roll-up). Sum the per-file totals as the linePercent
141
+ // basis.
142
+ for (const f of files.values()) {
143
+ totalCovered += f.covered;
144
+ totalMissed += f.total - f.covered;
145
+ }
146
+ }
147
+ const grandTotal = totalCovered + totalMissed;
148
+ if (grandTotal === 0 && files.size === 0)
149
+ return null;
150
+ return {
151
+ source: 'jacoco',
152
+ sourceFile,
153
+ linePercent: (0, coverage_1.round1)(grandTotal > 0 ? (totalCovered / grandTotal) * 100 : 0),
154
+ files,
155
+ };
156
+ }
157
+ /**
158
+ * Standard JaCoCo report locations across JVM build tools and project
159
+ * layouts:
160
+ *
161
+ * GRADLE (kotlin + java):
162
+ * - app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
163
+ * (Android default — `app` module, `jacocoTestReport` task)
164
+ * - build/reports/jacoco/test/jacocoTestReport.xml
165
+ * (plain JVM via the `jacoco` plugin's default `test` task)
166
+ * - build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
167
+ * (multi-module aggregate; many builds rename the task)
168
+ *
169
+ * MAVEN (java):
170
+ * - target/site/jacoco/jacoco.xml
171
+ * (default Maven JaCoCo plugin — single-module Java)
172
+ * - target/site/jacoco-aggregate/jacoco.xml
173
+ * (Maven multi-module aggregate via jacoco-maven-plugin's
174
+ * `report-aggregate` goal)
175
+ *
176
+ * FALLBACKS:
177
+ * - jacocoTestReport.xml (top-level — fixture / direct path)
178
+ * - jacoco.xml (top-level — Maven fixture / direct path)
179
+ *
180
+ * Returns the first existing path, relative to cwd. Conservative
181
+ * priority: most specific build-tool conventions first, root
182
+ * fallbacks last.
183
+ */
184
+ function findJaCoCoReport(cwd) {
185
+ const candidates = [
186
+ // Gradle (Android + plain JVM)
187
+ 'app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml',
188
+ 'build/reports/jacoco/test/jacocoTestReport.xml',
189
+ 'build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml',
190
+ // Maven (single-module + multi-module aggregate)
191
+ 'target/site/jacoco/jacoco.xml',
192
+ 'target/site/jacoco-aggregate/jacoco.xml',
193
+ // Direct-path fallbacks (fixture / hand-placed)
194
+ 'jacocoTestReport.xml',
195
+ 'jacoco.xml',
196
+ ];
197
+ for (const rel of candidates) {
198
+ const abs = path.join(cwd, rel);
199
+ if (fs.existsSync(abs))
200
+ return rel;
201
+ }
202
+ return null;
203
+ }
204
+ /**
205
+ * Locate + parse the JaCoCo XML report under cwd, wrap the result in a
206
+ * `CoverageResult` envelope. Identical glue across JVM packs (kotlin,
207
+ * java) — no language-specific dispatch needed because JaCoCo's
208
+ * `<sourcefile name>` carries the on-disk filename verbatim and the
209
+ * file extension survives intact through the parser. Both packs'
210
+ * `coverageProvider.gather` should delegate here.
211
+ */
212
+ function gatherJaCoCoCoverageResult(cwd) {
213
+ const reportRel = findJaCoCoReport(cwd);
214
+ if (!reportRel)
215
+ return null;
216
+ let raw;
217
+ try {
218
+ raw = fs.readFileSync(path.join(cwd, reportRel), 'utf-8');
219
+ }
220
+ catch {
221
+ return null;
222
+ }
223
+ const coverage = parseJaCoCoXml(raw, reportRel, cwd);
224
+ if (!coverage)
225
+ return null;
226
+ return { schemaVersion: 1, tool: `coverage:${coverage.source}`, coverage };
227
+ }
228
+ //# sourceMappingURL=jacoco.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jacoco.js","sourceRoot":"","sources":["../../../src/analyzers/tools/jacoco.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,wCAmEC;AA6BD,4CAkBC;AAUD,gEAYC;AA/LD;;;;;;;;;;;;;GAaG;AACH,uCAAyB;AACzB,2CAA6B;AAE7B,yCAAsE;AAGtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,SAAgB,cAAc,CAAC,GAAW,EAAE,UAAkB,EAAE,IAAY;IAC1E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC9C,sEAAsE;IACtE,qEAAqE;IACrE,4DAA4D;IAC5D,MAAM,SAAS,GAAG,kDAAkD,CAAC;IACrE,IAAI,EAA0B,CAAC;IAC/B,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,8CAA8C;QACzF,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACvB,iEAAiE;QACjE,MAAM,YAAY,GAAG,wDAAwD,CAAC;QAC9E,IAAI,EAA0B,CAAC;QAC/B,OAAO,CAAC,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1B,wDAAwD;YACxD,iEAAiE;YACjE,qCAAqC;YACrC,MAAM,SAAS,GAAG,kEAAkE,CAAC;YACrF,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,IAAI,EAA0B,CAAC;YAC/B,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBACnD,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjC,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,KAAK,GAAG,UAAU,GAAG,WAAW,CAAC;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC1D,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;gBACb,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,WAAW;gBACpB,KAAK;gBACL,GAAG,EAAE,IAAA,iBAAM,EAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aACzD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,oEAAoE;IACpE,2DAA2D;IAC3D,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CACzB,4FAA4F,CAC7F,CAAC;IACF,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,SAAS,EAAE,CAAC;QACd,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzC,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,mEAAmE;QACnE,gEAAgE;QAChE,SAAS;QACT,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/B,YAAY,IAAI,CAAC,CAAC,OAAO,CAAC;YAC1B,WAAW,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC;QACrC,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,CAAC;IAC9C,IAAI,UAAU,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtD,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,UAAU;QACV,WAAW,EAAE,IAAA,iBAAM,EAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,MAAM,UAAU,GAAG;QACjB,+BAA+B;QAC/B,gEAAgE;QAChE,gDAAgD;QAChD,4DAA4D;QAC5D,iDAAiD;QACjD,+BAA+B;QAC/B,yCAAyC;QACzC,gDAAgD;QAChD,sBAAsB;QACtB,YAAY;KACb,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,0BAA0B,CAAC,GAAW;IACpD,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IACrD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,QAAQ,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { DepVulnFinding, DepVulnGatherOutcome, SeverityCounts } from '../../languages/capabilities/types';
2
+ /**
3
+ * Pure parser for osv-scanner v2.x JSON output, scoped to a single
4
+ * ecosystem. Other ecosystems are filtered out so polyglot repos
5
+ * don't double-count: each pack handles its own ecosystem (typescript
6
+ * → npm, python → PyPI, kotlin/java → Maven, ruby → RubyGems, etc.).
7
+ *
8
+ * The ecosystem parameter is matched against the OSV record's
9
+ * `package.ecosystem` field verbatim — use the exact strings OSV
10
+ * emits (`'Maven'`, `'RubyGems'`, `'PyPI'`, `'npm'`, `'Go'`, etc.).
11
+ *
12
+ * Returns counts + findings + the raw OSV vuln records for downstream
13
+ * CVSS resolution. Exported for unit tests.
14
+ */
15
+ export declare function parseOsvScannerFindings(raw: string, ecosystem: string): {
16
+ counts: SeverityCounts;
17
+ findings: DepVulnFinding[];
18
+ vulnsForCvss: Array<{
19
+ primaryId: string;
20
+ embeddedCvss: number | null;
21
+ aliases: string[];
22
+ }>;
23
+ };
24
+ /**
25
+ * Single source of truth for osv-scanner-driven dep-vuln gathering.
26
+ * Caller supplies:
27
+ * - cwd: project root
28
+ * - source: pack id for envelope attribution (currently reserved —
29
+ * see note at end of function)
30
+ * - ecosystem: OSV ecosystem string (`'Maven'`, `'RubyGems'`, ...)
31
+ * - manifestCandidates: ordered list of manifest filenames to probe.
32
+ * First existing one is passed via `--lockfile`. Lockfiles
33
+ * preferred over higher-level manifests (kotlin: gradle.lockfile
34
+ * before pom.xml; ruby: Gemfile.lock).
35
+ *
36
+ * `scan source --lockfile <path>` is the v2.x form. JSON output to
37
+ * stdout. Exit code is non-zero when findings exist — we ignore the
38
+ * exit code and parse the JSON regardless (run() already swallows
39
+ * non-zero exits cleanly via execSync's catch).
40
+ *
41
+ * CVSS alias-fallback: osv-scanner ships CVSS vectors when present,
42
+ * but advisory data quality varies by ecosystem — some carry only
43
+ * `database_specific.severity` strings. resolveCvssScores looks up
44
+ * via CVE alias when the primary record lacks a vector.
45
+ */
46
+ export declare function gatherOsvScannerDepVulnsResult(cwd: string, source: string, ecosystem: string, manifestCandidates: string[]): Promise<DepVulnGatherOutcome>;
47
+ //# sourceMappingURL=osv-scanner-deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osv-scanner-deps.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-deps.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EAEpB,cAAc,EACf,MAAM,oCAAoC,CAAC;AAiB5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,YAAY,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC5F,CAiEA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,8BAA8B,CAClD,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAAE,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CA4C/B"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseOsvScannerFindings = parseOsvScannerFindings;
4
+ exports.gatherOsvScannerDepVulnsResult = gatherOsvScannerDepVulnsResult;
5
+ /**
6
+ * osv-scanner against any OSV ecosystem — shared across language packs
7
+ * that use osv-scanner as their canonical depVulns source. CLAUDE.md
8
+ * rule #2 — the gather function lives once.
9
+ *
10
+ * History: extracted from `src/languages/kotlin.ts` in 10k.1.4 (Phase
11
+ * 10k.1 SSOT validation), originally Maven-only. Generalized to all
12
+ * OSV ecosystems in 10k.2.6a (Ruby pack work) — caller passes the
13
+ * ecosystem string + manifest candidate list, parser filters
14
+ * accordingly so polyglot repos don't double-count across packs.
15
+ *
16
+ * Current consumers:
17
+ * - kotlin pack — `Maven` ecosystem, gradle.lockfile + pom.xml + verification-metadata.xml
18
+ * - java pack — `Maven` ecosystem (same manifest set)
19
+ * - ruby pack — `RubyGems` ecosystem, Gemfile.lock
20
+ *
21
+ * osv-scanner is the established multi-ecosystem scanner; no Tier-1
22
+ * native equivalent exists for several of the ecosystems above
23
+ * (CLAUDE.md rule #5 — bundler-audit's JSON is unstable, so Ruby
24
+ * intentionally uses osv-scanner-only rather than dual-source).
25
+ * The typescript pack's `osv-scanner-fix.ts` uses the `fix`
26
+ * subcommand for upgrade planning — different mode, no shared logic.
27
+ *
28
+ * Manifest gating: caller supplies the candidate list. First
29
+ * existing candidate wins. Without any of them, returns
30
+ * `tool-missing` (matches python/csharp's manifest-gating pattern).
31
+ */
32
+ const osv_1 = require("./osv");
33
+ const runner_1 = require("./runner");
34
+ const tool_registry_1 = require("./tool-registry");
35
+ /**
36
+ * Pure parser for osv-scanner v2.x JSON output, scoped to a single
37
+ * ecosystem. Other ecosystems are filtered out so polyglot repos
38
+ * don't double-count: each pack handles its own ecosystem (typescript
39
+ * → npm, python → PyPI, kotlin/java → Maven, ruby → RubyGems, etc.).
40
+ *
41
+ * The ecosystem parameter is matched against the OSV record's
42
+ * `package.ecosystem` field verbatim — use the exact strings OSV
43
+ * emits (`'Maven'`, `'RubyGems'`, `'PyPI'`, `'npm'`, `'Go'`, etc.).
44
+ *
45
+ * Returns counts + findings + the raw OSV vuln records for downstream
46
+ * CVSS resolution. Exported for unit tests.
47
+ */
48
+ function parseOsvScannerFindings(raw, ecosystem) {
49
+ const counts = { critical: 0, high: 0, medium: 0, low: 0 };
50
+ const findings = [];
51
+ const vulnsForCvss = [];
52
+ let data;
53
+ try {
54
+ data = JSON.parse(raw);
55
+ }
56
+ catch {
57
+ return { counts, findings, vulnsForCvss };
58
+ }
59
+ // Dedup at the source: osv-scanner can list the same advisory twice
60
+ // when a transitive dep is reachable through multiple top-level deps.
61
+ // Same (package, version, id) → same fingerprint, so collapse here.
62
+ const seen = new Set();
63
+ for (const result of data.results ?? []) {
64
+ for (const pkg of result.packages ?? []) {
65
+ if (pkg.package?.ecosystem !== ecosystem)
66
+ continue;
67
+ const pkgName = pkg.package.name ?? 'unknown';
68
+ const pkgVersion = pkg.package.version;
69
+ for (const vuln of pkg.vulnerabilities ?? []) {
70
+ if (!vuln.id)
71
+ continue;
72
+ const dedupKey = `${pkgName}\0${pkgVersion ?? ''}\0${vuln.id}`;
73
+ if (seen.has(dedupKey))
74
+ continue;
75
+ seen.add(dedupKey);
76
+ const sev = (0, osv_1.classifyOsvSeverity)(vuln);
77
+ const tier = sev === 'critical' || sev === 'high' || sev === 'medium' || sev === 'low'
78
+ ? sev
79
+ : 'medium';
80
+ counts[tier]++;
81
+ const cvss = (0, osv_1.extractOsvCvssScore)(vuln);
82
+ const aliases = (vuln.aliases ?? []).filter((a) => a && a.length > 0);
83
+ const finding = {
84
+ id: vuln.id,
85
+ package: pkgName,
86
+ installedVersion: pkgVersion,
87
+ tool: 'osv-scanner',
88
+ severity: tier,
89
+ };
90
+ if (cvss !== null)
91
+ finding.cvssScore = cvss;
92
+ if (aliases.length > 0)
93
+ finding.aliases = aliases;
94
+ if (vuln.summary)
95
+ finding.summary = vuln.summary;
96
+ // OSV.dev hosts a canonical page per id — synthesize when the
97
+ // record's `references[]` is empty, otherwise keep the
98
+ // tool-supplied URLs.
99
+ const refUrls = (vuln.references ?? []).map((r) => r.url).filter((u) => !!u);
100
+ finding.references =
101
+ refUrls.length > 0 ? refUrls : [`https://osv.dev/vulnerability/${vuln.id}`];
102
+ findings.push(finding);
103
+ vulnsForCvss.push({
104
+ primaryId: vuln.id,
105
+ embeddedCvss: cvss,
106
+ aliases,
107
+ });
108
+ }
109
+ }
110
+ }
111
+ return { counts, findings, vulnsForCvss };
112
+ }
113
+ /**
114
+ * Single source of truth for osv-scanner-driven dep-vuln gathering.
115
+ * Caller supplies:
116
+ * - cwd: project root
117
+ * - source: pack id for envelope attribution (currently reserved —
118
+ * see note at end of function)
119
+ * - ecosystem: OSV ecosystem string (`'Maven'`, `'RubyGems'`, ...)
120
+ * - manifestCandidates: ordered list of manifest filenames to probe.
121
+ * First existing one is passed via `--lockfile`. Lockfiles
122
+ * preferred over higher-level manifests (kotlin: gradle.lockfile
123
+ * before pom.xml; ruby: Gemfile.lock).
124
+ *
125
+ * `scan source --lockfile <path>` is the v2.x form. JSON output to
126
+ * stdout. Exit code is non-zero when findings exist — we ignore the
127
+ * exit code and parse the JSON regardless (run() already swallows
128
+ * non-zero exits cleanly via execSync's catch).
129
+ *
130
+ * CVSS alias-fallback: osv-scanner ships CVSS vectors when present,
131
+ * but advisory data quality varies by ecosystem — some carry only
132
+ * `database_specific.severity` strings. resolveCvssScores looks up
133
+ * via CVE alias when the primary record lacks a vector.
134
+ */
135
+ async function gatherOsvScannerDepVulnsResult(cwd, source, ecosystem, manifestCandidates) {
136
+ let manifest = null;
137
+ for (const rel of manifestCandidates) {
138
+ if ((0, runner_1.fileExists)(cwd, rel)) {
139
+ manifest = rel;
140
+ break;
141
+ }
142
+ }
143
+ if (!manifest)
144
+ return { kind: 'tool-missing' };
145
+ const scanner = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['osv-scanner'], cwd);
146
+ if (!scanner.available || !scanner.path)
147
+ return { kind: 'tool-missing' };
148
+ const raw = (0, runner_1.run)(`${scanner.path} scan source --lockfile ${manifest} --format json 2>/dev/null`, cwd, 180000);
149
+ if (!raw)
150
+ return { kind: 'no-output' };
151
+ const { counts, findings, vulnsForCvss } = parseOsvScannerFindings(raw, ecosystem);
152
+ if (findings.length > 0) {
153
+ const resolved = await (0, osv_1.resolveCvssScores)(vulnsForCvss);
154
+ for (const f of findings) {
155
+ const score = resolved.get(f.id);
156
+ if (score !== null && score !== undefined)
157
+ f.cvssScore = score;
158
+ }
159
+ }
160
+ const envelope = {
161
+ schemaVersion: 1,
162
+ tool: 'osv-scanner',
163
+ enrichment: 'osv.dev',
164
+ counts,
165
+ findings,
166
+ };
167
+ // Note: `source` is unused at the envelope level today — DepVulnResult
168
+ // carries `tool: 'osv-scanner'` as the producer attribution. Reserved
169
+ // for a future enhancement that distinguishes per-pack provenance
170
+ // (e.g., when both kotlin and java packs run on a mixed monorepo and
171
+ // we want to attribute findings to the originating pack).
172
+ void source;
173
+ return { kind: 'success', envelope };
174
+ }
175
+ //# sourceMappingURL=osv-scanner-deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osv-scanner-deps.js","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-deps.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,26 @@ import type { DepVulnFinding, DepVulnUpgradePlan } from '../../languages/capabil
32
32
  *
33
33
  * Never throws. `gatherTsDepVulnsResult` calls this unconditionally and
34
34
  * treats the empty map as "no enrichment available".
35
+ *
36
+ * **TEMP-DIR ISOLATION (10k.1.5b fix — discovered during 2.4.5 pre-ship
37
+ * regression):** osv-scanner v2's `fix` subcommand invokes `npm install`
38
+ * internally to compute upgrade patches. That `npm install` MUTATES the
39
+ * cwd's node_modules — wipes it then reinstalls (often with
40
+ * `--legacy-peer-deps` fallback if the project's deps don't resolve
41
+ * cleanly). On dxkit's own repo this caused subsequent dxkit subcommand
42
+ * invocations to crash with `Cannot find module 'hosted-git-info'`
43
+ * because osv-scanner's reinstall left an incomplete tree. On
44
+ * vyuhlabs-platform (835MB node_modules) the reinstall happened to
45
+ * succeed but still mutated state silently — a 5-month-old data-mutation
46
+ * bug shipped since 2.4.0 / Phase 10h.6 and only caught now because
47
+ * 2.4.5 pre-ship regression ran reports back-to-back on dxkit's own repo
48
+ * and tripped the chain.
49
+ *
50
+ * Mitigation: we copy `package.json` + `package-lock.json` to a fresh
51
+ * temp dir, run osv-scanner there, and discard the temp dir afterward.
52
+ * Output JSON identifies advisories by `(package, version, id)` tuples
53
+ * which are independent of cwd, so the upgrade-plan map we return is
54
+ * unchanged. The caller's project gets read-only treatment.
35
55
  */
36
56
  export declare function gatherOsvScannerFixPlans(cwd: string): Promise<Map<string, DepVulnUpgradePlan>>;
37
57
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"osv-scanner-fix.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-fix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAqC7F;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CA+B1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAwCrF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,GACrC,MAAM,CAaR;AAED;;;;;;;4BAO4B;AAC5B,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEhF"}
1
+ {"version":3,"file":"osv-scanner-fix.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-fix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAsC7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAwC1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAwCrF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,GACrC,MAAM,CAaR;AAED;;;;;;;4BAO4B;AAC5B,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEhF"}
@@ -58,9 +58,10 @@ exports.gatherOsvScannerFixPlans = gatherOsvScannerFixPlans;
58
58
  exports.parseOsvScannerFixOutput = parseOsvScannerFixOutput;
59
59
  exports.enrichWithUpgradePlans = enrichWithUpgradePlans;
60
60
  exports.planKey = planKey;
61
- const child_process_1 = require("child_process");
62
61
  const fs = __importStar(require("fs"));
62
+ const os = __importStar(require("os"));
63
63
  const path = __importStar(require("path"));
64
+ const runner_1 = require("./runner");
64
65
  const semver_bump_1 = require("./semver-bump");
65
66
  const tool_registry_1 = require("./tool-registry");
66
67
  /**
@@ -75,6 +76,26 @@ const tool_registry_1 = require("./tool-registry");
75
76
  *
76
77
  * Never throws. `gatherTsDepVulnsResult` calls this unconditionally and
77
78
  * treats the empty map as "no enrichment available".
79
+ *
80
+ * **TEMP-DIR ISOLATION (10k.1.5b fix — discovered during 2.4.5 pre-ship
81
+ * regression):** osv-scanner v2's `fix` subcommand invokes `npm install`
82
+ * internally to compute upgrade patches. That `npm install` MUTATES the
83
+ * cwd's node_modules — wipes it then reinstalls (often with
84
+ * `--legacy-peer-deps` fallback if the project's deps don't resolve
85
+ * cleanly). On dxkit's own repo this caused subsequent dxkit subcommand
86
+ * invocations to crash with `Cannot find module 'hosted-git-info'`
87
+ * because osv-scanner's reinstall left an incomplete tree. On
88
+ * vyuhlabs-platform (835MB node_modules) the reinstall happened to
89
+ * succeed but still mutated state silently — a 5-month-old data-mutation
90
+ * bug shipped since 2.4.0 / Phase 10h.6 and only caught now because
91
+ * 2.4.5 pre-ship regression ran reports back-to-back on dxkit's own repo
92
+ * and tripped the chain.
93
+ *
94
+ * Mitigation: we copy `package.json` + `package-lock.json` to a fresh
95
+ * temp dir, run osv-scanner there, and discard the temp dir afterward.
96
+ * Output JSON identifies advisories by `(package, version, id)` tuples
97
+ * which are independent of cwd, so the upgrade-plan map we return is
98
+ * unchanged. The caller's project gets read-only treatment.
78
99
  */
79
100
  async function gatherOsvScannerFixPlans(cwd) {
80
101
  const manifestRel = 'package.json';
@@ -87,28 +108,32 @@ async function gatherOsvScannerFixPlans(cwd) {
87
108
  const tool = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['osv-scanner'], cwd);
88
109
  if (!tool.available || !tool.path)
89
110
  return new Map();
90
- // Quote paths defensively repo paths with spaces break shell parsing
91
- // otherwise, and osv-scanner's CLI is shell-parsed.
92
- const cmd = `${tool.path} fix --format json --manifest ${JSON.stringify(manifestRel)} ` +
93
- `--lockfile ${JSON.stringify(lockfileRel)}`;
94
- let raw;
111
+ // Stage manifest + lockfile in a fresh temp dir. osv-scanner mutates
112
+ // node_modules in its working directory; staging here protects the
113
+ // caller's actual project tree from any side effects.
114
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dxkit-osv-fix-'));
95
115
  try {
96
- raw = (0, child_process_1.execSync)(cmd, {
97
- cwd,
98
- encoding: 'utf8',
99
- stdio: ['ignore', 'pipe', 'pipe'],
100
- timeout: 120_000,
101
- });
102
- }
103
- catch (err) {
104
- // osv-scanner exits non-zero whenever it finds vulns, even though the
105
- // JSON payload is complete. Capture stdout from the error and proceed.
106
- const e = err;
107
- if (!e.stdout)
116
+ fs.copyFileSync(manifestAbs, path.join(tempDir, manifestRel));
117
+ fs.copyFileSync(lockfileAbs, path.join(tempDir, lockfileRel));
118
+ // Use runDetached (10k.1.5c addition) to put osv-scanner in its own
119
+ // process group. osv-scanner's `fix` subcommand spawns `npm install`
120
+ // grandchildren that orphan if execSync's timeout merely sends
121
+ // SIGTERM to the immediate child (the original 10k.1.5b fix only
122
+ // addressed node_modules mutation; the orphan-process leak was a
123
+ // separate symptom of the same root cause). runDetached SIGKILLs
124
+ // the entire group on timeout taking npm-install + its
125
+ // subprocesses with it.
126
+ const outcome = await (0, runner_1.runDetached)(tool.path, ['fix', '--format', 'json', '--manifest', manifestRel, '--lockfile', lockfileRel], { cwd: tempDir, timeoutMs: 120_000 });
127
+ // osv-scanner exits non-zero whenever it finds vulns, even though
128
+ // the JSON payload is complete. Always parse stdout regardless of
129
+ // exit code. Empty stdout (timed-out or hard-failed) → empty map.
130
+ if (!outcome.stdout)
108
131
  return new Map();
109
- raw = typeof e.stdout === 'string' ? e.stdout : e.stdout.toString('utf8');
132
+ return parseOsvScannerFixOutput(outcome.stdout);
133
+ }
134
+ finally {
135
+ fs.rmSync(tempDir, { recursive: true, force: true });
110
136
  }
111
- return parseOsvScannerFixOutput(raw);
112
137
  }
113
138
  /**
114
139
  * Parse raw `osv-scanner fix --format json` stdout into a plan-lookup map.
@@ -1 +1 @@
1
- {"version":3,"file":"osv-scanner-fix.js","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-fix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"osv-scanner-fix.js","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-fix.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EH,4DA0CC;AAYD,4DAwCC;AAOD,wDAgBC;AAUD,0BAEC;AA3MD,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAE7B,qCAAuC;AACvC,+CAA4C;AAC5C,mDAAsD;AAmCtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACI,KAAK,UAAU,wBAAwB,CAC5C,GAAW;IAEX,MAAM,WAAW,GAAG,cAAc,CAAC;IACnC,MAAM,WAAW,GAAG,mBAAmB,CAAC;IACxC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/D,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,wBAAQ,EAAC,yBAAS,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;IACrD,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAEpD,qEAAqE;IACrE,mEAAmE;IACnE,sDAAsD;IACtD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAC9D,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAE9D,oEAAoE;QACpE,qEAAqE;QACrE,+DAA+D;QAC/D,iEAAiE;QACjE,iEAAiE;QACjE,iEAAiE;QACjE,yDAAyD;QACzD,wBAAwB;QACxB,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAW,EAC/B,IAAI,CAAC,IAAI,EACT,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,EACjF,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CACrC,CAAC;QACF,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,IAAI,GAAG,EAAE,CAAC;QACtC,OAAO,wBAAwB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,wBAAwB,CAAC,GAAW;IAClD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAC;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,MAAoB,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAiB,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC;QACrC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC/C,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,oEAAoE;QACpE,oEAAoE;QACpE,mEAAmE;QACnE,gEAAgE;QAChE,gEAAgE;QAChE,uBAAuB;QACvB,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,IAAI,GAAuB;YAC/B,MAAM,EAAE,YAAY,CAAC,IAAI;YACzB,aAAa,EAAE,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC;YACvD,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,IAAA,yBAAW,EACnB,gBAAgB,CAAC,YAAY,CAAC,WAAW,CAAC,EAC1C,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC,CACzC;SACF,CAAC;QACF,mEAAmE;QACnE,2BAA2B;QAC3B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACtC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;gBACvC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAgB,sBAAsB,CACpC,QAA0B,EAC1B,KAAsC;IAEtC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,CAAC,gBAAgB;YAAE,SAAS;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,IAAI,EAAE,CAAC;YACT,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC;YACrB,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;4BAO4B;AAC5B,SAAgB,OAAO,CAAC,GAAW,EAAE,OAAe,EAAE,UAAkB;IACtE,OAAO,GAAG,GAAG,KAAK,OAAO,KAAK,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;AAC3D,CAAC;AAED;;;qCAGqC;AACrC,SAAS,gBAAgB,CAAC,CAAS;IACjC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC"}