scanoss 0.33.0 → 0.34.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.
@@ -0,0 +1,251 @@
1
+ import path from "path";
2
+ import { PackageURL } from "packageurl-js";
3
+ const PURL_TYPE = "npm";
4
+ const MANIFEST_FILE = "pnpm-lock.yaml";
5
+ // Regex for pnpm lockfile v5 format: /package-name/version or /@scope/package-name/version
6
+ // May include peer dep suffixes like /@scope/pkg/1.0.0_peer@2.0.0
7
+ const V5_PACKAGE_REGEX = /^\s{2,4}\/?(?<fullname>(?:@(?<scope>[^/]+)\/)?(?<name>[^/]+))\/(?<version>\d[^_:]*)/;
8
+ // Regex for pnpm lockfile v6+ format: /package-name@version or /@scope/package-name@version
9
+ // May include peer dep suffixes like /@scope/pkg@1.0.0(@peer/pkg@2.0.0)
10
+ const V6_PACKAGE_REGEX = /^\s{2,4}'?\/?(?<fullname>(?:@(?<scope>[^/@]+)\/)?(?<name>[^@']+))@(?<version>\d[^(':\s]*)/;
11
+ function parseLockfileVersion(fileContent) {
12
+ const match = fileContent.match(/^lockfileVersion:\s*'?(\d+)/m);
13
+ if (match)
14
+ return parseInt(match[1], 10);
15
+ return 0;
16
+ }
17
+ // For pnpm v9+: Parse importers section to get direct prod/dev dependency resolved versions.
18
+ // Returns sets of package keys like "express@4.18.2" or "@angular/core@14.2.0".
19
+ function parseImportersDeps(lines) {
20
+ const prodKeys = new Set();
21
+ const devKeys = new Set();
22
+ let inImporters = false;
23
+ let currentTarget = null;
24
+ let pkgName = null;
25
+ for (const line of lines) {
26
+ const trimmed = line.trimEnd();
27
+ if (trimmed === '')
28
+ continue;
29
+ if (/^importers:\s*$/.test(trimmed)) {
30
+ inImporters = true;
31
+ currentTarget = null;
32
+ pkgName = null;
33
+ continue;
34
+ }
35
+ if (!inImporters)
36
+ continue;
37
+ // End of importers section (next top-level key)
38
+ if (/^\S/.test(trimmed) && !trimmed.startsWith('#')) {
39
+ inImporters = false;
40
+ break;
41
+ }
42
+ const indent = line.search(/\S/);
43
+ // Workspace key at indent 2 (e.g., " .:" or " packages/app:")
44
+ if (indent === 2) {
45
+ currentTarget = null;
46
+ pkgName = null;
47
+ continue;
48
+ }
49
+ // Section header at indent 4 (dependencies:, devDependencies:, etc.)
50
+ if (indent === 4) {
51
+ if (/^\s{4}dependencies:\s*$/.test(trimmed) || /^\s{4}optionalDependencies:\s*$/.test(trimmed)) {
52
+ currentTarget = prodKeys;
53
+ }
54
+ else if (/^\s{4}devDependencies:\s*$/.test(trimmed)) {
55
+ currentTarget = devKeys;
56
+ }
57
+ else {
58
+ currentTarget = null;
59
+ }
60
+ pkgName = null;
61
+ continue;
62
+ }
63
+ if (!currentTarget)
64
+ continue;
65
+ // Package name at indent 6 (e.g., " express:" or " '@angular/core':")
66
+ if (indent === 6) {
67
+ const match = trimmed.match(/^\s{6}'?([^':]+)'?:\s*$/);
68
+ if (match) {
69
+ pkgName = match[1];
70
+ }
71
+ continue;
72
+ }
73
+ // Version at indent 8 (e.g., " version: 4.18.2" or " version: 14.2.0(rxjs@7.8.0)")
74
+ if (indent === 8 && pkgName) {
75
+ const match = trimmed.match(/^\s{8}version:\s*'?([^'\s]+)'?\s*$/);
76
+ if (match) {
77
+ // Strip peer dep suffixes in parentheses
78
+ const version = match[1].replace(/\(.*$/, '');
79
+ currentTarget.add(`${pkgName}@${version}`);
80
+ pkgName = null;
81
+ }
82
+ }
83
+ }
84
+ return { prodKeys, devKeys };
85
+ }
86
+ // For pnpm v9+: Build dependency graph from snapshots section.
87
+ // Maps each package key (e.g., "express@4.18.2") to its dependency keys.
88
+ function buildSnapshotGraph(lines) {
89
+ const graph = new Map();
90
+ let inSnapshots = false;
91
+ let currentKey = null;
92
+ let inDeps = false;
93
+ for (const line of lines) {
94
+ const trimmed = line.trimEnd();
95
+ if (trimmed === '')
96
+ continue;
97
+ if (/^snapshots:\s*$/.test(trimmed)) {
98
+ inSnapshots = true;
99
+ currentKey = null;
100
+ inDeps = false;
101
+ continue;
102
+ }
103
+ if (!inSnapshots)
104
+ continue;
105
+ // End of snapshots section (next top-level key)
106
+ if (/^\S/.test(trimmed) && !trimmed.startsWith('#')) {
107
+ inSnapshots = false;
108
+ break;
109
+ }
110
+ const indent = line.search(/\S/);
111
+ // Snapshot entry at indent 2 (e.g., " express@4.18.2:" or " lodash@4.17.21: {}")
112
+ if (indent === 2) {
113
+ const match = trimmed.match(/^\s{2}'?(.+?)(?:\([^)]*\))*'?:\s*(\{\})?\s*$/);
114
+ if (match) {
115
+ // Strip peer dep suffixes from key
116
+ currentKey = match[1].replace(/\(.*$/, '');
117
+ if (!graph.has(currentKey)) {
118
+ graph.set(currentKey, []);
119
+ }
120
+ inDeps = false;
121
+ // Empty entry like " lodash@4.17.21: {}"
122
+ if (match[2] === '{}') {
123
+ currentKey = null;
124
+ }
125
+ }
126
+ continue;
127
+ }
128
+ if (!currentKey)
129
+ continue;
130
+ // Subsection header at indent 4
131
+ if (indent === 4) {
132
+ inDeps = /^\s{4}(?:dependencies|optionalDependencies):\s*$/.test(trimmed);
133
+ continue;
134
+ }
135
+ // Dependency entry at indent 6 (e.g., " accepts: 1.3.8")
136
+ if (indent === 6 && inDeps) {
137
+ const match = trimmed.match(/^\s{6}'?([^':]+)'?:\s*'?([^'\s]+)'?/);
138
+ if (match) {
139
+ const depVersion = match[2].replace(/\(.*$/, '');
140
+ const depKey = `${match[1]}@${depVersion}`;
141
+ graph.get(currentKey).push(depKey);
142
+ }
143
+ }
144
+ }
145
+ return graph;
146
+ }
147
+ // BFS from prod dependencies through the snapshot graph to find all production-reachable packages.
148
+ function findProductionPackages(prodKeys, graph) {
149
+ const visited = new Set();
150
+ const queue = [...prodKeys];
151
+ while (queue.length > 0) {
152
+ const key = queue.shift();
153
+ if (visited.has(key))
154
+ continue;
155
+ visited.add(key);
156
+ const deps = graph.get(key);
157
+ if (deps) {
158
+ for (const dep of deps) {
159
+ if (!visited.has(dep)) {
160
+ queue.push(dep);
161
+ }
162
+ }
163
+ }
164
+ }
165
+ return visited;
166
+ }
167
+ function parsePackagesSection(fileContent) {
168
+ const entries = [];
169
+ const lines = fileContent.split('\n');
170
+ const lockfileVersion = parseLockfileVersion(fileContent);
171
+ let inPackagesSection = false;
172
+ let currentEntry = null;
173
+ const packageRegex = lockfileVersion >= 6 ? V6_PACKAGE_REGEX : V5_PACKAGE_REGEX;
174
+ // For v9+, determine dev scope from importers + snapshots instead of dev: flag
175
+ let prodPackages = null;
176
+ if (lockfileVersion >= 9) {
177
+ const { prodKeys, devKeys } = parseImportersDeps(lines);
178
+ // Only use v9 logic if importers section was found; otherwise fall back to defaults
179
+ if (prodKeys.size > 0 || devKeys.size > 0) {
180
+ const graph = buildSnapshotGraph(lines);
181
+ prodPackages = findProductionPackages(prodKeys, graph);
182
+ }
183
+ }
184
+ for (const line of lines) {
185
+ // Detect start of packages section
186
+ if (/^packages:/.test(line)) {
187
+ inPackagesSection = true;
188
+ continue;
189
+ }
190
+ // Detect end of packages section (next top-level key)
191
+ if (inPackagesSection && /^\S/.test(line) && !line.startsWith('#')) {
192
+ // Save last entry
193
+ if (currentEntry)
194
+ entries.push(currentEntry);
195
+ inPackagesSection = false;
196
+ continue;
197
+ }
198
+ if (!inPackagesSection)
199
+ continue;
200
+ // Try to match a package key line
201
+ const match = line.match(packageRegex);
202
+ if (match && match.groups) {
203
+ // Save previous entry
204
+ if (currentEntry)
205
+ entries.push(currentEntry);
206
+ const pkgScope = match.groups.scope || undefined;
207
+ const pkgName = match.groups.name;
208
+ const pkgVersion = match.groups.version;
209
+ let isDev = false;
210
+ if (lockfileVersion >= 9 && prodPackages) {
211
+ // For v9+, a package is dev if it's NOT reachable from production dependencies
212
+ const key = pkgScope ? `@${pkgScope}/${pkgName}@${pkgVersion}` : `${pkgName}@${pkgVersion}`;
213
+ isDev = !prodPackages.has(key);
214
+ }
215
+ currentEntry = {
216
+ scope: pkgScope,
217
+ name: pkgName,
218
+ version: pkgVersion,
219
+ dev: isDev,
220
+ };
221
+ continue;
222
+ }
223
+ // Check for dev flag within current entry (v5-v8 only)
224
+ if (lockfileVersion < 9 && currentEntry && /^\s+dev:\s*true/.test(line)) {
225
+ currentEntry.dev = true;
226
+ }
227
+ }
228
+ // Don't forget last entry
229
+ if (currentEntry)
230
+ entries.push(currentEntry);
231
+ return entries;
232
+ }
233
+ export function pnpmLockParser(fileContent, filePath) {
234
+ const results = { file: filePath, purls: [] };
235
+ if (path.basename(filePath) != MANIFEST_FILE)
236
+ return Promise.resolve(results);
237
+ try {
238
+ const packages = parsePackagesSection(fileContent);
239
+ for (const pkg of packages) {
240
+ const namespace = pkg.scope ? `@${pkg.scope}` : undefined;
241
+ const purlString = new PackageURL(PURL_TYPE, namespace, pkg.name, pkg.version, undefined, undefined).toString();
242
+ const scope = pkg.dev ? "devDependencies" : "dependencies";
243
+ results.purls.push({ purl: purlString, requirement: pkg.version, scope: scope });
244
+ }
245
+ }
246
+ catch (e) {
247
+ console.error(e);
248
+ }
249
+ return Promise.resolve(results);
250
+ }
251
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG5wbVBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9zZGsvRGVwZW5kZW5jaWVzL0xvY2FsRGVwZW5kZW5jeS9wYXJzZXJzL3BucG1QYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHM0MsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFDO0FBRXZDLDJGQUEyRjtBQUMzRixrRUFBa0U7QUFDbEUsTUFBTSxnQkFBZ0IsR0FBRyxxRkFBcUYsQ0FBQztBQUUvRyw0RkFBNEY7QUFDNUYsd0VBQXdFO0FBQ3hFLE1BQU0sZ0JBQWdCLEdBQUcsMkZBQTJGLENBQUM7QUFTckgsU0FBUyxvQkFBb0IsQ0FBQyxXQUFtQjtJQUMvQyxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDaEUsSUFBSSxLQUFLO1FBQUUsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQUVELDZGQUE2RjtBQUM3RixnRkFBZ0Y7QUFDaEYsU0FBUyxrQkFBa0IsQ0FBQyxLQUFlO0lBQ3pDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDbkMsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUVsQyxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDeEIsSUFBSSxhQUFhLEdBQXVCLElBQUksQ0FBQztJQUM3QyxJQUFJLE9BQU8sR0FBa0IsSUFBSSxDQUFDO0lBRWxDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsTUFBTSxP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
@@ -1,2 +1,3 @@
1
1
  import { ILocalDependency } from "../DependencyTypes";
2
2
  export declare function requirementsParser(fileContent: string, filePath: string): Promise<ILocalDependency>;
3
+ export declare function pipRequirementsLockParser(fileContent: string, filePath: string): Promise<ILocalDependency>;
@@ -10,14 +10,8 @@ function parseDep(str) {
10
10
  };
11
11
  }
12
12
  const PURL_TYPE = 'pypi';
13
- // Parse a requirements.txt file from python projects
14
- // See reference on: https://pip.pypa.io/en/stable/reference/requirements-file-format/
15
- const MANIFEST_FILE = 'requirements.txt';
16
- export function requirementsParser(fileContent, filePath) {
17
- // If the file is not a python manifest file, return an empty results
13
+ function parseRequirementsContent(fileContent, filePath) {
18
14
  const results = { file: filePath, purls: [] };
19
- if (path.basename(filePath) != MANIFEST_FILE)
20
- return Promise.resolve(results);
21
15
  const lines = fileContent.split('\n');
22
16
  for (let line of lines) {
23
17
  line = line.trim();
@@ -35,6 +29,9 @@ export function requirementsParser(fileContent, filePath) {
35
29
  else if (line.startsWith('-r')) {
36
30
  continue;
37
31
  } // Recursive dependencies (NOT SUPPORTED YET)
32
+ else if (line.startsWith('-')) {
33
+ continue;
34
+ } // Skip pip options (e.g. --hash, -i, -e, etc.)
38
35
  else {
39
36
  const dep = parseDep(line);
40
37
  if (!dep.sym) {
@@ -52,6 +49,25 @@ export function requirementsParser(fileContent, filePath) {
52
49
  }
53
50
  }
54
51
  }
55
- return Promise.resolve(results);
52
+ return results;
53
+ }
54
+ // Parse a requirements.txt file from python projects
55
+ // See reference on: https://pip.pypa.io/en/stable/reference/requirements-file-format/
56
+ const MANIFEST_FILE = 'requirements.txt';
57
+ export function requirementsParser(fileContent, filePath) {
58
+ // If the file is not a python manifest file, return an empty results
59
+ const results = { file: filePath, purls: [] };
60
+ if (path.basename(filePath) != MANIFEST_FILE)
61
+ return Promise.resolve(results);
62
+ return Promise.resolve(parseRequirementsContent(fileContent, filePath));
63
+ }
64
+ // Parse a pip_requirements_lock.txt file (pip-compile / pip-tools lock file)
65
+ // Same format as requirements.txt but typically with pinned versions (==)
66
+ const LOCK_MANIFEST_FILE = 'pip_requirements_lock.txt';
67
+ export function pipRequirementsLockParser(fileContent, filePath) {
68
+ const results = { file: filePath, purls: [] };
69
+ if (path.basename(filePath) != LOCK_MANIFEST_FILE)
70
+ return Promise.resolve(results);
71
+ return Promise.resolve(parseRequirementsContent(fileContent, filePath));
56
72
  }
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHlQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvc2RrL0RlcGVuZGVuY2llcy9Mb2NhbERlcGVuZGVuY3kvcGFyc2Vycy9weVBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUdsRCxTQUFTLFFBQVEsQ0FBRSxHQUFXO0lBQzVCLE1BQU0sR0FBRyxHQUFHLDBEQUEwRCxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRixPQUFPO1FBQ0wsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSTtRQUN2QixHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHO1FBQ3JCLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU87S0FDOUIsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUM7QUFFekIscURBQXFEO0FBQ3JELHNGQUFzRjtBQUN0RixNQUFNLGFBQWEsR0FBRyxrQkFBa0IsQ0FBQztBQUN6QyxNQUFNLFVBQVUsa0JBQWtCLENBQUMsV0FBbUIsRUFBRSxRQUFnQjtJQUVwRSxxRUFBcUU7SUFDckUsTUFBTSxPQUFPLEdBQXFCLEVBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFDLENBQUM7SUFDOUQsSUFBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLGFBQWE7UUFDdkMsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXBDLE1BQU0sS0FBSyxHQUFrQixXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXJELEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixJQUFHLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQztZQUFFLFNBQVM7UUFDOUIsSUFBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLCtCQUErQjtZQUN4RSxJQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNsQixzRkFBc0Y7Z0JBQ3RGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsK0RBQStELENBQUMsQ0FBQztnQkFDeEYsU0FBUztZQUNiLENBQUM7aUJBQ0ksSUFBRyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFBQSxTQUFTO1lBQUEsQ0FBQyxDQUFDLG1DQUFtQztpQkFDckUsSUFBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQUEsU0FBUztZQUFBLENBQUMsQ0FBQyw2Q0FBNkM7aUJBQ25GLENBQUM7Z0JBRUYsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO29CQUNiLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUM5RyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO3FCQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztvQkFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNoSCxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQzlHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBQyxHQUFHLENBQUMsT0FBTyxFQUFDLENBQUMsQ0FBQztnQkFDM0UsQ0FBQztZQUNMLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNsQyxDQUFDIn0=
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHlQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvc2RrL0RlcGVuZGVuY2llcy9Mb2NhbERlcGVuZGVuY3kvcGFyc2Vycy9weVBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUdsRCxTQUFTLFFBQVEsQ0FBRSxHQUFXO0lBQzVCLE1BQU0sR0FBRyxHQUFHLDBEQUEwRCxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRixPQUFPO1FBQ0wsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSTtRQUN2QixHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHO1FBQ3JCLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU87S0FDOUIsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUM7QUFFekIsU0FBUyx3QkFBd0IsQ0FBQyxXQUFtQixFQUFFLFFBQWdCO0lBQ25FLE1BQU0sT0FBTyxHQUFxQixFQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFDO0lBQzlELE1BQU0sS0FBSyxHQUFrQixXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXJELEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixJQUFHLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQztZQUFFLFNBQVM7UUFDOUIsSUFBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUks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