@securecode-ai/mcp 0.2.0 → 0.3.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/dist/dependency/depCache.d.ts +22 -0
- package/dist/dependency/depCache.js +115 -0
- package/dist/dependency/depCache.js.map +1 -0
- package/dist/dependency/dependencyChecker.d.ts +48 -0
- package/dist/dependency/dependencyChecker.js +196 -0
- package/dist/dependency/dependencyChecker.js.map +1 -0
- package/dist/dependency/finding.d.ts +42 -0
- package/dist/dependency/finding.js +13 -0
- package/dist/dependency/finding.js.map +1 -0
- package/dist/dependency/licensePolicy.d.ts +56 -0
- package/dist/dependency/licensePolicy.js +109 -0
- package/dist/dependency/licensePolicy.js.map +1 -0
- package/dist/dependency/minSafeVersion.d.ts +32 -0
- package/dist/dependency/minSafeVersion.js +125 -0
- package/dist/dependency/minSafeVersion.js.map +1 -0
- package/dist/dependency/osvClient.d.ts +45 -0
- package/dist/dependency/osvClient.js +443 -0
- package/dist/dependency/osvClient.js.map +1 -0
- package/dist/dependency/parsers/npm.d.ts +13 -0
- package/dist/dependency/parsers/npm.js +160 -0
- package/dist/dependency/parsers/npm.js.map +1 -0
- package/dist/dependency/parsers/pipfile.d.ts +8 -0
- package/dist/dependency/parsers/pipfile.js +110 -0
- package/dist/dependency/parsers/pipfile.js.map +1 -0
- package/dist/dependency/parsers/pnpm.d.ts +11 -0
- package/dist/dependency/parsers/pnpm.js +148 -0
- package/dist/dependency/parsers/pnpm.js.map +1 -0
- package/dist/dependency/parsers/requirements.d.ts +24 -0
- package/dist/dependency/parsers/requirements.js +153 -0
- package/dist/dependency/parsers/requirements.js.map +1 -0
- package/dist/dependency/parsers/yarn.d.ts +10 -0
- package/dist/dependency/parsers/yarn.js +153 -0
- package/dist/dependency/parsers/yarn.js.map +1 -0
- package/dist/dependency/resolver.d.ts +28 -0
- package/dist/dependency/resolver.js +159 -0
- package/dist/dependency/resolver.js.map +1 -0
- package/dist/dependency/types.d.ts +85 -0
- package/dist/dependency/types.js +11 -0
- package/dist/dependency/types.js.map +1 -0
- package/dist/mcp/server.js +18 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.js +8 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-map/mapBuilder.js +44 -5
- package/dist/project-map/mapBuilder.js.map +1 -1
- package/dist/tools/map.js +13 -1
- package/dist/tools/map.js.map +1 -1
- package/dist/tools/scanDependencies.d.ts +11 -0
- package/dist/tools/scanDependencies.js +37 -0
- package/dist/tools/scanDependencies.js.map +1 -0
- package/package.json +9 -2
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ResolvedPackage, Vulnerability } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Compute the smallest version bump that exits ALL affected ranges for a
|
|
4
|
+
* given vulnerable package.
|
|
5
|
+
*
|
|
6
|
+
* Strategy:
|
|
7
|
+
* - Collect all explicit `fixed` bounds from affected ranges; the smallest
|
|
8
|
+
* such fixed version is the minimal safe bump (you must reach at least it).
|
|
9
|
+
* - If no `fixed` is available, but `introduced` is, there is no known fix —
|
|
10
|
+
* return undefined and surface "no known fix" upstream.
|
|
11
|
+
* - For npm-family we use `semver.minSatisfying` against the candidate set
|
|
12
|
+
* and validate via `semver.valid`. For Python we fall back to a simple
|
|
13
|
+
* dotted-version comparator since we deliberately do not depend on a
|
|
14
|
+
* full PEP 440 library.
|
|
15
|
+
*
|
|
16
|
+
* The result is a *version string* (e.g. "4.17.21") suitable for an in-place
|
|
17
|
+
* manifest edit. We do NOT try to pick the smallest *major* bump — the user
|
|
18
|
+
* asked for the smallest version that exits all ranges, which is exactly
|
|
19
|
+
* the smallest `fixed` across all advisory ranges.
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeMinSafeVersion(pkg: ResolvedPackage, vulns: Vulnerability[]): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Loose PEP 440-ish comparator for dotted versions like "1.2.3" or "1.2.3rc1".
|
|
24
|
+
* Returns -1, 0, or 1. Good enough for "smallest fixed version" — not a
|
|
25
|
+
* general PEP 440 implementation (we explicitly avoid the `packaging` dep).
|
|
26
|
+
*/
|
|
27
|
+
export declare function comparePep440Loose(a: string, b: string): number;
|
|
28
|
+
/**
|
|
29
|
+
* Build a human-readable upgrade suggestion for the webview / Apply flow.
|
|
30
|
+
* e.g. "Upgrade lodash 4.17.19 -> 4.17.21"
|
|
31
|
+
*/
|
|
32
|
+
export declare function upgradeSuggestion(pkg: ResolvedPackage, minSafe: string): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
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.computeMinSafeVersion = computeMinSafeVersion;
|
|
37
|
+
exports.comparePep440Loose = comparePep440Loose;
|
|
38
|
+
exports.upgradeSuggestion = upgradeSuggestion;
|
|
39
|
+
const semver = __importStar(require("semver"));
|
|
40
|
+
/**
|
|
41
|
+
* Compute the smallest version bump that exits ALL affected ranges for a
|
|
42
|
+
* given vulnerable package.
|
|
43
|
+
*
|
|
44
|
+
* Strategy:
|
|
45
|
+
* - Collect all explicit `fixed` bounds from affected ranges; the smallest
|
|
46
|
+
* such fixed version is the minimal safe bump (you must reach at least it).
|
|
47
|
+
* - If no `fixed` is available, but `introduced` is, there is no known fix —
|
|
48
|
+
* return undefined and surface "no known fix" upstream.
|
|
49
|
+
* - For npm-family we use `semver.minSatisfying` against the candidate set
|
|
50
|
+
* and validate via `semver.valid`. For Python we fall back to a simple
|
|
51
|
+
* dotted-version comparator since we deliberately do not depend on a
|
|
52
|
+
* full PEP 440 library.
|
|
53
|
+
*
|
|
54
|
+
* The result is a *version string* (e.g. "4.17.21") suitable for an in-place
|
|
55
|
+
* manifest edit. We do NOT try to pick the smallest *major* bump — the user
|
|
56
|
+
* asked for the smallest version that exits all ranges, which is exactly
|
|
57
|
+
* the smallest `fixed` across all advisory ranges.
|
|
58
|
+
*/
|
|
59
|
+
function computeMinSafeVersion(pkg, vulns) {
|
|
60
|
+
const candidates = [];
|
|
61
|
+
for (const v of vulns) {
|
|
62
|
+
for (const a of v.affected) {
|
|
63
|
+
if (a.fixed)
|
|
64
|
+
candidates.push(a.fixed);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (candidates.length === 0)
|
|
68
|
+
return undefined;
|
|
69
|
+
if (isNpmFamily(pkg)) {
|
|
70
|
+
// Pick the smallest valid semver among candidates.
|
|
71
|
+
const valid = candidates
|
|
72
|
+
.map(c => semver.coerce(c))
|
|
73
|
+
.filter((c) => c !== null)
|
|
74
|
+
.map(c => c.version)
|
|
75
|
+
.sort((a, b) => semver.compare(a, b));
|
|
76
|
+
return valid[0];
|
|
77
|
+
}
|
|
78
|
+
// Python: simple dotted-numeric compare.
|
|
79
|
+
const valid = candidates
|
|
80
|
+
.filter(c => /^\d+(\.\d+)*([._-]?[a-z0-9]+)?$/i.test(c))
|
|
81
|
+
.sort(comparePep440Loose);
|
|
82
|
+
return valid[0];
|
|
83
|
+
}
|
|
84
|
+
function isNpmFamily(pkg) {
|
|
85
|
+
return pkg.ecosystem === 'npm' || pkg.ecosystem === 'yarn' || pkg.ecosystem === 'pnpm';
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Loose PEP 440-ish comparator for dotted versions like "1.2.3" or "1.2.3rc1".
|
|
89
|
+
* Returns -1, 0, or 1. Good enough for "smallest fixed version" — not a
|
|
90
|
+
* general PEP 440 implementation (we explicitly avoid the `packaging` dep).
|
|
91
|
+
*/
|
|
92
|
+
function comparePep440Loose(a, b) {
|
|
93
|
+
const pa = parseLooseVersion(a);
|
|
94
|
+
const pb = parseLooseVersion(b);
|
|
95
|
+
for (let i = 0; i < Math.max(pa.nums.length, pb.nums.length); i++) {
|
|
96
|
+
const ai = pa.nums[i] ?? 0;
|
|
97
|
+
const bi = pb.nums[i] ?? 0;
|
|
98
|
+
if (ai !== bi)
|
|
99
|
+
return ai - bi;
|
|
100
|
+
}
|
|
101
|
+
// Pre-release sorts before release (1.2.3rc1 < 1.2.3) — match PEP 440.
|
|
102
|
+
if (pa.pre && !pb.pre)
|
|
103
|
+
return -1;
|
|
104
|
+
if (!pa.pre && pb.pre)
|
|
105
|
+
return 1;
|
|
106
|
+
if (pa.pre && pb.pre)
|
|
107
|
+
return pa.pre < pb.pre ? -1 : pa.pre > pb.pre ? 1 : 0;
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
function parseLooseVersion(v) {
|
|
111
|
+
const m = v.match(/^(\d+(?:\.\d+)*)(?:([a-z]+\d*))?$/i);
|
|
112
|
+
if (!m)
|
|
113
|
+
return { nums: [0] };
|
|
114
|
+
const nums = m[1].split('.').map(n => parseInt(n, 10));
|
|
115
|
+
const pre = m[2];
|
|
116
|
+
return { nums, pre };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Build a human-readable upgrade suggestion for the webview / Apply flow.
|
|
120
|
+
* e.g. "Upgrade lodash 4.17.19 -> 4.17.21"
|
|
121
|
+
*/
|
|
122
|
+
function upgradeSuggestion(pkg, minSafe) {
|
|
123
|
+
return `Upgrade ${pkg.name} ${pkg.version} -> ${minSafe}`;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=minSafeVersion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minSafeVersion.js","sourceRoot":"","sources":["../../src/dependency/minSafeVersion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ResolvedPackage, Vulnerability } from './types';
|
|
2
|
+
import { CacheStore } from './finding';
|
|
3
|
+
/**
|
|
4
|
+
* Query OSV.dev in batches for the given resolved packages.
|
|
5
|
+
*
|
|
6
|
+
* Only package NAME + VERSION leave the machine. No source code is sent.
|
|
7
|
+
* Skips packages marked `unresolved` (we don't know the installed version).
|
|
8
|
+
*
|
|
9
|
+
* Returns a map keyed by `${ecosystem}:${name}@${version}` to a list of
|
|
10
|
+
* normalized Vulnerability records. Failures (network, parse) for a given
|
|
11
|
+
* batch are swallowed and that batch contributes no entries — the scan
|
|
12
|
+
* does not hard-fail on OSV being unreachable.
|
|
13
|
+
*/
|
|
14
|
+
export declare function queryOsvBatch(packages: ResolvedPackage[]): Promise<Map<string, Vulnerability[]>>;
|
|
15
|
+
/**
|
|
16
|
+
* GitHub Advisory Database query via the REST API (https://api.github.com/advisories).
|
|
17
|
+
*
|
|
18
|
+
* This replaces the previous `gh` CLI approach. The REST API:
|
|
19
|
+
* - Requires no CLI installation (just `fetch()`)
|
|
20
|
+
* - Returns real CVSS scores (not approximated severity strings)
|
|
21
|
+
* - Provides `patched_version_range` with the first fixed version
|
|
22
|
+
* - Works unauthenticated at 60 req/hr (5000 req/hr with a token)
|
|
23
|
+
*
|
|
24
|
+
* Design: GHSA is an ENRICHMENT source, not a primary source. We only
|
|
25
|
+
* query for packages that OSV already flagged as vulnerable. This keeps
|
|
26
|
+
* the request count low (typically 5-30 packages) and within the
|
|
27
|
+
* unauthenticated rate limit.
|
|
28
|
+
*
|
|
29
|
+
* If a GitHub token is available (`gh auth token` or GITHUB_TOKEN env),
|
|
30
|
+
* it is used to lift the rate limit to 5000 req/hr for large projects.
|
|
31
|
+
*/
|
|
32
|
+
export declare function queryGhsaViaCli(packages: ResolvedPackage[]): Promise<Map<string, Vulnerability[]>>;
|
|
33
|
+
/**
|
|
34
|
+
* With the REST API approach, GHSA is always "available" (works
|
|
35
|
+
* unauthenticated at 60 req/hr). Kept for backward compat with the
|
|
36
|
+
* `ghsaSkipped` flag in DependencyScanResult.
|
|
37
|
+
*/
|
|
38
|
+
export declare function ghCliAvailable(): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Enrich OSV records with NVD CVSS scores when missing, caching results
|
|
41
|
+
* in workspaceState for 24h.
|
|
42
|
+
*
|
|
43
|
+
* Mutates the records in place and returns them for convenience.
|
|
44
|
+
*/
|
|
45
|
+
export declare function enrichWithNvd(records: Vulnerability[], state: CacheStore): Promise<Vulnerability[]>;
|
|
@@ -0,0 +1,443 @@
|
|
|
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.queryOsvBatch = queryOsvBatch;
|
|
37
|
+
exports.queryGhsaViaCli = queryGhsaViaCli;
|
|
38
|
+
exports.ghCliAvailable = ghCliAvailable;
|
|
39
|
+
exports.enrichWithNvd = enrichWithNvd;
|
|
40
|
+
const cp = __importStar(require("child_process"));
|
|
41
|
+
const OSV_QUERYBATCH_URL = 'https://api.osv.dev/v1/querybatch';
|
|
42
|
+
const OSV_BATCH_SIZE = 1000; // OSV limit per batch request.
|
|
43
|
+
const GHSA_ADVISORIES_URL = 'https://api.github.com/advisories';
|
|
44
|
+
const GHSA_PER_PAGE = 100;
|
|
45
|
+
// Unauthenticated: 60 req/hr. With token: 5000 req/hr.
|
|
46
|
+
// We only query GHSA for packages OSV flagged (enrichment), so 60/hr is
|
|
47
|
+
// enough for typical projects (5-30 vulns). For larger projects, a token
|
|
48
|
+
// from `gh auth token` or GITHUB_TOKEN env var lifts the limit.
|
|
49
|
+
const GHSA_TIMEOUT_MS = 15000;
|
|
50
|
+
/**
|
|
51
|
+
* Map our ecosystem to OSV's. npm-family all share the `npm` OSV ecosystem
|
|
52
|
+
* (they hit the same advisory data on the npm registry).
|
|
53
|
+
*/
|
|
54
|
+
function osvEcosystemOf(pkg) {
|
|
55
|
+
switch (pkg.ecosystem) {
|
|
56
|
+
case 'npm':
|
|
57
|
+
case 'yarn':
|
|
58
|
+
case 'pnpm':
|
|
59
|
+
return 'npm';
|
|
60
|
+
case 'pip':
|
|
61
|
+
case 'pipenv':
|
|
62
|
+
return 'PyPI';
|
|
63
|
+
default:
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Query OSV.dev in batches for the given resolved packages.
|
|
69
|
+
*
|
|
70
|
+
* Only package NAME + VERSION leave the machine. No source code is sent.
|
|
71
|
+
* Skips packages marked `unresolved` (we don't know the installed version).
|
|
72
|
+
*
|
|
73
|
+
* Returns a map keyed by `${ecosystem}:${name}@${version}` to a list of
|
|
74
|
+
* normalized Vulnerability records. Failures (network, parse) for a given
|
|
75
|
+
* batch are swallowed and that batch contributes no entries — the scan
|
|
76
|
+
* does not hard-fail on OSV being unreachable.
|
|
77
|
+
*/
|
|
78
|
+
async function queryOsvBatch(packages) {
|
|
79
|
+
const out = new Map();
|
|
80
|
+
const queryable = packages.filter(p => !p.unresolved && !!p.version && !!p.name);
|
|
81
|
+
if (queryable.length === 0)
|
|
82
|
+
return out;
|
|
83
|
+
for (let i = 0; i < queryable.length; i += OSV_BATCH_SIZE) {
|
|
84
|
+
const slice = queryable.slice(i, i + OSV_BATCH_SIZE);
|
|
85
|
+
const queries = [];
|
|
86
|
+
const keyForIndex = [];
|
|
87
|
+
for (const p of slice) {
|
|
88
|
+
const eco = osvEcosystemOf(p);
|
|
89
|
+
if (!eco)
|
|
90
|
+
continue;
|
|
91
|
+
// npm-family names must match the npm registry casing OSV expects;
|
|
92
|
+
// OSV is case-sensitive on the npm ecosystem. Use the original name
|
|
93
|
+
// (npm is case-insensitive in practice but OSV stores as-published).
|
|
94
|
+
queries.push({ package: { name: p.name, ecosystem: eco }, version: p.version });
|
|
95
|
+
keyForIndex.push(`${eco}:${p.name}@${p.version}`);
|
|
96
|
+
}
|
|
97
|
+
if (queries.length === 0)
|
|
98
|
+
continue;
|
|
99
|
+
let body;
|
|
100
|
+
try {
|
|
101
|
+
body = JSON.stringify({ queries: queries.map(q => ({ package: q.package, version: q.version })) });
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
let resp = null;
|
|
107
|
+
try {
|
|
108
|
+
const controller = new AbortController();
|
|
109
|
+
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
110
|
+
const r = await fetch(OSV_QUERYBATCH_URL, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: { 'Content-Type': 'application/json' },
|
|
113
|
+
body,
|
|
114
|
+
signal: controller.signal,
|
|
115
|
+
});
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
if (r.ok) {
|
|
118
|
+
resp = (await r.json());
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// network error — skip this batch
|
|
123
|
+
}
|
|
124
|
+
if (!resp || !Array.isArray(resp.results))
|
|
125
|
+
continue;
|
|
126
|
+
for (let j = 0; j < resp.results.length; j++) {
|
|
127
|
+
const key = keyForIndex[j];
|
|
128
|
+
if (!key)
|
|
129
|
+
continue;
|
|
130
|
+
const r = resp.results[j];
|
|
131
|
+
const vulns = r?.vulns;
|
|
132
|
+
if (!vulns || vulns.length === 0)
|
|
133
|
+
continue;
|
|
134
|
+
const list = [];
|
|
135
|
+
for (const v of vulns) {
|
|
136
|
+
const affected = [];
|
|
137
|
+
if (Array.isArray(v.affected)) {
|
|
138
|
+
for (const a of v.affected) {
|
|
139
|
+
const ranges = a?.ranges || [];
|
|
140
|
+
for (const rng of ranges) {
|
|
141
|
+
if (!Array.isArray(rng.events))
|
|
142
|
+
continue;
|
|
143
|
+
let introduced;
|
|
144
|
+
let fixed;
|
|
145
|
+
for (const ev of rng.events) {
|
|
146
|
+
if (typeof ev.introduced === 'string')
|
|
147
|
+
introduced = ev.introduced;
|
|
148
|
+
if (typeof ev.fixed === 'string')
|
|
149
|
+
fixed = ev.fixed;
|
|
150
|
+
}
|
|
151
|
+
affected.push({
|
|
152
|
+
ecosystem: a?.package?.ecosystem || 'npm',
|
|
153
|
+
introduced,
|
|
154
|
+
fixed,
|
|
155
|
+
raw: JSON.stringify(rng),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
let cvssScore;
|
|
161
|
+
if (Array.isArray(v.severity)) {
|
|
162
|
+
for (const s of v.severity) {
|
|
163
|
+
if (s?.type === 'CVSS_V3' && typeof s.score === 'string') {
|
|
164
|
+
// Try plain numeric score first (some records use "7.5").
|
|
165
|
+
const num = parseFloat(s.score);
|
|
166
|
+
if (!Number.isNaN(num) && s.score.trim().length <= 5) {
|
|
167
|
+
cvssScore = num;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Parse CVSS vector string (e.g. "CVSS:3.1/AV:N/AC:L/...").
|
|
171
|
+
// Extract the base score from the vector by counting
|
|
172
|
+
// the metrics — but since the vector doesn't contain a
|
|
173
|
+
// precomputed score, fall back to NVD enrichment which
|
|
174
|
+
// has the real baseScore field.
|
|
175
|
+
// NVD enrichment (enrichWithNvd) will fill this in
|
|
176
|
+
// if the record has a CVE alias.
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const references = [];
|
|
182
|
+
if (Array.isArray(v.references)) {
|
|
183
|
+
for (const ref of v.references) {
|
|
184
|
+
if (typeof ref?.url === 'string')
|
|
185
|
+
references.push(ref.url);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
list.push({
|
|
189
|
+
id: v.id,
|
|
190
|
+
source: 'osv',
|
|
191
|
+
summary: v.summary || '',
|
|
192
|
+
affected,
|
|
193
|
+
cvssScore,
|
|
194
|
+
references,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
out.set(key, list);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* GitHub Advisory Database query via the REST API (https://api.github.com/advisories).
|
|
204
|
+
*
|
|
205
|
+
* This replaces the previous `gh` CLI approach. The REST API:
|
|
206
|
+
* - Requires no CLI installation (just `fetch()`)
|
|
207
|
+
* - Returns real CVSS scores (not approximated severity strings)
|
|
208
|
+
* - Provides `patched_version_range` with the first fixed version
|
|
209
|
+
* - Works unauthenticated at 60 req/hr (5000 req/hr with a token)
|
|
210
|
+
*
|
|
211
|
+
* Design: GHSA is an ENRICHMENT source, not a primary source. We only
|
|
212
|
+
* query for packages that OSV already flagged as vulnerable. This keeps
|
|
213
|
+
* the request count low (typically 5-30 packages) and within the
|
|
214
|
+
* unauthenticated rate limit.
|
|
215
|
+
*
|
|
216
|
+
* If a GitHub token is available (`gh auth token` or GITHUB_TOKEN env),
|
|
217
|
+
* it is used to lift the rate limit to 5000 req/hr for large projects.
|
|
218
|
+
*/
|
|
219
|
+
async function queryGhsaViaCli(packages) {
|
|
220
|
+
const out = new Map();
|
|
221
|
+
const queryable = packages.filter(p => !p.unresolved && !!p.version && !!p.name);
|
|
222
|
+
for (const p of queryable) {
|
|
223
|
+
const eco = osvEcosystemOf(p);
|
|
224
|
+
if (!eco)
|
|
225
|
+
continue;
|
|
226
|
+
const ghEco = eco === 'npm' ? 'npm' : 'pip';
|
|
227
|
+
let advisories;
|
|
228
|
+
try {
|
|
229
|
+
advisories = await queryGhsaRest(ghEco, p.name);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (!advisories || advisories.length === 0)
|
|
235
|
+
continue;
|
|
236
|
+
const list = [];
|
|
237
|
+
for (const adv of advisories) {
|
|
238
|
+
if (!adv?.ghsa_id)
|
|
239
|
+
continue;
|
|
240
|
+
// Real CVSS score from the API (not approximated).
|
|
241
|
+
let cvssScore;
|
|
242
|
+
if (typeof adv.cvss?.score === 'number') {
|
|
243
|
+
cvssScore = adv.cvss.score;
|
|
244
|
+
}
|
|
245
|
+
else if (typeof adv.cvss_score === 'number') {
|
|
246
|
+
cvssScore = adv.cvss_score;
|
|
247
|
+
}
|
|
248
|
+
// Parse affected + fixed versions from the vulnerabilities array.
|
|
249
|
+
const affected = [];
|
|
250
|
+
const vulns = Array.isArray(adv.vulnerabilities) ? adv.vulnerabilities : [];
|
|
251
|
+
for (const v of vulns) {
|
|
252
|
+
const rawRange = typeof v?.vulnerable_version_range === 'string'
|
|
253
|
+
? v.vulnerable_version_range : '';
|
|
254
|
+
const patched = typeof v?.patched_version_range === 'string'
|
|
255
|
+
? v.patched_version_range : '';
|
|
256
|
+
// Extract the fixed version from the patched range.
|
|
257
|
+
// GitHub uses ">= X.Y.Z" for the first patched version.
|
|
258
|
+
let fixed;
|
|
259
|
+
if (patched) {
|
|
260
|
+
const m = patched.match(/>=?\s*([0-9][0-9a-zA-Z.\-+]*)/);
|
|
261
|
+
if (m)
|
|
262
|
+
fixed = m[1];
|
|
263
|
+
}
|
|
264
|
+
// Extract the introduced version from the vulnerable range.
|
|
265
|
+
let introduced;
|
|
266
|
+
if (rawRange) {
|
|
267
|
+
const m = rawRange.match(/>=?\s*([0-9][0-9a-zA-Z.\-+]*)/);
|
|
268
|
+
if (m)
|
|
269
|
+
introduced = m[1];
|
|
270
|
+
}
|
|
271
|
+
affected.push({ ecosystem: eco, introduced, fixed, raw: rawRange });
|
|
272
|
+
}
|
|
273
|
+
// References from the API.
|
|
274
|
+
const refs = Array.isArray(adv.references)
|
|
275
|
+
? adv.references.map((r) => r?.url).filter((x) => typeof x === 'string')
|
|
276
|
+
: [];
|
|
277
|
+
// If there's a CVE alias, include it in references for NVD enrichment.
|
|
278
|
+
if (typeof adv.cve_id === 'string' && adv.cve_id) {
|
|
279
|
+
refs.push(`https://nvd.nist.gov/vuln/detail/${adv.cve_id}`);
|
|
280
|
+
}
|
|
281
|
+
list.push({
|
|
282
|
+
id: adv.ghsa_id,
|
|
283
|
+
source: 'ghsa',
|
|
284
|
+
summary: adv.summary || '',
|
|
285
|
+
affected,
|
|
286
|
+
cvssScore,
|
|
287
|
+
references: refs,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
if (list.length > 0) {
|
|
291
|
+
const key = `${eco}:${p.name}@${p.version}`;
|
|
292
|
+
const existing = out.get(key) || [];
|
|
293
|
+
out.set(key, [...existing, ...list]);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return out;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Query the GitHub Advisory REST API for a single package.
|
|
300
|
+
*
|
|
301
|
+
* Uses optional authentication (GITHUB_TOKEN env or `gh auth token`)
|
|
302
|
+
* to lift the rate limit from 60/hr to 5000/hr. Without a token, the
|
|
303
|
+
* 60/hr limit is sufficient for enrichment (we only query packages OSV
|
|
304
|
+
* already flagged).
|
|
305
|
+
*/
|
|
306
|
+
async function queryGhsaRest(ecosystem, packageName) {
|
|
307
|
+
const url = `${GHSA_ADVISORIES_URL}?ecosystem=${encodeURIComponent(ecosystem)}&affected_package=${encodeURIComponent(packageName)}&per_page=${GHSA_PER_PAGE}`;
|
|
308
|
+
const headers = {
|
|
309
|
+
'Accept': 'application/vnd.github+json',
|
|
310
|
+
'User-Agent': 'SecureCode-Extension',
|
|
311
|
+
};
|
|
312
|
+
// Try to get a GitHub token for higher rate limits.
|
|
313
|
+
const token = await getGithubToken();
|
|
314
|
+
if (token) {
|
|
315
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
316
|
+
}
|
|
317
|
+
const controller = new AbortController();
|
|
318
|
+
const timeout = setTimeout(() => controller.abort(), GHSA_TIMEOUT_MS);
|
|
319
|
+
try {
|
|
320
|
+
const r = await fetch(url, {
|
|
321
|
+
method: 'GET',
|
|
322
|
+
headers,
|
|
323
|
+
signal: controller.signal,
|
|
324
|
+
});
|
|
325
|
+
if (!r.ok)
|
|
326
|
+
return [];
|
|
327
|
+
const data = await r.json();
|
|
328
|
+
return Array.isArray(data) ? data : [];
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
clearTimeout(timeout);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Detect a GitHub token from env vars or `gh auth token`.
|
|
339
|
+
* Returns null if no token is available (unauthenticated mode).
|
|
340
|
+
*/
|
|
341
|
+
let _cachedToken;
|
|
342
|
+
async function getGithubToken() {
|
|
343
|
+
if (_cachedToken !== undefined)
|
|
344
|
+
return _cachedToken;
|
|
345
|
+
// 1. Environment variables
|
|
346
|
+
const envToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
|
|
347
|
+
if (envToken) {
|
|
348
|
+
_cachedToken = envToken;
|
|
349
|
+
return _cachedToken;
|
|
350
|
+
}
|
|
351
|
+
// 2. `gh auth token` (if gh CLI is installed and authenticated)
|
|
352
|
+
try {
|
|
353
|
+
_cachedToken = await new Promise(resolve => {
|
|
354
|
+
const child = cp.spawn('gh', ['auth', 'token'], { shell: true });
|
|
355
|
+
let stdout = '';
|
|
356
|
+
child.stdout.on('data', d => { stdout += d.toString(); });
|
|
357
|
+
child.on('error', () => resolve(null));
|
|
358
|
+
child.on('exit', code => {
|
|
359
|
+
const t = stdout.trim();
|
|
360
|
+
resolve(code === 0 && t ? t : null);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
_cachedToken = null;
|
|
366
|
+
}
|
|
367
|
+
return _cachedToken;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* With the REST API approach, GHSA is always "available" (works
|
|
371
|
+
* unauthenticated at 60 req/hr). Kept for backward compat with the
|
|
372
|
+
* `ghsaSkipped` flag in DependencyScanResult.
|
|
373
|
+
*/
|
|
374
|
+
async function ghCliAvailable() {
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* NVD CVSS fallback. Uses the public NVD REST endpoint keyed by CVE id.
|
|
379
|
+
*
|
|
380
|
+
* Cached in `workspaceState` for 24h to respect the public rate limit
|
|
381
|
+
* (5 req/30s without an API key). We only call NVD when an OSV record has
|
|
382
|
+
* a CVE alias but no CVSS score, to fill in the severity number.
|
|
383
|
+
*/
|
|
384
|
+
const NVD_CACHE_KEY_PREFIX = 'securecode.nvd.';
|
|
385
|
+
const NVD_TTL_MS = 24 * 60 * 60 * 1000;
|
|
386
|
+
async function nvdLookup(cveId) {
|
|
387
|
+
const url = `https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=${encodeURIComponent(cveId)}`;
|
|
388
|
+
try {
|
|
389
|
+
const r = await fetch(url, { headers: { 'User-Agent': 'SecureCode-Extension' } });
|
|
390
|
+
if (!r.ok)
|
|
391
|
+
return null;
|
|
392
|
+
const data = await r.json();
|
|
393
|
+
const vuln = data?.vulnerabilities?.[0]?.cve;
|
|
394
|
+
if (!vuln)
|
|
395
|
+
return null;
|
|
396
|
+
let score;
|
|
397
|
+
const metrics = vuln?.metrics;
|
|
398
|
+
const cvss = metrics?.cvssMetricV31?.[0] ?? metrics?.cvssMetricV30?.[0] ?? metrics?.cvssMetricV2?.[0];
|
|
399
|
+
if (cvss?.cvssData?.baseScore)
|
|
400
|
+
score = cvss.cvssData.baseScore;
|
|
401
|
+
const refs = Array.isArray(vuln?.references)
|
|
402
|
+
? vuln.references.map((x) => x?.url).filter((y) => typeof y === 'string')
|
|
403
|
+
: [];
|
|
404
|
+
return { fetchedAt: Date.now(), score, url: refs[0] };
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Enrich OSV records with NVD CVSS scores when missing, caching results
|
|
412
|
+
* in workspaceState for 24h.
|
|
413
|
+
*
|
|
414
|
+
* Mutates the records in place and returns them for convenience.
|
|
415
|
+
*/
|
|
416
|
+
async function enrichWithNvd(records, state) {
|
|
417
|
+
for (const v of records) {
|
|
418
|
+
if (v.cvssScore !== undefined)
|
|
419
|
+
continue;
|
|
420
|
+
// Only CVE-ids are resolvable on NVD.
|
|
421
|
+
if (!/^CVE-\d{4}-\d+$/i.test(v.id))
|
|
422
|
+
continue;
|
|
423
|
+
const cacheKey = NVD_CACHE_KEY_PREFIX + v.id;
|
|
424
|
+
const cached = state.get(cacheKey);
|
|
425
|
+
let entry;
|
|
426
|
+
if (cached && Date.now() - cached.fetchedAt < NVD_TTL_MS) {
|
|
427
|
+
entry = cached;
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
entry = await nvdLookup(v.id);
|
|
431
|
+
if (entry)
|
|
432
|
+
state.update(cacheKey, entry);
|
|
433
|
+
}
|
|
434
|
+
if (entry?.score !== undefined) {
|
|
435
|
+
v.cvssScore = entry.score;
|
|
436
|
+
if (entry.url && (!v.references || v.references.length === 0)) {
|
|
437
|
+
v.references = [entry.url];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return records;
|
|
442
|
+
}
|
|
443
|
+
//# sourceMappingURL=osvClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osvClient.js","sourceRoot":"","sources":["../../src/dependency/osvClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,sCAsHC;AAmBD,0CA0EC;AA4ED,wCAEC;AAyCD,sCA0BC;AAzZD,kDAAoC;AAIpC,MAAM,kBAAkB,GAAG,mCAAmC,CAAC;AAC/D,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC,+BAA+B;AAC5D,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;AAChE,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,uDAAuD;AACvD,wEAAwE;AACxE,yEAAyE;AACzE,gEAAgE;AAChE,MAAM,eAAe,GAAG,KAAK,CAAC;AAY9B;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAoB;IACxC,QAAQ,GAAG,CAAC,SAAS,EAAE,CAAC;QACpB,KAAK,KAAK,CAAC;QACX,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM;YACP,OAAO,KAAK,CAAC;QACjB,KAAK,KAAK,CAAC;QACX,KAAK,QAAQ;YACT,OAAO,MAAM,CAAC;QAClB;YACI,OAAO,IAAI,CAAC;IACpB,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,aAAa,CAC/B,QAA2B;IAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE/C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC;QACrD,MAAM,OAAO,GAAe,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,mEAAmE;YACnE,oEAAoE;YACpE,qEAAqE;YACrE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAChF,WAAW,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEnC,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACvG,CAAC;QAAC,MAAM,CAAC;YACL,SAAS;QACb,CAAC;QAED,IAAI,IAAI,GAA4B,IAAI,CAAC;QACzC,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;YAC5D,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,kBAAkB,EAAE;gBACtC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI;gBACJ,MAAM,EAAE,UAAU,CAAC,MAAM;aAC5B,CAAC,CAAC;YACH,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;gBACP,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAqB,CAAC;YAChD,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,kCAAkC;QACtC,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QAEpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,KAAK,GAAG,CAAC,EAAE,KAAK,CAAC;YACvB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC3C,MAAM,IAAI,GAAoB,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAoB,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;wBACzB,MAAM,MAAM,GAAU,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC;wBACtC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;4BACvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;gCAAE,SAAS;4BACzC,IAAI,UAA8B,CAAC;4BACnC,IAAI,KAAyB,CAAC;4BAC9B,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gCAC1B,IAAI,OAAO,EAAE,CAAC,UAAU,KAAK,QAAQ;oCAAE,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC;gCAClE,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ;oCAAE,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;4BACvD,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC;gCACV,SAAS,EAAG,CAAC,EAAE,OAAO,EAAE,SAA0B,IAAI,KAAK;gCAC3D,UAAU;gCACV,KAAK;gCACL,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;6BAC3B,CAAC,CAAC;wBACP,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,IAAI,SAA6B,CAAC;gBAClC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;wBACzB,IAAI,CAAC,EAAE,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;4BACvD,0DAA0D;4BAC1D,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;4BAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gCACnD,SAAS,GAAG,GAAG,CAAC;4BACpB,CAAC;iCAAM,CAAC;gCACJ,4DAA4D;gCAC5D,qDAAqD;gCACrD,uDAAuD;gCACvD,uDAAuD;gCACvD,gCAAgC;gCAChC,mDAAmD;gCACnD,iCAAiC;4BACrC,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,MAAM,UAAU,GAAa,EAAE,CAAC;gBAChC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9B,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;wBAC7B,IAAI,OAAO,GAAG,EAAE,GAAG,KAAK,QAAQ;4BAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC/D,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC;oBACN,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE;oBACxB,QAAQ;oBACR,SAAS;oBACT,UAAU;iBACb,CAAC,CAAC;YACP,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACI,KAAK,UAAU,eAAe,CACjC,QAA2B;IAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE/C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,KAAK,GAAG,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC5C,IAAI,UAAiB,CAAC;QACtB,IAAI,CAAC;YACD,UAAU,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACL,SAAS;QACb,CAAC;QACD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACrD,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,EAAE,OAAO;gBAAE,SAAS;YAC5B,mDAAmD;YACnD,IAAI,SAA6B,CAAC;YAClC,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;YAC/B,CAAC;iBAAM,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC5C,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC;YAC/B,CAAC;YACD,kEAAkE;YAClE,MAAM,QAAQ,GAAoB,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAG,OAAO,CAAC,EAAE,wBAAwB,KAAK,QAAQ;oBAC5D,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtC,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,qBAAqB,KAAK,QAAQ;oBACxD,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnC,oDAAoD;gBACpD,wDAAwD;gBACxD,IAAI,KAAyB,CAAC;gBAC9B,IAAI,OAAO,EAAE,CAAC;oBACV,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;oBACzD,IAAI,CAAC;wBAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxB,CAAC;gBACD,4DAA4D;gBAC5D,IAAI,UAA8B,CAAC;gBACnC,IAAI,QAAQ,EAAE,CAAC;oBACX,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;oBAC1D,IAAI,CAAC;wBAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7B,CAAC;gBACD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,2BAA2B;YAC3B,MAAM,IAAI,GAAa,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;gBAChD,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;gBAClF,CAAC,CAAC,EAAE,CAAC;YACT,uEAAuE;YACvE,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,oCAAoC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,CAAC,IAAI,CAAC;gBACN,EAAE,EAAE,GAAG,CAAC,OAAO;gBACf,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE;gBAC1B,QAAQ;gBACR,SAAS;gBACT,UAAU,EAAE,IAAI;aACnB,CAAC,CAAC;QACP,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACpC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,WAAmB;IAC/D,MAAM,GAAG,GAAG,GAAG,mBAAmB,cAAc,kBAAkB,CAAC,SAAS,CAAC,qBAAqB,kBAAkB,CAAC,WAAW,CAAC,aAAa,aAAa,EAAE,CAAC;IAC9J,MAAM,OAAO,GAA2B;QACpC,QAAQ,EAAE,6BAA6B;QACvC,YAAY,EAAE,sBAAsB;KACvC,CAAC;IACF,oDAAoD;IACpD,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;IACrC,IAAI,KAAK,EAAE,CAAC;QACR,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,CAAC;IACtE,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YACvB,MAAM,EAAE,KAAK;YACb,OAAO;YACP,MAAM,EAAE,UAAU,CAAC,MAAM;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACP,YAAY,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,IAAI,YAAuC,CAAC;AAC5C,KAAK,UAAU,cAAc;IACzB,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IACpD,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClE,IAAI,QAAQ,EAAE,CAAC;QACX,YAAY,GAAG,QAAQ,CAAC;QACxB,OAAO,YAAY,CAAC;IACxB,CAAC;IACD,gEAAgE;IAChE,IAAI,CAAC;QACD,YAAY,GAAG,MAAM,IAAI,OAAO,CAAgB,OAAO,CAAC,EAAE;YACtD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACvC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;gBACpB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACL,YAAY,GAAG,IAAI,CAAC;IACxB,CAAC;IACD,OAAO,YAAY,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,cAAc;IAChC,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAC/C,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAIvC,KAAK,UAAU,SAAS,CAAC,KAAa;IAClC,MAAM,GAAG,GAAG,0DAA0D,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;IAClG,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAC;QAClF,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,IAAI,GAAQ,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QAC7C,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,IAAI,KAAyB,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;QACtG,IAAI,IAAI,EAAE,QAAQ,EAAE,SAAS;YAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC/D,MAAM,IAAI,GAAa,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC;YAClD,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACnF,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,aAAa,CAC/B,OAAwB,EACxB,KAAiB;IAEjB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS;YAAE,SAAS;QACxC,sCAAsC;QACtC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,SAAS;QAE7C,MAAM,QAAQ,GAAG,oBAAoB,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAgB,QAAQ,CAAC,CAAC;QAClD,IAAI,KAA2B,CAAC;QAChC,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,UAAU,EAAE,CAAC;YACvD,KAAK,GAAG,MAAM,CAAC;QACnB,CAAC;aAAM,CAAC;YACJ,KAAK,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,KAAK;gBAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC5D,CAAC,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
|