@dbx-tools/core 0.9.12 → 0.9.18

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,515 @@
1
+ /**
2
+ * Resolve npm dependency specifiers against a registry.
3
+ *
4
+ * Callers pass an already-parsed `package.json`. The functions never write that
5
+ * project and never run an installer: they GET packuments over HTTP and walk
6
+ * declared plus transitive `dependencies`. Exact versions stay exact when they
7
+ * exist; ranges stay ranges when a published version satisfies them.
8
+ *
9
+ * `registryUrl` defaults to {@link npmRegistry} from `project-utils`.
10
+ *
11
+ * @module
12
+ */
13
+ import { json, object } from "@dbx-tools/shared-core";
14
+ import { maxSatisfying, satisfies, valid, validRange } from "semver";
15
+ import { npmRegistry } from "./project-utils.js";
16
+ const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org/";
17
+ const PACKUMENT_TIMEOUT_MS = 30_000;
18
+ const DEPENDENCY_FIELDS = [
19
+ "dependencies",
20
+ "devDependencies",
21
+ "optionalDependencies",
22
+ "peerDependencies",
23
+ ];
24
+ const DEFAULT_MAX_ITERATIONS = 100;
25
+ /**
26
+ * Return packages the configured registry cannot satisfy for this manifest.
27
+ *
28
+ * Walks declared registry specifiers and each reachable packument
29
+ * `dependencies` map. The input object is not mutated.
30
+ */
31
+ export async function missingDependencies(manifest, options = {}) {
32
+ const packageInfo = options.packageInfo ?? createPackageInfoLookup(options.registryUrl);
33
+ const overrides = overrideMap(manifest);
34
+ const missing = new Map();
35
+ const visited = new Set();
36
+ const consider = async (dep) => {
37
+ if (!isRegistrySpecifier(toNpmSpecifier(dep)))
38
+ return;
39
+ const request = overrides[dep.name] ?? dep;
40
+ const resolved = await matchingPublishedVersion(request, packageInfo);
41
+ if (resolved) {
42
+ await walk(resolved, packageInfo, visited, consider, options.registryUrl);
43
+ return;
44
+ }
45
+ if (!missing.has(dep.name))
46
+ missing.set(dep.name, request);
47
+ };
48
+ await Promise.all(Object.values(declaredDependencies(manifest)).map(consider));
49
+ return [...missing.values()].sort((left, right) => left.name.localeCompare(right.name));
50
+ }
51
+ /**
52
+ * Return a registry version for one package.
53
+ *
54
+ * `request` may be a package name, `name@version` / `name@range`, or a
55
+ * structured `{ name, version?, range? }` object. A second string argument is
56
+ * treated as the specifier. An exact version that exists is returned
57
+ * unchanged. A range is retained when a published version satisfies it.
58
+ */
59
+ export async function resolveVersion(request, specifierOrOptions, maybeOptions) {
60
+ const { dependency, options } = resolveVersionArgs(request, specifierOrOptions, maybeOptions);
61
+ if (dependency.version && !isRegistrySpecifier(dependency.version)) {
62
+ return {
63
+ name: dependency.name,
64
+ version: dependency.version,
65
+ ...(dependency.range === undefined ? {} : { range: dependency.range }),
66
+ };
67
+ }
68
+ if (dependency.range && !isRegistrySpecifier(dependency.range)) {
69
+ return { name: dependency.name, version: dependency.range, range: dependency.range };
70
+ }
71
+ const packageInfo = options.packageInfo ?? createPackageInfoLookup(options.registryUrl);
72
+ const info = await packageInfo(dependency.name);
73
+ if (!info)
74
+ return undefined;
75
+ return pickVersion(info, dependency, options.skip);
76
+ }
77
+ function resolveVersionArgs(request, specifierOrOptions, maybeOptions) {
78
+ if (typeof specifierOrOptions === "string") {
79
+ const name = typeof request === "string" ? request : request.name;
80
+ return {
81
+ dependency: specifierToDependency(name, specifierOrOptions),
82
+ options: maybeOptions ?? {},
83
+ };
84
+ }
85
+ return {
86
+ dependency: parseDependencyRequest(request),
87
+ options: specifierOrOptions ?? maybeOptions ?? {},
88
+ };
89
+ }
90
+ /**
91
+ * Return resolvable dependency specifiers for an in-memory `package.json`.
92
+ *
93
+ * The input object is not mutated. Unavailable registry packages (or their
94
+ * parents) are pinned until the packument graph is complete.
95
+ */
96
+ export async function resolveDependencies(manifest, options = {}) {
97
+ const working = structuredClone(manifest);
98
+ const packageInfo = options.packageInfo ?? createPackageInfoLookup(options.registryUrl);
99
+ const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS;
100
+ const attempted = new Set();
101
+ const shared = {
102
+ packageInfo,
103
+ ...(options.registryUrl === undefined ? {} : { registryUrl: options.registryUrl }),
104
+ };
105
+ for (let iteration = 1; iteration <= maxIterations; iteration += 1) {
106
+ const missing = await missingDependencies(working, shared);
107
+ if (missing.length === 0)
108
+ return snapshot(working, packageInfo);
109
+ let changed = false;
110
+ for (const entry of missing) {
111
+ const pin = await pinForMissing(entry, working, packageInfo, attempted);
112
+ if (pin)
113
+ changed = pinPackage(working, pin) || changed;
114
+ }
115
+ if (!changed) {
116
+ throw new Error(`No remaining registry pin for: ${missing.map((entry) => entry.name).join(", ")}`);
117
+ }
118
+ }
119
+ throw new Error(`Reached ${maxIterations} pin attempts without a complete registry graph.`);
120
+ }
121
+ async function matchingPublishedVersion(request, packageInfo) {
122
+ const info = await packageInfo(request.name);
123
+ if (!info)
124
+ return undefined;
125
+ const version = publishedMatch(info, request);
126
+ if (!version)
127
+ return undefined;
128
+ return request.range === undefined
129
+ ? { name: info.name, version }
130
+ : { name: info.name, version, range: request.range };
131
+ }
132
+ function publishedMatch(info, request) {
133
+ if (request.range && validRange(request.range)) {
134
+ if (request.version &&
135
+ info.versions.includes(request.version) &&
136
+ satisfies(request.version, request.range)) {
137
+ return request.version;
138
+ }
139
+ return maxSatisfying(info.versions, request.range) ?? undefined;
140
+ }
141
+ if (request.version) {
142
+ if (info.versions.includes(request.version))
143
+ return request.version;
144
+ if (validRange(request.version)) {
145
+ return maxSatisfying(info.versions, request.version) ?? undefined;
146
+ }
147
+ return undefined;
148
+ }
149
+ return newestPublished(info, info.versions);
150
+ }
151
+ async function walk(resolved, packageInfo, visited, consider, registryUrl) {
152
+ const key = `${resolved.name}@${resolved.version}`;
153
+ if (visited.has(key))
154
+ return;
155
+ visited.add(key);
156
+ const info = await packageInfo(resolved.name);
157
+ let deps = info?.dependencies[resolved.version];
158
+ if (deps === undefined && info) {
159
+ deps = await loadVersionDependencies(resolved.name, resolved.version, registryUrl);
160
+ info.dependencies[resolved.version] = deps;
161
+ }
162
+ await Promise.all(Object.entries(deps ?? {}).map(([name, spec]) => consider(specifierToDependency(name, spec))));
163
+ }
164
+ async function snapshot(manifest, packageInfo) {
165
+ return {
166
+ dependencies: await specifierMap(manifest, "dependencies", packageInfo),
167
+ devDependencies: await specifierMap(manifest, "devDependencies", packageInfo),
168
+ optionalDependencies: await specifierMap(manifest, "optionalDependencies", packageInfo),
169
+ peerDependencies: await specifierMap(manifest, "peerDependencies", packageInfo),
170
+ overrides: await structuredMap(overrideMap(manifest), packageInfo),
171
+ };
172
+ }
173
+ async function specifierMap(manifest, field, packageInfo) {
174
+ return structuredMap(dependencyMap(manifest, field), packageInfo);
175
+ }
176
+ async function structuredMap(specs, packageInfo) {
177
+ const out = {};
178
+ for (const [name, spec] of Object.entries(specs)) {
179
+ out[name] = await structuredSpecifier(spec, packageInfo);
180
+ }
181
+ return out;
182
+ }
183
+ async function structuredSpecifier(spec, packageInfo) {
184
+ const resolved = await resolveVersion(spec, { packageInfo });
185
+ if (resolved)
186
+ return resolved;
187
+ const fallback = spec.version ?? spec.range ?? spec.semver;
188
+ return fallback === undefined
189
+ ? { name: spec.name, version: "*" }
190
+ : { name: spec.name, version: fallback };
191
+ }
192
+ function parseDependencyRequest(request) {
193
+ if (typeof request !== "string")
194
+ return normalizeDependency(request);
195
+ const name = stripVersion(request);
196
+ if (name === request)
197
+ return { name };
198
+ if (!request.startsWith(`${name}@`))
199
+ return { name };
200
+ return specifierToDependency(name, request.slice(name.length + 1));
201
+ }
202
+ function specifierToDependency(name, spec) {
203
+ if (!spec || spec === "latest")
204
+ return { name };
205
+ if (!isRegistrySpecifier(spec))
206
+ return { name, version: spec };
207
+ if (valid(spec))
208
+ return { name, version: spec };
209
+ if (validRange(spec))
210
+ return { name, range: spec };
211
+ return { name, version: spec };
212
+ }
213
+ function normalizeDependency(request) {
214
+ const version = request.version ?? request.semver;
215
+ const range = request.range;
216
+ const out = { name: request.name };
217
+ if (version && !valid(version) && !range && validRange(version) && isRegistrySpecifier(version)) {
218
+ out.range = version;
219
+ return out;
220
+ }
221
+ if (version)
222
+ out.version = version;
223
+ if (range)
224
+ out.range = range;
225
+ return out;
226
+ }
227
+ function parseSpecifierInput(name, value) {
228
+ if (typeof value === "string")
229
+ return specifierToDependency(name, value);
230
+ if (!object.isRecord(value))
231
+ return undefined;
232
+ const version = typeof value.version === "string" ? value.version : undefined;
233
+ const semverValue = typeof value.semver === "string" ? value.semver : undefined;
234
+ const range = typeof value.range === "string" ? value.range : undefined;
235
+ const entryName = typeof value.name === "string" ? value.name : name;
236
+ if (!version && !semverValue && !range)
237
+ return undefined;
238
+ return normalizeDependency({ name: entryName, version, semver: semverValue, range });
239
+ }
240
+ function dependencyMap(manifest, field) {
241
+ return parseDependencyField(manifest[field]);
242
+ }
243
+ function parseDependencyField(value) {
244
+ if (!object.isRecord(value))
245
+ return {};
246
+ const out = {};
247
+ for (const [name, spec] of Object.entries(value)) {
248
+ const parsed = parseSpecifierInput(name, spec);
249
+ if (parsed)
250
+ out[name] = parsed;
251
+ }
252
+ return out;
253
+ }
254
+ function declaredDependencies(manifest) {
255
+ const out = {};
256
+ for (const field of DEPENDENCY_FIELDS)
257
+ Object.assign(out, dependencyMap(manifest, field));
258
+ return out;
259
+ }
260
+ function isRegistrySpecifier(spec) {
261
+ return !/^(workspace:|catalog:|file:|link:|git\+|github:|https?:|npm:)/i.test(spec);
262
+ }
263
+ function overrideMap(manifest) {
264
+ return parseDependencyField(manifest.overrides);
265
+ }
266
+ function toNpmSpecifier(dependency) {
267
+ if (dependency.range && dependency.version && isRegistrySpecifier(dependency.range)) {
268
+ if (valid(dependency.version) && satisfies(dependency.version, dependency.range)) {
269
+ return dependency.range;
270
+ }
271
+ }
272
+ if (dependency.range)
273
+ return dependency.range;
274
+ if (dependency.version)
275
+ return dependency.version;
276
+ return "*";
277
+ }
278
+ function pinPackage(manifest, resolved) {
279
+ let changed = false;
280
+ const overrides = overrideMap(manifest);
281
+ const overridePin = { name: resolved.name, version: resolved.version };
282
+ if (toNpmSpecifier(overrides[resolved.name] ?? { name: resolved.name }) !== resolved.version) {
283
+ overrides[resolved.name] = overridePin;
284
+ manifest.overrides = Object.fromEntries(Object.entries(overrides).map(([name, dependency]) => [name, dependency]));
285
+ changed = true;
286
+ }
287
+ const depPin = {
288
+ name: resolved.name,
289
+ version: resolved.version,
290
+ ...(resolved.range === undefined ? {} : { range: resolved.range }),
291
+ };
292
+ for (const field of DEPENDENCY_FIELDS) {
293
+ const deps = dependencyMap(manifest, field);
294
+ const current = deps[resolved.name];
295
+ if (!current)
296
+ continue;
297
+ if (!isRegistrySpecifier(toNpmSpecifier(current)))
298
+ continue;
299
+ if (sameDependency(current, depPin))
300
+ continue;
301
+ deps[resolved.name] = depPin;
302
+ manifest[field] = deps;
303
+ changed = true;
304
+ }
305
+ return changed;
306
+ }
307
+ function sameDependency(left, right) {
308
+ return left.version === right.version && left.range === right.range;
309
+ }
310
+ function newestFirst(versions) {
311
+ return [...versions].sort((left, right) => right.localeCompare(left, undefined, { numeric: true, sensitivity: "base" }));
312
+ }
313
+ function pickVersion(info, request, skip) {
314
+ const versions = info.versions.filter((version) => !skip?.has(version));
315
+ if (versions.length === 0)
316
+ return undefined;
317
+ const fallback = newestPublished(info, versions);
318
+ if (!fallback)
319
+ return undefined;
320
+ if (request.range && validRange(request.range)) {
321
+ const matched = maxSatisfying(versions, request.range);
322
+ if (request.version &&
323
+ versions.includes(request.version) &&
324
+ satisfies(request.version, request.range)) {
325
+ return { name: info.name, version: request.version, range: request.range };
326
+ }
327
+ return matched
328
+ ? { name: info.name, version: matched, range: request.range }
329
+ : { name: info.name, version: fallback, range: request.range };
330
+ }
331
+ if (request.version) {
332
+ return {
333
+ name: info.name,
334
+ version: versions.includes(request.version) ? request.version : fallback,
335
+ };
336
+ }
337
+ return { name: info.name, version: fallback };
338
+ }
339
+ function newestPublished(info, versions) {
340
+ if (info.latest && versions.includes(info.latest))
341
+ return info.latest;
342
+ return newestFirst(versions)[0];
343
+ }
344
+ function skippedVersions(name, attempted) {
345
+ const prefix = `${name}@`;
346
+ const skipped = new Set();
347
+ for (const key of attempted) {
348
+ if (key.startsWith(prefix))
349
+ skipped.add(key.slice(prefix.length));
350
+ }
351
+ return skipped;
352
+ }
353
+ function stripVersion(value) {
354
+ if (value.startsWith("@")) {
355
+ const slash = value.indexOf("/");
356
+ const at = value.indexOf("@", slash + 1);
357
+ return at === -1 ? value : value.slice(0, at);
358
+ }
359
+ const at = value.indexOf("@");
360
+ return at === -1 ? value : value.slice(0, at);
361
+ }
362
+ async function pinForMissing(missing, manifest, packageInfo, attempted) {
363
+ const resolved = await resolveVersion(missing, {
364
+ packageInfo,
365
+ skip: skippedVersions(missing.name, attempted),
366
+ });
367
+ if (resolved) {
368
+ attempted.add(`${missing.name}@${resolved.version}`);
369
+ return resolved;
370
+ }
371
+ for (const parent of await parentPackages(missing.name, manifest, packageInfo)) {
372
+ const info = await packageInfo(parent);
373
+ if (!info)
374
+ continue;
375
+ const version = compatibleParentVersion(missing.name, info, attempted);
376
+ if (!version)
377
+ continue;
378
+ attempted.add(`${parent}@${version}`);
379
+ const declared = declaredDependencies(manifest)[parent] ?? { name: parent };
380
+ return pickVersion({ ...info, versions: [version], latest: version }, declared);
381
+ }
382
+ return undefined;
383
+ }
384
+ function compatibleParentVersion(missing, info, attempted) {
385
+ for (const version of newestFirst(info.versions)) {
386
+ if (attempted.has(`${info.name}@${version}`))
387
+ continue;
388
+ if (!(missing in (info.dependencies[version] ?? {})))
389
+ return version;
390
+ }
391
+ return undefined;
392
+ }
393
+ async function parentPackages(missing, manifest, packageInfo) {
394
+ const declared = declaredDependencies(manifest);
395
+ const declaredSpec = declared[missing];
396
+ if (declaredSpec && isRegistrySpecifier(toNpmSpecifier(declaredSpec)))
397
+ return [];
398
+ const parents = [];
399
+ for (const name of Object.keys(declared)) {
400
+ if (name === missing || !isRegistrySpecifier(toNpmSpecifier(declared[name] ?? { name }))) {
401
+ continue;
402
+ }
403
+ const info = await packageInfo(name);
404
+ if (!info)
405
+ continue;
406
+ if (Object.values(info.dependencies).some((map) => missing in map))
407
+ parents.push(name);
408
+ }
409
+ return parents;
410
+ }
411
+ function resolveRegistryUrl(registryUrl) {
412
+ const raw = registryUrl?.toString() ||
413
+ npmRegistry(null, { envVars: true })?.toString() ||
414
+ DEFAULT_NPM_REGISTRY;
415
+ return raw.replace(/\/+$/, "");
416
+ }
417
+ function encodePackageName(name) {
418
+ if (name.startsWith("@")) {
419
+ const slash = name.indexOf("/");
420
+ if (slash !== -1) {
421
+ return `${name.slice(0, slash)}%2f${encodeURIComponent(name.slice(slash + 1))}`;
422
+ }
423
+ }
424
+ return encodeURIComponent(name);
425
+ }
426
+ function packumentUrl(name, registryUrl) {
427
+ return `${resolveRegistryUrl(registryUrl)}/${encodePackageName(name)}`;
428
+ }
429
+ async function fetchRegistryJson(url) {
430
+ const response = await fetch(url, {
431
+ headers: { accept: "application/json" },
432
+ signal: AbortSignal.timeout(PACKUMENT_TIMEOUT_MS),
433
+ }).catch(() => undefined);
434
+ if (!response?.ok)
435
+ return undefined;
436
+ const text = await response.text();
437
+ return json.parse(text);
438
+ }
439
+ function createPackageInfoLookup(registryUrl) {
440
+ const cache = new Map();
441
+ return (name) => {
442
+ const cached = cache.get(name);
443
+ if (cached)
444
+ return cached;
445
+ const pending = loadPackageInfo(name, registryUrl);
446
+ cache.set(name, pending);
447
+ void pending.then(undefined, () => {
448
+ cache.delete(name);
449
+ });
450
+ return pending;
451
+ };
452
+ }
453
+ async function loadPackageInfo(name, registryUrl) {
454
+ const packument = await fetchRegistryJson(packumentUrl(name, registryUrl));
455
+ if (!object.isRecord(packument))
456
+ return undefined;
457
+ const versions = publishedVersions(packument);
458
+ if (versions.length === 0)
459
+ return undefined;
460
+ return {
461
+ name,
462
+ versions,
463
+ latest: latestTag(packument) ?? versions.at(-1),
464
+ dependencies: versionDependencies(packument),
465
+ };
466
+ }
467
+ async function loadVersionDependencies(name, version, registryUrl) {
468
+ const doc = await fetchRegistryJson(`${packumentUrl(name, registryUrl)}/${encodeURIComponent(version)}`);
469
+ if (!object.isRecord(doc))
470
+ return {};
471
+ return stringMap(doc.dependencies);
472
+ }
473
+ function publishedVersions(packument) {
474
+ if (typeof packument.version === "string" && !packument.versions) {
475
+ return [packument.version];
476
+ }
477
+ const versions = packument.versions;
478
+ if (Array.isArray(versions)) {
479
+ return versions.filter((value) => typeof value === "string");
480
+ }
481
+ if (object.isRecord(versions))
482
+ return Object.keys(versions);
483
+ return [];
484
+ }
485
+ function latestTag(packument) {
486
+ const tags = packument["dist-tags"];
487
+ if (!object.isRecord(tags) || typeof tags.latest !== "string")
488
+ return undefined;
489
+ return tags.latest;
490
+ }
491
+ function versionDependencies(packument) {
492
+ const versions = packument.versions;
493
+ if (!object.isRecord(versions)) {
494
+ return typeof packument.version === "string"
495
+ ? { [packument.version]: stringMap(packument.dependencies) }
496
+ : {};
497
+ }
498
+ const out = {};
499
+ for (const [version, value] of Object.entries(versions)) {
500
+ if (object.isRecord(value))
501
+ out[version] = stringMap(value.dependencies);
502
+ }
503
+ return out;
504
+ }
505
+ function stringMap(value) {
506
+ if (!object.isRecord(value))
507
+ return {};
508
+ const out = {};
509
+ for (const [name, spec] of Object.entries(value)) {
510
+ if (typeof spec === "string")
511
+ out[name] = spec;
512
+ }
513
+ return out;
514
+ }
515
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwZW5kZW5jeS1yZXNvbHZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kZXBlbmRlbmN5LXJlc29sdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7OztHQVdHO0FBRUgsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXJFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVqRCxNQUFNLG9CQUFvQixHQUFHLDZCQUE2QixDQUFDO0FBQzNELE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDO0FBRXBDLE1BQU0saUJBQWlCLEdBQUc7SUFDeEIsY0FBYztJQUNkLGlCQUFpQjtJQUNqQixzQkFBc0I7SUFDdEIsa0JBQWtCO0NBQ1YsQ0FBQztBQUVYLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0FBMERuQzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsbUJBQW1CLENBQ3ZDLFFBQWlDLEVBQ2pDLFVBQXFDLEVBQUU7SUFFdkMsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDeEYsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUEwQixDQUFDO0lBQ2xELE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFFbEMsTUFBTSxRQUFRLEdBQUcsS0FBSyxFQUFFLEdBQW1CLEVBQWlCLEVBQUU7UUFDNUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUFFLE9BQU87UUFDdEQs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TUFBTSxHQUFHLEdBQTJDLEVBQUUsQ0FBQztJQUN2RCxLQUFLLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ3hELElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsS0FBYztJQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN2QyxNQUFNLEdBQUcsR0FBMkIsRUFBRSxDQUFDO0lBQ3ZDLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDakQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRO1lBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQztJQUNqRCxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZXNvbHZlIG5wbSBkZXBlbmRlbmN5IHNwZWNpZmllcnMgYWdhaW5zdCBhIHJlZ2lzdHJ5LlxuICpcbiAqIENhbGxlcnMgcGFzcyBhbiBhbHJlYWR5LXBhcnNlZCBgcGFja2FnZS5qc29uYC4gVGhlIGZ1bmN0aW9ucyBuZXZlciB3cml0ZSB0aGF0XG4gKiBwcm9qZWN0IGFuZCBuZXZlciBydW4gYW4gaW5zdGFsbGVyOiB0aGV5IEdFVCBwYWNrdW1lbnRzIG92ZXIgSFRUUCBhbmQgd2Fsa1xuICogZGVjbGFyZWQgcGx1cyB0cmFuc2l0aXZlIGBkZXBlbmRlbmNpZXNgLiBFeGFjdCB2ZXJzaW9ucyBzdGF5IGV4YWN0IHdoZW4gdGhleVxuICogZXhpc3Q7IHJhbmdlcyBzdGF5IHJhbmdlcyB3aGVuIGEgcHVibGlzaGVkIHZlcnNpb24gc2F0aXNmaWVzIHRoZW0uXG4gKlxuICogYHJlZ2lzdHJ5VXJsYCBkZWZhdWx0cyB0byB7QGxpbmsgbnBtUmVnaXN0cnl9IGZyb20gYHByb2plY3QtdXRpbHNgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBqc29uLCBvYmplY3QgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgbWF4U2F0aXNmeWluZywgc2F0aXNmaWVzLCB2YWxpZCwgdmFsaWRSYW5nZSB9IGZyb20gXCJzZW12ZXJcIjtcblxuaW1wb3J0IHsgbnBtUmVnaXN0cnkgfSBmcm9tIFwiLi9wcm9qZWN0LXV0aWxzLnRzXCI7XG5cbmNvbnN0IERFRkFVTFRfTlBNX1JFR0lTVFJZID0gXCJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy9cIjtcbmNvbnN0IFBBQ0tVTUVOVF9USU1FT1VUX01TID0gMzBfMDAwO1xuXG5jb25zdCBERVBFTkRFTkNZX0ZJRUxEUyA9IFtcbiAgXCJkZXBlbmRlbmNpZXNcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIixcbiAgXCJvcHRpb25hbERlcGVuZGVuY2llc1wiLFxuICBcInBlZXJEZXBlbmRlbmNpZXNcIixcbl0gYXMgY29uc3Q7XG5cbmNvbnN0IERFRkFVTFRfTUFYX0lURVJBVElPTlMgPSAxMDA7XG5cbnR5cGUgRGVwZW5kZW5jeUZpZWxkID0gKHR5cGVvZiBERVBFTkRFTkNZX0ZJRUxEUylbbnVtYmVyXTtcblxudHlwZSBQYWNrYWdlSW5mbyA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2ZXJzaW9uczogc3RyaW5nW107XG4gIGxhdGVzdD86IHN0cmluZztcbiAgZGVwZW5kZW5jaWVzOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pjtcbn07XG5cbi8qKiBSZWdpc3RyeSBhbmQgdHJhdmVyc2FsIHBvbGljeSBmb3IgZGVwZW5kZW5jeSByZXNvbHV0aW9uLiAqL1xuZXhwb3J0IHR5cGUgRGVwZW5kZW5jeVJlc29sdmVyT3B0aW9ucyA9IHtcbiAgLyoqIEdyYXBoLXdhbGsgYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cC4gRGVmYXVsdHMgdG8gMTAwLiAqL1xuICBtYXhJdGVyYXRpb25zPzogbnVtYmVyO1xuICAvKipcbiAgICogUmVnaXN0cnkgb3JpZ2luIHVzZWQgZm9yIHBhY2t1bWVudCBHRVRzLiBEZWZhdWx0cyB0b1xuICAgKiBgcHJvamVjdFV0aWxzLm5wbVJlZ2lzdHJ5KClgIChlbnYsIG5wbXJjLCBidW5maWcsIHBucG0geWFtbCwgdGhlbiBwdWJsaWMgbnBtKS5cbiAgICovXG4gIHJlZ2lzdHJ5VXJsPzogc3RyaW5nIHwgVVJMO1xuICBwYWNrYWdlSW5mbz86IChuYW1lOiBzdHJpbmcpID0+IFByb21pc2U8UGFja2FnZUluZm8gfCB1bmRlZmluZWQ+O1xuICBza2lwPzogUmVhZG9ubHlTZXQ8c3RyaW5nPjtcbn07XG5cbi8qKlxuICogUGFja2FnZSBpZGVudGl0eSBwbHVzIG9wdGlvbmFsIGV4YWN0IHZlcnNpb24gYW5kL29yIHNlbXZlciByYW5nZS5cbiAqXG4gKiBgc2VtdmVyYCBpcyBhY2NlcHRlZCBhcyBhbiBpbnB1dCBhbGlhcyBmb3IgYHZlcnNpb25gLlxuICovXG5leHBvcnQgdHlwZSBEZXBlbmRlbmN5SW5mbyA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2ZXJzaW9uPzogc3RyaW5nO1xuICBzZW12ZXI/OiBzdHJpbmc7XG4gIHJhbmdlPzogc3RyaW5nO1xufTtcblxuLyoqIENvbmNyZXRlIHJlZ2lzdHJ5IHZlcnNpb24sIHBsdXMgdGhlIG9yaWdpbmFsIHJhbmdlIHdoZW4gb25lIHdhcyByZXF1ZXN0ZWQuICovXG5leHBvcnQgdHlwZSBSZXNvbHZlZE5wbVZlcnNpb24gPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdmVyc2lvbjogc3RyaW5nO1xuICByYW5nZT86IHN0cmluZztcbn07XG5cbi8qKiBTdHJpbmcgc3BlY2lmaWVyIG9yIHN0cnVjdHVyZWQgYHsgdmVyc2lvbiwgcmFuZ2UsIG5hbWU/IH1gIHZhbHVlLiAqL1xuZXhwb3J0IHR5cGUgTnBtU3BlY2lmaWVySW5wdXQgPSBzdHJpbmcgfCBPbWl0PERlcGVuZGVuY3lJbmZvLCBcIm5hbWVcIj4gfCBEZXBlbmRlbmN5SW5mbztcblxuLyoqIFJlZ2lzdHJ5IGRlcGVuZGVuY3kgbWFwcyB3aXRoIHJlc29sdmVkIHZlcnNpb25zIGFuZCByZXRhaW5lZCByYW5nZXMuICovXG5leHBvcnQgdHlwZSBSZXNvbHZlZE5wbURlcGVuZGVuY2llcyA9IHtcbiAgZGVwZW5kZW5jaWVzOiBSZWNvcmQ8c3RyaW5nLCBSZXNvbHZlZE5wbVZlcnNpb24+O1xuICBkZXZEZXBlbmRlbmNpZXM6IFJlY29yZDxzdHJpbmcsIFJlc29sdmVkTnBtVmVyc2lvbj47XG4gIG9wdGlvbmFsRGVwZW5kZW5jaWVzOiBSZWNvcmQ8c3RyaW5nLCBSZXNvbHZlZE5wbVZlcnNpb24+O1xuICBwZWVyRGVwZW5kZW5jaWVzOiBSZWNvcmQ8c3RyaW5nLCBSZXNvbHZlZE5wbVZlcnNpb24+O1xuICBvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIFJlc29sdmVkTnBtVmVyc2lvbj47XG59O1xuXG4vKiogQSBwYWNrYWdlIHdob3NlIHJlcXVlc3RlZCBzcGVjaWZpZXIgaXMgbm90IGluIHRoZSBjb25maWd1cmVkIHJlZ2lzdHJ5LiAqL1xuZXhwb3J0IHR5cGUgTWlzc2luZ0RlcGVuZGVuY3lJbmZvID0gRGVwZW5kZW5jeUluZm87XG5cbi8qKlxuICogUmV0dXJuIHBhY2thZ2VzIHRoZSBjb25maWd1cmVkIHJlZ2lzdHJ5IGNhbm5vdCBzYXRpc2Z5IGZvciB0aGlzIG1hbmlmZXN0LlxuICpcbiAqIFdhbGtzIGRlY2xhcmVkIHJlZ2lzdHJ5IHNwZWNpZmllcnMgYW5kIGVhY2ggcmVhY2hhYmxlIHBhY2t1bWVudFxuICogYGRlcGVuZGVuY2llc2AgbWFwLiBUaGUgaW5wdXQgb2JqZWN0IGlzIG5vdCBtdXRhdGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWlzc2luZ0RlcGVuZGVuY2llcyhcbiAgbWFuaWZlc3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvcHRpb25zOiBEZXBlbmRlbmN5UmVzb2x2ZXJPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPE1pc3NpbmdEZXBlbmRlbmN5SW5mb1tdPiB7XG4gIGNvbnN0IHBhY2thZ2VJbmZvID0gb3B0aW9ucy5wYWNrYWdlSW5mbyA/PyBjcmVhdGVQYWNrYWdlSW5mb0xvb2t1cChvcHRpb25zLnJlZ2lzdHJ5VXJsKTtcbiAgY29uc3Qgb3ZlcnJpZGVzID0gb3ZlcnJpZGVNYXAobWFuaWZlc3QpO1xuICBjb25zdCBtaXNzaW5nID0gbmV3IE1hcDxzdHJpbmcsIERlcGVuZGVuY3lJbmZvPigpO1xuICBjb25zdCB2aXNpdGVkID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgY29uc3QgY29uc2lkZXIgPSBhc3luYyAoZGVwOiBEZXBlbmRlbmN5SW5mbyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmICghaXNSZWdpc3RyeVNwZWNpZmllcih0b05wbVNwZWNpZmllcihkZXApKSkgcmV0dXJuO1xuICAgIGNvbnN0IHJlcXVlc3QgPSBvdmVycmlkZXNbZGVwLm5hbWVdID8/IGRlcDtcbiAgICBjb25zdCByZXNvbHZlZCA9IGF3YWl0IG1hdGNoaW5nUHVibGlzaGVkVmVyc2lvbihyZXF1ZXN0LCBwYWNrYWdlSW5mbyk7XG4gICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICBhd2FpdCB3YWxrKHJlc29sdmVkLCBwYWNrYWdlSW5mbywgdmlzaXRlZCwgY29uc2lkZXIsIG9wdGlvbnMucmVnaXN0cnlVcmwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIW1pc3NpbmcuaGFzKGRlcC5uYW1lKSkgbWlzc2luZy5zZXQoZGVwLm5hbWUsIHJlcXVlc3QpO1xuICB9O1xuXG4gIGF3YWl0IFByb21pc2UuYWxsKE9iamVjdC52YWx1ZXMoZGVjbGFyZWREZXBlbmRlbmNpZXMobWFuaWZlc3QpKS5tYXAoY29uc2lkZXIpKTtcbiAgcmV0dXJuIFsuLi5taXNzaW5nLnZhbHVlcygpXS5zb3J0KChsZWZ0LCByaWdodCkgPT4gbGVmdC5uYW1lLmxvY2FsZUNvbXBhcmUocmlnaHQubmFtZSkpO1xufVxuXG4vKipcbiAqIFJldHVybiBhIHJlZ2lzdHJ5IHZlcnNpb24gZm9yIG9uZSBwYWNrYWdlLlxuICpcbiAqIGByZXF1ZXN0YCBtYXkgYmUgYSBwYWNrYWdlIG5hbWUsIGBuYW1lQHZlcnNpb25gIC8gYG5hbWVAcmFuZ2VgLCBvciBhXG4gKiBzdHJ1Y3R1cmVkIGB7IG5hbWUsIHZlcnNpb24/LCByYW5nZT8gfWAgb2JqZWN0LiBBIHNlY29uZCBzdHJpbmcgYXJndW1lbnQgaXNcbiAqIHRyZWF0ZWQgYXMgdGhlIHNwZWNpZmllci4gQW4gZXhhY3QgdmVyc2lvbiB0aGF0IGV4aXN0cyBpcyByZXR1cm5lZFxuICogdW5jaGFuZ2VkLiBBIHJhbmdlIGlzIHJldGFpbmVkIHdoZW4gYSBwdWJsaXNoZWQgdmVyc2lvbiBzYXRpc2ZpZXMgaXQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlVmVyc2lvbihcbiAgcmVxdWVzdDogc3RyaW5nIHwgRGVwZW5kZW5jeUluZm8sXG4gIHNwZWNpZmllck9yT3B0aW9ucz86IHN0cmluZyB8IERlcGVuZGVuY3lSZXNvbHZlck9wdGlvbnMsXG4gIG1heWJlT3B0aW9ucz86IERlcGVuZGVuY3lSZXNvbHZlck9wdGlvbnMsXG4pOiBQcm9taXNlPFJlc29sdmVkTnBtVmVyc2lvbiB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB7IGRlcGVuZGVuY3ksIG9wdGlvbnMgfSA9IHJlc29sdmVWZXJzaW9uQXJncyhyZXF1ZXN0LCBzcGVjaWZpZXJPck9wdGlvbnMsIG1heWJlT3B0aW9ucyk7XG4gIGlmIChkZXBlbmRlbmN5LnZlcnNpb24gJiYgIWlzUmVnaXN0cnlTcGVjaWZpZXIoZGVwZW5kZW5jeS52ZXJzaW9uKSkge1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBkZXBlbmRlbmN5Lm5hbWUsXG4gICAgICB2ZXJzaW9uOiBkZXBlbmRlbmN5LnZlcnNpb24sXG4gICAgICAuLi4oZGVwZW5kZW5jeS5yYW5nZSA9PT0gdW5kZWZpbmVkID8ge30gOiB7IHJhbmdlOiBkZXBlbmRlbmN5LnJhbmdlIH0pLFxuICAgIH07XG4gIH1cbiAgaWYgKGRlcGVuZGVuY3kucmFuZ2UgJiYgIWlzUmVnaXN0cnlTcGVjaWZpZXIoZGVwZW5kZW5jeS5yYW5nZSkpIHtcbiAgICByZXR1cm4geyBuYW1lOiBkZXBlbmRlbmN5Lm5hbWUsIHZlcnNpb246IGRlcGVuZGVuY3kucmFuZ2UsIHJhbmdlOiBkZXBlbmRlbmN5LnJhbmdlIH07XG4gIH1cbiAgY29uc3QgcGFja2FnZUluZm8gPSBvcHRpb25zLnBhY2thZ2VJbmZvID8/IGNyZWF0ZVBhY2thZ2VJbmZvTG9va3VwKG9wdGlvbnMucmVnaXN0cnlVcmwpO1xuICBjb25zdCBpbmZvID0gYXdhaXQgcGFja2FnZUluZm8oZGVwZW5kZW5jeS5uYW1lKTtcbiAgaWYgKCFpbmZvKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gcGlja1ZlcnNpb24oaW5mbywgZGVwZW5kZW5jeSwgb3B0aW9ucy5za2lwKTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVZlcnNpb25BcmdzKFxuICByZXF1ZXN0OiBzdHJpbmcgfCBEZXBlbmRlbmN5SW5mbyxcbiAgc3BlY2lmaWVyT3JPcHRpb25zPzogc3RyaW5nIHwgRGVwZW5kZW5jeVJlc29sdmVyT3B0aW9ucyxcbiAgbWF5YmVPcHRpb25zPzogRGVwZW5kZW5jeVJlc29sdmVyT3B0aW9ucyxcbik6IHsgZGVwZW5kZW5jeTogRGVwZW5kZW5jeUluZm87IG9wdGlvbnM6IERlcGVuZGVuY3lSZXNvbHZlck9wdGlvbnMgfSB7XG4gIGlmICh0eXBlb2Ygc3BlY2lmaWVyT3JPcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgY29uc3QgbmFtZSA9IHR5cGVvZiByZXF1ZXN0ID09PSBcInN0cmluZ1wiID8gcmVxdWVzdCA6IHJlcXVlc3QubmFtZTtcbiAgICByZXR1cm4ge1xuICAgICAgZGVwZW5kZW5jeTogc3BlY2lmaWVyVG9EZXBlbmRlbmN5KG5hbWUsIHNwZWNpZmllck9yT3B0aW9ucyksXG4gICAgICBvcHRpb25zOiBtYXliZU9wdGlvbnMgPz8ge30sXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGRlcGVuZGVuY3k6IHBhcnNlRGVwZW5kZW5jeVJlcXVlc3QocmVxdWVzdCksXG4gICAgb3B0aW9uczogc3BlY2lmaWVyT3JPcHRpb25zID8/IG1heWJlT3B0aW9ucyA/PyB7fSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gcmVzb2x2YWJsZSBkZXBlbmRlbmN5IHNwZWNpZmllcnMgZm9yIGFuIGluLW1lbW9yeSBgcGFja2FnZS5qc29uYC5cbiAqXG4gKiBUaGUgaW5wdXQgb2JqZWN0IGlzIG5vdCBtdXRhdGVkLiBVbmF2YWlsYWJsZSByZWdpc3RyeSBwYWNrYWdlcyAob3IgdGhlaXJcbiAqIHBhcmVudHMpIGFyZSBwaW5uZWQgdW50aWwgdGhlIHBhY2t1bWVudCBncmFwaCBpcyBjb21wbGV0ZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVEZXBlbmRlbmNpZXMoXG4gIG1hbmlmZXN0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgb3B0aW9uczogRGVwZW5kZW5jeVJlc29sdmVyT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxSZXNvbHZlZE5wbURlcGVuZGVuY2llcz4ge1xuICBjb25zdCB3b3JraW5nID0gc3RydWN0dXJlZENsb25lKG1hbmlmZXN0KTtcbiAgY29uc3QgcGFja2FnZUluZm8gPSBvcHRpb25zLnBhY2thZ2VJbmZvID8/IGNyZWF0ZVBhY2thZ2VJbmZvTG9va3VwKG9wdGlvbnMucmVnaXN0cnlVcmwpO1xuICBjb25zdCBtYXhJdGVyYXRpb25zID0gb3B0aW9ucy5tYXhJdGVyYXRpb25zID8/IERFRkFVTFRfTUFYX0lURVJBVElPTlM7XG4gIGNvbnN0IGF0dGVtcHRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBzaGFyZWQ6IERlcGVuZGVuY3lSZXNvbHZlck9wdGlvbnMgPSB7XG4gICAgcGFja2FnZUluZm8sXG4gICAgLi4uKG9wdGlvbnMucmVnaXN0cnlVcmwgPT09IHVuZGVmaW5lZCA/IHt9IDogeyByZWdpc3RyeVVybDogb3B0aW9ucy5yZWdpc3RyeVVybCB9KSxcbiAgfTtcblxuICBmb3IgKGxldCBpdGVyYXRpb24gPSAxOyBpdGVyYXRpb24gPD0gbWF4SXRlcmF0aW9uczsgaXRlcmF0aW9uICs9IDEpIHtcbiAgICBjb25zdCBtaXNzaW5nID0gYXdhaXQgbWlzc2luZ0RlcGVuZGVuY2llcyh3b3JraW5nLCBzaGFyZWQpO1xuICAgIGlmIChtaXNzaW5nLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHNuYXBzaG90KHdvcmtpbmcsIHBhY2thZ2VJbmZvKTtcblxuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBtaXNzaW5nKSB7XG4gICAgICBjb25zdCBwaW4gPSBhd2FpdCBwaW5Gb3JNaXNzaW5nKGVudHJ5LCB3b3JraW5nLCBwYWNrYWdlSW5mbywgYXR0ZW1wdGVkKTtcbiAgICAgIGlmIChwaW4pIGNoYW5nZWQgPSBwaW5QYWNrYWdlKHdvcmtpbmcsIHBpbikgfHwgY2hhbmdlZDtcbiAgICB9XG4gICAgaWYgKCFjaGFuZ2VkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyByZW1haW5pbmcgcmVnaXN0cnkgcGluIGZvcjogJHttaXNzaW5nLm1hcCgoZW50cnkpID0+IGVudHJ5Lm5hbWUpLmpvaW4oXCIsIFwiKX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoYFJlYWNoZWQgJHttYXhJdGVyYXRpb25zfSBwaW4gYXR0ZW1wdHMgd2l0aG91dCBhIGNvbXBsZXRlIHJlZ2lzdHJ5IGdyYXBoLmApO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtYXRjaGluZ1B1Ymxpc2hlZFZlcnNpb24oXG4gIHJlcXVlc3Q6IERlcGVuZGVuY3lJbmZvLFxuICBwYWNrYWdlSW5mbzogKG5hbWU6IHN0cmluZykgPT4gUHJvbWlzZTxQYWNrYWdlSW5mbyB8IHVuZGVmaW5lZD4sXG4pOiBQcm9taXNlPFJlc29sdmVkTnBtVmVyc2lvbiB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBpbmZvID0gYXdhaXQgcGFja2FnZUluZm8ocmVxdWVzdC5uYW1lKTtcbiAgaWYgKCFpbmZvKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB2ZXJzaW9uID0gcHVibGlzaGVkTWF0Y2goaW5mbywgcmVxdWVzdCk7XG4gIGlmICghdmVyc2lvbikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHJlcXVlc3QucmFuZ2UgPT09IHVuZGVmaW5lZFxuICAgID8geyBuYW1lOiBpbmZvLm5hbWUsIHZlcnNpb24gfVxuICAgIDogeyBuYW1lOiBpbmZvLm5hbWUsIHZlcnNpb24sIHJhbmdlOiByZXF1ZXN0LnJhbmdlIH07XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2hlZE1hdGNoKGluZm86IFBhY2thZ2VJbmZvLCByZXF1ZXN0OiBEZXBlbmRlbmN5SW5mbyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChyZXF1ZXN0LnJhbmdlICYmIHZhbGlkUmFuZ2UocmVxdWVzdC5yYW5nZSkpIHtcbiAgICBpZiAoXG4gICAgICByZXF1ZXN0LnZlcnNpb24gJiZcbiAgICAgIGluZm8udmVyc2lvbnMuaW5jbHVkZXMocmVxdWVzdC52ZXJzaW9uKSAmJlxuICAgICAgc2F0aXNmaWVzKHJlcXVlc3QudmVyc2lvbiwgcmVxdWVzdC5yYW5nZSlcbiAgICApIHtcbiAgICAgIHJldHVybiByZXF1ZXN0LnZlcnNpb247XG4gICAgfVxuICAgIHJldHVybiBtYXhTYXRpc2Z5aW5nKGluZm8udmVyc2lvbnMsIHJlcXVlc3QucmFuZ2UpID8/IHVuZGVmaW5lZDtcbiAgfVxuICBpZiAocmVxdWVzdC52ZXJzaW9uKSB7XG4gICAgaWYgKGluZm8udmVyc2lvbnMuaW5jbHVkZXMocmVxdWVzdC52ZXJzaW9uKSkgcmV0dXJuIHJlcXVlc3QudmVyc2lvbjtcbiAgICBpZiAodmFsaWRSYW5nZShyZXF1ZXN0LnZlcnNpb24pKSB7XG4gICAgICByZXR1cm4gbWF4U2F0aXNmeWluZyhpbmZvLnZlcnNpb25zLCByZXF1ZXN0LnZlcnNpb24pID8/IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gbmV3ZXN0UHVibGlzaGVkKGluZm8sIGluZm8udmVyc2lvbnMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3YWxrKFxuICByZXNvbHZlZDogUmVzb2x2ZWROcG1WZXJzaW9uLFxuICBwYWNrYWdlSW5mbzogKG5hbWU6IHN0cmluZykgPT4gUHJvbWlzZTxQYWNrYWdlSW5mbyB8IHVuZGVmaW5lZD4sXG4gIHZpc2l0ZWQ6IFNldDxzdHJpbmc+LFxuICBjb25zaWRlcjogKGRlcDogRGVwZW5kZW5jeUluZm8pID0+IFByb21pc2U8dm9pZD4sXG4gIHJlZ2lzdHJ5VXJsPzogc3RyaW5nIHwgVVJMLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGtleSA9IGAke3Jlc29sdmVkLm5hbWV9QCR7cmVzb2x2ZWQudmVyc2lvbn1gO1xuICBpZiAodmlzaXRlZC5oYXMoa2V5KSkgcmV0dXJuO1xuICB2aXNpdGVkLmFkZChrZXkpO1xuICBjb25zdCBpbmZvID0gYXdhaXQgcGFja2FnZUluZm8ocmVzb2x2ZWQubmFtZSk7XG4gIGxldCBkZXBzID0gaW5mbz8uZGVwZW5kZW5jaWVzW3Jlc29sdmVkLnZlcnNpb25dO1xuICBpZiAoZGVwcyA9PT0gdW5kZWZpbmVkICYmIGluZm8pIHtcbiAgICBkZXBzID0gYXdhaXQgbG9hZFZlcnNpb25EZXBlbmRlbmNpZXMocmVzb2x2ZWQubmFtZSwgcmVzb2x2ZWQudmVyc2lvbiwgcmVnaXN0cnlVcmwpO1xuICAgIGluZm8uZGVwZW5kZW5jaWVzW3Jlc29sdmVkLnZlcnNpb25dID0gZGVwcztcbiAgfVxuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBPYmplY3QuZW50cmllcyhkZXBzID8/IHt9KS5tYXAoKFtuYW1lLCBzcGVjXSkgPT4gY29uc2lkZXIoc3BlY2lmaWVyVG9EZXBlbmRlbmN5KG5hbWUsIHNwZWMpKSksXG4gICk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNuYXBzaG90KFxuICBtYW5pZmVzdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHBhY2thZ2VJbmZvOiAobmFtZTogc3RyaW5nKSA9PiBQcm9taXNlPFBhY2thZ2VJbmZvIHwgdW5kZWZpbmVkPixcbik6IFByb21pc2U8UmVzb2x2ZWROcG1EZXBlbmRlbmNpZXM+IHtcbiAgcmV0dXJuIHtcbiAgICBkZXBlbmRlbmNpZXM6IGF3YWl0IHNwZWNpZmllck1hcChtYW5pZmVzdCwgXCJkZXBlbmRlbmNpZXNcIiwgcGFja2FnZUluZm8pLFxuICAgIGRldkRlcGVuZGVuY2llczogYXdhaXQgc3BlY2lmaWVyTWFwKG1hbmlmZXN0LCBcImRldkRlcGVuZGVuY2llc1wiLCBwYWNrYWdlSW5mbyksXG4gICAgb3B0aW9uYWxEZXBlbmRlbmNpZXM6IGF3YWl0IHNwZWNpZmllck1hcChtYW5pZmVzdCwgXCJvcHRpb25hbERlcGVuZGVuY2llc1wiLCBwYWNrYWdlSW5mbyksXG4gICAgcGVlckRlcGVuZGVuY2llczogYXdhaXQgc3BlY2lmaWVyTWFwKG1hbmlmZXN0LCBcInBlZXJEZXBlbmRlbmNpZXNcIiwgcGFja2FnZUluZm8pLFxuICAgIG92ZXJyaWRlczogYXdhaXQgc3RydWN0dXJlZE1hcChvdmVycmlkZU1hcChtYW5pZmVzdCksIHBhY2thZ2VJbmZvKSxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3BlY2lmaWVyTWFwKFxuICBtYW5pZmVzdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGZpZWxkOiBEZXBlbmRlbmN5RmllbGQsXG4gIHBhY2thZ2VJbmZvOiAobmFtZTogc3RyaW5nKSA9PiBQcm9taXNlPFBhY2thZ2VJbmZvIHwgdW5kZWZpbmVkPixcbik6IFByb21pc2U8UmVjb3JkPHN0cmluZywgUmVzb2x2ZWROcG1WZXJzaW9uPj4ge1xuICByZXR1cm4gc3RydWN0dXJlZE1hcChkZXBlbmRlbmN5TWFwKG1hbmlmZXN0LCBmaWVsZCksIHBhY2thZ2VJbmZvKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3RydWN0dXJlZE1hcChcbiAgc3BlY3M6IFJlY29yZDxzdHJpbmcsIERlcGVuZGVuY3lJbmZvPixcbiAgcGFja2FnZUluZm86IChuYW1lOiBzdHJpbmcpID0+IFByb21pc2U8UGFja2FnZUluZm8gfCB1bmRlZmluZWQ+LFxuKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBSZXNvbHZlZE5wbVZlcnNpb24+PiB7XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgUmVzb2x2ZWROcG1WZXJzaW9uPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCBzcGVjXSBvZiBPYmplY3QuZW50cmllcyhzcGVjcykpIHtcbiAgICBvdXRbbmFtZV0gPSBhd2FpdCBzdHJ1Y3R1cmVkU3BlY2lmaWVyKHNwZWMsIHBhY2thZ2VJbmZvKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdHJ1Y3R1cmVkU3BlY2lmaWVyKFxuICBzcGVjOiBEZXBlbmRlbmN5SW5mbyxcbiAgcGFja2FnZUluZm86IChuYW1lOiBzdHJpbmcpID0+IFByb21pc2U8UGFja2FnZUluZm8gfCB1bmRlZmluZWQ+LFxuKTogUHJvbWlzZTxSZXNvbHZlZE5wbVZlcnNpb24+IHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBhd2FpdCByZXNvbHZlVmVyc2lvbihzcGVjLCB7IHBhY2thZ2VJbmZvIH0pO1xuICBpZiAocmVzb2x2ZWQpIHJldHVybiByZXNvbHZlZDtcbiAgY29uc3QgZmFsbGJhY2sgPSBzcGVjLnZlcnNpb24gPz8gc3BlYy5yYW5nZSA/PyBzcGVjLnNlbXZlcjtcbiAgcmV0dXJuIGZhbGxiYWNrID09PSB1bmRlZmluZWRcbiAgICA/IHsgbmFtZTogc3BlYy5uYW1lLCB2ZXJzaW9uOiBcIipcIiB9XG4gICAgOiB7IG5hbWU6IHNwZWMubmFtZSwgdmVyc2lvbjogZmFsbGJhY2sgfTtcbn1cblxuZnVuY3Rpb24gcGFyc2VEZXBlbmRlbmN5UmVxdWVzdChyZXF1ZXN0OiBzdHJpbmcgfCBEZXBlbmRlbmN5SW5mbyk6IERlcGVuZGVuY3lJbmZvIHtcbiAgaWYgKHR5cGVvZiByZXF1ZXN0ICE9PSBcInN0cmluZ1wiKSByZXR1cm4gbm9ybWFsaXplRGVwZW5kZW5jeShyZXF1ZXN0KTtcbiAgY29uc3QgbmFtZSA9IHN0cmlwVmVyc2lvbihyZXF1ZXN0KTtcbiAgaWYgKG5hbWUgPT09IHJlcXVlc3QpIHJldHVybiB7IG5hbWUgfTtcbiAgaWYgKCFyZXF1ZXN0LnN0YXJ0c1dpdGgoYCR7bmFtZX1AYCkpIHJldHVybiB7IG5hbWUgfTtcbiAgcmV0dXJuIHNwZWNpZmllclRvRGVwZW5kZW5jeShuYW1lLCByZXF1ZXN0LnNsaWNlKG5hbWUubGVuZ3RoICsgMSkpO1xufVxuXG5mdW5jdGlvbiBzcGVjaWZpZXJUb0RlcGVuZGVuY3kobmFtZTogc3RyaW5nLCBzcGVjOiBzdHJpbmcpOiBEZXBlbmRlbmN5SW5mbyB7XG4gIGlmICghc3BlYyB8fCBzcGVjID09PSBcImxhdGVzdFwiKSByZXR1cm4geyBuYW1lIH07XG4gIGlmICghaXNSZWdpc3RyeVNwZWNpZmllcihzcGVjKSkgcmV0dXJuIHsgbmFtZSwgdmVyc2lvbjogc3BlYyB9O1xuICBpZiAodmFsaWQoc3BlYykpIHJldHVybiB7IG5hbWUsIHZlcnNpb246IHNwZWMgfTtcbiAgaWYgKHZhbGlkUmFuZ2Uoc3BlYykpIHJldHVybiB7IG5hbWUsIHJhbmdlOiBzcGVjIH07XG4gIHJldHVybiB7IG5hbWUsIHZlcnNpb246IHNwZWMgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplRGVwZW5kZW5jeShyZXF1ZXN0OiBEZXBlbmRlbmN5SW5mbyk6IERlcGVuZGVuY3lJbmZvIHtcbiAgY29uc3QgdmVyc2lvbiA9IHJlcXVlc3QudmVyc2lvbiA/PyByZXF1ZXN0LnNlbXZlcjtcbiAgY29uc3QgcmFuZ2UgPSByZXF1ZXN0LnJhbmdlO1xuICBjb25zdCBvdXQ6IERlcGVuZGVuY3lJbmZvID0geyBuYW1lOiByZXF1ZXN0Lm5hbWUgfTtcbiAgaWYgKHZlcnNpb24gJiYgIXZhbGlkKHZlcnNpb24pICYmICFyYW5nZSAmJiB2YWxpZFJhbmdlKHZlcnNpb24pICYmIGlzUmVnaXN0cnlTcGVjaWZpZXIodmVyc2lvbikpIHtcbiAgICBvdXQucmFuZ2UgPSB2ZXJzaW9uO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cbiAgaWYgKHZlcnNpb24pIG91dC52ZXJzaW9uID0gdmVyc2lvbjtcbiAgaWYgKHJhbmdlKSBvdXQucmFuZ2UgPSByYW5nZTtcbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gcGFyc2VTcGVjaWZpZXJJbnB1dChuYW1lOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogRGVwZW5kZW5jeUluZm8gfCB1bmRlZmluZWQge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSByZXR1cm4gc3BlY2lmaWVyVG9EZXBlbmRlbmN5KG5hbWUsIHZhbHVlKTtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQodmFsdWUpKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB2ZXJzaW9uID0gdHlwZW9mIHZhbHVlLnZlcnNpb24gPT09IFwic3RyaW5nXCIgPyB2YWx1ZS52ZXJzaW9uIDogdW5kZWZpbmVkO1xuICBjb25zdCBzZW12ZXJWYWx1ZSA9IHR5cGVvZiB2YWx1ZS5zZW12ZXIgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS5zZW12ZXIgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHJhbmdlID0gdHlwZW9mIHZhbHVlLnJhbmdlID09PSBcInN0cmluZ1wiID8gdmFsdWUucmFuZ2UgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGVudHJ5TmFtZSA9IHR5cGVvZiB2YWx1ZS5uYW1lID09PSBcInN0cmluZ1wiID8gdmFsdWUubmFtZSA6IG5hbWU7XG4gIGlmICghdmVyc2lvbiAmJiAhc2VtdmVyVmFsdWUgJiYgIXJhbmdlKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gbm9ybWFsaXplRGVwZW5kZW5jeSh7IG5hbWU6IGVudHJ5TmFtZSwgdmVyc2lvbiwgc2VtdmVyOiBzZW12ZXJWYWx1ZSwgcmFuZ2UgfSk7XG59XG5cbmZ1bmN0aW9uIGRlcGVuZGVuY3lNYXAoXG4gIG1hbmlmZXN0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgZmllbGQ6IERlcGVuZGVuY3lGaWVsZCxcbik6IFJlY29yZDxzdHJpbmcsIERlcGVuZGVuY3lJbmZvPiB7XG4gIHJldHVybiBwYXJzZURlcGVuZGVuY3lGaWVsZChtYW5pZmVzdFtmaWVsZF0pO1xufVxuXG5mdW5jdGlvbiBwYXJzZURlcGVuZGVuY3lGaWVsZCh2YWx1ZTogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIERlcGVuZGVuY3lJbmZvPiB7XG4gIGlmICghb2JqZWN0LmlzUmVjb3JkKHZhbHVlKSkgcmV0dXJuIHt9O1xuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIERlcGVuZGVuY3lJbmZvPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCBzcGVjXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICBjb25zdCBwYXJzZWQgPSBwYXJzZVNwZWNpZmllcklucHV0KG5hbWUsIHNwZWMpO1xuICAgIGlmIChwYXJzZWQpIG91dFtuYW1lXSA9IHBhcnNlZDtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBkZWNsYXJlZERlcGVuZGVuY2llcyhtYW5pZmVzdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCBEZXBlbmRlbmN5SW5mbz4ge1xuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIERlcGVuZGVuY3lJbmZvPiA9IHt9O1xuICBmb3IgKGNvbnN0IGZpZWxkIG9mIERFUEVOREVOQ1lfRklFTERTKSBPYmplY3QuYXNzaWduKG91dCwgZGVwZW5kZW5jeU1hcChtYW5pZmVzdCwgZmllbGQpKTtcbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gaXNSZWdpc3RyeVNwZWNpZmllcihzcGVjOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuICEvXih3b3Jrc3BhY2U6fGNhdGFsb2c6fGZpbGU6fGxpbms6fGdpdFxcK3xnaXRodWI6fGh0dHBzPzp8bnBtOikvaS50ZXN0KHNwZWMpO1xufVxuXG5mdW5jdGlvbiBvdmVycmlkZU1hcChtYW5pZmVzdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCBEZXBlbmRlbmN5SW5mbz4ge1xuICByZXR1cm4gcGFyc2VEZXBlbmRlbmN5RmllbGQobWFuaWZlc3Qub3ZlcnJpZGVzKTtcbn1cblxuZnVuY3Rpb24gdG9OcG1TcGVjaWZpZXIoZGVwZW5kZW5jeTogRGVwZW5kZW5jeUluZm8pOiBzdHJpbmcge1xuICBpZiAoZGVwZW5kZW5jeS5yYW5nZSAmJiBkZXBlbmRlbmN5LnZlcnNpb24gJiYgaXNSZWdpc3RyeVNwZWNpZmllcihkZXBlbmRlbmN5LnJhbmdlKSkge1xuICAgIGlmICh2YWxpZChkZXBlbmRlbmN5LnZlcnNpb24pICYmIHNhdGlzZmllcyhkZXBlbmRlbmN5LnZlcnNpb24sIGRlcGVuZGVuY3kucmFuZ2UpKSB7XG4gICAgICByZXR1cm4gZGVwZW5kZW5jeS5yYW5nZTtcbiAgICB9XG4gIH1cbiAgaWYgKGRlcGVuZGVuY3kucmFuZ2UpIHJldHVybiBkZXBlbmRlbmN5LnJhbmdlO1xuICBpZiAoZGVwZW5kZW5jeS52ZXJzaW9uKSByZXR1cm4gZGVwZW5kZW5jeS52ZXJzaW9uO1xuICByZXR1cm4gXCIqXCI7XG59XG5cbmZ1bmN0aW9uIHBpblBhY2thZ2UobWFuaWZlc3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCByZXNvbHZlZDogUmVzb2x2ZWROcG1WZXJzaW9uKTogYm9vbGVhbiB7XG4gIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gIGNvbnN0IG92ZXJyaWRlcyA9IG92ZXJyaWRlTWFwKG1hbmlmZXN0KTtcbiAgY29uc3Qgb3ZlcnJpZGVQaW46IERlcGVuZGVuY3lJbmZvID0geyBuYW1lOiByZXNvbHZlZC5uYW1lLCB2ZXJzaW9uOiByZXNvbHZlZC52ZXJzaW9uIH07XG4gIGlmICh0b05wbVNwZWNpZmllcihvdmVycmlkZXNbcmVzb2x2ZWQubmFtZV0gPz8geyBuYW1lOiByZXNvbHZlZC5uYW1lIH0pICE9PSByZXNvbHZlZC52ZXJzaW9uKSB7XG4gICAgb3ZlcnJpZGVzW3Jlc29sdmVkLm5hbWVdID0gb3ZlcnJpZGVQaW47XG4gICAgbWFuaWZlc3Qub3ZlcnJpZGVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMob3ZlcnJpZGVzKS5tYXAoKFtuYW1lLCBkZXBlbmRlbmN5XSkgPT4gW25hbWUsIGRlcGVuZGVuY3ldKSxcbiAgICApO1xuICAgIGNoYW5nZWQgPSB0cnVlO1xuICB9XG4gIGNvbnN0IGRlcFBpbjogRGVwZW5kZW5jeUluZm8gPSB7XG4gICAgbmFtZTogcmVzb2x2ZWQubmFtZSxcbiAgICB2ZXJzaW9uOiByZXNvbHZlZC52ZXJzaW9uLFxuICAgIC4uLihyZXNvbHZlZC5yYW5nZSA9PT0gdW5kZWZpbmVkID8ge30gOiB7IHJhbmdlOiByZXNvbHZlZC5yYW5nZSB9KSxcbiAgfTtcbiAgZm9yIChjb25zdCBmaWVsZCBvZiBERVBFTkRFTkNZX0ZJRUxEUykge1xuICAgIGNvbnN0IGRlcHMgPSBkZXBlbmRlbmN5TWFwKG1hbmlmZXN0LCBmaWVsZCk7XG4gICAgY29uc3QgY3VycmVudCA9IGRlcHNbcmVzb2x2ZWQubmFtZV07XG4gICAgaWYgKCFjdXJyZW50KSBjb250aW51ZTtcbiAgICBpZiAoIWlzUmVnaXN0cnlTcGVjaWZpZXIodG9OcG1TcGVjaWZpZXIoY3VycmVudCkpKSBjb250aW51ZTtcbiAgICBpZiAoc2FtZURlcGVuZGVuY3koY3VycmVudCwgZGVwUGluKSkgY29udGludWU7XG4gICAgZGVwc1tyZXNvbHZlZC5uYW1lXSA9IGRlcFBpbjtcbiAgICBtYW5pZmVzdFtmaWVsZF0gPSBkZXBzO1xuICAgIGNoYW5nZWQgPSB0cnVlO1xuICB9XG4gIHJldHVybiBjaGFuZ2VkO1xufVxuXG5mdW5jdGlvbiBzYW1lRGVwZW5kZW5jeShsZWZ0OiBEZXBlbmRlbmN5SW5mbywgcmlnaHQ6IERlcGVuZGVuY3lJbmZvKTogYm9vbGVhbiB7XG4gIHJldHVybiBsZWZ0LnZlcnNpb24gPT09IHJpZ2h0LnZlcnNpb24gJiYgbGVmdC5yYW5nZSA9PT0gcmlnaHQucmFuZ2U7XG59XG5cbmZ1bmN0aW9uIG5ld2VzdEZpcnN0KHZlcnNpb25zOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIFsuLi52ZXJzaW9uc10uc29ydCgobGVmdCwgcmlnaHQpID0+XG4gICAgcmlnaHQubG9jYWxlQ29tcGFyZShsZWZ0LCB1bmRlZmluZWQsIHsgbnVtZXJpYzogdHJ1ZSwgc2Vuc2l0aXZpdHk6IFwiYmFzZVwiIH0pLFxuICApO1xufVxuXG5mdW5jdGlvbiBwaWNrVmVyc2lvbihcbiAgaW5mbzogUGFja2FnZUluZm8sXG4gIHJlcXVlc3Q6IERlcGVuZGVuY3lJbmZvLFxuICBza2lwPzogUmVhZG9ubHlTZXQ8c3RyaW5nPixcbik6IFJlc29sdmVkTnBtVmVyc2lvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHZlcnNpb25zID0gaW5mby52ZXJzaW9ucy5maWx0ZXIoKHZlcnNpb24pID0+ICFza2lwPy5oYXModmVyc2lvbikpO1xuICBpZiAodmVyc2lvbnMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBmYWxsYmFjayA9IG5ld2VzdFB1Ymxpc2hlZChpbmZvLCB2ZXJzaW9ucyk7XG4gIGlmICghZmFsbGJhY2spIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChyZXF1ZXN0LnJhbmdlICYmIHZhbGlkUmFuZ2UocmVxdWVzdC5yYW5nZSkpIHtcbiAgICBjb25zdCBtYXRjaGVkID0gbWF4U2F0aXNmeWluZyh2ZXJzaW9ucywgcmVxdWVzdC5yYW5nZSk7XG4gICAgaWYgKFxuICAgICAgcmVxdWVzdC52ZXJzaW9uICYmXG4gICAgICB2ZXJzaW9ucy5pbmNsdWRlcyhyZXF1ZXN0LnZlcnNpb24pICYmXG4gICAgICBzYXRpc2ZpZXMocmVxdWVzdC52ZXJzaW9uLCByZXF1ZXN0LnJhbmdlKVxuICAgICkge1xuICAgICAgcmV0dXJuIHsgbmFtZTogaW5mby5uYW1lLCB2ZXJzaW9uOiByZXF1ZXN0LnZlcnNpb24sIHJhbmdlOiByZXF1ZXN0LnJhbmdlIH07XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGVkXG4gICAgICA/IHsgbmFtZTogaW5mby5uYW1lLCB2ZXJzaW9uOiBtYXRjaGVkLCByYW5nZTogcmVxdWVzdC5yYW5nZSB9XG4gICAgICA6IHsgbmFtZTogaW5mby5uYW1lLCB2ZXJzaW9uOiBmYWxsYmFjaywgcmFuZ2U6IHJlcXVlc3QucmFuZ2UgfTtcbiAgfVxuICBpZiAocmVxdWVzdC52ZXJzaW9uKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IGluZm8ubmFtZSxcbiAgICAgIHZlcnNpb246IHZlcnNpb25zLmluY2x1ZGVzKHJlcXVlc3QudmVyc2lvbikgPyByZXF1ZXN0LnZlcnNpb24gOiBmYWxsYmFjayxcbiAgICB9O1xuICB9XG4gIHJldHVybiB7IG5hbWU6IGluZm8ubmFtZSwgdmVyc2lvbjogZmFsbGJhY2sgfTtcbn1cblxuZnVuY3Rpb24gbmV3ZXN0UHVibGlzaGVkKGluZm86IFBhY2thZ2VJbmZvLCB2ZXJzaW9uczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoaW5mby5sYXRlc3QgJiYgdmVyc2lvbnMuaW5jbHVkZXMoaW5mby5sYXRlc3QpKSByZXR1cm4gaW5mby5sYXRlc3Q7XG4gIHJldHVybiBuZXdlc3RGaXJzdCh2ZXJzaW9ucylbMF07XG59XG5cbmZ1bmN0aW9uIHNraXBwZWRWZXJzaW9ucyhuYW1lOiBzdHJpbmcsIGF0dGVtcHRlZDogUmVhZG9ubHlTZXQ8c3RyaW5nPik6IFNldDxzdHJpbmc+IHtcbiAgY29uc3QgcHJlZml4ID0gYCR7bmFtZX1AYDtcbiAgY29uc3Qgc2tpcHBlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IGtleSBvZiBhdHRlbXB0ZWQpIHtcbiAgICBpZiAoa2V5LnN0YXJ0c1dpdGgocHJlZml4KSkgc2tpcHBlZC5hZGQoa2V5LnNsaWNlKHByZWZpeC5sZW5ndGgpKTtcbiAgfVxuICByZXR1cm4gc2tpcHBlZDtcbn1cblxuZnVuY3Rpb24gc3RyaXBWZXJzaW9uKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAodmFsdWUuc3RhcnRzV2l0aChcIkBcIikpIHtcbiAgICBjb25zdCBzbGFzaCA9IHZhbHVlLmluZGV4T2YoXCIvXCIpO1xuICAgIGNvbnN0IGF0ID0gdmFsdWUuaW5kZXhPZihcIkBcIiwgc2xhc2ggKyAxKTtcbiAgICByZXR1cm4gYXQgPT09IC0xID8gdmFsdWUgOiB2YWx1ZS5zbGljZSgwLCBhdCk7XG4gIH1cbiAgY29uc3QgYXQgPSB2YWx1ZS5pbmRleE9mKFwiQFwiKTtcbiAgcmV0dXJuIGF0ID09PSAtMSA/IHZhbHVlIDogdmFsdWUuc2xpY2UoMCwgYXQpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwaW5Gb3JNaXNzaW5nKFxuICBtaXNzaW5nOiBNaXNzaW5nRGVwZW5kZW5jeUluZm8sXG4gIG1hbmlmZXN0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgcGFja2FnZUluZm86IChuYW1lOiBzdHJpbmcpID0+IFByb21pc2U8UGFja2FnZUluZm8gfCB1bmRlZmluZWQ+LFxuICBhdHRlbXB0ZWQ6IFNldDxzdHJpbmc+LFxuKTogUHJvbWlzZTxSZXNvbHZlZE5wbVZlcnNpb24gfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBhd2FpdCByZXNvbHZlVmVyc2lvbihtaXNzaW5nLCB7XG4gICAgcGFja2FnZUluZm8sXG4gICAgc2tpcDogc2tpcHBlZFZlcnNpb25zKG1pc3NpbmcubmFtZSwgYXR0ZW1wdGVkKSxcbiAgfSk7XG4gIGlmIChyZXNvbHZlZCkge1xuICAgIGF0dGVtcHRlZC5hZGQoYCR7bWlzc2luZy5uYW1lfUAke3Jlc29sdmVkLnZlcnNpb259YCk7XG4gICAgcmV0dXJuIHJlc29sdmVkO1xuICB9XG5cbiAgZm9yIChjb25zdCBwYXJlbnQgb2YgYXdhaXQgcGFyZW50UGFja2FnZXMobWlzc2luZy5uYW1lLCBtYW5pZmVzdCwgcGFja2FnZUluZm8pKSB7XG4gICAgY29uc3QgaW5mbyA9IGF3YWl0IHBhY2thZ2VJbmZvKHBhcmVudCk7XG4gICAgaWYgKCFpbmZvKSBjb250aW51ZTtcbiAgICBjb25zdCB2ZXJzaW9uID0gY29tcGF0aWJsZVBhcmVudFZlcnNpb24obWlzc2luZy5uYW1lLCBpbmZvLCBhdHRlbXB0ZWQpO1xuICAgIGlmICghdmVyc2lvbikgY29udGludWU7XG4gICAgYXR0ZW1wdGVkLmFkZChgJHtwYXJlbnR9QCR7dmVyc2lvbn1gKTtcbiAgICBjb25zdCBkZWNsYXJlZCA9IGRlY2xhcmVkRGVwZW5kZW5jaWVzKG1hbmlmZXN0KVtwYXJlbnRdID8/IHsgbmFtZTogcGFyZW50IH07XG4gICAgcmV0dXJuIHBpY2tWZXJzaW9uKHsgLi4uaW5mbywgdmVyc2lvbnM6IFt2ZXJzaW9uXSwgbGF0ZXN0OiB2ZXJzaW9uIH0sIGRlY2xhcmVkKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBjb21wYXRpYmxlUGFyZW50VmVyc2lvbihcbiAgbWlzc2luZzogc3RyaW5nLFxuICBpbmZvOiBQYWNrYWdlSW5mbyxcbiAgYXR0ZW1wdGVkOiBTZXQ8c3RyaW5nPixcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGZvciAoY29uc3QgdmVyc2lvbiBvZiBuZXdlc3RGaXJzdChpbmZvLnZlcnNpb25zKSkge1xuICAgIGlmIChhdHRlbXB0ZWQuaGFzKGAke2luZm8ubmFtZX1AJHt2ZXJzaW9ufWApKSBjb250aW51ZTtcbiAgICBpZiAoIShtaXNzaW5nIGluIChpbmZvLmRlcGVuZGVuY2llc1t2ZXJzaW9uXSA/PyB7fSkpKSByZXR1cm4gdmVyc2lvbjtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwYXJlbnRQYWNrYWdlcyhcbiAgbWlzc2luZzogc3RyaW5nLFxuICBtYW5pZmVzdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHBhY2thZ2VJbmZvOiAobmFtZTogc3RyaW5nKSA9PiBQcm9taXNlPFBhY2thZ2VJbmZvIHwgdW5kZWZpbmVkPixcbik6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgY29uc3QgZGVjbGFyZWQgPSBkZWNsYXJlZERlcGVuZGVuY2llcyhtYW5pZmVzdCk7XG4gIGNvbnN0IGRlY2xhcmVkU3BlYyA9IGRlY2xhcmVkW21pc3NpbmddO1xuICBpZiAoZGVjbGFyZWRTcGVjICYmIGlzUmVnaXN0cnlTcGVjaWZpZXIodG9OcG1TcGVjaWZpZXIoZGVjbGFyZWRTcGVjKSkpIHJldHVybiBbXTtcbiAgY29uc3QgcGFyZW50czogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGRlY2xhcmVkKSkge1xuICAgIGlmIChuYW1lID09PSBtaXNzaW5nIHx8ICFpc1JlZ2lzdHJ5U3BlY2lmaWVyKHRvTnBtU3BlY2lmaWVyKGRlY2xhcmVkW25hbWVdID8/IHsgbmFtZSB9KSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBpbmZvID0gYXdhaXQgcGFja2FnZUluZm8obmFtZSk7XG4gICAgaWYgKCFpbmZvKSBjb250aW51ZTtcbiAgICBpZiAoT2JqZWN0LnZhbHVlcyhpbmZvLmRlcGVuZGVuY2llcykuc29tZSgobWFwKSA9PiBtaXNzaW5nIGluIG1hcCkpIHBhcmVudHMucHVzaChuYW1lKTtcbiAgfVxuICByZXR1cm4gcGFyZW50cztcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVJlZ2lzdHJ5VXJsKHJlZ2lzdHJ5VXJsPzogc3RyaW5nIHwgVVJMKTogc3RyaW5nIHtcbiAgY29uc3QgcmF3ID1cbiAgICByZWdpc3RyeVVybD8udG9TdHJpbmcoKSB8fFxuICAgIG5wbVJlZ2lzdHJ5KG51bGwsIHsgZW52VmFyczogdHJ1ZSB9KT8udG9TdHJpbmcoKSB8fFxuICAgIERFRkFVTFRfTlBNX1JFR0lTVFJZO1xuICByZXR1cm4gcmF3LnJlcGxhY2UoL1xcLyskLywgXCJcIik7XG59XG5cbmZ1bmN0aW9uIGVuY29kZVBhY2thZ2VOYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChuYW1lLnN0YXJ0c1dpdGgoXCJAXCIpKSB7XG4gICAgY29uc3Qgc2xhc2ggPSBuYW1lLmluZGV4T2YoXCIvXCIpO1xuICAgIGlmIChzbGFzaCAhPT0gLTEpIHtcbiAgICAgIHJldHVybiBgJHtuYW1lLnNsaWNlKDAsIHNsYXNoKX0lMmYke2VuY29kZVVSSUNvbXBvbmVudChuYW1lLnNsaWNlKHNsYXNoICsgMSkpfWA7XG4gICAgfVxuICB9XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQobmFtZSk7XG59XG5cbmZ1bmN0aW9uIHBhY2t1bWVudFVybChuYW1lOiBzdHJpbmcsIHJlZ2lzdHJ5VXJsPzogc3RyaW5nIHwgVVJMKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3Jlc29sdmVSZWdpc3RyeVVybChyZWdpc3RyeVVybCl9LyR7ZW5jb2RlUGFja2FnZU5hbWUobmFtZSl9YDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hSZWdpc3RyeUpzb24odXJsOiBzdHJpbmcpOiBQcm9taXNlPHVua25vd24+IHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICBoZWFkZXJzOiB7IGFjY2VwdDogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSxcbiAgICBzaWduYWw6IEFib3J0U2lnbmFsLnRpbWVvdXQoUEFDS1VNRU5UX1RJTUVPVVRfTVMpLFxuICB9KS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICBpZiAoIXJlc3BvbnNlPy5vaykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgdGV4dCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgcmV0dXJuIGpzb24ucGFyc2UodGV4dCk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVBhY2thZ2VJbmZvTG9va3VwKFxuICByZWdpc3RyeVVybD86IHN0cmluZyB8IFVSTCxcbik6IChuYW1lOiBzdHJpbmcpID0+IFByb21pc2U8UGFja2FnZUluZm8gfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgY2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxQYWNrYWdlSW5mbyB8IHVuZGVmaW5lZD4+KCk7XG4gIHJldHVybiAobmFtZSkgPT4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChuYW1lKTtcbiAgICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkO1xuICAgIGNvbnN0IHBlbmRpbmcgPSBsb2FkUGFja2FnZUluZm8obmFtZSwgcmVnaXN0cnlVcmwpO1xuICAgIGNhY2hlLnNldChuYW1lLCBwZW5kaW5nKTtcbiAgICB2b2lkIHBlbmRpbmcudGhlbih1bmRlZmluZWQsICgpID0+IHtcbiAgICAgIGNhY2hlLmRlbGV0ZShuYW1lKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcGVuZGluZztcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZFBhY2thZ2VJbmZvKFxuICBuYW1lOiBzdHJpbmcsXG4gIHJlZ2lzdHJ5VXJsPzogc3RyaW5nIHwgVVJMLFxuKTogUHJvbWlzZTxQYWNrYWdlSW5mbyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBwYWNrdW1lbnQgPSBhd2FpdCBmZXRjaFJlZ2lzdHJ5SnNvbihwYWNrdW1lbnRVcmwobmFtZSwgcmVnaXN0cnlVcmwpKTtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQocGFja3VtZW50KSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgdmVyc2lvbnMgPSBwdWJsaXNoZWRWZXJzaW9ucyhwYWNrdW1lbnQpO1xuICBpZiAodmVyc2lvbnMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgdmVyc2lvbnMsXG4gICAgbGF0ZXN0OiBsYXRlc3RUYWcocGFja3VtZW50KSA/PyB2ZXJzaW9ucy5hdCgtMSksXG4gICAgZGVwZW5kZW5jaWVzOiB2ZXJzaW9uRGVwZW5kZW5jaWVzKHBhY2t1bWVudCksXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxvYWRWZXJzaW9uRGVwZW5kZW5jaWVzKFxuICBuYW1lOiBzdHJpbmcsXG4gIHZlcnNpb246IHN0cmluZyxcbiAgcmVnaXN0cnlVcmw/OiBzdHJpbmcgfCBVUkwsXG4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgY29uc3QgZG9jID0gYXdhaXQgZmV0Y2hSZWdpc3RyeUpzb24oXG4gICAgYCR7cGFja3VtZW50VXJsKG5hbWUsIHJlZ2lzdHJ5VXJsKX0vJHtlbmNvZGVVUklDb21wb25lbnQodmVyc2lvbil9YCxcbiAgKTtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQoZG9jKSkgcmV0dXJuIHt9O1xuICByZXR1cm4gc3RyaW5nTWFwKGRvYy5kZXBlbmRlbmNpZXMpO1xufVxuXG5mdW5jdGlvbiBwdWJsaXNoZWRWZXJzaW9ucyhwYWNrdW1lbnQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogc3RyaW5nW10ge1xuICBpZiAodHlwZW9mIHBhY2t1bWVudC52ZXJzaW9uID09PSBcInN0cmluZ1wiICYmICFwYWNrdW1lbnQudmVyc2lvbnMpIHtcbiAgICByZXR1cm4gW3BhY2t1bWVudC52ZXJzaW9uXTtcbiAgfVxuICBjb25zdCB2ZXJzaW9ucyA9IHBhY2t1bWVudC52ZXJzaW9ucztcbiAgaWYgKEFycmF5LmlzQXJyYXkodmVyc2lvbnMpKSB7XG4gICAgcmV0dXJuIHZlcnNpb25zLmZpbHRlcigodmFsdWUpOiB2YWx1ZSBpcyBzdHJpbmcgPT4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKTtcbiAgfVxuICBpZiAob2JqZWN0LmlzUmVjb3JkKHZlcnNpb25zKSkgcmV0dXJuIE9iamVjdC5rZXlzKHZlcnNpb25zKTtcbiAgcmV0dXJuIFtdO1xufVxuXG5mdW5jdGlvbiBsYXRlc3RUYWcocGFja3VtZW50OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHRhZ3MgPSBwYWNrdW1lbnRbXCJkaXN0LXRhZ3NcIl07XG4gIGlmICghb2JqZWN0LmlzUmVjb3JkKHRhZ3MpIHx8IHR5cGVvZiB0YWdzLmxhdGVzdCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHRhZ3MubGF0ZXN0O1xufVxuXG5mdW5jdGlvbiB2ZXJzaW9uRGVwZW5kZW5jaWVzKFxuICBwYWNrdW1lbnQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuKTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj4ge1xuICBjb25zdCB2ZXJzaW9ucyA9IHBhY2t1bWVudC52ZXJzaW9ucztcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQodmVyc2lvbnMpKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBwYWNrdW1lbnQudmVyc2lvbiA9PT0gXCJzdHJpbmdcIlxuICAgICAgPyB7IFtwYWNrdW1lbnQudmVyc2lvbl06IHN0cmluZ01hcChwYWNrdW1lbnQuZGVwZW5kZW5jaWVzKSB9XG4gICAgICA6IHt9O1xuICB9XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj4gPSB7fTtcbiAgZm9yIChjb25zdCBbdmVyc2lvbiwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHZlcnNpb25zKSkge1xuICAgIGlmIChvYmplY3QuaXNSZWNvcmQodmFsdWUpKSBvdXRbdmVyc2lvbl0gPSBzdHJpbmdNYXAodmFsdWUuZGVwZW5kZW5jaWVzKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBzdHJpbmdNYXAodmFsdWU6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQodmFsdWUpKSByZXR1cm4ge307XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCBzcGVjXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICBpZiAodHlwZW9mIHNwZWMgPT09IFwic3RyaW5nXCIpIG91dFtuYW1lXSA9IHNwZWM7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==