@mnemonica/tactica 0.1.14 → 0.2.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,690 @@
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.ModuleGraphBuilder = void 0;
37
+ const module_1 = require("module");
38
+ const path = __importStar(require("path"));
39
+ const ts = __importStar(require("typescript"));
40
+ // Bare builtin names from node:module; both 'path' and 'node:path' accepted
41
+ const BUILTIN_MODULES = new Set(module_1.builtinModules);
42
+ /**
43
+ * Module-scope walker (instrumentation walker plan, Phase 1).
44
+ *
45
+ * Builds the cross-file module graph: every export/import binding (functions,
46
+ * classes, consts, types — not only mnemonica types), resolved with
47
+ * `ts.resolveModuleName` driven by the program's compilerOptions (tsconfig
48
+ * `paths`, extensionless imports, index files). This is module resolution,
49
+ * NOT the type checker — the no-`getTypeChecker()` precedent stays intact.
50
+ *
51
+ * Usage: addFile() per source file during the definitions pass, then
52
+ * build(definedTypesByFile) once definitions are known.
53
+ */
54
+ class ModuleGraphBuilder {
55
+ constructor(program, compilerOptions) {
56
+ this.modules = new Map();
57
+ // filePath -> (local name -> kind) for every named top-level declaration
58
+ this.localDecls = new Map();
59
+ // filePath -> import/export specifier sites, for build()-time resolution
60
+ this.importSites = new Map();
61
+ // `${filePath}\n${specifier}` -> resolution (undefined = failed)
62
+ this.resolutionCache = new Map();
63
+ const options = compilerOptions ?? program?.getCompilerOptions() ?? {};
64
+ this.compilerOptions = options;
65
+ }
66
+ /**
67
+ * Track one source file. Re-adding the same file replaces its record,
68
+ * so a builder may safely be reused across passes.
69
+ */
70
+ addFile(sourceFile) {
71
+ const filePath = path.resolve(sourceFile.fileName);
72
+ const moduleInfo = {
73
+ filePath,
74
+ definedTypes: [],
75
+ exportedBindings: [],
76
+ importedBindings: [],
77
+ dependencies: [],
78
+ unresolvedSpecifiers: [],
79
+ builtinSpecifiers: [],
80
+ };
81
+ const decls = new Map();
82
+ const sites = [];
83
+ this.modules.set(filePath, moduleInfo);
84
+ this.localDecls.set(filePath, decls);
85
+ this.importSites.set(filePath, sites);
86
+ // Pass 1: collect every named top-level declaration, so later
87
+ // `export { X }` statements can be classified regardless of order
88
+ for (const statement of sourceFile.statements) {
89
+ this.collectLocalDecl(statement, decls);
90
+ }
91
+ // Pass 2: process imports, exports, and exported declarations
92
+ for (const statement of sourceFile.statements) {
93
+ this.processStatement(statement, sourceFile, moduleInfo, decls, sites);
94
+ }
95
+ return moduleInfo;
96
+ }
97
+ /**
98
+ * Resolve all specifiers, backfill binding kinds from origin modules,
99
+ * derive dependencies, cross-module mnemonica-type edges, and cycles.
100
+ * `definedTypesByFile` maps absolute file path -> mnemonica type fullPaths
101
+ * defined there (from the analyzer's definitions).
102
+ */
103
+ build(definedTypesByFile) {
104
+ if (definedTypesByFile) {
105
+ for (const [file, types] of definedTypesByFile) {
106
+ const moduleInfo = this.modules.get(path.resolve(file));
107
+ if (moduleInfo) {
108
+ moduleInfo.definedTypes = types;
109
+ }
110
+ }
111
+ }
112
+ // Resolution pass: rewrite sourceModule to the resolved absolute path
113
+ for (const [filePath, sites] of this.importSites) {
114
+ const moduleInfo = this.modules.get(filePath);
115
+ if (!moduleInfo) {
116
+ continue;
117
+ }
118
+ for (const site of sites) {
119
+ const resolution = this.resolveModule(site.specifier, filePath);
120
+ if (!resolution?.resolvedPath) {
121
+ if (!moduleInfo.unresolvedSpecifiers.includes(site.specifier)) {
122
+ moduleInfo.unresolvedSpecifiers.push(site.specifier);
123
+ }
124
+ continue;
125
+ }
126
+ const { resolvedPath, isExternal } = resolution;
127
+ for (const binding of site.bindings) {
128
+ binding.sourceModule = resolvedPath;
129
+ if (isExternal) {
130
+ binding.external = true;
131
+ }
132
+ }
133
+ // Dependencies stay project-internal: external (node_modules)
134
+ // modules are never addFile()'d, so modules.has() gates them out
135
+ if (this.modules.has(resolvedPath) && !moduleInfo.dependencies.includes(resolvedPath)) {
136
+ moduleInfo.dependencies.push(resolvedPath);
137
+ }
138
+ }
139
+ }
140
+ // Kind backfill + edge collection
141
+ const edges = [];
142
+ for (const [filePath, sites] of this.importSites) {
143
+ const moduleInfo = this.modules.get(filePath);
144
+ if (!moduleInfo) {
145
+ continue;
146
+ }
147
+ for (const site of sites) {
148
+ for (const binding of site.bindings) {
149
+ const origin = this.resolveOrigin(binding);
150
+ if (origin && binding.kind === 'unknown') {
151
+ binding.kind = origin.binding.kind;
152
+ }
153
+ if (!origin || origin.module.filePath === filePath) {
154
+ continue;
155
+ }
156
+ const typePath = this.matchDefinedType(origin.module, binding);
157
+ if (typePath) {
158
+ edges.push({
159
+ typePath,
160
+ definitionModule: origin.module.filePath,
161
+ usageModule: filePath,
162
+ usageLocation: site.location,
163
+ });
164
+ }
165
+ }
166
+ }
167
+ }
168
+ const cycles = this.detectCycles();
169
+ const graph = {
170
+ modules: this.modules,
171
+ edges,
172
+ cycles,
173
+ };
174
+ return graph;
175
+ }
176
+ /**
177
+ * Resolve a specifier to an absolute file path via ts.resolveModuleName
178
+ * with the program's compilerOptions. Returns undefined on failure.
179
+ */
180
+ resolveModule(specifier, fromFile) {
181
+ const cacheKey = `${fromFile}\n${specifier}`;
182
+ if (this.resolutionCache.has(cacheKey)) {
183
+ const cached = this.resolutionCache.get(cacheKey);
184
+ return cached;
185
+ }
186
+ const result = ts.resolveModuleName(specifier, fromFile, this.compilerOptions, ts.sys);
187
+ const resolution = result.resolvedModule
188
+ ? {
189
+ resolvedPath: path.resolve(result.resolvedModule.resolvedFileName),
190
+ isExternal: result.resolvedModule.isExternalLibraryImport === true,
191
+ }
192
+ : undefined;
193
+ this.resolutionCache.set(cacheKey, resolution);
194
+ return resolution;
195
+ }
196
+ /**
197
+ * True for Node.js builtins in both bare and `node:`-prefixed forms
198
+ * ('path', 'node:path', 'fs/promises', 'node:fs/promises', …).
199
+ */
200
+ static isBuiltinSpecifier(specifier) {
201
+ const bare = specifier.startsWith('node:') ? specifier.slice('node:'.length) : specifier;
202
+ const result = BUILTIN_MODULES.has(bare);
203
+ return result;
204
+ }
205
+ /**
206
+ * Record a builtin import on the module (honesty marker) and skip it
207
+ * entirely: no bindings, no site, no dependency, no edge.
208
+ * Returns true when the specifier was a builtin (caller must return early).
209
+ */
210
+ static skipBuiltin(moduleInfo, specifier) {
211
+ if (!ModuleGraphBuilder.isBuiltinSpecifier(specifier)) {
212
+ return false;
213
+ }
214
+ if (!moduleInfo.builtinSpecifiers.includes(specifier)) {
215
+ moduleInfo.builtinSpecifiers.push(specifier);
216
+ }
217
+ return true;
218
+ }
219
+ /**
220
+ * Chase a binding to the module that actually declares it, following
221
+ * re-export chains (barrels). Cycle-guarded. Returns undefined when the
222
+ * origin is external or the chain loops.
223
+ */
224
+ resolveOrigin(binding, visited = new Set()) {
225
+ const sourcePath = path.resolve(binding.sourceModule);
226
+ if (visited.has(sourcePath)) {
227
+ return undefined;
228
+ }
229
+ visited.add(sourcePath);
230
+ const sourceModuleInfo = this.modules.get(sourcePath);
231
+ if (!sourceModuleInfo) {
232
+ return undefined;
233
+ }
234
+ // The name to look up in the source module's export list
235
+ const lookupKey = binding.importKind === 'default'
236
+ ? 'default'
237
+ : binding.importAlias ?? binding.name;
238
+ for (const exported of sourceModuleInfo.exportedBindings) {
239
+ if (exported.name !== lookupKey) {
240
+ continue;
241
+ }
242
+ if (!exported.isReExport) {
243
+ const result = { module: sourceModuleInfo, binding: exported };
244
+ return result;
245
+ }
246
+ const chased = this.resolveOrigin(exported, visited);
247
+ return chased;
248
+ }
249
+ // `export * from './y'` barrels: the name may live behind a star
250
+ for (const exported of sourceModuleInfo.exportedBindings) {
251
+ if (!exported.isReExport || exported.importKind !== 'namespace' || exported.name !== '*') {
252
+ continue;
253
+ }
254
+ const chased = this.resolveOrigin({
255
+ name: lookupKey,
256
+ kind: 'unknown',
257
+ sourceModule: exported.sourceModule,
258
+ isReExport: true,
259
+ }, visited);
260
+ if (chased) {
261
+ return chased;
262
+ }
263
+ }
264
+ return undefined;
265
+ }
266
+ /**
267
+ * Match a binding against a module's defined mnemonica types.
268
+ * Returns the matched fullPath, or undefined when the binding is not a
269
+ * mnemonica type of that module.
270
+ */
271
+ matchDefinedType(moduleInfo, binding) {
272
+ const candidate = binding.importAlias ?? binding.name;
273
+ for (const definedType of moduleInfo.definedTypes) {
274
+ // Custom-collection types are keyed `collectionId::Path`
275
+ const bare = definedType.includes('::')
276
+ ? definedType.slice(definedType.indexOf('::') + 2)
277
+ : definedType;
278
+ if (bare === candidate || bare.startsWith(`${candidate}.`)) {
279
+ return definedType;
280
+ }
281
+ }
282
+ return undefined;
283
+ }
284
+ /**
285
+ * Three-color DFS over project-internal dependencies. Cycles are recorded
286
+ * (mnemonica strictChain:false permits non-linear construction), never
287
+ * treated as errors.
288
+ */
289
+ detectCycles() {
290
+ const cycles = [];
291
+ const seenCycles = new Set();
292
+ // 1 = on the current stack, 2 = fully explored
293
+ const state = new Map();
294
+ const visit = (filePath, stack) => {
295
+ state.set(filePath, 1);
296
+ stack.push(filePath);
297
+ const moduleInfo = this.modules.get(filePath);
298
+ for (const dep of moduleInfo?.dependencies ?? []) {
299
+ if (state.get(dep) === 1) {
300
+ const cycle = stack.slice(stack.indexOf(dep));
301
+ const key = ModuleGraphBuilder.cycleKey(cycle);
302
+ if (!seenCycles.has(key)) {
303
+ seenCycles.add(key);
304
+ cycles.push(cycle);
305
+ }
306
+ continue;
307
+ }
308
+ if (!state.get(dep)) {
309
+ visit(dep, stack);
310
+ }
311
+ }
312
+ stack.pop();
313
+ state.set(filePath, 2);
314
+ };
315
+ for (const filePath of this.modules.keys()) {
316
+ if (!state.get(filePath)) {
317
+ visit(filePath, []);
318
+ }
319
+ }
320
+ return cycles;
321
+ }
322
+ /**
323
+ * Rotation-independent cycle key: smallest path first.
324
+ */
325
+ static cycleKey(cycle) {
326
+ let minIndex = 0;
327
+ for (let i = 1; i < cycle.length; i++) {
328
+ if (cycle[i] < cycle[minIndex]) {
329
+ minIndex = i;
330
+ }
331
+ }
332
+ const rotated = cycle.slice(minIndex).concat(cycle.slice(0, minIndex));
333
+ const key = rotated.join('\n');
334
+ return key;
335
+ }
336
+ /**
337
+ * Pass 1: record every named top-level declaration's kind.
338
+ */
339
+ collectLocalDecl(statement, decls) {
340
+ if (ts.isFunctionDeclaration(statement) && statement.name) {
341
+ decls.set(statement.name.text, 'function');
342
+ return;
343
+ }
344
+ if (ts.isClassDeclaration(statement) && statement.name) {
345
+ decls.set(statement.name.text, 'class');
346
+ return;
347
+ }
348
+ if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) {
349
+ decls.set(statement.name.text, 'type');
350
+ return;
351
+ }
352
+ if (ts.isEnumDeclaration(statement)) {
353
+ decls.set(statement.name.text, 'type');
354
+ return;
355
+ }
356
+ if (ts.isVariableStatement(statement)) {
357
+ for (const decl of statement.declarationList.declarations) {
358
+ if (ts.isIdentifier(decl.name)) {
359
+ decls.set(decl.name.text, ModuleGraphBuilder.variableKind(decl));
360
+ }
361
+ }
362
+ }
363
+ }
364
+ /**
365
+ * Classify a variable declaration: arrow/function initializers are
366
+ * 'function' (holder functions the walker follows), class expressions
367
+ * are 'class', everything else is 'const'.
368
+ */
369
+ static variableKind(decl) {
370
+ const { initializer } = decl;
371
+ if (initializer && (ts.isArrowFunction(initializer) || ts.isFunctionExpression(initializer))) {
372
+ return 'function';
373
+ }
374
+ if (initializer && ts.isClassExpression(initializer)) {
375
+ return 'class';
376
+ }
377
+ return 'const';
378
+ }
379
+ /**
380
+ * Pass 2: imports, exports, requires, exported declarations.
381
+ */
382
+ processStatement(statement, sourceFile, moduleInfo, decls, sites) {
383
+ if (ts.isImportDeclaration(statement)) {
384
+ this.processImport(statement, sourceFile, moduleInfo, sites);
385
+ return;
386
+ }
387
+ if (ts.isExportDeclaration(statement)) {
388
+ this.processExportDeclaration(statement, sourceFile, moduleInfo, decls, sites);
389
+ return;
390
+ }
391
+ if (ts.isImportEqualsDeclaration(statement)) {
392
+ this.processImportEquals(statement, sourceFile, moduleInfo, sites);
393
+ return;
394
+ }
395
+ if (ts.isExportAssignment(statement)) {
396
+ this.processExportAssignment(statement, moduleInfo, decls);
397
+ return;
398
+ }
399
+ this.processMaybeExportedDecl(statement, moduleInfo, decls);
400
+ this.processRequireCall(statement, sourceFile, moduleInfo, sites);
401
+ }
402
+ processImport(importDecl, sourceFile, moduleInfo, sites) {
403
+ const { moduleSpecifier } = importDecl;
404
+ if (!ts.isStringLiteral(moduleSpecifier)) {
405
+ return;
406
+ }
407
+ if (ModuleGraphBuilder.skipBuiltin(moduleInfo, moduleSpecifier.text)) {
408
+ return;
409
+ }
410
+ const site = {
411
+ specifier: moduleSpecifier.text,
412
+ location: this.locationOf(moduleSpecifier, sourceFile),
413
+ bindings: [],
414
+ };
415
+ sites.push(site);
416
+ const { importClause } = importDecl;
417
+ if (!importClause) {
418
+ // Side-effect import: dependency only, no bindings
419
+ return;
420
+ }
421
+ // Default import: import Type from './module'
422
+ if (importClause.name) {
423
+ const binding = {
424
+ name: importClause.name.text,
425
+ kind: 'unknown',
426
+ sourceModule: site.specifier,
427
+ importKind: 'default',
428
+ isReExport: false,
429
+ };
430
+ moduleInfo.importedBindings.push(binding);
431
+ site.bindings.push(binding);
432
+ }
433
+ const { namedBindings } = importClause;
434
+ if (namedBindings && ts.isNamedImports(namedBindings)) {
435
+ for (const element of namedBindings.elements) {
436
+ const originalName = element.propertyName?.text;
437
+ const binding = {
438
+ name: element.name.text,
439
+ kind: 'unknown',
440
+ sourceModule: site.specifier,
441
+ importKind: 'named',
442
+ isReExport: false,
443
+ };
444
+ if (originalName) {
445
+ binding.importAlias = originalName;
446
+ }
447
+ moduleInfo.importedBindings.push(binding);
448
+ site.bindings.push(binding);
449
+ }
450
+ return;
451
+ }
452
+ // Namespace import: import * as Types from './module'
453
+ if (namedBindings && ts.isNamespaceImport(namedBindings)) {
454
+ const binding = {
455
+ name: namedBindings.name.text,
456
+ kind: 'unknown',
457
+ sourceModule: site.specifier,
458
+ importKind: 'namespace',
459
+ isReExport: false,
460
+ };
461
+ moduleInfo.importedBindings.push(binding);
462
+ site.bindings.push(binding);
463
+ }
464
+ }
465
+ processExportDeclaration(exportDecl, sourceFile, moduleInfo, decls, sites) {
466
+ const { moduleSpecifier } = exportDecl;
467
+ const { exportClause } = exportDecl;
468
+ // Re-export forms carry a module specifier: `export … from './y'`
469
+ if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier)) {
470
+ if (ModuleGraphBuilder.skipBuiltin(moduleInfo, moduleSpecifier.text)) {
471
+ return;
472
+ }
473
+ const site = {
474
+ specifier: moduleSpecifier.text,
475
+ location: this.locationOf(moduleSpecifier, sourceFile),
476
+ bindings: [],
477
+ };
478
+ sites.push(site);
479
+ if (!exportClause) {
480
+ // `export * from './y'`
481
+ const binding = {
482
+ name: '*',
483
+ kind: 'unknown',
484
+ sourceModule: site.specifier,
485
+ importKind: 'namespace',
486
+ isReExport: true,
487
+ };
488
+ moduleInfo.exportedBindings.push(binding);
489
+ moduleInfo.importedBindings.push(binding);
490
+ site.bindings.push(binding);
491
+ return;
492
+ }
493
+ if (ts.isNamespaceExport(exportClause)) {
494
+ // `export * as ns from './y'`
495
+ const binding = {
496
+ name: exportClause.name.text,
497
+ kind: 'unknown',
498
+ sourceModule: site.specifier,
499
+ importKind: 'namespace',
500
+ isReExport: true,
501
+ };
502
+ moduleInfo.exportedBindings.push(binding);
503
+ moduleInfo.importedBindings.push(binding);
504
+ site.bindings.push(binding);
505
+ return;
506
+ }
507
+ // `export { X, Y as Z } from './y'`
508
+ for (const element of exportClause.elements) {
509
+ const originalName = element.propertyName?.text;
510
+ const binding = {
511
+ name: element.name.text,
512
+ kind: 'unknown',
513
+ sourceModule: site.specifier,
514
+ importKind: 'named',
515
+ isReExport: true,
516
+ };
517
+ if (originalName) {
518
+ binding.importAlias = originalName;
519
+ }
520
+ moduleInfo.exportedBindings.push(binding);
521
+ moduleInfo.importedBindings.push(binding);
522
+ site.bindings.push(binding);
523
+ }
524
+ return;
525
+ }
526
+ // Plain `export { X, Y as Z }` — local declarations
527
+ if (exportClause && ts.isNamedExports(exportClause)) {
528
+ for (const element of exportClause.elements) {
529
+ const originalName = element.propertyName?.text ?? element.name.text;
530
+ const binding = {
531
+ name: element.name.text,
532
+ kind: decls.get(originalName) ?? 'unknown',
533
+ sourceModule: moduleInfo.filePath,
534
+ isReExport: false,
535
+ };
536
+ if (element.propertyName) {
537
+ binding.importAlias = element.propertyName.text;
538
+ }
539
+ moduleInfo.exportedBindings.push(binding);
540
+ }
541
+ }
542
+ }
543
+ /**
544
+ * `import foo = require('./y')`
545
+ */
546
+ processImportEquals(importDecl, sourceFile, moduleInfo, sites) {
547
+ const { moduleReference } = importDecl;
548
+ if (!ts.isExternalModuleReference(moduleReference)) {
549
+ return;
550
+ }
551
+ const { expression } = moduleReference;
552
+ if (!ts.isStringLiteral(expression)) {
553
+ return;
554
+ }
555
+ if (ModuleGraphBuilder.skipBuiltin(moduleInfo, expression.text)) {
556
+ return;
557
+ }
558
+ const binding = {
559
+ name: importDecl.name.text,
560
+ kind: 'unknown',
561
+ sourceModule: expression.text,
562
+ importKind: 'require',
563
+ isReExport: false,
564
+ };
565
+ moduleInfo.importedBindings.push(binding);
566
+ sites.push({
567
+ specifier: expression.text,
568
+ location: this.locationOf(expression, sourceFile),
569
+ bindings: [binding],
570
+ });
571
+ }
572
+ /**
573
+ * `export default <expression>`
574
+ */
575
+ processExportAssignment(statement, moduleInfo, decls) {
576
+ const { expression } = statement;
577
+ const kind = ts.isIdentifier(expression)
578
+ ? decls.get(expression.text) ?? 'unknown'
579
+ : 'unknown';
580
+ const binding = {
581
+ name: 'default',
582
+ kind,
583
+ sourceModule: moduleInfo.filePath,
584
+ importKind: 'default',
585
+ isReExport: false,
586
+ };
587
+ if (ts.isIdentifier(expression)) {
588
+ binding.importAlias = expression.text;
589
+ }
590
+ moduleInfo.exportedBindings.push(binding);
591
+ }
592
+ /**
593
+ * `export function/class/const/interface/type …` declarations.
594
+ */
595
+ processMaybeExportedDecl(statement, moduleInfo, decls) {
596
+ const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined;
597
+ const hasExport = modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
598
+ const hasDefault = modifiers?.some(m => m.kind === ts.SyntaxKind.DefaultKeyword) ?? false;
599
+ if (!hasExport) {
600
+ return;
601
+ }
602
+ const addExport = (localName, kind) => {
603
+ const binding = {
604
+ name: hasDefault ? 'default' : localName ?? 'default',
605
+ kind,
606
+ sourceModule: moduleInfo.filePath,
607
+ isReExport: false,
608
+ };
609
+ if (hasDefault) {
610
+ binding.importKind = 'default';
611
+ if (localName) {
612
+ binding.importAlias = localName;
613
+ }
614
+ }
615
+ moduleInfo.exportedBindings.push(binding);
616
+ };
617
+ if (ts.isFunctionDeclaration(statement)) {
618
+ addExport(statement.name?.text, 'function');
619
+ return;
620
+ }
621
+ if (ts.isClassDeclaration(statement)) {
622
+ addExport(statement.name?.text, 'class');
623
+ return;
624
+ }
625
+ if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) {
626
+ addExport(statement.name.text, 'type');
627
+ return;
628
+ }
629
+ if (ts.isEnumDeclaration(statement)) {
630
+ addExport(statement.name.text, 'type');
631
+ return;
632
+ }
633
+ if (ts.isVariableStatement(statement)) {
634
+ for (const decl of statement.declarationList.declarations) {
635
+ if (ts.isIdentifier(decl.name)) {
636
+ addExport(decl.name.text, decls.get(decl.name.text) ?? 'const');
637
+ }
638
+ }
639
+ }
640
+ }
641
+ /**
642
+ * CommonJS `const x = require('./y')` (JS sources with allowJs).
643
+ */
644
+ processRequireCall(statement, sourceFile, moduleInfo, sites) {
645
+ if (!ts.isVariableStatement(statement)) {
646
+ return;
647
+ }
648
+ for (const decl of statement.declarationList.declarations) {
649
+ const { initializer } = decl;
650
+ if (!initializer || !ts.isCallExpression(initializer)) {
651
+ continue;
652
+ }
653
+ if (!ts.isIdentifier(initializer.expression) || initializer.expression.text !== 'require') {
654
+ continue;
655
+ }
656
+ const [firstArg] = initializer.arguments;
657
+ if (!firstArg || !ts.isStringLiteral(firstArg)) {
658
+ continue;
659
+ }
660
+ if (ModuleGraphBuilder.skipBuiltin(moduleInfo, firstArg.text)) {
661
+ continue;
662
+ }
663
+ const localName = ts.isIdentifier(decl.name) ? decl.name.text : decl.name.getText();
664
+ const binding = {
665
+ name: localName,
666
+ kind: 'unknown',
667
+ sourceModule: firstArg.text,
668
+ importKind: 'require',
669
+ isReExport: false,
670
+ };
671
+ moduleInfo.importedBindings.push(binding);
672
+ sites.push({
673
+ specifier: firstArg.text,
674
+ location: this.locationOf(firstArg, sourceFile),
675
+ bindings: [binding],
676
+ });
677
+ }
678
+ }
679
+ /**
680
+ * Format a node's position as file.ts:Line:Col (1-based), matching the
681
+ * location format of the other .tactica outputs.
682
+ */
683
+ locationOf(node, sourceFile) {
684
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
685
+ const location = `${path.resolve(sourceFile.fileName)}:${position.line + 1}:${position.character + 1}`;
686
+ return location;
687
+ }
688
+ }
689
+ exports.ModuleGraphBuilder = ModuleGraphBuilder;
690
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLWdyYXBoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21vZHVsZS1ncmFwaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUViLG1DQUF3QztBQUN4QywyQ0FBNkI7QUFDN0IsK0NBQWlDO0FBeUJqQyw0RUFBNEU7QUFDNUUsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQUMsdUJBQWMsQ0FBQyxDQUFDO0FBRWhEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBYSxrQkFBa0I7SUFVOUIsWUFBYSxPQUFvQixFQUFFLGVBQW9DO1FBUi9ELFlBQU8sR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztRQUNoRCx5RUFBeUU7UUFDakUsZUFBVSxHQUFHLElBQUksR0FBRyxFQUEwQyxDQUFDO1FBQ3ZFLHlFQUF5RTtRQUNqRSxnQkFBVyxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO1FBQ3RELGlFQUFpRTtRQUN6RCxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUF3QyxDQUFDO1FBR3pFLE1BQU0sT0FBTyxHQUFHLGVBQWUsSUFBSSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDdkUsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7T0FHRztJQUNILE9BQU8sQ0FBRSxVQUF5QjtRQUNqQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVuRCxNQUFNLFVBQVUsR0FBZTtZQUM5QixRQUFRO1lBQ1IsWUFBWSxFQUFXLEVBQUU7WUFDekIsZ0JBQWdCLEVBQU8sRUFBRTtZQUN6QixnQkFBZ0IsRUFBTyxFQUFFO1lBQ3pCLFlBQVksRUFBVyxFQUFFO1lBQ3pCLG9CQUFvQixFQUFHLEVBQUU7WUFDekIsaUJBQWlCLEVBQU0sRUFBRTtTQUN6QixDQUFDO1FBQ0YsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQTZCLENBQUM7UUFDbkQsTUFBTSxLQUFLLEdBQWlCLEVBQUUsQ0FBQztRQUUvQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV0Qyw4REFBOEQ7UUFDOUQsa0VBQWtFO1FBQ2xFLEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQy9DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELDhEQUE4RDtRQUM5RCxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUUsa0JBQTBDO1FBQ2hELElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUN4QixLQUFLLE1BQU0sQ0FBRSxJQUFJLEVBQUUsS0FBSyxDQUFFLElBQUksa0JBQWtCLEVBQUUsQ0FBQztnQkFDbEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUN4RCxJQUFJLFVBQVUsRUFBRSxDQUFDO29CQUNoQixVQUFVLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDakMsQ0FBQztZQUNGLENBQUM7UUFDRixDQUFDO1FBRUQsc0VBQXNFO1FBQ3RFLEtBQUssTUFBTSxDQUFFLFFBQVEsRUFBRSxLQUFLLENBQUUsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDcEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNqQixTQUFTO1lBQ1YsQ0FBQztZQUNELEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDaEUsSUFBSSxDQUFDLFVBQVUsRUFBRSxZQUFZLEVBQUUsQ0FBQztvQkFDL0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7d0JBQy9ELFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUN0RCxDQUFDO29CQUNELFNBQVM7Z0JBQ1YsQ0FBQztnQkFDRCxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxHQUFHLFVBQVUsQ0FBQztnQkFDaEQsS0FBSyxNQUFNLE9BQU8sSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3JDLE9BQU8sQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO29CQUNwQyxJQUFJLFVBQVUsRUFBRSxDQUFDO3dCQUNoQixPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztvQkFDekIsQ0FBQztnQkFDRixDQUFDO2dCQUNELDhEQUE4RDtnQkFDOUQsaUVBQWlFO2dCQUNqRSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztvQkFDdkYsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzVDLENBQUM7WUFDRixDQUFDO1FBQ0YsQ0FBQztRQUVELGtDQUFrQztRQUNsQyxNQUFNLEtBQUssR0FBdUIsRUFBRSxDQUFDO1FBQ3JDLEtBQUssTUFBTSxDQUFFLFFBQVEsRUFBRSxLQUFLLENBQUUsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDcEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNqQixTQUFTO1lBQ1YsQ0FBQztZQUNELEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQzFCLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUMzQyxJQUFJLE1BQU0sSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO3dCQUMxQyxPQUFPLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO29CQUNwQyxDQUFDO29CQUNELElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7d0JBQ3BELFNBQVM7b0JBQ1YsQ0FBQztvQkFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztvQkFDL0QsSUFBSSxRQUFRLEVBQUUsQ0FBQzt3QkFDZCxLQUFLLENBQUMsSUFBSSxDQUFDOzRCQUNWLFFBQVE7NEJBQ1IsZ0JBQWdCLEVBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFROzRCQUN6QyxXQUFXLEVBQVEsUUFBUTs0QkFDM0IsYUFBYSxFQUFNLElBQUksQ0FBQyxRQUFRO3lCQUNoQyxDQUFDLENBQUM7b0JBQ0osQ0FBQztnQkFDRixDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbkMsTUFBTSxLQUFLLEdBQWdCO1lBQzFCLE9BQU8sRUFBRyxJQUFJLENBQUMsT0FBTztZQUN0QixLQUFLO1lBQ0wsTUFBTTtTQUNOLENBQUM7UUFDRixPQUFPLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSyxhQUFhLENBQUUsU0FBaUIsRUFBRSxRQUFnQjtRQUN6RCxNQUFNLFFBQVEsR0FBRyxHQUFHLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUM3QyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDeEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbEQsT0FBTyxNQUFNLENBQUM7UUFDZixDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkYsTUFBTSxVQUFVLEdBQWlDLE1BQU0sQ0FBQyxjQUFjO1lBQ3JFLENBQUMsQ0FBQztnQkFDRCxZQUFZLEVBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDO2dCQUNuRSxVQUFVLEVBQUssTUFBTSxDQUFDLGNBQWMsQ0FBQyx1QkFBdUIsS0FBSyxJQUFJO2FBQ3JFO1lBQ0QsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNiLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUMvQyxPQUFPLFVBQVUsQ0FBQztJQUNuQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssTUFBTSxDQUFDLGtCQUFrQixDQUFFLFNBQWlCO1FBQ25ELE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDekYsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxPQUFPLE1BQU0sQ0FBQztJQUNmLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssTUFBTSxDQUFDLFdBQVcsQ0FBRSxVQUFzQixFQUFFLFNBQWlCO1FBQ3BFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3ZELE9BQU8sS0FBSyxDQUFDO1FBQ2QsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdkQsVUFBVSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGFBQWEsQ0FDcEIsT0FBc0IsRUFDdEIsVUFBVSxJQUFJLEdBQUcsRUFBVTtRQUUzQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN0RCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUM3QixPQUFPLFNBQVMsQ0FBQztRQUNsQixDQUFDO1FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV4QixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sU0FBUyxDQUFDO1FBQ2xCLENBQUM7UUFFRCx5REFBeUQ7UUFDekQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFVBQVUsS0FBSyxTQUFTO1lBQ2pELENBQUMsQ0FBQyxTQUFTO1lBQ1gsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQztRQUV2QyxLQUFLLE1BQU0sUUFBUSxJQUFJLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUQsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxTQUFTO1lBQ1YsQ0FBQztZQUNELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sTUFBTSxHQUFHLEVBQUUsTUFBTSxFQUFHLGdCQUFnQixFQUFFLE9BQU8sRUFBRyxRQUFRLEVBQUUsQ0FBQztnQkFDakUsT0FBTyxNQUFNLENBQUM7WUFDZixDQUFDO1lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDckQsT0FBTyxNQUFNLENBQUM7UUFDZixDQUFDO1FBRUQsaUVBQWlFO1FBQ2pFLEtBQUssTUFBTSxRQUFRLElBQUksZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxRCxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFdBQVcsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUMxRixTQUFTO1lBQ1YsQ0FBQztZQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7Z0JBQ2pDLElBQUksRUFBVyxTQUFTO2dCQUN4QixJQUFJLEVBQVcsU0FBUztnQkFDeEIsWUFBWSxFQUFHLFFBQVEsQ0FBQyxZQUFZO2dCQUNwQyxVQUFVLEVBQUssSUFBSTthQUNuQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ1osSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDWixPQUFPLE1BQU0sQ0FBQztZQUNmLENBQUM7UUFDRixDQUFDO1FBRUQsT0FBTyxTQUFTLENBQUM7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxnQkFBZ0IsQ0FBRSxVQUFzQixFQUFFLE9BQXNCO1FBQ3ZFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQztRQUN0RCxLQUFLLE1BQU0sV0FBVyxJQUFJLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNuRCx5REFBeUQ7WUFDekQsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQ3RDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNsRCxDQUFDLENBQUMsV0FBVyxDQUFDO1lBQ2YsSUFBSSxJQUFJLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxTQUFXLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzlELE9BQU8sV0FBVyxDQUFDO1lBQ3BCLENBQUM7UUFDRixDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxZQUFZO1FBQ25CLE1BQU0sTUFBTSxHQUFlLEVBQUUsQ0FBQztRQUM5QixNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQ3JDLCtDQUErQztRQUMvQyxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUV4QyxNQUFNLEtBQUssR0FBRyxDQUFDLFFBQWdCLEVBQUUsS0FBZSxFQUFRLEVBQUU7WUFDekQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkIsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUVyQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM5QyxLQUFLLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxZQUFZLElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQ2xELElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDMUIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQzlDLE1BQU0sR0FBRyxHQUFHLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDL0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDMUIsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFDcEIsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDcEIsQ0FBQztvQkFDRCxTQUFTO2dCQUNWLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDckIsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDbkIsQ0FBQztZQUNGLENBQUM7WUFFRCxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDWixLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4QixDQUFDLENBQUM7UUFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUM1QyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUMxQixLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3JCLENBQUM7UUFDRixDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDZixDQUFDO0lBRUQ7O09BRUc7SUFDSyxNQUFNLENBQUMsUUFBUSxDQUFFLEtBQWU7UUFDdkMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDdkMsSUFBSSxLQUFLLENBQUUsQ0FBQyxDQUFFLEdBQUcsS0FBSyxDQUFFLFFBQVEsQ0FBRSxFQUFFLENBQUM7Z0JBQ3BDLFFBQVEsR0FBRyxDQUFDLENBQUM7WUFDZCxDQUFDO1FBQ0YsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDdkUsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixPQUFPLEdBQUcsQ0FBQztJQUNaLENBQUM7SUFFRDs7T0FFRztJQUNLLGdCQUFnQixDQUFFLFNBQXVCLEVBQUUsS0FBcUM7UUFDdkYsSUFBSSxFQUFFLENBQUMscUJBQXFCLENBQUMsU0FBUyxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzNELEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDM0MsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDeEQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztZQUN4QyxPQUFPO1FBQ1IsQ0FBQztRQUNELElBQUksRUFBRSxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ2xGLEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkMsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3JDLEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkMsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLEtBQUssTUFBTSxJQUFJLElBQUksU0FBUyxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDM0QsSUFBSSxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNoQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7SUFDRixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLE1BQU0sQ0FBQyxZQUFZLENBQUUsSUFBNEI7UUFDeEQsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQztRQUM3QixJQUFJLFdBQVcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUM5RixPQUFPLFVBQVUsQ0FBQztRQUNuQixDQUFDO1FBQ0QsSUFBSSxXQUFXLElBQUksRUFBRSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDdEQsT0FBTyxPQUFPLENBQUM7UUFDaEIsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNLLGdCQUFnQixDQUN2QixTQUF1QixFQUN2QixVQUF5QixFQUN6QixVQUFzQixFQUN0QixLQUFxQyxFQUNyQyxLQUFtQjtRQUVuQixJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0QsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDL0UsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuRSxPQUFPO1FBQ1IsQ0FBQztRQUNELElBQUksRUFBRSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0QsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVPLGFBQWEsQ0FDcEIsVUFBZ0MsRUFDaEMsVUFBeUIsRUFDekIsVUFBc0IsRUFDdEIsS0FBbUI7UUFFbkIsTUFBTSxFQUFFLGVBQWUsRUFBRSxHQUFHLFVBQVUsQ0FBQztRQUN2QyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1lBQzFDLE9BQU87UUFDUixDQUFDO1FBQ0QsSUFBSSxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3RFLE9BQU87UUFDUixDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQWU7WUFDeEIsU0FBUyxFQUFHLGVBQWUsQ0FBQyxJQUFJO1lBQ2hDLFFBQVEsRUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUM7WUFDeEQsUUFBUSxFQUFJLEVBQUU7U0FDZCxDQUFDO1FBQ0YsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsVUFBVSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNuQixtREFBbUQ7WUFDbkQsT0FBTztRQUNSLENBQUM7UUFFRCw4Q0FBOEM7UUFDOUMsSUFBSSxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDdkIsTUFBTSxPQUFPLEdBQWtCO2dCQUM5QixJQUFJLEVBQVcsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJO2dCQUNyQyxJQUFJLEVBQVcsU0FBUztnQkFDeEIsWUFBWSxFQUFHLElBQUksQ0FBQyxTQUFTO2dCQUM3QixVQUFVLEVBQUssU0FBUztnQkFDeEIsVUFBVSxFQUFLLEtBQUs7YUFDcEIsQ0FBQztZQUNGLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUVELE1BQU0sRUFBRSxhQUFhLEVBQUUsR0FBRyxZQUFZLENBQUM7UUFDdkMsSUFBSSxhQUFhLElBQUksRUFBRSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1lBQ3ZELEtBQUssTUFBTSxPQUFPLElBQUksYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUM5QyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQztnQkFDaEQsTUFBTSxPQUFPLEdBQWtCO29CQUM5QixJQUFJLEVBQVcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJO29CQUNoQyxJQUFJLEVBQVcsU0FBUztvQkFDeEIsWUFBWSxFQUFHLElBQUksQ0FBQyxTQUFTO29CQUM3QixVQUFVLEVBQUssT0FBTztvQkFDdEIsVUFBVSxFQUFLLEtBQUs7aUJBQ3BCLENBQUM7Z0JBQ0YsSUFBSSxZQUFZLEVBQUUsQ0FBQztvQkFDbEIsT0FBTyxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7Z0JBQ3BDLENBQUM7Z0JBQ0QsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0IsQ0FBQztZQUNELE9BQU87UUFDUixDQUFDO1FBRUQsc0RBQXNEO1FBQ3RELElBQUksYUFBYSxJQUFJLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1lBQzFELE1BQU0sT0FBTyxHQUFrQjtnQkFDOUIsSUFBSSxFQUFXLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSTtnQkFDdEMsSUFBSSxFQUFXLFNBQVM7Z0JBQ3hCLFlBQVksRUFBRyxJQUFJLENBQUMsU0FBUztnQkFDN0IsVUFBVSxFQUFLLFdBQVc7Z0JBQzFCLFVBQVUsRUFBSyxLQUFLO2FBQ3BCLENBQUM7WUFDRixVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLENBQUM7SUFDRixDQUFDO0lBRU8sd0JBQXdCLENBQy9CLFVBQWdDLEVBQ2hDLFVBQXlCLEVBQ3pCLFVBQXNCLEVBQ3RCLEtBQXFDLEVBQ3JDLEtBQW1CO1FBRW5CLE1BQU0sRUFBRSxlQUFlLEVBQUUsR0FBRyxVQUFVLENBQUM7UUFDdkMsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLFVBQVUsQ0FBQztRQUVwQyxrRUFBa0U7UUFDbEUsSUFBSSxlQUFlLElBQUksRUFBRSxDQUFDLGVBQWUsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1lBQzVELElBQUksa0JBQWtCLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDdEUsT0FBTztZQUNSLENBQUM7WUFFRCxNQUFNLElBQUksR0FBZTtnQkFDeEIsU0FBUyxFQUFHLGVBQWUsQ0FBQyxJQUFJO2dCQUNoQyxRQUFRLEVBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUUsVUFBVSxDQUFDO2dCQUN4RCxRQUFRLEVBQUksRUFBRTthQUNkLENBQUM7WUFDRixLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRWpCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbkIsd0JBQXdCO2dCQUN4QixNQUFNLE9BQU8sR0FBa0I7b0JBQzlCLElBQUksRUFBVyxHQUFHO29CQUNsQixJQUFJLEVBQVcsU0FBUztvQkFDeEIsWUFBWSxFQUFHLElBQUksQ0FBQyxTQUFTO29CQUM3QixVQUFVLEVBQUssV0FBVztvQkFDMUIsVUFBVSxFQUFLLElBQUk7aUJBQ25CLENBQUM7Z0JBQ0YsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDMUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzVCLE9BQU87WUFDUixDQUFDO1lBRUQsSUFBSSxFQUFFLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsOEJBQThCO2dCQUM5QixNQUFNLE9BQU8sR0FBa0I7b0JBQzlCLElBQUksRUFBVyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUk7b0JBQ3JDLElBQUksRUFBVyxTQUFTO29CQUN4QixZQUFZLEVBQUcsSUFBSSxDQUFDLFNBQVM7b0JBQzdCLFVBQVUsRUFBSyxXQUFXO29CQUMxQixVQUFVLEVBQUssSUFBSTtpQkFDbkIsQ0FBQztnQkFDRixVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMxQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDNUIsT0FBTztZQUNSLENBQUM7WUFFRCxvQ0FBb0M7WUFDcEMsS0FBSyxNQUFNLE9BQU8sSUFBSSxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDO2dCQUNoRCxNQUFNLE9BQU8sR0FBa0I7b0JBQzlCLElBQUksRUFBVyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUk7b0JBQ2hDLElBQUksRUFBVyxTQUFTO29CQUN4QixZQUFZLEVBQUcsSUFBSSxDQUFDLFNBQVM7b0JBQzdCLFVBQVUsRUFBSyxPQUFPO29CQUN0QixVQUFVLEVBQUssSUFBSTtpQkFDbkIsQ0FBQztnQkFDRixJQUFJLFlBQVksRUFBRSxDQUFDO29CQUNsQixPQUFPLENBQUMsV0FBVyxHQUFHLFlBQVksQ0FBQztnQkFDcEMsQ0FBQztnQkFDRCxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMxQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM3QixDQUFDO1lBQ0QsT0FBTztRQUNSLENBQUM7UUFFRCxvREFBb0Q7UUFDcEQsSUFBSSxZQUFZLElBQUksRUFBRSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3JELEtBQUssTUFBTSxPQUFPLElBQUksWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxFQUFFLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDckUsTUFBTSxPQUFPLEdBQWtCO29CQUM5QixJQUFJLEVBQVcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJO29CQUNoQyxJQUFJLEVBQVcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxTQUFTO29CQUNuRCxZQUFZLEVBQUcsVUFBVSxDQUFDLFFBQVE7b0JBQ2xDLFVBQVUsRUFBSyxLQUFLO2lCQUNwQixDQUFDO2dCQUNGLElBQUksT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDO29CQUMxQixPQUFPLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO2dCQUNqRCxDQUFDO2dCQUNELFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDM0MsQ0FBQztRQUNGLENBQUM7SUFDRixDQUFDO0lBRUQ7O09BRUc7SUFDSyxtQkFBbUIsQ0FDMUIsVUFBc0MsRUFDdEMsVUFBeUIsRUFDekIsVUFBc0IsRUFDdEIsS0FBbUI7UUFFbkIsTUFBTSxFQUFFLGVBQWUsRUFBRSxHQUFHLFVBQVUsQ0FBQztRQUN2QyxJQUFJLENBQUMsRUFBRSxDQUFDLHlCQUF5QixDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDcEQsT0FBTztRQUNSLENBQUM7UUFDRCxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsZUFBZSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDckMsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDakUsT0FBTztRQUNSLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBa0I7WUFDOUIsSUFBSSxFQUFXLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSTtZQUNuQyxJQUFJLEVBQVcsU0FBUztZQUN4QixZQUFZLEVBQUcsVUFBVSxDQUFDLElBQUk7WUFDOUIsVUFBVSxFQUFLLFNBQVM7WUFDeEIsVUFBVSxFQUFLLEtBQUs7U0FDcEIsQ0FBQztRQUNGLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUMsS0FBSyxDQUFDLElBQUksQ0FBQztZQUNWLFNBQVMsRUFBRyxVQUFVLENBQUMsSUFBSTtZQUMzQixRQUFRLEVBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDO1lBQ25ELFFBQVEsRUFBSSxDQUFFLE9BQU8sQ0FBRTtTQUN2QixDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyx1QkFBdUIsQ0FDOUIsU0FBOEIsRUFDOUIsVUFBc0IsRUFDdEIsS0FBcUM7UUFFckMsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLFNBQVMsQ0FBQztRQUNqQyxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQztZQUN2QyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksU0FBUztZQUN6QyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ2IsTUFBTSxPQUFPLEdBQWtCO1lBQzlCLElBQUksRUFBVyxTQUFTO1lBQ3hCLElBQUk7WUFDSixZQUFZLEVBQUcsVUFBVSxDQUFDLFFBQVE7WUFDbEMsVUFBVSxFQUFLLFNBQVM7WUFDeEIsVUFBVSxFQUFLLEtBQUs7U0FDcEIsQ0FBQztRQUNGLElBQUksRUFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQztRQUN2QyxDQUFDO1FBQ0QsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQ7O09BRUc7SUFDSyx3QkFBd0IsQ0FDL0IsU0FBdUIsRUFDdkIsVUFBc0IsRUFDdEIsS0FBcUM7UUFFckMsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDMUYsTUFBTSxTQUFTLEdBQUcsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxLQUFLLENBQUM7UUFDeEYsTUFBTSxVQUFVLEdBQUcsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsSUFBSSxLQUFLLENBQUM7UUFDMUYsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2hCLE9BQU87UUFDUixDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxTQUE2QixFQUFFLElBQXVCLEVBQVEsRUFBRTtZQUNsRixNQUFNLE9BQU8sR0FBa0I7Z0JBQzlCLElBQUksRUFBVyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxJQUFJLFNBQVM7Z0JBQzlELElBQUk7Z0JBQ0osWUFBWSxFQUFHLFVBQVUsQ0FBQyxRQUFRO2dCQUNsQyxVQUFVLEVBQUssS0FBSzthQUNwQixDQUFDO1lBQ0YsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDaEIsT0FBTyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7Z0JBQy9CLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2YsT0FBTyxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7Z0JBQ2pDLENBQUM7WUFDRixDQUFDO1lBQ0QsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUM7UUFFRixJQUFJLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3pDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztZQUM1QyxPQUFPO1FBQ1IsQ0FBQztRQUNELElBQUksRUFBRSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdEMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3pDLE9BQU87UUFDUixDQUFDO1FBQ0QsSUFBSSxFQUFFLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDbEYsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZDLE9BQU87UUFDUixDQUFDO1FBQ0QsSUFBSSxFQUFFLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNyQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkMsT0FBTztRQUNSLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLEtBQUssTUFBTSxJQUFJLElBQUksU0FBUyxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDM0QsSUFBSSxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNoQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDO2dCQUNqRSxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7SUFDRixDQUFDO0lBRUQ7O09BRUc7SUFDSyxrQkFBa0IsQ0FDekIsU0FBdUIsRUFDdkIsVUFBeUIsRUFDekIsVUFBc0IsRUFDdEIsS0FBbUI7UUFFbkIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU87UUFDUixDQUFDO1FBQ0QsS0FBSyxNQUFNLElBQUksSUFBSSxTQUFTLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzNELE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxJQUFJLENBQUM7WUFDN0IsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUN2RCxTQUFTO1lBQ1YsQ0FBQztZQUNELElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDM0YsU0FBUztZQUNWLENBQUM7WUFDRCxNQUFNLENBQUUsUUFBUSxDQUFFLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQztZQUMzQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUNoRCxTQUFTO1lBQ1YsQ0FBQztZQUNELElBQUksa0JBQWtCLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDL0QsU0FBUztZQUNWLENBQUM7WUFDRCxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEYsTUFBTSxPQUFPLEdBQWtCO2dCQUM5QixJQUFJLEVBQVcsU0FBUztnQkFDeEIsSUFBSSxFQUFXLFNBQVM7Z0JBQ3hCLFlBQVksRUFBRyxRQUFRLENBQUMsSUFBSTtnQkFDNUIsVUFBVSxFQUFLLFNBQVM7Z0JBQ3hCLFVBQVUsRUFBSyxLQUFLO2FBQ3BCLENBQUM7WUFDRixVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFDLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1YsU0FBUyxFQUFHLFFBQVEsQ0FBQyxJQUFJO2dCQUN6QixRQUFRLEVBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDO2dCQUNqRCxRQUFRLEVBQUksQ0FBRSxPQUFPLENBQUU7YUFDdkIsQ0FBQyxDQUFDO1FBQ0osQ0FBQztJQUNGLENBQUM7SUFFRDs7O09BR0c7SUFDSyxVQUFVLENBQUUsSUFBYSxFQUFFLFVBQXlCO1FBQzNELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDckYsTUFBTSxRQUFRLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxRQUFRLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3ZHLE9BQU8sUUFBUSxDQUFDO0lBQ2pCLENBQUM7Q0FDRDtBQXZ0QkQsZ0RBdXRCQyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgYnVpbHRpbk1vZHVsZXMgfSBmcm9tICdtb2R1bGUnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIHRzIGZyb20gJ3R5cGVzY3JpcHQnO1xuaW1wb3J0IHtcblx0TW9kdWxlQmluZGluZywgTW9kdWxlQmluZGluZ0tpbmQsIE1vZHVsZUdyYXBoLCBNb2R1bGVJbmZvLCBDcm9zc01vZHVsZVVzYWdlXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIEludGVybmFsIHJlY29yZCBvZiBvbmUgaW1wb3J0L2V4cG9ydCBzaXRlOiB0aGUgc3BlY2lmaWVyIGFzIHdyaXR0ZW4sIGl0c1xuICogbG9jYXRpb24sIGFuZCB0aGUgYmluZGluZyBvYmplY3RzIGl0IHByb2R1Y2VkIChzaGFyZWQgYnkgcmVmZXJlbmNlIHdpdGhcbiAqIE1vZHVsZUluZm8sIHNvIGJ1aWxkKCktdGltZSByZXNvbHV0aW9uIHJld3JpdGVzIHRoZW0gaW4gcGxhY2UpLlxuICovXG5pbnRlcmZhY2UgSW1wb3J0U2l0ZSB7XG5cdHNwZWNpZmllcjogc3RyaW5nO1xuXHRsb2NhdGlvbjogc3RyaW5nO1xuXHRiaW5kaW5nczogTW9kdWxlQmluZGluZ1tdO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiByZXNvbHZpbmcgb25lIHNwZWNpZmllcjogdGhlIGFic29sdXRlIHBhdGggKHVuZGVmaW5lZCB3aGVuXG4gKiB1bnJlc29sdmFibGUpIGFuZCB3aGV0aGVyIGl0IGxhbmRlZCBpbiBub2RlX21vZHVsZXMuXG4gKi9cbmludGVyZmFjZSBNb2R1bGVSZXNvbHV0aW9uIHtcblx0cmVzb2x2ZWRQYXRoPzogc3RyaW5nO1xuXHRpc0V4dGVybmFsOiBib29sZWFuO1xufVxuXG4vLyBCYXJlIGJ1aWx0aW4gbmFtZXMgZnJvbSBub2RlOm1vZHVsZTsgYm90aCAncGF0aCcgYW5kICdub2RlOnBhdGgnIGFjY2VwdGVkXG5jb25zdCBCVUlMVElOX01PRFVMRVMgPSBuZXcgU2V0KGJ1aWx0aW5Nb2R1bGVzKTtcblxuLyoqXG4gKiBNb2R1bGUtc2NvcGUgd2Fsa2VyIChpbnN0cnVtZW50YXRpb24gd2Fsa2VyIHBsYW4sIFBoYXNlIDEpLlxuICpcbiAqIEJ1aWxkcyB0aGUgY3Jvc3MtZmlsZSBtb2R1bGUgZ3JhcGg6IGV2ZXJ5IGV4cG9ydC9pbXBvcnQgYmluZGluZyAoZnVuY3Rpb25zLFxuICogY2xhc3NlcywgY29uc3RzLCB0eXBlcyDigJQgbm90IG9ubHkgbW5lbW9uaWNhIHR5cGVzKSwgcmVzb2x2ZWQgd2l0aFxuICogYHRzLnJlc29sdmVNb2R1bGVOYW1lYCBkcml2ZW4gYnkgdGhlIHByb2dyYW0ncyBjb21waWxlck9wdGlvbnMgKHRzY29uZmlnXG4gKiBgcGF0aHNgLCBleHRlbnNpb25sZXNzIGltcG9ydHMsIGluZGV4IGZpbGVzKS4gVGhpcyBpcyBtb2R1bGUgcmVzb2x1dGlvbixcbiAqIE5PVCB0aGUgdHlwZSBjaGVja2VyIOKAlCB0aGUgbm8tYGdldFR5cGVDaGVja2VyKClgIHByZWNlZGVudCBzdGF5cyBpbnRhY3QuXG4gKlxuICogVXNhZ2U6IGFkZEZpbGUoKSBwZXIgc291cmNlIGZpbGUgZHVyaW5nIHRoZSBkZWZpbml0aW9ucyBwYXNzLCB0aGVuXG4gKiBidWlsZChkZWZpbmVkVHlwZXNCeUZpbGUpIG9uY2UgZGVmaW5pdGlvbnMgYXJlIGtub3duLlxuICovXG5leHBvcnQgY2xhc3MgTW9kdWxlR3JhcGhCdWlsZGVyIHtcblx0cHJpdmF0ZSBjb21waWxlck9wdGlvbnM6IHRzLkNvbXBpbGVyT3B0aW9ucztcblx0cHJpdmF0ZSBtb2R1bGVzID0gbmV3IE1hcDxzdHJpbmcsIE1vZHVsZUluZm8+KCk7XG5cdC8vIGZpbGVQYXRoIC0+IChsb2NhbCBuYW1lIC0+IGtpbmQpIGZvciBldmVyeSBuYW1lZCB0b3AtbGV2ZWwgZGVjbGFyYXRpb25cblx0cHJpdmF0ZSBsb2NhbERlY2xzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIE1vZHVsZUJpbmRpbmdLaW5kPj4oKTtcblx0Ly8gZmlsZVBhdGggLT4gaW1wb3J0L2V4cG9ydCBzcGVjaWZpZXIgc2l0ZXMsIGZvciBidWlsZCgpLXRpbWUgcmVzb2x1dGlvblxuXHRwcml2YXRlIGltcG9ydFNpdGVzID0gbmV3IE1hcDxzdHJpbmcsIEltcG9ydFNpdGVbXT4oKTtcblx0Ly8gYCR7ZmlsZVBhdGh9XFxuJHtzcGVjaWZpZXJ9YCAtPiByZXNvbHV0aW9uICh1bmRlZmluZWQgPSBmYWlsZWQpXG5cdHByaXZhdGUgcmVzb2x1dGlvbkNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIE1vZHVsZVJlc29sdXRpb24gfCB1bmRlZmluZWQ+KCk7XG5cblx0Y29uc3RydWN0b3IgKHByb2dyYW0/OiB0cy5Qcm9ncmFtLCBjb21waWxlck9wdGlvbnM/OiB0cy5Db21waWxlck9wdGlvbnMpIHtcblx0XHRjb25zdCBvcHRpb25zID0gY29tcGlsZXJPcHRpb25zID8/IHByb2dyYW0/LmdldENvbXBpbGVyT3B0aW9ucygpID8/IHt9O1xuXHRcdHRoaXMuY29tcGlsZXJPcHRpb25zID0gb3B0aW9ucztcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmFjayBvbmUgc291cmNlIGZpbGUuIFJlLWFkZGluZyB0aGUgc2FtZSBmaWxlIHJlcGxhY2VzIGl0cyByZWNvcmQsXG5cdCAqIHNvIGEgYnVpbGRlciBtYXkgc2FmZWx5IGJlIHJldXNlZCBhY3Jvc3MgcGFzc2VzLlxuXHQgKi9cblx0YWRkRmlsZSAoc291cmNlRmlsZTogdHMuU291cmNlRmlsZSk6IE1vZHVsZUluZm8ge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuXG5cdFx0Y29uc3QgbW9kdWxlSW5mbzogTW9kdWxlSW5mbyA9IHtcblx0XHRcdGZpbGVQYXRoLFxuXHRcdFx0ZGVmaW5lZFR5cGVzICAgICAgICAgOiBbXSxcblx0XHRcdGV4cG9ydGVkQmluZGluZ3MgICAgIDogW10sXG5cdFx0XHRpbXBvcnRlZEJpbmRpbmdzICAgICA6IFtdLFxuXHRcdFx0ZGVwZW5kZW5jaWVzICAgICAgICAgOiBbXSxcblx0XHRcdHVucmVzb2x2ZWRTcGVjaWZpZXJzIDogW10sXG5cdFx0XHRidWlsdGluU3BlY2lmaWVycyAgICA6IFtdLFxuXHRcdH07XG5cdFx0Y29uc3QgZGVjbHMgPSBuZXcgTWFwPHN0cmluZywgTW9kdWxlQmluZGluZ0tpbmQ+KCk7XG5cdFx0Y29uc3Qgc2l0ZXM6IEltcG9ydFNpdGVbXSA9IFtdO1xuXG5cdFx0dGhpcy5tb2R1bGVzLnNldChmaWxlUGF0aCwgbW9kdWxlSW5mbyk7XG5cdFx0dGhpcy5sb2NhbERlY2xzLnNldChmaWxlUGF0aCwgZGVjbHMpO1xuXHRcdHRoaXMuaW1wb3J0U2l0ZXMuc2V0KGZpbGVQYXRoLCBzaXRlcyk7XG5cblx0XHQvLyBQYXNzIDE6IGNvbGxlY3QgZXZlcnkgbmFtZWQgdG9wLWxldmVsIGRlY2xhcmF0aW9uLCBzbyBsYXRlclxuXHRcdC8vIGBleHBvcnQgeyBYIH1gIHN0YXRlbWVudHMgY2FuIGJlIGNsYXNzaWZpZWQgcmVnYXJkbGVzcyBvZiBvcmRlclxuXHRcdGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIHNvdXJjZUZpbGUuc3RhdGVtZW50cykge1xuXHRcdFx0dGhpcy5jb2xsZWN0TG9jYWxEZWNsKHN0YXRlbWVudCwgZGVjbHMpO1xuXHRcdH1cblxuXHRcdC8vIFBhc3MgMjogcHJvY2VzcyBpbXBvcnRzLCBleHBvcnRzLCBhbmQgZXhwb3J0ZWQgZGVjbGFyYXRpb25zXG5cdFx0Zm9yIChjb25zdCBzdGF0ZW1lbnQgb2Ygc291cmNlRmlsZS5zdGF0ZW1lbnRzKSB7XG5cdFx0XHR0aGlzLnByb2Nlc3NTdGF0ZW1lbnQoc3RhdGVtZW50LCBzb3VyY2VGaWxlLCBtb2R1bGVJbmZvLCBkZWNscywgc2l0ZXMpO1xuXHRcdH1cblxuXHRcdHJldHVybiBtb2R1bGVJbmZvO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlc29sdmUgYWxsIHNwZWNpZmllcnMsIGJhY2tmaWxsIGJpbmRpbmcga2luZHMgZnJvbSBvcmlnaW4gbW9kdWxlcyxcblx0ICogZGVyaXZlIGRlcGVuZGVuY2llcywgY3Jvc3MtbW9kdWxlIG1uZW1vbmljYS10eXBlIGVkZ2VzLCBhbmQgY3ljbGVzLlxuXHQgKiBgZGVmaW5lZFR5cGVzQnlGaWxlYCBtYXBzIGFic29sdXRlIGZpbGUgcGF0aCAtPiBtbmVtb25pY2EgdHlwZSBmdWxsUGF0aHNcblx0ICogZGVmaW5lZCB0aGVyZSAoZnJvbSB0aGUgYW5hbHl6ZXIncyBkZWZpbml0aW9ucykuXG5cdCAqL1xuXHRidWlsZCAoZGVmaW5lZFR5cGVzQnlGaWxlPzogTWFwPHN0cmluZywgc3RyaW5nW10+KTogTW9kdWxlR3JhcGgge1xuXHRcdGlmIChkZWZpbmVkVHlwZXNCeUZpbGUpIHtcblx0XHRcdGZvciAoY29uc3QgWyBmaWxlLCB0eXBlcyBdIG9mIGRlZmluZWRUeXBlc0J5RmlsZSkge1xuXHRcdFx0XHRjb25zdCBtb2R1bGVJbmZvID0gdGhpcy5tb2R1bGVzLmdldChwYXRoLnJlc29sdmUoZmlsZSkpO1xuXHRcdFx0XHRpZiAobW9kdWxlSW5mbykge1xuXHRcdFx0XHRcdG1vZHVsZUluZm8uZGVmaW5lZFR5cGVzID0gdHlwZXM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZXNvbHV0aW9uIHBhc3M6IHJld3JpdGUgc291cmNlTW9kdWxlIHRvIHRoZSByZXNvbHZlZCBhYnNvbHV0ZSBwYXRoXG5cdFx0Zm9yIChjb25zdCBbIGZpbGVQYXRoLCBzaXRlcyBdIG9mIHRoaXMuaW1wb3J0U2l0ZXMpIHtcblx0XHRcdGNvbnN0IG1vZHVsZUluZm8gPSB0aGlzLm1vZHVsZXMuZ2V0KGZpbGVQYXRoKTtcblx0XHRcdGlmICghbW9kdWxlSW5mbykge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGZvciAoY29uc3Qgc2l0ZSBvZiBzaXRlcykge1xuXHRcdFx0XHRjb25zdCByZXNvbHV0aW9uID0gdGhpcy5yZXNvbHZlTW9kdWxlKHNpdGUuc3BlY2lmaWVyLCBmaWxlUGF0aCk7XG5cdFx0XHRcdGlmICghcmVzb2x1dGlvbj8ucmVzb2x2ZWRQYXRoKSB7XG5cdFx0XHRcdFx0aWYgKCFtb2R1bGVJbmZvLnVucmVzb2x2ZWRTcGVjaWZpZXJzLmluY2x1ZGVzKHNpdGUuc3BlY2lmaWVyKSkge1xuXHRcdFx0XHRcdFx0bW9kdWxlSW5mby51bnJlc29sdmVkU3BlY2lmaWVycy5wdXNoKHNpdGUuc3BlY2lmaWVyKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29uc3QgeyByZXNvbHZlZFBhdGgsIGlzRXh0ZXJuYWwgfSA9IHJlc29sdXRpb247XG5cdFx0XHRcdGZvciAoY29uc3QgYmluZGluZyBvZiBzaXRlLmJpbmRpbmdzKSB7XG5cdFx0XHRcdFx0YmluZGluZy5zb3VyY2VNb2R1bGUgPSByZXNvbHZlZFBhdGg7XG5cdFx0XHRcdFx0aWYgKGlzRXh0ZXJuYWwpIHtcblx0XHRcdFx0XHRcdGJpbmRpbmcuZXh0ZXJuYWwgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBEZXBlbmRlbmNpZXMgc3RheSBwcm9qZWN0LWludGVybmFsOiBleHRlcm5hbCAobm9kZV9tb2R1bGVzKVxuXHRcdFx0XHQvLyBtb2R1bGVzIGFyZSBuZXZlciBhZGRGaWxlKCknZCwgc28gbW9kdWxlcy5oYXMoKSBnYXRlcyB0aGVtIG91dFxuXHRcdFx0XHRpZiAodGhpcy5tb2R1bGVzLmhhcyhyZXNvbHZlZFBhdGgpICYmICFtb2R1bGVJbmZvLmRlcGVuZGVuY2llcy5pbmNsdWRlcyhyZXNvbHZlZFBhdGgpKSB7XG5cdFx0XHRcdFx0bW9kdWxlSW5mby5kZXBlbmRlbmNpZXMucHVzaChyZXNvbHZlZFBhdGgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gS2luZCBiYWNrZmlsbCArIGVkZ2UgY29sbGVjdGlvblxuXHRcdGNvbnN0IGVkZ2VzOiBDcm9zc01vZHVsZVVzYWdlW10gPSBbXTtcblx0XHRmb3IgKGNvbnN0IFsgZmlsZVBhdGgsIHNpdGVzIF0gb2YgdGhpcy5pbXBvcnRTaXRlcykge1xuXHRcdFx0Y29uc3QgbW9kdWxlSW5mbyA9IHRoaXMubW9kdWxlcy5nZXQoZmlsZVBhdGgpO1xuXHRcdFx0aWYgKCFtb2R1bGVJbmZvKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXHRcdFx0Zm9yIChjb25zdCBzaXRlIG9mIHNpdGVzKSB7XG5cdFx0XHRcdGZvciAoY29uc3QgYmluZGluZyBvZiBzaXRlLmJpbmRpbmdzKSB7XG5cdFx0XHRcdFx0Y29uc3Qgb3JpZ2luID0gdGhpcy5yZXNvbHZlT3JpZ2luKGJpbmRpbmcpO1xuXHRcdFx0XHRcdGlmIChvcmlnaW4gJiYgYmluZGluZy5raW5kID09PSAndW5rbm93bicpIHtcblx0XHRcdFx0XHRcdGJpbmRpbmcua2luZCA9IG9yaWdpbi5iaW5kaW5nLmtpbmQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICghb3JpZ2luIHx8IG9yaWdpbi5tb2R1bGUuZmlsZVBhdGggPT09IGZpbGVQYXRoKSB7XG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgdHlwZVBhdGggPSB0aGlzLm1hdGNoRGVmaW5lZFR5cGUob3JpZ2luLm1vZHVsZSwgYmluZGluZyk7XG5cdFx0XHRcdFx0aWYgKHR5cGVQYXRoKSB7XG5cdFx0XHRcdFx0XHRlZGdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdFx0dHlwZVBhdGgsXG5cdFx0XHRcdFx0XHRcdGRlZmluaXRpb25Nb2R1bGUgOiBvcmlnaW4ubW9kdWxlLmZpbGVQYXRoLFxuXHRcdFx0XHRcdFx0XHR1c2FnZU1vZHVsZSAgICAgIDogZmlsZVBhdGgsXG5cdFx0XHRcdFx0XHRcdHVzYWdlTG9jYXRpb24gICAgOiBzaXRlLmxvY2F0aW9uLFxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Y29uc3QgY3ljbGVzID0gdGhpcy5kZXRlY3RDeWNsZXMoKTtcblxuXHRcdGNvbnN0IGdyYXBoOiBNb2R1bGVHcmFwaCA9IHtcblx0XHRcdG1vZHVsZXMgOiB0aGlzLm1vZHVsZXMsXG5cdFx0XHRlZGdlcyxcblx0XHRcdGN5Y2xlcyxcblx0XHR9O1xuXHRcdHJldHVybiBncmFwaDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXNvbHZlIGEgc3BlY2lmaWVyIHRvIGFuIGFic29sdXRlIGZpbGUgcGF0aCB2aWEgdHMucmVzb2x2ZU1vZHVsZU5hbWVcblx0ICogd2l0aCB0aGUgcHJvZ3JhbSdzIGNvbXBpbGVyT3B0aW9ucy4gUmV0dXJucyB1bmRlZmluZWQgb24gZmFpbHVyZS5cblx0ICovXG5cdHByaXZhdGUgcmVzb2x2ZU1vZHVsZSAoc3BlY2lmaWVyOiBzdHJpbmcsIGZyb21GaWxlOiBzdHJpbmcpOiBNb2R1bGVSZXNvbHV0aW9uIHwgdW5kZWZpbmVkIHtcblx0XHRjb25zdCBjYWNoZUtleSA9IGAke2Zyb21GaWxlfVxcbiR7c3BlY2lmaWVyfWA7XG5cdFx0aWYgKHRoaXMucmVzb2x1dGlvbkNhY2hlLmhhcyhjYWNoZUtleSkpIHtcblx0XHRcdGNvbnN0IGNhY2hlZCA9IHRoaXMucmVzb2x1dGlvbkNhY2hlLmdldChjYWNoZUtleSk7XG5cdFx0XHRyZXR1cm4gY2FjaGVkO1xuXHRcdH1cblxuXHRcdGNvbnN0IHJlc3VsdCA9IHRzLnJlc29sdmVNb2R1bGVOYW1lKHNwZWNpZmllciwgZnJvbUZpbGUsIHRoaXMuY29tcGlsZXJPcHRpb25zLCB0cy5zeXMpO1xuXHRcdGNvbnN0IHJlc29sdXRpb246IE1vZHVsZVJlc29sdXRpb24gfCB1bmRlZmluZWQgPSByZXN1bHQucmVzb2x2ZWRNb2R1bGVcblx0XHRcdD8ge1xuXHRcdFx0XHRyZXNvbHZlZFBhdGggOiBwYXRoLnJlc29sdmUocmVzdWx0LnJlc29sdmVkTW9kdWxlLnJlc29sdmVkRmlsZU5hbWUpLFxuXHRcdFx0XHRpc0V4dGVybmFsICAgOiByZXN1bHQucmVzb2x2ZWRNb2R1bGUuaXNFeHRlcm5hbExpYnJhcnlJbXBvcnQgPT09IHRydWUsXG5cdFx0XHR9XG5cdFx0XHQ6IHVuZGVmaW5lZDtcblx0XHR0aGlzLnJlc29sdXRpb25DYWNoZS5zZXQoY2FjaGVLZXksIHJlc29sdXRpb24pO1xuXHRcdHJldHVybiByZXNvbHV0aW9uO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRydWUgZm9yIE5vZGUuanMgYnVpbHRpbnMgaW4gYm90aCBiYXJlIGFuZCBgbm9kZTpgLXByZWZpeGVkIGZvcm1zXG5cdCAqICgncGF0aCcsICdub2RlOnBhdGgnLCAnZnMvcHJvbWlzZXMnLCAnbm9kZTpmcy9wcm9taXNlcycsIOKApikuXG5cdCAqL1xuXHRwcml2YXRlIHN0YXRpYyBpc0J1aWx0aW5TcGVjaWZpZXIgKHNwZWNpZmllcjogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0Y29uc3QgYmFyZSA9IHNwZWNpZmllci5zdGFydHNXaXRoKCdub2RlOicpID8gc3BlY2lmaWVyLnNsaWNlKCdub2RlOicubGVuZ3RoKSA6IHNwZWNpZmllcjtcblx0XHRjb25zdCByZXN1bHQgPSBCVUlMVElOX01PRFVMRVMuaGFzKGJhcmUpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHQvKipcblx0ICogUmVjb3JkIGEgYnVpbHRpbiBpbXBvcnQgb24gdGhlIG1vZHVsZSAoaG9uZXN0eSBtYXJrZXIpIGFuZCBza2lwIGl0XG5cdCAqIGVudGlyZWx5OiBubyBiaW5kaW5ncywgbm8gc2l0ZSwgbm8gZGVwZW5kZW5jeSwgbm8gZWRnZS5cblx0ICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIHNwZWNpZmllciB3YXMgYSBidWlsdGluIChjYWxsZXIgbXVzdCByZXR1cm4gZWFybHkpLlxuXHQgKi9cblx0cHJpdmF0ZSBzdGF0aWMgc2tpcEJ1aWx0aW4gKG1vZHVsZUluZm86IE1vZHVsZUluZm8sIHNwZWNpZmllcjogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0aWYgKCFNb2R1bGVHcmFwaEJ1aWxkZXIuaXNCdWlsdGluU3BlY2lmaWVyKHNwZWNpZmllcikpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCFtb2R1bGVJbmZvLmJ1aWx0aW5TcGVjaWZpZXJzLmluY2x1ZGVzKHNwZWNpZmllcikpIHtcblx0XHRcdG1vZHVsZUluZm8uYnVpbHRpblNwZWNpZmllcnMucHVzaChzcGVjaWZpZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGFzZSBhIGJpbmRpbmcgdG8gdGhlIG1vZHVsZSB0aGF0IGFjdHVhbGx5IGRlY2xhcmVzIGl0LCBmb2xsb3dpbmdcblx0ICogcmUtZXhwb3J0IGNoYWlucyAoYmFycmVscykuIEN5Y2xlLWd1YXJkZWQuIFJldHVybnMgdW5kZWZpbmVkIHdoZW4gdGhlXG5cdCAqIG9yaWdpbiBpcyBleHRlcm5hbCBvciB0aGUgY2hhaW4gbG9vcHMuXG5cdCAqL1xuXHRwcml2YXRlIHJlc29sdmVPcmlnaW4gKFxuXHRcdGJpbmRpbmc6IE1vZHVsZUJpbmRpbmcsXG5cdFx0dmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpXG5cdCk6IHsgbW9kdWxlOiBNb2R1bGVJbmZvOyBiaW5kaW5nOiBNb2R1bGVCaW5kaW5nIH0gfCB1bmRlZmluZWQge1xuXHRcdGNvbnN0IHNvdXJjZVBhdGggPSBwYXRoLnJlc29sdmUoYmluZGluZy5zb3VyY2VNb2R1bGUpO1xuXHRcdGlmICh2aXNpdGVkLmhhcyhzb3VyY2VQYXRoKSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dmlzaXRlZC5hZGQoc291cmNlUGF0aCk7XG5cblx0XHRjb25zdCBzb3VyY2VNb2R1bGVJbmZvID0gdGhpcy5tb2R1bGVzLmdldChzb3VyY2VQYXRoKTtcblx0XHRpZiAoIXNvdXJjZU1vZHVsZUluZm8pIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gVGhlIG5hbWUgdG8gbG9vayB1cCBpbiB0aGUgc291cmNlIG1vZHVsZSdzIGV4cG9ydCBsaXN0XG5cdFx0Y29uc3QgbG9va3VwS2V5ID0gYmluZGluZy5pbXBvcnRLaW5kID09PSAnZGVmYXVsdCdcblx0XHRcdD8gJ2RlZmF1bHQnXG5cdFx0XHQ6IGJpbmRpbmcuaW1wb3J0QWxpYXMgPz8gYmluZGluZy5uYW1lO1xuXG5cdFx0Zm9yIChjb25zdCBleHBvcnRlZCBvZiBzb3VyY2VNb2R1bGVJbmZvLmV4cG9ydGVkQmluZGluZ3MpIHtcblx0XHRcdGlmIChleHBvcnRlZC5uYW1lICE9PSBsb29rdXBLZXkpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIWV4cG9ydGVkLmlzUmVFeHBvcnQpIHtcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0geyBtb2R1bGUgOiBzb3VyY2VNb2R1bGVJbmZvLCBiaW5kaW5nIDogZXhwb3J0ZWQgfTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGNoYXNlZCA9IHRoaXMucmVzb2x2ZU9yaWdpbihleHBvcnRlZCwgdmlzaXRlZCk7XG5cdFx0XHRyZXR1cm4gY2hhc2VkO1xuXHRcdH1cblxuXHRcdC8vIGBleHBvcnQgKiBmcm9tICcuL3knYCBiYXJyZWxzOiB0aGUgbmFtZSBtYXkgbGl2ZSBiZWhpbmQgYSBzdGFyXG5cdFx0Zm9yIChjb25zdCBleHBvcnRlZCBvZiBzb3VyY2VNb2R1bGVJbmZvLmV4cG9ydGVkQmluZGluZ3MpIHtcblx0XHRcdGlmICghZXhwb3J0ZWQuaXNSZUV4cG9ydCB8fCBleHBvcnRlZC5pbXBvcnRLaW5kICE9PSAnbmFtZXNwYWNlJyB8fCBleHBvcnRlZC5uYW1lICE9PSAnKicpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBjaGFzZWQgPSB0aGlzLnJlc29sdmVPcmlnaW4oe1xuXHRcdFx0XHRuYW1lICAgICAgICAgOiBsb29rdXBLZXksXG5cdFx0XHRcdGtpbmQgICAgICAgICA6ICd1bmtub3duJyxcblx0XHRcdFx0c291cmNlTW9kdWxlIDogZXhwb3J0ZWQuc291cmNlTW9kdWxlLFxuXHRcdFx0XHRpc1JlRXhwb3J0ICAgOiB0cnVlLFxuXHRcdFx0fSwgdmlzaXRlZCk7XG5cdFx0XHRpZiAoY2hhc2VkKSB7XG5cdFx0XHRcdHJldHVybiBjaGFzZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXRjaCBhIGJpbmRpbmcgYWdhaW5zdCBhIG1vZHVsZSdzIGRlZmluZWQgbW5lbW9uaWNhIHR5cGVzLlxuXHQgKiBSZXR1cm5zIHRoZSBtYXRjaGVkIGZ1bGxQYXRoLCBvciB1bmRlZmluZWQgd2hlbiB0aGUgYmluZGluZyBpcyBub3QgYVxuXHQgKiBtbmVtb25pY2EgdHlwZSBvZiB0aGF0IG1vZHVsZS5cblx0ICovXG5cdHByaXZhdGUgbWF0Y2hEZWZpbmVkVHlwZSAobW9kdWxlSW5mbzogTW9kdWxlSW5mbywgYmluZGluZzogTW9kdWxlQmluZGluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG5cdFx0Y29uc3QgY2FuZGlkYXRlID0gYmluZGluZy5pbXBvcnRBbGlhcyA/PyBiaW5kaW5nLm5hbWU7XG5cdFx0Zm9yIChjb25zdCBkZWZpbmVkVHlwZSBvZiBtb2R1bGVJbmZvLmRlZmluZWRUeXBlcykge1xuXHRcdFx0Ly8gQ3VzdG9tLWNvbGxlY3Rpb24gdHlwZXMgYXJlIGtleWVkIGBjb2xsZWN0aW9uSWQ6OlBhdGhgXG5cdFx0XHRjb25zdCBiYXJlID0gZGVmaW5lZFR5cGUuaW5jbHVkZXMoJzo6Jylcblx0XHRcdFx0PyBkZWZpbmVkVHlwZS5zbGljZShkZWZpbmVkVHlwZS5pbmRleE9mKCc6OicpICsgMilcblx0XHRcdFx0OiBkZWZpbmVkVHlwZTtcblx0XHRcdGlmIChiYXJlID09PSBjYW5kaWRhdGUgfHwgYmFyZS5zdGFydHNXaXRoKGAke2NhbmRpZGF0ZSAgfS5gKSkge1xuXHRcdFx0XHRyZXR1cm4gZGVmaW5lZFR5cGU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKipcblx0ICogVGhyZWUtY29sb3IgREZTIG92ZXIgcHJvamVjdC1pbnRlcm5hbCBkZXBlbmRlbmNpZXMuIEN5Y2xlcyBhcmUgcmVjb3JkZWRcblx0ICogKG1uZW1vbmljYSBzdHJpY3RDaGFpbjpmYWxzZSBwZXJtaXRzIG5vbi1saW5lYXIgY29uc3RydWN0aW9uKSwgbmV2ZXJcblx0ICogdHJlYXRlZCBhcyBlcnJvcnMuXG5cdCAqL1xuXHRwcml2YXRlIGRldGVjdEN5Y2xlcyAoKTogc3RyaW5nW11bXSB7XG5cdFx0Y29uc3QgY3ljbGVzOiBzdHJpbmdbXVtdID0gW107XG5cdFx0Y29uc3Qgc2VlbkN5Y2xlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXHRcdC8vIDEgPSBvbiB0aGUgY3VycmVudCBzdGFjaywgMiA9IGZ1bGx5IGV4cGxvcmVkXG5cdFx0Y29uc3Qgc3RhdGUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5cdFx0Y29uc3QgdmlzaXQgPSAoZmlsZVBhdGg6IHN0cmluZywgc3RhY2s6IHN0cmluZ1tdKTogdm9pZCA9PiB7XG5cdFx0XHRzdGF0ZS5zZXQoZmlsZVBhdGgsIDEpO1xuXHRcdFx0c3RhY2sucHVzaChmaWxlUGF0aCk7XG5cblx0XHRcdGNvbnN0IG1vZHVsZUluZm8gPSB0aGlzLm1vZHVsZXMuZ2V0KGZpbGVQYXRoKTtcblx0XHRcdGZvciAoY29uc3QgZGVwIG9mIG1vZHVsZUluZm8/LmRlcGVuZGVuY2llcyA/PyBbXSkge1xuXHRcdFx0XHRpZiAoc3RhdGUuZ2V0KGRlcCkgPT09IDEpIHtcblx0XHRcdFx0XHRjb25zdCBjeWNsZSA9IHN0YWNrLnNsaWNlKHN0YWNrLmluZGV4T2YoZGVwKSk7XG5cdFx0XHRcdFx0Y29uc3Qga2V5ID0gTW9kdWxlR3JhcGhCdWlsZGVyLmN5Y2xlS2V5KGN5Y2xlKTtcblx0XHRcdFx0XHRpZiAoIXNlZW5DeWNsZXMuaGFzKGtleSkpIHtcblx0XHRcdFx0XHRcdHNlZW5DeWNsZXMuYWRkKGtleSk7XG5cdFx0XHRcdFx0XHRjeWNsZXMucHVzaChjeWNsZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICghc3RhdGUuZ2V0KGRlcCkpIHtcblx0XHRcdFx0XHR2aXNpdChkZXAsIHN0YWNrKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRzdGFjay5wb3AoKTtcblx0XHRcdHN0YXRlLnNldChmaWxlUGF0aCwgMik7XG5cdFx0fTtcblxuXHRcdGZvciAoY29uc3QgZmlsZVBhdGggb2YgdGhpcy5tb2R1bGVzLmtleXMoKSkge1xuXHRcdFx0aWYgKCFzdGF0ZS5nZXQoZmlsZVBhdGgpKSB7XG5cdFx0XHRcdHZpc2l0KGZpbGVQYXRoLCBbXSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGN5Y2xlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSb3RhdGlvbi1pbmRlcGVuZGVudCBjeWNsZSBrZXk6IHNtYWxsZXN0IHBhdGggZmlyc3QuXG5cdCAqL1xuXHRwcml2YXRlIHN0YXRpYyBjeWNsZUtleSAoY3ljbGU6IHN0cmluZ1tdKTogc3RyaW5nIHtcblx0XHRsZXQgbWluSW5kZXggPSAwO1xuXHRcdGZvciAobGV0IGkgPSAxOyBpIDwgY3ljbGUubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChjeWNsZVsgaSBdIDwgY3ljbGVbIG1pbkluZGV4IF0pIHtcblx0XHRcdFx0bWluSW5kZXggPSBpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRjb25zdCByb3RhdGVkID0gY3ljbGUuc2xpY2UobWluSW5kZXgpLmNvbmNhdChjeWNsZS5zbGljZSgwLCBtaW5JbmRleCkpO1xuXHRcdGNvbnN0IGtleSA9IHJvdGF0ZWQuam9pbignXFxuJyk7XG5cdFx0cmV0dXJuIGtleTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXNzIDE6IHJlY29yZCBldmVyeSBuYW1lZCB0b3AtbGV2ZWwgZGVjbGFyYXRpb24ncyBraW5kLlxuXHQgKi9cblx0cHJpdmF0ZSBjb2xsZWN0TG9jYWxEZWNsIChzdGF0ZW1lbnQ6IHRzLlN0YXRlbWVudCwgZGVjbHM6IE1hcDxzdHJpbmcsIE1vZHVsZUJpbmRpbmdLaW5kPik6IHZvaWQge1xuXHRcdGlmICh0cy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24oc3RhdGVtZW50KSAmJiBzdGF0ZW1lbnQubmFtZSkge1xuXHRcdFx0ZGVjbHMuc2V0KHN0YXRlbWVudC5uYW1lLnRleHQsICdmdW5jdGlvbicpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKHN0YXRlbWVudCkgJiYgc3RhdGVtZW50Lm5hbWUpIHtcblx0XHRcdGRlY2xzLnNldChzdGF0ZW1lbnQubmFtZS50ZXh0LCAnY2xhc3MnKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aWYgKHRzLmlzSW50ZXJmYWNlRGVjbGFyYXRpb24oc3RhdGVtZW50KSB8fCB0cy5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKHN0YXRlbWVudCkpIHtcblx0XHRcdGRlY2xzLnNldChzdGF0ZW1lbnQubmFtZS50ZXh0LCAndHlwZScpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodHMuaXNFbnVtRGVjbGFyYXRpb24oc3RhdGVtZW50KSkge1xuXHRcdFx0ZGVjbHMuc2V0KHN0YXRlbWVudC5uYW1lLnRleHQsICd0eXBlJyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmICh0cy5pc1ZhcmlhYmxlU3RhdGVtZW50KHN0YXRlbWVudCkpIHtcblx0XHRcdGZvciAoY29uc3QgZGVjbCBvZiBzdGF0ZW1lbnQuZGVjbGFyYXRpb25MaXN0LmRlY2xhcmF0aW9ucykge1xuXHRcdFx0XHRpZiAodHMuaXNJZGVudGlmaWVyKGRlY2wubmFtZSkpIHtcblx0XHRcdFx0XHRkZWNscy5zZXQoZGVjbC5uYW1lLnRleHQsIE1vZHVsZUdyYXBoQnVpbGRlci52YXJpYWJsZUtpbmQoZGVjbCkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENsYXNzaWZ5IGEgdmFyaWFibGUgZGVjbGFyYXRpb246IGFycm93L2Z1bmN0aW9uIGluaXRpYWxpemVycyBhcmVcblx0ICogJ2Z1bmN0aW9uJyAoaG9sZGVyIGZ1bmN0aW9ucyB0aGUgd2Fsa2VyIGZvbGxvd3MpLCBjbGFzcyBleHByZXNzaW9uc1xuXHQgKiBhcmUgJ2NsYXNzJywgZXZlcnl0aGluZyBlbHNlIGlzICdjb25zdCcuXG5cdCAqL1xuXHRwcml2YXRlIHN0YXRpYyB2YXJpYWJsZUtpbmQgKGRlY2w6IHRzLlZhcmlhYmxlRGVjbGFyYXRpb24pOiBNb2R1bGVCaW5kaW5nS2luZCB7XG5cdFx0Y29uc3QgeyBpbml0aWFsaXplciB9ID0gZGVjbDtcblx0XHRpZiAoaW5pdGlhbGl6ZXIgJiYgKHRzLmlzQXJyb3dGdW5jdGlvbihpbml0aWFsaXplcikgfHwgdHMuaXNGdW5jdGlvbkV4cHJlc3Npb24oaW5pdGlhbGl6ZXIpKSkge1xuXHRcdFx0cmV0dXJuICdmdW5jdGlvbic7XG5cdFx0fVxuXHRcdGlmIChpbml0aWFsaXplciAmJiB0cy5pc0NsYXNzRXhwcmVzc2lvbihpbml0aWFsaXplcikpIHtcblx0XHRcdHJldHVybiAnY2xhc3MnO1xuXHRcdH1cblx0XHRyZXR1cm4gJ2NvbnN0Jztcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXNzIDI6IGltcG9ydHMsIGV4cG9ydHMsIHJlcXVpcmVzLCBleHBvcnRlZCBkZWNsYXJhdGlvbnMuXG5cdCAqL1xuXHRwcml2YXRlIHByb2Nlc3NTdGF0ZW1lbnQgKFxuXHRcdHN0YXRlbWVudDogdHMuU3RhdGVtZW50LFxuXHRcdHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG5cdFx0bW9kdWxlSW5mbzogTW9kdWxlSW5mbyxcblx0XHRkZWNsczogTWFwPHN0cmluZywgTW9kdWxlQmluZGluZ0tpbmQ+LFxuXHRcdHNpdGVzOiBJbXBvcnRTaXRlW11cblx0KTogdm9pZCB7XG5cdFx0aWYgKHRzLmlzSW1wb3J0RGVjbGFyYXRpb24oc3RhdGVtZW50KSkge1xuXHRcdFx0dGhpcy5wcm9jZXNzSW1wb3J0KHN0YXRlbWVudCwgc291cmNlRmlsZSwgbW9kdWxlSW5mbywgc2l0ZXMpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodHMuaXNFeHBvcnREZWNsYXJhdGlvbihzdGF0ZW1lbnQpKSB7XG5cdFx0XHR0aGlzLnByb2Nlc3NFeHBvcnREZWNsYXJhdGlvbihzdGF0ZW1lbnQsIHNvdXJjZUZpbGUsIG1vZHVsZUluZm8sIGRlY2xzLCBzaXRlcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmICh0cy5pc0ltcG9ydEVxdWFsc0RlY2xhcmF0aW9uKHN0YXRlbWVudCkpIHtcblx0XHRcdHRoaXMucHJvY2Vzc0ltcG9ydEVxdWFscyhzdGF0ZW1lbnQsIHNvdXJjZUZpbGUsIG1vZHVsZUluZm8sIHNpdGVzKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aWYgKHRzLmlzRXhwb3J0QXNzaWdubWVudChzdGF0ZW1lbnQpKSB7XG5cdFx0XHR0aGlzLnByb2Nlc3NFeHBvcnRBc3NpZ25tZW50KHN0YXRlbWVudCwgbW9kdWxlSW5mbywgZGVjbHMpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLnByb2Nlc3NNYXliZUV4cG9ydGVkRGVjbChzdGF0ZW1lbnQsIG1vZHVsZUluZm8sIGRlY2xzKTtcblx0XHR0aGlzLnByb2Nlc3NSZXF1aXJlQ2FsbChzdGF0ZW1lbnQsIHNvdXJjZUZpbGUsIG1vZHVsZUluZm8sIHNpdGVzKTtcblx0fVxuXG5cdHByaXZhdGUgcHJvY2Vzc0ltcG9ydCAoXG5cdFx0aW1wb3J0RGVjbDogdHMuSW1wb3J0RGVjbGFyYXRpb24sXG5cdFx0c291cmNlRmlsZTogdHMuU291cmNlRmlsZSxcblx0XHRtb2R1bGVJbmZvOiBNb2R1bGVJbmZvLFxuXHRcdHNpdGVzOiBJbXBvcnRTaXRlW11cblx0KTogdm9pZCB7XG5cdFx0Y29uc3QgeyBtb2R1bGVTcGVjaWZpZXIgfSA9IGltcG9ydERlY2w7XG5cdFx0aWYgKCF0cy5pc1N0cmluZ0xpdGVyYWwobW9kdWxlU3BlY2lmaWVyKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAoTW9kdWxlR3JhcGhCdWlsZGVyLnNraXBCdWlsdGluKG1vZHVsZUluZm8sIG1vZHVsZVNwZWNpZmllci50ZXh0KSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHNpdGU6IEltcG9ydFNpdGUgPSB7XG5cdFx0XHRzcGVjaWZpZXIgOiBtb2R1bGVTcGVjaWZpZXIudGV4dCxcblx0XHRcdGxvY2F0aW9uICA6IHRoaXMubG9jYXRpb25PZihtb2R1bGVTcGVjaWZpZXIsIHNvdXJjZUZpbGUpLFxuXHRcdFx0YmluZGluZ3MgIDogW10sXG5cdFx0fTtcblx0XHRzaXRlcy5wdXNoKHNpdGUpO1xuXG5cdFx0Y29uc3QgeyBpbXBvcnRDbGF1c2UgfSA9IGltcG9ydERlY2w7XG5cdFx0aWYgKCFpbXBvcnRDbGF1c2UpIHtcblx0XHRcdC8vIFNpZGUtZWZmZWN0IGltcG9ydDogZGVwZW5kZW5jeSBvbmx5LCBubyBiaW5kaW5nc1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERlZmF1bHQgaW1wb3J0OiBpbXBvcnQgVHlwZSBmcm9tICcuL21vZHVsZSdcblx0XHRpZiAoaW1wb3J0Q2xhdXNlLm5hbWUpIHtcblx0XHRcdGNvbnN0IGJpbmRpbmc6IE1vZHVsZUJpbmRpbmcgPSB7XG5cdFx0XHRcdG5hbWUgICAgICAgICA6IGltcG9ydENsYXVzZS5uYW1lLnRleHQsXG5cdFx0XHRcdGtpbmQgICAgICAgICA6ICd1bmtub3duJyxcblx0XHRcdFx0c291cmNlTW9kdWxlIDogc2l0ZS5zcGVjaWZpZXIsXG5cdFx0XHRcdGltcG9ydEtpbmQgICA6ICdkZWZhdWx0Jyxcblx0XHRcdFx0aXNSZUV4cG9ydCAgIDogZmFsc2UsXG5cdFx0XHR9O1xuXHRcdFx0bW9kdWxlSW5mby5pbXBvcnRlZEJpbmRpbmdzLnB1c2goYmluZGluZyk7XG5cdFx0XHRzaXRlLmJpbmRpbmdzLnB1c2goYmluZGluZyk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgeyBuYW1lZEJpbmRpbmdzIH0gPSBpbXBvcnRDbGF1c2U7XG5cdFx0aWYgKG5hbWVkQmluZGluZ3MgJiYgdHMuaXNOYW1lZEltcG9ydHMobmFtZWRCaW5kaW5ncykpIHtcblx0XHRcdGZvciAoY29uc3QgZWxlbWVudCBvZiBuYW1lZEJpbmRpbmdzLmVsZW1lbnRzKSB7XG5cdFx0XHRcdGNvbnN0IG9yaWdpbmFsTmFtZSA9IGVsZW1lbnQucHJvcGVydHlOYW1lPy50ZXh0O1xuXHRcdFx0XHRjb25zdCBiaW5kaW5nOiBNb2R1bGVCaW5kaW5nID0ge1xuXHRcdFx0XHRcdG5hbWUgICAgICAgICA6IGVsZW1lbnQubmFtZS50ZXh0LFxuXHRcdFx0XHRcdGtpbmQgICAgICAgICA6ICd1bmtub3duJyxcblx0XHRcdFx0XHRzb3VyY2VNb2R1bGUgOiBzaXRlLnNwZWNpZmllcixcblx0XHRcdFx0XHRpbXBvcnRLaW5kICAgOiAnbmFtZWQnLFxuXHRcdFx0XHRcdGlzUmVFeHBvcnQgICA6IGZhbHNlLFxuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAob3JpZ2luYWxOYW1lKSB7XG5cdFx0XHRcdFx0YmluZGluZy5pbXBvcnRBbGlhcyA9IG9yaWdpbmFsTmFtZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRtb2R1bGVJbmZvLmltcG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdFx0c2l0ZS5iaW5kaW5ncy5wdXNoKGJpbmRpbmcpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE5hbWVzcGFjZSBpbXBvcnQ6IGltcG9ydCAqIGFzIFR5cGVzIGZyb20gJy4vbW9kdWxlJ1xuXHRcdGlmIChuYW1lZEJpbmRpbmdzICYmIHRzLmlzTmFtZXNwYWNlSW1wb3J0KG5hbWVkQmluZGluZ3MpKSB7XG5cdFx0XHRjb25zdCBiaW5kaW5nOiBNb2R1bGVCaW5kaW5nID0ge1xuXHRcdFx0XHRuYW1lICAgICAgICAgOiBuYW1lZEJpbmRpbmdzLm5hbWUudGV4dCxcblx0XHRcdFx0a2luZCAgICAgICAgIDogJ3Vua25vd24nLFxuXHRcdFx0XHRzb3VyY2VNb2R1bGUgOiBzaXRlLnNwZWNpZmllcixcblx0XHRcdFx0aW1wb3J0S2luZCAgIDogJ25hbWVzcGFjZScsXG5cdFx0XHRcdGlzUmVFeHBvcnQgICA6IGZhbHNlLFxuXHRcdFx0fTtcblx0XHRcdG1vZHVsZUluZm8uaW1wb3J0ZWRCaW5kaW5ncy5wdXNoKGJpbmRpbmcpO1xuXHRcdFx0c2l0ZS5iaW5kaW5ncy5wdXNoKGJpbmRpbmcpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgcHJvY2Vzc0V4cG9ydERlY2xhcmF0aW9uIChcblx0XHRleHBvcnREZWNsOiB0cy5FeHBvcnREZWNsYXJhdGlvbixcblx0XHRzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlLFxuXHRcdG1vZHVsZUluZm86IE1vZHVsZUluZm8sXG5cdFx0ZGVjbHM6IE1hcDxzdHJpbmcsIE1vZHVsZUJpbmRpbmdLaW5kPixcblx0XHRzaXRlczogSW1wb3J0U2l0ZVtdXG5cdCk6IHZvaWQge1xuXHRcdGNvbnN0IHsgbW9kdWxlU3BlY2lmaWVyIH0gPSBleHBvcnREZWNsO1xuXHRcdGNvbnN0IHsgZXhwb3J0Q2xhdXNlIH0gPSBleHBvcnREZWNsO1xuXG5cdFx0Ly8gUmUtZXhwb3J0IGZvcm1zIGNhcnJ5IGEgbW9kdWxlIHNwZWNpZmllcjogYGV4cG9ydCDigKYgZnJvbSAnLi95J2Bcblx0XHRpZiAobW9kdWxlU3BlY2lmaWVyICYmIHRzLmlzU3RyaW5nTGl0ZXJhbChtb2R1bGVTcGVjaWZpZXIpKSB7XG5cdFx0XHRpZiAoTW9kdWxlR3JhcGhCdWlsZGVyLnNraXBCdWlsdGluKG1vZHVsZUluZm8sIG1vZHVsZVNwZWNpZmllci50ZXh0KSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHNpdGU6IEltcG9ydFNpdGUgPSB7XG5cdFx0XHRcdHNwZWNpZmllciA6IG1vZHVsZVNwZWNpZmllci50ZXh0LFxuXHRcdFx0XHRsb2NhdGlvbiAgOiB0aGlzLmxvY2F0aW9uT2YobW9kdWxlU3BlY2lmaWVyLCBzb3VyY2VGaWxlKSxcblx0XHRcdFx0YmluZGluZ3MgIDogW10sXG5cdFx0XHR9O1xuXHRcdFx0c2l0ZXMucHVzaChzaXRlKTtcblxuXHRcdFx0aWYgKCFleHBvcnRDbGF1c2UpIHtcblx0XHRcdFx0Ly8gYGV4cG9ydCAqIGZyb20gJy4veSdgXG5cdFx0XHRcdGNvbnN0IGJpbmRpbmc6IE1vZHVsZUJpbmRpbmcgPSB7XG5cdFx0XHRcdFx0bmFtZSAgICAgICAgIDogJyonLFxuXHRcdFx0XHRcdGtpbmQgICAgICAgICA6ICd1bmtub3duJyxcblx0XHRcdFx0XHRzb3VyY2VNb2R1bGUgOiBzaXRlLnNwZWNpZmllcixcblx0XHRcdFx0XHRpbXBvcnRLaW5kICAgOiAnbmFtZXNwYWNlJyxcblx0XHRcdFx0XHRpc1JlRXhwb3J0ICAgOiB0cnVlLFxuXHRcdFx0XHR9O1xuXHRcdFx0XHRtb2R1bGVJbmZvLmV4cG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdFx0bW9kdWxlSW5mby5pbXBvcnRlZEJpbmRpbmdzLnB1c2goYmluZGluZyk7XG5cdFx0XHRcdHNpdGUuYmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodHMuaXNOYW1lc3BhY2VFeHBvcnQoZXhwb3J0Q2xhdXNlKSkge1xuXHRcdFx0XHQvLyBgZXhwb3J0ICogYXMgbnMgZnJvbSAnLi95J2Bcblx0XHRcdFx0Y29uc3QgYmluZGluZzogTW9kdWxlQmluZGluZyA9IHtcblx0XHRcdFx0XHRuYW1lICAgICAgICAgOiBleHBvcnRDbGF1c2UubmFtZS50ZXh0LFxuXHRcdFx0XHRcdGtpbmQgICAgICAgICA6ICd1bmtub3duJyxcblx0XHRcdFx0XHRzb3VyY2VNb2R1bGUgOiBzaXRlLnNwZWNpZmllcixcblx0XHRcdFx0XHRpbXBvcnRLaW5kICAgOiAnbmFtZXNwYWNlJyxcblx0XHRcdFx0XHRpc1JlRXhwb3J0ICAgOiB0cnVlLFxuXHRcdFx0XHR9O1xuXHRcdFx0XHRtb2R1bGVJbmZvLmV4cG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdFx0bW9kdWxlSW5mby5pbXBvcnRlZEJpbmRpbmdzLnB1c2goYmluZGluZyk7XG5cdFx0XHRcdHNpdGUuYmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBgZXhwb3J0IHsgWCwgWSBhcyBaIH0gZnJvbSAnLi95J2Bcblx0XHRcdGZvciAoY29uc3QgZWxlbWVudCBvZiBleHBvcnRDbGF1c2UuZWxlbWVudHMpIHtcblx0XHRcdFx0Y29uc3Qgb3JpZ2luYWxOYW1lID0gZWxlbWVudC5wcm9wZXJ0eU5hbWU/LnRleHQ7XG5cdFx0XHRcdGNvbnN0IGJpbmRpbmc6IE1vZHVsZUJpbmRpbmcgPSB7XG5cdFx0XHRcdFx0bmFtZSAgICAgICAgIDogZWxlbWVudC5uYW1lLnRleHQsXG5cdFx0XHRcdFx0a2luZCAgICAgICAgIDogJ3Vua25vd24nLFxuXHRcdFx0XHRcdHNvdXJjZU1vZHVsZSA6IHNpdGUuc3BlY2lmaWVyLFxuXHRcdFx0XHRcdGltcG9ydEtpbmQgICA6ICduYW1lZCcsXG5cdFx0XHRcdFx0aXNSZUV4cG9ydCAgIDogdHJ1ZSxcblx0XHRcdFx0fTtcblx0XHRcdFx0aWYgKG9yaWdpbmFsTmFtZSkge1xuXHRcdFx0XHRcdGJpbmRpbmcuaW1wb3J0QWxpYXMgPSBvcmlnaW5hbE5hbWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0bW9kdWxlSW5mby5leHBvcnRlZEJpbmRpbmdzLnB1c2goYmluZGluZyk7XG5cdFx0XHRcdG1vZHVsZUluZm8uaW1wb3J0ZWRCaW5kaW5ncy5wdXNoKGJpbmRpbmcpO1xuXHRcdFx0XHRzaXRlLmJpbmRpbmdzLnB1c2goYmluZGluZyk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUGxhaW4gYGV4cG9ydCB7IFgsIFkgYXMgWiB9YCDigJQgbG9jYWwgZGVjbGFyYXRpb25zXG5cdFx0aWYgKGV4cG9ydENsYXVzZSAmJiB0cy5pc05hbWVkRXhwb3J0cyhleHBvcnRDbGF1c2UpKSB7XG5cdFx0XHRmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZXhwb3J0Q2xhdXNlLmVsZW1lbnRzKSB7XG5cdFx0XHRcdGNvbnN0IG9yaWdpbmFsTmFtZSA9IGVsZW1lbnQucHJvcGVydHlOYW1lPy50ZXh0ID8/IGVsZW1lbnQubmFtZS50ZXh0O1xuXHRcdFx0XHRjb25zdCBiaW5kaW5nOiBNb2R1bGVCaW5kaW5nID0ge1xuXHRcdFx0XHRcdG5hbWUgICAgICAgICA6IGVsZW1lbnQubmFtZS50ZXh0LFxuXHRcdFx0XHRcdGtpbmQgICAgICAgICA6IGRlY2xzLmdldChvcmlnaW5hbE5hbWUpID8/ICd1bmtub3duJyxcblx0XHRcdFx0XHRzb3VyY2VNb2R1bGUgOiBtb2R1bGVJbmZvLmZpbGVQYXRoLFxuXHRcdFx0XHRcdGlzUmVFeHBvcnQgICA6IGZhbHNlLFxuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAoZWxlbWVudC5wcm9wZXJ0eU5hbWUpIHtcblx0XHRcdFx0XHRiaW5kaW5nLmltcG9ydEFsaWFzID0gZWxlbWVudC5wcm9wZXJ0eU5hbWUudGV4dDtcblx0XHRcdFx0fVxuXHRcdFx0XHRtb2R1bGVJbmZvLmV4cG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogYGltcG9ydCBmb28gPSByZXF1aXJlKCcuL3knKWBcblx0ICovXG5cdHByaXZhdGUgcHJvY2Vzc0ltcG9ydEVxdWFscyAoXG5cdFx0aW1wb3J0RGVjbDogdHMuSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24sXG5cdFx0c291cmNlRmlsZTogdHMuU291cmNlRmlsZSxcblx0XHRtb2R1bGVJbmZvOiBNb2R1bGVJbmZvLFxuXHRcdHNpdGVzOiBJbXBvcnRTaXRlW11cblx0KTogdm9pZCB7XG5cdFx0Y29uc3QgeyBtb2R1bGVSZWZlcmVuY2UgfSA9IGltcG9ydERlY2w7XG5cdFx0aWYgKCF0cy5pc0V4dGVybmFsTW9kdWxlUmVmZXJlbmNlKG1vZHVsZVJlZmVyZW5jZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Y29uc3QgeyBleHByZXNzaW9uIH0gPSBtb2R1bGVSZWZlcmVuY2U7XG5cdFx0aWYgKCF0cy5pc1N0cmluZ0xpdGVyYWwoZXhwcmVzc2lvbikpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aWYgKE1vZHVsZUdyYXBoQnVpbGRlci5za2lwQnVpbHRpbihtb2R1bGVJbmZvLCBleHByZXNzaW9uLnRleHQpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgYmluZGluZzogTW9kdWxlQmluZGluZyA9IHtcblx0XHRcdG5hbWUgICAgICAgICA6IGltcG9ydERlY2wubmFtZS50ZXh0LFxuXHRcdFx0a2luZCAgICAgICAgIDogJ3Vua25vd24nLFxuXHRcdFx0c291cmNlTW9kdWxlIDogZXhwcmVzc2lvbi50ZXh0LFxuXHRcdFx0aW1wb3J0S2luZCAgIDogJ3JlcXVpcmUnLFxuXHRcdFx0aXNSZUV4cG9ydCAgIDogZmFsc2UsXG5cdFx0fTtcblx0XHRtb2R1bGVJbmZvLmltcG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRzaXRlcy5wdXNoKHtcblx0XHRcdHNwZWNpZmllciA6IGV4cHJlc3Npb24udGV4dCxcblx0XHRcdGxvY2F0aW9uICA6IHRoaXMubG9jYXRpb25PZihleHByZXNzaW9uLCBzb3VyY2VGaWxlKSxcblx0XHRcdGJpbmRpbmdzICA6IFsgYmluZGluZyBdLFxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIGBleHBvcnQgZGVmYXVsdCA8ZXhwcmVzc2lvbj5gXG5cdCAqL1xuXHRwcml2YXRlIHByb2Nlc3NFeHBvcnRBc3NpZ25tZW50IChcblx0XHRzdGF0ZW1lbnQ6IHRzLkV4cG9ydEFzc2lnbm1lbnQsXG5cdFx0bW9kdWxlSW5mbzogTW9kdWxlSW5mbyxcblx0XHRkZWNsczogTWFwPHN0cmluZywgTW9kdWxlQmluZGluZ0tpbmQ+XG5cdCk6IHZvaWQge1xuXHRcdGNvbnN0IHsgZXhwcmVzc2lvbiB9ID0gc3RhdGVtZW50O1xuXHRcdGNvbnN0IGtpbmQgPSB0cy5pc0lkZW50aWZpZXIoZXhwcmVzc2lvbilcblx0XHRcdD8gZGVjbHMuZ2V0KGV4cHJlc3Npb24udGV4dCkgPz8gJ3Vua25vd24nXG5cdFx0XHQ6ICd1bmtub3duJztcblx0XHRjb25zdCBiaW5kaW5nOiBNb2R1bGVCaW5kaW5nID0ge1xuXHRcdFx0bmFtZSAgICAgICAgIDogJ2RlZmF1bHQnLFxuXHRcdFx0a2luZCxcblx0XHRcdHNvdXJjZU1vZHVsZSA6IG1vZHVsZUluZm8uZmlsZVBhdGgsXG5cdFx0XHRpbXBvcnRLaW5kICAgOiAnZGVmYXVsdCcsXG5cdFx0XHRpc1JlRXhwb3J0ICAgOiBmYWxzZSxcblx0XHR9O1xuXHRcdGlmICh0cy5pc0lkZW50aWZpZXIoZXhwcmVzc2lvbikpIHtcblx0XHRcdGJpbmRpbmcuaW1wb3J0QWxpYXMgPSBleHByZXNzaW9uLnRleHQ7XG5cdFx0fVxuXHRcdG1vZHVsZUluZm8uZXhwb3J0ZWRCaW5kaW5ncy5wdXNoKGJpbmRpbmcpO1xuXHR9XG5cblx0LyoqXG5cdCAqIGBleHBvcnQgZnVuY3Rpb24vY2xhc3MvY29uc3QvaW50ZXJmYWNlL3R5cGUg4oCmYCBkZWNsYXJhdGlvbnMuXG5cdCAqL1xuXHRwcml2YXRlIHByb2Nlc3NNYXliZUV4cG9ydGVkRGVjbCAoXG5cdFx0c3RhdGVtZW50OiB0cy5TdGF0ZW1lbnQsXG5cdFx0bW9kdWxlSW5mbzogTW9kdWxlSW5mbyxcblx0XHRkZWNsczogTWFwPHN0cmluZywgTW9kdWxlQmluZGluZ0tpbmQ+XG5cdCk6IHZvaWQge1xuXHRcdGNvbnN0IG1vZGlmaWVycyA9IHRzLmNhbkhhdmVNb2RpZmllcnMoc3RhdGVtZW50KSA/IHRzLmdldE1vZGlmaWVycyhzdGF0ZW1lbnQpIDogdW5kZWZpbmVkO1xuXHRcdGNvbnN0IGhhc0V4cG9ydCA9IG1vZGlmaWVycz8uc29tZShtID0+IG0ua2luZCA9PT0gdHMuU3ludGF4S2luZC5FeHBvcnRLZXl3b3JkKSA/PyBmYWxzZTtcblx0XHRjb25zdCBoYXNEZWZhdWx0ID0gbW9kaWZpZXJzPy5zb21lKG0gPT4gbS5raW5kID09PSB0cy5TeW50YXhLaW5kLkRlZmF1bHRLZXl3b3JkKSA/PyBmYWxzZTtcblx0XHRpZiAoIWhhc0V4cG9ydCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGFkZEV4cG9ydCA9IChsb2NhbE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZCwga2luZDogTW9kdWxlQmluZGluZ0tpbmQpOiB2b2lkID0+IHtcblx0XHRcdGNvbnN0IGJpbmRpbmc6IE1vZHVsZUJpbmRpbmcgPSB7XG5cdFx0XHRcdG5hbWUgICAgICAgICA6IGhhc0RlZmF1bHQgPyAnZGVmYXVsdCcgOiBsb2NhbE5hbWUgPz8gJ2RlZmF1bHQnLFxuXHRcdFx0XHRraW5kLFxuXHRcdFx0XHRzb3VyY2VNb2R1bGUgOiBtb2R1bGVJbmZvLmZpbGVQYXRoLFxuXHRcdFx0XHRpc1JlRXhwb3J0ICAgOiBmYWxzZSxcblx0XHRcdH07XG5cdFx0XHRpZiAoaGFzRGVmYXVsdCkge1xuXHRcdFx0XHRiaW5kaW5nLmltcG9ydEtpbmQgPSAnZGVmYXVsdCc7XG5cdFx0XHRcdGlmIChsb2NhbE5hbWUpIHtcblx0XHRcdFx0XHRiaW5kaW5nLmltcG9ydEFsaWFzID0gbG9jYWxOYW1lO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRtb2R1bGVJbmZvLmV4cG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHR9O1xuXG5cdFx0aWYgKHRzLmlzRnVuY3Rpb25EZWNsYXJhdGlvbihzdGF0ZW1lbnQpKSB7XG5cdFx0XHRhZGRFeHBvcnQoc3RhdGVtZW50Lm5hbWU/LnRleHQsICdmdW5jdGlvbicpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKHN0YXRlbWVudCkpIHtcblx0XHRcdGFkZEV4cG9ydChzdGF0ZW1lbnQubmFtZT8udGV4dCwgJ2NsYXNzJyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmICh0cy5pc0ludGVyZmFjZURlY2xhcmF0aW9uKHN0YXRlbWVudCkgfHwgdHMuaXNUeXBlQWxpYXNEZWNsYXJhdGlvbihzdGF0ZW1lbnQpKSB7XG5cdFx0XHRhZGRFeHBvcnQoc3RhdGVtZW50Lm5hbWUudGV4dCwgJ3R5cGUnKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aWYgKHRzLmlzRW51bURlY2xhcmF0aW9uKHN0YXRlbWVudCkpIHtcblx0XHRcdGFkZEV4cG9ydChzdGF0ZW1lbnQubmFtZS50ZXh0LCAndHlwZScpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodHMuaXNWYXJpYWJsZVN0YXRlbWVudChzdGF0ZW1lbnQpKSB7XG5cdFx0XHRmb3IgKGNvbnN0IGRlY2wgb2Ygc3RhdGVtZW50LmRlY2xhcmF0aW9uTGlzdC5kZWNsYXJhdGlvbnMpIHtcblx0XHRcdFx0aWYgKHRzLmlzSWRlbnRpZmllcihkZWNsLm5hbWUpKSB7XG5cdFx0XHRcdFx0YWRkRXhwb3J0KGRlY2wubmFtZS50ZXh0LCBkZWNscy5nZXQoZGVjbC5uYW1lLnRleHQpID8/ICdjb25zdCcpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENvbW1vbkpTIGBjb25zdCB4ID0gcmVxdWlyZSgnLi95JylgIChKUyBzb3VyY2VzIHdpdGggYWxsb3dKcykuXG5cdCAqL1xuXHRwcml2YXRlIHByb2Nlc3NSZXF1aXJlQ2FsbCAoXG5cdFx0c3RhdGVtZW50OiB0cy5TdGF0ZW1lbnQsXG5cdFx0c291cmNlRmlsZTogdHMuU291cmNlRmlsZSxcblx0XHRtb2R1bGVJbmZvOiBNb2R1bGVJbmZvLFxuXHRcdHNpdGVzOiBJbXBvcnRTaXRlW11cblx0KTogdm9pZCB7XG5cdFx0aWYgKCF0cy5pc1ZhcmlhYmxlU3RhdGVtZW50KHN0YXRlbWVudCkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Zm9yIChjb25zdCBkZWNsIG9mIHN0YXRlbWVudC5kZWNsYXJhdGlvbkxpc3QuZGVjbGFyYXRpb25zKSB7XG5cdFx0XHRjb25zdCB7IGluaXRpYWxpemVyIH0gPSBkZWNsO1xuXHRcdFx0aWYgKCFpbml0aWFsaXplciB8fCAhdHMuaXNDYWxsRXhwcmVzc2lvbihpbml0aWFsaXplcikpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIXRzLmlzSWRlbnRpZmllcihpbml0aWFsaXplci5leHByZXNzaW9uKSB8fCBpbml0aWFsaXplci5leHByZXNzaW9uLnRleHQgIT09ICdyZXF1aXJlJykge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IFsgZmlyc3RBcmcgXSA9IGluaXRpYWxpemVyLmFyZ3VtZW50cztcblx0XHRcdGlmICghZmlyc3RBcmcgfHwgIXRzLmlzU3RyaW5nTGl0ZXJhbChmaXJzdEFyZykpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHRpZiAoTW9kdWxlR3JhcGhCdWlsZGVyLnNraXBCdWlsdGluKG1vZHVsZUluZm8sIGZpcnN0QXJnLnRleHQpKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgbG9jYWxOYW1lID0gdHMuaXNJZGVudGlmaWVyKGRlY2wubmFtZSkgPyBkZWNsLm5hbWUudGV4dCA6IGRlY2wubmFtZS5nZXRUZXh0KCk7XG5cdFx0XHRjb25zdCBiaW5kaW5nOiBNb2R1bGVCaW5kaW5nID0ge1xuXHRcdFx0XHRuYW1lICAgICAgICAgOiBsb2NhbE5hbWUsXG5cdFx0XHRcdGtpbmQgICAgICAgICA6ICd1bmtub3duJyxcblx0XHRcdFx0c291cmNlTW9kdWxlIDogZmlyc3RBcmcudGV4dCxcblx0XHRcdFx0aW1wb3J0S2luZCAgIDogJ3JlcXVpcmUnLFxuXHRcdFx0XHRpc1JlRXhwb3J0ICAgOiBmYWxzZSxcblx0XHRcdH07XG5cdFx0XHRtb2R1bGVJbmZvLmltcG9ydGVkQmluZGluZ3MucHVzaChiaW5kaW5nKTtcblx0XHRcdHNpdGVzLnB1c2goe1xuXHRcdFx0XHRzcGVjaWZpZXIgOiBmaXJzdEFyZy50ZXh0LFxuXHRcdFx0XHRsb2NhdGlvbiAgOiB0aGlzLmxvY2F0aW9uT2YoZmlyc3RBcmcsIHNvdXJjZUZpbGUpLFxuXHRcdFx0XHRiaW5kaW5ncyAgOiBbIGJpbmRpbmcgXSxcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBGb3JtYXQgYSBub2RlJ3MgcG9zaXRpb24gYXMgZmlsZS50czpMaW5lOkNvbCAoMS1iYXNlZCksIG1hdGNoaW5nIHRoZVxuXHQgKiBsb2NhdGlvbiBmb3JtYXQgb2YgdGhlIG90aGVyIC50YWN0aWNhIG91dHB1dHMuXG5cdCAqL1xuXHRwcml2YXRlIGxvY2F0aW9uT2YgKG5vZGU6IHRzLk5vZGUsIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUpOiBzdHJpbmcge1xuXHRcdGNvbnN0IHBvc2l0aW9uID0gc291cmNlRmlsZS5nZXRMaW5lQW5kQ2hhcmFjdGVyT2ZQb3NpdGlvbihub2RlLmdldFN0YXJ0KHNvdXJjZUZpbGUpKTtcblx0XHRjb25zdCBsb2NhdGlvbiA9IGAke3BhdGgucmVzb2x2ZShzb3VyY2VGaWxlLmZpbGVOYW1lKX06JHtwb3NpdGlvbi5saW5lICsgMX06JHtwb3NpdGlvbi5jaGFyYWN0ZXIgKyAxfWA7XG5cdFx0cmV0dXJuIGxvY2F0aW9uO1xuXHR9XG59XG4iXX0=