UNPKG

233 kBJavaScriptView Raw
1import { join, normalize, relative, strings, JsonParseMode, parseJson, basename, dirname as dirname$1, tags, resolve } from '@angular-devkit/core';
2import { __values, __spread, __makeTemplateObject, __assign, __extends } from 'tslib';
3import { SyntaxKind, forEachChild, isClassDeclaration, createSourceFile, ScriptTarget } from 'typescript';
4import { SchematicsException } from '@angular-devkit/schematics';
5import { dirname, join as join$1, normalize as normalize$1, parse } from 'path';
6import { isString, cloneDeep } from 'lodash';
7import { isString as isString$1, assertObject, isNil, isNotNil, assertArray, isArray, isPlainObject } from '@ibm-wch-sdk/utils';
8export { wchGetDeliveryUrlFromApiURL } from '@ibm-wch-sdk/utils';
9import { ok } from 'assert';
10import { validate } from 'email-validator';
11import { isWebUri, isUri } from 'valid-url';
12import { ajax } from 'rxjs/ajax';
13import { map, catchError, mergeMap, mapTo, pluck, switchMap, switchMapTo, first, filter, takeUntil, tap } from 'rxjs/operators';
14import { Observable, of, bindNodeCallback, throwError, defer, fromEvent } from 'rxjs';
15import { readFile } from 'fs';
16import { exec } from 'child_process';
17import { RSA_PKCS1_PADDING } from 'constants';
18import { privateDecrypt } from 'crypto';
19import { homedir, platform } from 'os';
20import { env } from 'process';
21import 'sshpk';
22import { satisfies, coerce } from 'semver';
23import { KEY_BASICAUTH_LOGIN_PASSWORD, KEY_BASICAUTH_LOGIN_USERNAME, REL_PATH_BASICAUTH_LOGIN, REL_PATH_CURRENT_USER } from '@ibm-wch-sdk/api';
24import { VError } from 'verror';
25import { get } from 'request';
26import { Writable } from 'stream';
27import { Parse } from 'unzip';
28import { load } from 'cheerio';
29
30/**
31 * @fileoverview added by tsickle
32 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
33 */
34/**
35 * Find the module referred by a set of options passed to the schematics.
36 * @param {?} host
37 * @param {?} options
38 * @return {?}
39 */
40function findModuleFromOptions(host, options) {
41 if (options.hasOwnProperty('skipImport') && options.skipImport) {
42 return undefined;
43 }
44 if (!options.module) {
45 /** @type {?} */
46 var pathToCheck = (options.path || '')
47 + (options.flat ? '' : '/' + strings.dasherize(options.name));
48 return normalize(findModule(host, pathToCheck));
49 }
50 else {
51 /** @type {?} */
52 var modulePath = normalize('/' + (options.path) + '/' + options.module);
53 /** @type {?} */
54 var moduleBaseName = normalize(modulePath).split('/').pop();
55 if (host.exists(modulePath)) {
56 return normalize(modulePath);
57 }
58 else if (host.exists(modulePath + '.ts')) {
59 return normalize(modulePath + '.ts');
60 }
61 else if (host.exists(modulePath + '.module.ts')) {
62 return normalize(modulePath + '.module.ts');
63 }
64 else if (host.exists(modulePath + '/' + moduleBaseName + '.module.ts')) {
65 return normalize(modulePath + '/' + moduleBaseName + '.module.ts');
66 }
67 else {
68 throw new Error('Specified module does not exist');
69 }
70 }
71}
72/**
73 * Function to find the "closest" module to a generated file's path.
74 * @param {?} host
75 * @param {?} generateDir
76 * @return {?}
77 */
78function findModule(host, generateDir) {
79 /** @type {?} */
80 var dir = host.getDir('/' + generateDir);
81 /** @type {?} */
82 var moduleRe = /\.module\.ts$/;
83 /** @type {?} */
84 var routingModuleRe = /-routing\.module\.ts/;
85 while (dir) {
86 /** @type {?} */
87 var matches = dir.subfiles.filter(function (p) { return moduleRe.test(p) && !routingModuleRe.test(p); });
88 if (matches.length == 1) {
89 return join(dir.path, matches[0]);
90 }
91 else if (matches.length > 1) {
92 throw new Error('More than one module matches. Use skip-import option to skip importing '
93 + 'the component into the closest module.');
94 }
95 dir = dir.parent;
96 }
97 throw new Error('Could not find an NgModule. Use the skip-import '
98 + 'option to skip importing in NgModule.');
99}
100/**
101 * Build a relative path from one file path to another file path.
102 * @param {?} from
103 * @param {?} to
104 * @return {?}
105 */
106function buildRelativePath(from, to) {
107 from = normalize(from);
108 to = normalize(to);
109 /** @type {?} */
110 var fromParts = from.split('/');
111 /** @type {?} */
112 var toParts = to.split('/');
113 // Remove file names (preserving destination)
114 fromParts.pop();
115 /** @type {?} */
116 var toFileName = toParts.pop();
117 /** @type {?} */
118 var relativePath = relative(normalize(fromParts.join('/')), normalize(toParts.join('/')));
119 /** @type {?} */
120 var pathPrefix = '';
121 // Set the path prefix for same dir or child dir, parent dir starts with `..`
122 if (!relativePath) {
123 pathPrefix = '.';
124 }
125 else if (!relativePath.startsWith('.')) {
126 pathPrefix = "./";
127 }
128 if (pathPrefix && !pathPrefix.endsWith('/')) {
129 pathPrefix += '/';
130 }
131 return pathPrefix + (relativePath ? relativePath + '/' : '') + toFileName;
132}
133
134/**
135 * @fileoverview added by tsickle
136 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
137 */
138/**
139 * An operation that does nothing.
140 */
141var /**
142 * An operation that does nothing.
143 */
144NoopChange = /** @class */ (function () {
145 function NoopChange() {
146 this.description = 'No operation.';
147 this.order = Infinity;
148 this.path = null;
149 }
150 /**
151 * @return {?}
152 */
153 NoopChange.prototype.apply = /**
154 * @return {?}
155 */
156 function () { return Promise.resolve(); };
157 return NoopChange;
158}());
159/**
160 * Will add text to the source code.
161 */
162var /**
163 * Will add text to the source code.
164 */
165InsertChange = /** @class */ (function () {
166 function InsertChange(path, pos, toAdd) {
167 this.path = path;
168 this.pos = pos;
169 this.toAdd = toAdd;
170 if (pos < 0) {
171 throw new Error('Negative positions are invalid');
172 }
173 this.description = "Inserted " + toAdd + " into position " + pos + " of " + path;
174 this.order = pos;
175 }
176 /**
177 * This method does not insert spaces if there is none in the original string.
178 */
179 /**
180 * This method does not insert spaces if there is none in the original string.
181 * @param {?} host
182 * @return {?}
183 */
184 InsertChange.prototype.apply = /**
185 * This method does not insert spaces if there is none in the original string.
186 * @param {?} host
187 * @return {?}
188 */
189 function (host) {
190 var _this = this;
191 return host.read(this.path).then(function (content) {
192 /** @type {?} */
193 var prefix = content.substring(0, _this.pos);
194 /** @type {?} */
195 var suffix = content.substring(_this.pos);
196 return host.write(_this.path, "" + prefix + _this.toAdd + suffix);
197 });
198 };
199 return InsertChange;
200}());
201/**
202 * Will remove text from the source code.
203 */
204var /**
205 * Will remove text from the source code.
206 */
207RemoveChange = /** @class */ (function () {
208 function RemoveChange(path, pos, toRemove) {
209 this.path = path;
210 this.pos = pos;
211 this.toRemove = toRemove;
212 if (pos < 0) {
213 throw new Error('Negative positions are invalid');
214 }
215 this.description = "Removed " + toRemove + " into position " + pos + " of " + path;
216 this.order = pos;
217 }
218 /**
219 * @param {?} host
220 * @return {?}
221 */
222 RemoveChange.prototype.apply = /**
223 * @param {?} host
224 * @return {?}
225 */
226 function (host) {
227 var _this = this;
228 return host.read(this.path).then(function (content) {
229 /** @type {?} */
230 var prefix = content.substring(0, _this.pos);
231 /** @type {?} */
232 var suffix = content.substring(_this.pos + _this.toRemove.length);
233 // TODO: throw error if toRemove doesn't match removed string.
234 return host.write(_this.path, "" + prefix + suffix);
235 });
236 };
237 return RemoveChange;
238}());
239/**
240 * Will replace text from the source code.
241 */
242var /**
243 * Will replace text from the source code.
244 */
245ReplaceChange = /** @class */ (function () {
246 function ReplaceChange(path, pos, oldText, newText) {
247 this.path = path;
248 this.pos = pos;
249 this.oldText = oldText;
250 this.newText = newText;
251 if (pos < 0) {
252 throw new Error('Negative positions are invalid');
253 }
254 this.description = "Replaced " + oldText + " into position " + pos + " of " + path + " with " + newText;
255 this.order = pos;
256 }
257 /**
258 * @param {?} host
259 * @return {?}
260 */
261 ReplaceChange.prototype.apply = /**
262 * @param {?} host
263 * @return {?}
264 */
265 function (host) {
266 var _this = this;
267 return host.read(this.path).then(function (content) {
268 /** @type {?} */
269 var prefix = content.substring(0, _this.pos);
270 /** @type {?} */
271 var suffix = content.substring(_this.pos + _this.oldText.length);
272 /** @type {?} */
273 var text = content.substring(_this.pos, _this.pos + _this.oldText.length);
274 if (text !== _this.oldText) {
275 return Promise.reject(new Error("Invalid replace: \"" + text + "\" != \"" + _this.oldText + "\"."));
276 }
277 // TODO: throw error if oldText doesn't match removed string.
278 return host.write(_this.path, "" + prefix + _this.newText + suffix);
279 });
280 };
281 return ReplaceChange;
282}());
283
284/**
285 * @fileoverview added by tsickle
286 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
287 */
288/**
289 * Add Import `import { symbolName } from fileName` if the import doesn't exit
290 * already. Assumes fileToEdit can be resolved and accessed.
291 * @param {?} source
292 * @param {?} fileToEdit (file we want to add import to)
293 * @param {?} symbolName (item to import)
294 * @param {?} fileName (path to the file)
295 * @param {?=} isDefault (if true, import follows style for importing default exports)
296 * @return {?} Change
297 */
298function insertImport(source, fileToEdit, symbolName, fileName, isDefault) {
299 if (isDefault === void 0) { isDefault = false; }
300 /** @type {?} */
301 var rootNode = source;
302 /** @type {?} */
303 var allImports = findNodes(rootNode, SyntaxKind.ImportDeclaration);
304 /** @type {?} */
305 var relevantImports = allImports.filter(function (node) {
306 /** @type {?} */
307 var importFiles = node
308 .getChildren()
309 .filter(function (child) { return child.kind === SyntaxKind.StringLiteral; })
310 .map(function (n) { return (/** @type {?} */ (n)).text; });
311 return importFiles.filter(function (file) { return file === fileName; }).length === 1;
312 });
313 if (relevantImports.length > 0) {
314 /** @type {?} */
315 var importsAsterisk_1 = false;
316 /** @type {?} */
317 var imports_1 = [];
318 relevantImports.forEach(function (n) {
319 Array.prototype.push.apply(imports_1, findNodes(n, SyntaxKind.Identifier));
320 if (findNodes(n, SyntaxKind.AsteriskToken).length > 0) {
321 importsAsterisk_1 = true;
322 }
323 });
324 // if imports * from fileName, don't add symbolName
325 if (importsAsterisk_1) {
326 return new NoopChange();
327 }
328 /** @type {?} */
329 var importTextNodes = imports_1.filter(function (n) { return (/** @type {?} */ (n)).text === symbolName; });
330 // insert import if it's not there
331 if (importTextNodes.length === 0) {
332 /** @type {?} */
333 var fallbackPos_1 = findNodes(relevantImports[0], SyntaxKind.CloseBraceToken)[0].getStart() ||
334 findNodes(relevantImports[0], SyntaxKind.FromKeyword)[0].getStart();
335 return insertAfterLastOccurrence(imports_1, ", " + symbolName, fileToEdit, fallbackPos_1);
336 }
337 return new NoopChange();
338 }
339 /** @type {?} */
340 var useStrict = findNodes(rootNode, SyntaxKind.StringLiteral).filter(function (n) { return n.text === 'use strict'; });
341 /** @type {?} */
342 var fallbackPos = 0;
343 if (useStrict.length > 0) {
344 fallbackPos = useStrict[0].end;
345 }
346 /** @type {?} */
347 var open = isDefault ? '' : '{ ';
348 /** @type {?} */
349 var close = isDefault ? '' : ' }';
350 /** @type {?} */
351 var insertAtBeginning = allImports.length === 0 && useStrict.length === 0;
352 /** @type {?} */
353 var separator = insertAtBeginning ? '' : ';\n';
354 /** @type {?} */
355 var toInsert = separator + "import " + open + symbolName + close +
356 (" from '" + fileName + "'" + (insertAtBeginning ? ';\n' : ''));
357 return insertAfterLastOccurrence(allImports, toInsert, fileToEdit, fallbackPos, SyntaxKind.StringLiteral);
358}
359/**
360 * Find all nodes from the AST in the subtree of node of SyntaxKind kind.
361 * @param {?} node
362 * @param {?} kind
363 * @param {?=} max The maximum number of items to return.
364 * @return {?} all nodes of kind, or [] if none is found
365 */
366function findNodes(node, kind, max) {
367 if (max === void 0) { max = Infinity; }
368 var e_1, _a;
369 if (!node || max == 0) {
370 return [];
371 }
372 /** @type {?} */
373 var arr = [];
374 if (node.kind === kind) {
375 arr.push(node);
376 max--;
377 }
378 if (max > 0) {
379 try {
380 for (var _b = __values(node.getChildren()), _c = _b.next(); !_c.done; _c = _b.next()) {
381 var child = _c.value;
382 findNodes(child, kind, max).forEach(function (node) {
383 if (max > 0) {
384 arr.push(node);
385 }
386 max--;
387 });
388 if (max <= 0) {
389 break;
390 }
391 }
392 }
393 catch (e_1_1) { e_1 = { error: e_1_1 }; }
394 finally {
395 try {
396 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
397 }
398 finally { if (e_1) throw e_1.error; }
399 }
400 }
401 return arr;
402}
403/**
404 * Get all the nodes from a source.
405 * @param {?} sourceFile The source file object.
406 * @return {?} An observable of all the nodes in the source.
407 */
408function getSourceNodes(sourceFile) {
409 /** @type {?} */
410 var nodes = [sourceFile];
411 /** @type {?} */
412 var result = [];
413 while (nodes.length > 0) {
414 /** @type {?} */
415 var node = nodes.shift();
416 if (node) {
417 result.push(node);
418 if (node.getChildCount(sourceFile) >= 0) {
419 nodes.unshift.apply(nodes, __spread(node.getChildren()));
420 }
421 }
422 }
423 return result;
424}
425/**
426 * @param {?} node
427 * @param {?} kind
428 * @param {?} text
429 * @return {?}
430 */
431function findNode(node, kind, text) {
432 if (node.kind === kind && node.getText() === text) {
433 // throw new Error(node.getText());
434 return node;
435 }
436 /** @type {?} */
437 var foundNode = null;
438 forEachChild(node, function (childNode) {
439 foundNode = foundNode || findNode(childNode, kind, text);
440 });
441 return foundNode;
442}
443/**
444 * Helper for sorting nodes.
445 * @param {?} first
446 * @param {?} second
447 * @return {?} function to sort nodes in increasing order of position in sourceFile
448 */
449function nodesByPosition(first$$1, second) {
450 return first$$1.getStart() - second.getStart();
451}
452/**
453 * Insert `toInsert` after the last occurence of `ts.SyntaxKind[nodes[i].kind]`
454 * or after the last of occurence of `syntaxKind` if the last occurence is a sub child
455 * of ts.SyntaxKind[nodes[i].kind] and save the changes in file.
456 *
457 * \@throw Error if toInsert is first occurence but fall back is not set
458 * @param {?} nodes insert after the last occurence of nodes
459 * @param {?} toInsert string to insert
460 * @param {?} file file to insert changes into
461 * @param {?} fallbackPos position to insert if toInsert happens to be the first occurence
462 * @param {?=} syntaxKind the ts.SyntaxKind of the subchildren to insert after
463 * @return {?} Change instance
464 */
465function insertAfterLastOccurrence(nodes, toInsert, file, fallbackPos, syntaxKind) {
466 /** @type {?} */
467 var lastItem = __spread(nodes).sort(nodesByPosition).pop();
468 if (!lastItem) {
469 throw new Error();
470 }
471 if (syntaxKind) {
472 lastItem = findNodes(lastItem, syntaxKind)
473 .sort(nodesByPosition)
474 .pop();
475 }
476 if (!lastItem && fallbackPos == undefined) {
477 throw new Error("tried to insert " + toInsert + " as first occurence with no fallback position");
478 }
479 /** @type {?} */
480 var lastItemPosition = lastItem ? lastItem.getEnd() : fallbackPos;
481 return new InsertChange(file, lastItemPosition, toInsert);
482}
483/**
484 * @param {?} _source
485 * @param {?} node
486 * @return {?}
487 */
488function getContentOfKeyLiteral(_source, node) {
489 if (node.kind == SyntaxKind.Identifier) {
490 return (/** @type {?} */ (node)).text;
491 }
492 else if (node.kind == SyntaxKind.StringLiteral) {
493 return (/** @type {?} */ (node)).text;
494 }
495 else {
496 return null;
497 }
498}
499/**
500 * @param {?} node
501 * @param {?} _sourceFile
502 * @return {?}
503 */
504function _angularImportsFromNode(node, _sourceFile) {
505 var _a;
506 /** @type {?} */
507 var ms = node.moduleSpecifier;
508 /** @type {?} */
509 var modulePath;
510 switch (ms.kind) {
511 case SyntaxKind.StringLiteral:
512 modulePath = (/** @type {?} */ (ms)).text;
513 break;
514 default:
515 return {};
516 }
517 if (!modulePath.startsWith('@angular/')) {
518 return {};
519 }
520 if (node.importClause) {
521 if (node.importClause.name) {
522 // This is of the form `import Name from 'path'`. Ignore.
523 return {};
524 }
525 else if (node.importClause.namedBindings) {
526 /** @type {?} */
527 var nb = node.importClause.namedBindings;
528 if (nb.kind == SyntaxKind.NamespaceImport) {
529 // This is of the form `import * as name from 'path'`. Return `name.`.
530 return _a = {},
531 _a[(/** @type {?} */ (nb)).name.text + '.'] = modulePath,
532 _a;
533 }
534 else {
535 /** @type {?} */
536 var namedImports = /** @type {?} */ (nb);
537 return namedImports.elements
538 .map(function (is) {
539 return is.propertyName ? is.propertyName.text : is.name.text;
540 })
541 .reduce(function (acc, curr) {
542 acc[curr] = modulePath;
543 return acc;
544 }, {});
545 }
546 }
547 return {};
548 }
549 else {
550 // This is of the form `import 'path';`. Nothing to do.
551 return {};
552 }
553}
554/**
555 * @param {?} source
556 * @param {?} identifier
557 * @param {?} module
558 * @return {?}
559 */
560function getDecoratorMetadata(source, identifier, module) {
561 /** @type {?} */
562 var angularImports = findNodes(source, SyntaxKind.ImportDeclaration)
563 .map(function (node) { return _angularImportsFromNode(node, source); })
564 .reduce(function (acc, current) {
565 var e_2, _a;
566 try {
567 for (var _b = __values(Object.keys(current)), _c = _b.next(); !_c.done; _c = _b.next()) {
568 var key = _c.value;
569 acc[key] = current[key];
570 }
571 }
572 catch (e_2_1) { e_2 = { error: e_2_1 }; }
573 finally {
574 try {
575 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
576 }
577 finally { if (e_2) throw e_2.error; }
578 }
579 return acc;
580 }, {});
581 return getSourceNodes(source)
582 .filter(function (node) {
583 return (node.kind == SyntaxKind.Decorator &&
584 (/** @type {?} */ (node)).expression.kind == SyntaxKind.CallExpression);
585 })
586 .map(function (node) { return ((/** @type {?} */ (node)).expression); })
587 .filter(function (expr) {
588 if (expr.expression.kind == SyntaxKind.Identifier) {
589 /** @type {?} */
590 var id = /** @type {?} */ (expr.expression);
591 return (id.getFullText(source) == identifier &&
592 angularImports[id.getFullText(source)] === module);
593 }
594 else if (expr.expression.kind == SyntaxKind.PropertyAccessExpression) {
595 /** @type {?} */
596 var paExpr = /** @type {?} */ (expr.expression);
597 // If the left expression is not an identifier, just give up at that point.
598 if (paExpr.expression.kind !== SyntaxKind.Identifier) {
599 return false;
600 }
601 /** @type {?} */
602 var id = paExpr.name.text;
603 /** @type {?} */
604 var moduleId = (/** @type {?} */ (paExpr.expression)).getText(source);
605 return id === identifier && angularImports[moduleId + '.'] === module;
606 }
607 return false;
608 })
609 .filter(function (expr) {
610 return expr.arguments[0] &&
611 expr.arguments[0].kind == SyntaxKind.ObjectLiteralExpression;
612 })
613 .map(function (expr) { return (expr.arguments[0]); });
614}
615/**
616 * @param {?} node
617 * @return {?}
618 */
619function findClassDeclarationParent(node) {
620 if (isClassDeclaration(node)) {
621 return node;
622 }
623 return node.parent && findClassDeclarationParent(node.parent);
624}
625/**
626 * Given a source file with \@NgModule class(es), find the name of the first \@NgModule class.
627 *
628 * @param {?} source source file containing one or more \@NgModule
629 * @return {?} the name of the first \@NgModule, or `undefined` if none is found
630 */
631function getFirstNgModuleName(source) {
632 /** @type {?} */
633 var ngModulesMetadata = getDecoratorMetadata(source, 'NgModule', '@angular/core');
634 if (ngModulesMetadata.length === 0) {
635 return undefined;
636 }
637 /** @type {?} */
638 var moduleClass = findClassDeclarationParent(ngModulesMetadata[0]);
639 if (!moduleClass || !moduleClass.name) {
640 return undefined;
641 }
642 // Get the class name of the module ClassDeclaration.
643 return moduleClass.name.text;
644}
645/**
646 * @param {?} source
647 * @param {?} ngModulePath
648 * @param {?} metadataField
649 * @param {?} symbolName
650 * @param {?=} importPath
651 * @return {?}
652 */
653function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbolName, importPath) {
654 if (importPath === void 0) { importPath = null; }
655 /** @type {?} */
656 var nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
657 /** @type {?} */
658 var node = nodes[0]; // tslint:disable-line:no-any
659 // Find the decorator declaration.
660 if (!node) {
661 return [];
662 }
663 /** @type {?} */
664 var matchingProperties = (/** @type {?} */ (node)).properties
665 .filter(function (prop) { return prop.kind == SyntaxKind.PropertyAssignment; })
666 // Filter out every fields that's not "metadataField". Also handles string literals
667 // (but not expressions).
668 .filter(function (prop) {
669 /** @type {?} */
670 var name = prop.name;
671 switch (name.kind) {
672 case SyntaxKind.Identifier:
673 return (/** @type {?} */ (name)).getText(source) == metadataField;
674 case SyntaxKind.StringLiteral:
675 return (/** @type {?} */ (name)).text == metadataField;
676 }
677 return false;
678 });
679 // Get the last node of the array literal.
680 if (!matchingProperties) {
681 return [];
682 }
683 if (matchingProperties.length == 0) {
684 /** @type {?} */
685 var expr = /** @type {?} */ (node);
686 /** @type {?} */
687 var position_1 = void 0;
688 /** @type {?} */
689 var toInsert_1 = void 0;
690 if (expr.properties.length == 0) {
691 position_1 = expr.getEnd() - 1;
692 toInsert_1 = " " + metadataField + ": [" + symbolName + "]\n";
693 }
694 else {
695 node = expr.properties[expr.properties.length - 1];
696 position_1 = node.getEnd();
697 /** @type {?} */
698 var text = node.getFullText(source);
699 /** @type {?} */
700 var matches = text.match(/^\r?\n\s*/);
701 if (matches.length > 0) {
702 toInsert_1 = "," + matches[0] + metadataField + ": [" + symbolName + "]";
703 }
704 else {
705 toInsert_1 = ", " + metadataField + ": [" + symbolName + "]";
706 }
707 }
708 if (importPath !== null) {
709 return [
710 new InsertChange(ngModulePath, position_1, toInsert_1),
711 insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath)
712 ];
713 }
714 else {
715 return [new InsertChange(ngModulePath, position_1, toInsert_1)];
716 }
717 }
718 /** @type {?} */
719 var assignment = /** @type {?} */ (matchingProperties[0]);
720 // If it's not an array, nothing we can do really.
721 if (assignment.initializer.kind !== SyntaxKind.ArrayLiteralExpression) {
722 return [];
723 }
724 /** @type {?} */
725 var arrLiteral = /** @type {?} */ (assignment.initializer);
726 if (arrLiteral.elements.length == 0) {
727 // Forward the property.
728 node = arrLiteral;
729 }
730 else {
731 node = arrLiteral.elements;
732 }
733 if (!node) {
734 console.log('No app module found. Please add your new class to your component.');
735 return [];
736 }
737 if (Array.isArray(node)) {
738 /** @type {?} */
739 var nodeArray = /** @type {?} */ ((/** @type {?} */ (node)));
740 /** @type {?} */
741 var symbolsArray = nodeArray.map(function (node) { return node.getText(); });
742 if (symbolsArray.indexOf(symbolName) >= 0) {
743 return [];
744 }
745 node = node[node.length - 1];
746 }
747 /** @type {?} */
748 var toInsert;
749 /** @type {?} */
750 var position = node.getEnd();
751 if (node.kind == SyntaxKind.ObjectLiteralExpression) {
752 /** @type {?} */
753 var expr = /** @type {?} */ (node);
754 if (expr.properties.length == 0) {
755 position = expr.getEnd() - 1;
756 toInsert = " " + metadataField + ": [" + symbolName + "]\n";
757 }
758 else {
759 node = expr.properties[expr.properties.length - 1];
760 position = node.getEnd();
761 /** @type {?} */
762 var text = node.getFullText(source);
763 if (text.match('^\r?\r?\n')) {
764 toInsert = "," + text.match(/^\r?\n\s+/)[0] + metadataField + ": [" + symbolName + "]";
765 }
766 else {
767 toInsert = ", " + metadataField + ": [" + symbolName + "]";
768 }
769 }
770 }
771 else if (node.kind == SyntaxKind.ArrayLiteralExpression) {
772 // We found the field but it's empty. Insert it just before the `]`.
773 position--;
774 toInsert = "" + symbolName;
775 }
776 else {
777 /** @type {?} */
778 var text = node.getFullText(source);
779 if (text.match(/^\r?\n/)) {
780 toInsert = "," + text.match(/^\r?\n(\r?)\s+/)[0] + symbolName;
781 }
782 else {
783 toInsert = ", " + symbolName;
784 }
785 }
786 if (importPath !== null) {
787 return [
788 new InsertChange(ngModulePath, position, toInsert),
789 insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath)
790 ];
791 }
792 return [new InsertChange(ngModulePath, position, toInsert)];
793}
794/**
795 * Custom function to insert a declaration (component, pipe, directive)
796 * into NgModule declarations. It also imports the component.
797 * @param {?} source
798 * @param {?} modulePath
799 * @param {?} classifiedName
800 * @param {?} importPath
801 * @return {?}
802 */
803function addDeclarationToModule(source, modulePath, classifiedName, importPath) {
804 return addSymbolToNgModuleMetadata(source, modulePath, 'declarations', classifiedName, importPath);
805}
806/**
807 * Custom function to insert an NgModule into NgModule imports. It also imports the module.
808 * @param {?} source
809 * @param {?} modulePath
810 * @param {?} classifiedName
811 * @param {?} importPath
812 * @return {?}
813 */
814function addImportToModule(source, modulePath, classifiedName, importPath) {
815 return addSymbolToNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath);
816}
817/**
818 * Custom function to insert a provider into NgModule. It also imports it.
819 * @param {?} source
820 * @param {?} modulePath
821 * @param {?} classifiedName
822 * @param {?} importPath
823 * @return {?}
824 */
825function addProviderToModule(source, modulePath, classifiedName, importPath) {
826 return addSymbolToNgModuleMetadata(source, modulePath, 'providers', classifiedName, importPath);
827}
828/**
829 * Custom function to insert an export into NgModule. It also imports it.
830 * @param {?} source
831 * @param {?} modulePath
832 * @param {?} classifiedName
833 * @param {?} importPath
834 * @return {?}
835 */
836function addExportToModule(source, modulePath, classifiedName, importPath) {
837 return addSymbolToNgModuleMetadata(source, modulePath, 'exports', classifiedName, importPath);
838}
839/**
840 * Custom function to insert an export into NgModule. It also imports it.
841 * @param {?} source
842 * @param {?} modulePath
843 * @param {?} classifiedName
844 * @param {?} importPath
845 * @return {?}
846 */
847function addBootstrapToModule(source, modulePath, classifiedName, importPath) {
848 return addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath);
849}
850/**
851 * Custom function to insert an entryComponent into NgModule. It also imports it.
852 * @param {?} source
853 * @param {?} modulePath
854 * @param {?} classifiedName
855 * @param {?} importPath
856 * @return {?}
857 */
858function addEntryComponentToModule(source, modulePath, classifiedName, importPath) {
859 return addSymbolToNgModuleMetadata(source, modulePath, 'entryComponents', classifiedName, importPath);
860}
861/**
862 * Determine if an import already exists.
863 * @param {?} source
864 * @param {?} classifiedName
865 * @param {?} importPath
866 * @return {?}
867 */
868function isImported(source, classifiedName, importPath) {
869 /** @type {?} */
870 var allNodes = getSourceNodes(source);
871 /** @type {?} */
872 var matchingNodes = allNodes
873 .filter(function (node) { return node.kind === SyntaxKind.ImportDeclaration; })
874 .filter(function (imp) {
875 return imp.moduleSpecifier.kind === SyntaxKind.StringLiteral;
876 })
877 .filter(function (imp) {
878 return (/** @type {?} */ (imp.moduleSpecifier)).text === importPath;
879 })
880 .filter(function (imp) {
881 if (!imp.importClause) {
882 return false;
883 }
884 /** @type {?} */
885 var nodes = findNodes(imp.importClause, SyntaxKind.ImportSpecifier).filter(function (n) { return n.getText() === classifiedName; });
886 return nodes.length > 0;
887 });
888 return matchingNodes.length > 0;
889}
890
891/**
892 * @fileoverview added by tsickle
893 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
894 */
895/**
896 * @param {?} host
897 * @return {?}
898 */
899function getWorkspacePath(host) {
900 /** @type {?} */
901 var possibleFiles = ['/angular.json', '/.angular.json'];
902 /** @type {?} */
903 var path = possibleFiles.filter(function (path) { return host.exists(path); })[0];
904 return path;
905}
906/**
907 * @param {?} host
908 * @return {?}
909 */
910function getWorkspace(host) {
911 /** @type {?} */
912 var path = getWorkspacePath(host);
913 /** @type {?} */
914 var configBuffer = host.read(path);
915 if (configBuffer === null) {
916 throw new SchematicsException("Could not find (" + path + ")");
917 }
918 /** @type {?} */
919 var content = configBuffer.toString();
920 return /** @type {?} */ ((parseJson(content, JsonParseMode.Loose)));
921}
922/**
923 * @param {?} workspace
924 * @param {?} name
925 * @param {?} project
926 * @return {?}
927 */
928function addProjectToWorkspace(workspace, name, project) {
929 return function (host, context) {
930 if (workspace.projects[name]) {
931 throw new Error("Project '" + name + "' already exists in workspace.");
932 }
933 // Add project to workspace.
934 workspace.projects[name] = project;
935 if (!workspace.defaultProject && Object.keys(workspace.projects).length === 1) {
936 // Make the new project the default one.
937 workspace.defaultProject = name;
938 }
939 host.overwrite(getWorkspacePath(host), JSON.stringify(workspace, null, 2));
940 };
941}
942/** @type {?} */
943var configPath = '/.angular-cli.json';
944/**
945 * @param {?} host
946 * @return {?}
947 */
948function getConfig(host) {
949 /** @type {?} */
950 var configBuffer = host.read(configPath);
951 if (configBuffer === null) {
952 throw new SchematicsException('Could not find .angular-cli.json');
953 }
954 /** @type {?} */
955 var config = /** @type {?} */ ((parseJson(configBuffer.toString(), JsonParseMode.Loose)));
956 return config;
957}
958/**
959 * @param {?} config
960 * @param {?} appIndexOrName
961 * @return {?}
962 */
963function getAppFromConfig(config, appIndexOrName) {
964 if (!config.apps) {
965 return null;
966 }
967 if (parseInt(appIndexOrName) >= 0) {
968 return config.apps[parseInt(appIndexOrName)];
969 }
970 return config.apps.filter(function (app) { return app.name === appIndexOrName; })[0];
971}
972
973/**
974 * @fileoverview added by tsickle
975 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
976 */
977/**
978 * @param {?} host
979 * @param {?} mainPath
980 * @return {?}
981 */
982function findBootstrapModuleCall(host, mainPath) {
983 var e_1, _a;
984 /** @type {?} */
985 var mainBuffer = host.read(mainPath);
986 if (!mainBuffer) {
987 throw new SchematicsException("Main file (" + mainPath + ") not found");
988 }
989 /** @type {?} */
990 var mainText = mainBuffer.toString('utf-8');
991 /** @type {?} */
992 var source = createSourceFile(mainPath, mainText, ScriptTarget.Latest, true);
993 /** @type {?} */
994 var allNodes = getSourceNodes(source);
995 /** @type {?} */
996 var bootstrapCall = null;
997 try {
998 for (var allNodes_1 = __values(allNodes), allNodes_1_1 = allNodes_1.next(); !allNodes_1_1.done; allNodes_1_1 = allNodes_1.next()) {
999 var node = allNodes_1_1.value;
1000 /** @type {?} */
1001 var bootstrapCallNode = null;
1002 bootstrapCallNode = findNode(node, SyntaxKind.Identifier, 'bootstrapModule');
1003 // Walk up the parent until CallExpression is found.
1004 while (bootstrapCallNode && bootstrapCallNode.parent
1005 && bootstrapCallNode.parent.kind !== SyntaxKind.CallExpression) {
1006 bootstrapCallNode = bootstrapCallNode.parent;
1007 }
1008 if (bootstrapCallNode !== null &&
1009 bootstrapCallNode.parent !== undefined &&
1010 bootstrapCallNode.parent.kind === SyntaxKind.CallExpression) {
1011 bootstrapCall = /** @type {?} */ (bootstrapCallNode.parent);
1012 break;
1013 }
1014 }
1015 }
1016 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1017 finally {
1018 try {
1019 if (allNodes_1_1 && !allNodes_1_1.done && (_a = allNodes_1.return)) _a.call(allNodes_1);
1020 }
1021 finally { if (e_1) throw e_1.error; }
1022 }
1023 return bootstrapCall;
1024}
1025/**
1026 * @param {?} host
1027 * @param {?} mainPath
1028 * @return {?}
1029 */
1030function findBootstrapModulePath(host, mainPath) {
1031 /** @type {?} */
1032 var bootstrapCall = findBootstrapModuleCall(host, mainPath);
1033 if (!bootstrapCall) {
1034 throw new SchematicsException('Bootstrap call not found');
1035 }
1036 /** @type {?} */
1037 var bootstrapModule = bootstrapCall.arguments[0];
1038 /** @type {?} */
1039 var mainBuffer = host.read(mainPath);
1040 if (!mainBuffer) {
1041 throw new SchematicsException("Client app main file (" + mainPath + ") not found");
1042 }
1043 /** @type {?} */
1044 var mainText = mainBuffer.toString('utf-8');
1045 /** @type {?} */
1046 var source = createSourceFile(mainPath, mainText, ScriptTarget.Latest, true);
1047 /** @type {?} */
1048 var allNodes = getSourceNodes(source);
1049 /** @type {?} */
1050 var bootstrapModuleRelativePath = allNodes
1051 .filter(function (node) { return node.kind === SyntaxKind.ImportDeclaration; })
1052 .filter(function (imp) {
1053 return findNode(imp, SyntaxKind.Identifier, bootstrapModule.getText());
1054 })
1055 .map(function (imp) {
1056 /** @type {?} */
1057 var modulePathStringLiteral = /** @type {?} */ (imp.moduleSpecifier);
1058 return modulePathStringLiteral.text;
1059 })[0];
1060 return bootstrapModuleRelativePath;
1061}
1062/**
1063 * @param {?} host
1064 * @param {?} mainPath
1065 * @return {?}
1066 */
1067function getAppModulePath(host, mainPath) {
1068 /** @type {?} */
1069 var moduleRelativePath = findBootstrapModulePath(host, mainPath);
1070 /** @type {?} */
1071 var mainDir = dirname(mainPath);
1072 /** @type {?} */
1073 var modulePath = normalize("/" + mainDir + "/" + moduleRelativePath + ".ts");
1074 return modulePath;
1075}
1076
1077/**
1078 * @fileoverview added by tsickle
1079 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1080 */
1081/**
1082 * @param {?} path
1083 * @param {?} name
1084 * @return {?}
1085 */
1086function parseName(path, name) {
1087 /** @type {?} */
1088 var nameWithoutPath = basename(/** @type {?} */ (name));
1089 /** @type {?} */
1090 var namePath = dirname$1(/** @type {?} */ ((path + '/' + name)));
1091 return {
1092 name: nameWithoutPath,
1093 path: normalize('/' + namePath),
1094 };
1095}
1096
1097/**
1098 * @fileoverview added by tsickle
1099 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1100 */
1101/**
1102 * @param {?} name
1103 * @return {?}
1104 */
1105function validateName(name) {
1106 if (name && /^\d/.test(name)) {
1107 throw new SchematicsException(tags.oneLine(templateObject_1 || (templateObject_1 = __makeTemplateObject(["name (", ")\n can not start with a digit."], ["name (", ")\n can not start with a digit."])), name));
1108 }
1109}
1110/** @type {?} */
1111var htmlSelectorRe = /^[a-zA-Z][.0-9a-zA-Z]*(:?-[a-zA-Z][.0-9a-zA-Z]*)*$/;
1112/**
1113 * @param {?} selector
1114 * @return {?}
1115 */
1116function validateHtmlSelector(selector) {
1117 if (selector && !htmlSelectorRe.test(selector)) {
1118 throw new SchematicsException(tags.oneLine(templateObject_2 || (templateObject_2 = __makeTemplateObject(["Selector (", ")\n is invalid."], ["Selector (", ")\n is invalid."])), selector));
1119 }
1120}
1121/**
1122 * @param {?} projectName
1123 * @return {?}
1124 */
1125function validateProjectName(projectName) {
1126 /** @type {?} */
1127 var errorIndex = getRegExpFailPosition(projectName);
1128 /** @type {?} */
1129 var unsupportedProjectNames = ['test', 'ember', 'ember-cli', 'vendor', 'app'];
1130 /** @type {?} */
1131 var packageNameRegex = /^(?:@[a-zA-Z0-9_-]+\/)?[a-zA-Z0-9_-]+$/;
1132 if (errorIndex !== null) {
1133 /** @type {?} */
1134 var firstMessage = tags.oneLine(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n Project name \"", "\" is not valid. New project names must\n start with a letter, and must contain only alphanumeric characters or dashes.\n When adding a dash the segment after the dash must also start with a letter.\n "], ["\n Project name \"", "\" is not valid. New project names must\n start with a letter, and must contain only alphanumeric characters or dashes.\n When adding a dash the segment after the dash must also start with a letter.\n "])), projectName);
1135 /** @type {?} */
1136 var msg = tags.stripIndent(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n ", "\n ", "\n ", "\n "], ["\n ", "\n ", "\n ", "\n "])), firstMessage, projectName, Array(errorIndex + 1).join(' ') + '^');
1137 throw new SchematicsException(msg);
1138 }
1139 else if (unsupportedProjectNames.indexOf(projectName) !== -1) {
1140 throw new SchematicsException("Project name " + JSON.stringify(projectName) + " is not a supported name.");
1141 }
1142 else if (!packageNameRegex.test(projectName)) {
1143 throw new SchematicsException("Project name " + JSON.stringify(projectName) + " is invalid.");
1144 }
1145}
1146/**
1147 * @param {?} str
1148 * @return {?}
1149 */
1150function getRegExpFailPosition(str) {
1151 /** @type {?} */
1152 var isScope = /^@.*\/.*/.test(str);
1153 if (isScope) {
1154 // Remove starting @
1155 str = str.replace(/^@/, '');
1156 // Change / to - for validation
1157 str = str.replace(/\//g, '-');
1158 }
1159 /** @type {?} */
1160 var parts = str.indexOf('-') >= 0 ? str.split('-') : [str];
1161 /** @type {?} */
1162 var matched = [];
1163 /** @type {?} */
1164 var projectNameRegexp = /^[a-zA-Z][.0-9a-zA-Z]*(-[.0-9a-zA-Z]*)*$/;
1165 parts.forEach(function (part) {
1166 if (part.match(projectNameRegexp)) {
1167 matched.push(part);
1168 }
1169 });
1170 /** @type {?} */
1171 var compare = matched.join('-');
1172 return (str !== compare) ? compare.length : null;
1173}
1174var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
1175
1176/**
1177 * @fileoverview added by tsickle
1178 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1179 */
1180
1181/**
1182 * @fileoverview added by tsickle
1183 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1184 */
1185/**
1186 * @param {?} aUrl
1187 * @return {?}
1188 */
1189function _ensureTrailingSlash(aUrl) {
1190 return aUrl.endsWith('/') ? aUrl : aUrl + '/';
1191}
1192/**
1193 * @param {?} aUrl
1194 * @return {?}
1195 */
1196function _hasTrailingSlash(aUrl) {
1197 return !!(aUrl && isString(aUrl) && aUrl.endsWith('/'));
1198}
1199
1200/**
1201 * @fileoverview added by tsickle
1202 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1203 */
1204/**
1205 * @param {?} aValue
1206 * @param {?=} aName
1207 * @return {?}
1208 */
1209function assertNotNull(aValue, aName) {
1210 ok(aValue != null, aName
1211 ? "Value [" + aName + "] must not be null or undefined."
1212 : 'Value must not be null or undefined.');
1213}
1214/**
1215 * @param {?} aValue
1216 * @param {?} aParameterName
1217 * @return {?}
1218 */
1219function assertParameter(aValue, aParameterName) {
1220 ok(!!aValue, "Please specify the '--" + aParameterName + "' parameter.");
1221}
1222/**
1223 * @param {?} aValue
1224 * @return {?}
1225 */
1226function isValidUrl(aValue) {
1227 return isString$1(aValue) && !!isWebUri(aValue);
1228}
1229/**
1230 * @param {?} aValue
1231 * @param {?=} aName
1232 * @return {?}
1233 */
1234function assertIsUrl(aValue, aName) {
1235 ok(isValidUrl(aValue), aName
1236 ? "Value [" + aName + "] must be a valid URL."
1237 : 'Value must be a valid URL.');
1238 return aValue;
1239}
1240/**
1241 * @param {?} aValue
1242 * @return {?}
1243 */
1244function isValidEmail(aValue) {
1245 return isString$1(aValue) && !!validate(aValue);
1246}
1247/**
1248 * @param {?} aValue
1249 * @return {?}
1250 */
1251function isValidUserName(aValue) {
1252 return isString$1(aValue) && (!!validate(aValue) || aValue === 'apikey');
1253}
1254/**
1255 * @param {?} aValue
1256 * @param {?=} aName
1257 * @return {?}
1258 */
1259function assertIsEmail(aValue, aName) {
1260 ok(isValidEmail(aValue), aName
1261 ? "Value [" + aName + "] must be a valid e-mail address."
1262 : 'Value must be a valid e-mail address.');
1263 return aValue;
1264}
1265/**
1266 * @param {?} aValue
1267 * @param {?=} aName
1268 * @return {?}
1269 */
1270function assertIsValidUserName(aValue, aName) {
1271 ok(isValidUserName(aValue), aName
1272 ? "Value [" + aName + "] must be a valid e-mail address or the term 'apikey'."
1273 : "Value must be a valid e-mail address or the term 'apikey'.");
1274 return aValue;
1275}
1276/**
1277 * @param {?} aValue
1278 * @return {?}
1279 */
1280function assertHasTrailingSlash(aValue) {
1281 ok(isValidUrl(aValue) && _hasTrailingSlash(aValue), 'URL [${aValue}] must end with a slash.');
1282 return aValue;
1283}
1284
1285/**
1286 * @fileoverview added by tsickle
1287 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1288 */
1289/* Copyright IBM Corp. 2018 */
1290/** @type {?} */
1291var HEX_REGEXP_STRING = '[0-9a-fA-F]';
1292/** @type {?} */
1293var UUID_V4_REGEXP_STRING = HEX_REGEXP_STRING + "{8}-" + HEX_REGEXP_STRING + "{4}-4" + HEX_REGEXP_STRING + "{3}-[89abAB]" + HEX_REGEXP_STRING + "{3}-" + HEX_REGEXP_STRING + "{12}";
1294/** @type {?} */
1295var TENANT_BASED_URL = "^(?:\\/api)?\\/(" + UUID_V4_REGEXP_STRING + ")(?:\\/)?(?:.*)$";
1296/** @type {?} */
1297var TENANT_BASED_URL_REGEXP = new RegExp(TENANT_BASED_URL);
1298
1299/**
1300 * @fileoverview added by tsickle
1301 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1302 */
1303/** @type {?} */
1304var createXHR = function () {
1305 /** @type {?} */
1306 var XMLHttpRequest = require('xhr2');
1307 return new XMLHttpRequest();
1308};
1309/** @type {?} */
1310var ajaxRequest = function (req) {
1311 return ajax(__assign({}, req, { responseType: 'text', createXHR: createXHR })).pipe(map(function (resp) { return (resp.response); }));
1312};
1313/**
1314 * @param {?} aUri
1315 * @return {?}
1316 */
1317function rxGet(aUri) {
1318 // setup the request
1319 return ajaxRequest({
1320 url: aUri
1321 });
1322}
1323/**
1324 * @param {?} aUri
1325 * @return {?}
1326 */
1327function rxGetJson(aUri) {
1328 return rxGet(aUri).pipe(map(function (data) { return JSON.parse(data); }));
1329}
1330/**
1331 * @param {?} aUri
1332 * @param {?} aData
1333 * @return {?}
1334 */
1335function rxFormPost(aUri, aData) {
1336 // setup the request
1337 return ajaxRequest({
1338 method: 'POST',
1339 url: aUri,
1340 body: aData
1341 });
1342}
1343
1344/**
1345 * @fileoverview added by tsickle
1346 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1347 */
1348/**
1349 * @param {?} aPath
1350 * @return {?}
1351 */
1352function rxReadFile(aPath) {
1353 return Observable.create(function (observer) {
1354 readFile(aPath, 'utf-8', function (err, data) {
1355 if (err) {
1356 observer.error(err);
1357 }
1358 else {
1359 observer.next(data);
1360 observer.complete();
1361 }
1362 });
1363 });
1364}
1365
1366/**
1367 * @fileoverview added by tsickle
1368 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1369 */
1370/**
1371 * @param {?=} aCred
1372 * @return {?}
1373 */
1374function _isValidCredential(aCred) {
1375 return !!(aCred &&
1376 isValidUserName(aCred.username) &&
1377 isString(aCred.password));
1378}
1379/**
1380 * @return {?}
1381 */
1382function _emptyCredentials() {
1383 return {
1384 username: '',
1385 password: ''
1386 };
1387}
1388/**
1389 * @return {?}
1390 */
1391function _getCredentialsFromEnvironment() {
1392 /** @type {?} */
1393 var username = env['ibm_wch_sdk_cli_username'] || '';
1394 /** @type {?} */
1395 var password = env['ibm_wch_sdk_cli_password'] || '';
1396 // construct
1397 return { username: username, password: password };
1398}
1399/**
1400 * Merge different credentials layers
1401 *
1402 * @param {?} aBase base layer
1403 * @param {?=} aOverride override layer
1404 *
1405 * @return {?} the merged credentials
1406 */
1407function _mergeCredentials(aBase, aOverride) {
1408 // target
1409 if (!aOverride) {
1410 return aBase;
1411 }
1412 /** @type {?} */
1413 var cred = cloneDeep(aBase);
1414 // override
1415 if (!!aOverride.username) {
1416 cred.username = aOverride.username;
1417 }
1418 if (!!aOverride.password) {
1419 cred.password = aOverride.password;
1420 }
1421 // ok
1422 return cred;
1423}
1424/** @type {?} */
1425var PADDING_MODE = RSA_PKCS1_PADDING;
1426/**
1427 * @return {?}
1428 */
1429function _loadPrivateKey() {
1430 /** @type {?} */
1431 var name = join$1(homedir(), '.ssh', 'id_rsa');
1432 return rxReadFile(name).pipe(map(function (key) { return ({ key: key, padding: PADDING_MODE }); }));
1433}
1434/** @type {?} */
1435var ENCRYPTED_ENCODING = 'base64';
1436/** @type {?} */
1437var DECTYPTED_ENCODING = 'utf8';
1438/**
1439 * @param {?} aHash
1440 * @param {?} aKey
1441 * @return {?}
1442 */
1443function _decryptPassword(aHash, aKey) {
1444 return privateDecrypt(aKey, Buffer.from(aHash, ENCRYPTED_ENCODING)).toString(DECTYPTED_ENCODING);
1445}
1446/**
1447 * @param {?} aApiBase
1448 * @return {?}
1449 */
1450function _loadCredentials(aApiBase) {
1451 // validate the URL
1452 assertHasTrailingSlash(aApiBase);
1453 /** @type {?} */
1454 var filename = join$1(homedir(), '.ibm-wch-sdk-cli', '.credentials');
1455 /** @type {?} */
1456 var key = _loadPrivateKey();
1457 // load the file
1458 return rxReadFile(filename).pipe(map(function (data) { return JSON.parse(data); }), map(function (data) { return data[aApiBase]; }), mergeMap(function (cred) {
1459 return key.pipe(map(function (k) { return _decryptPassword(cred.password, k); }), map(function (p) {
1460 cred.password = p;
1461 return cred;
1462 }));
1463 }), catchError(function () { return of(_emptyCredentials()); }));
1464}
1465/**
1466 * @param {?} aApiUrl
1467 * @return {?}
1468 */
1469function _getWindowsCredentials(aApiUrl) {
1470 // validate the URL
1471 assertHasTrailingSlash(aApiUrl);
1472 /** @type {?} */
1473 var path = normalize$1(join$1(__dirname, '..', '..', '..', 'assets', 'credman', process.arch, 'WchCredMan.exe'));
1474 /** @type {?} */
1475 var cmd = "\"" + path + "\" \"" + aApiUrl + "\"";
1476 // construct the observable
1477 return Observable.create(function (observer) {
1478 // execute the command
1479 exec(cmd, {
1480 encoding: 'utf8'
1481 }, function (error, stdout, stderr) {
1482 if (error) {
1483 observer.error(error);
1484 }
1485 else {
1486 try {
1487 // parse
1488 observer.next(JSON.parse(stdout));
1489 observer.complete();
1490 }
1491 catch (e) {
1492 observer.error(e);
1493 }
1494 }
1495 });
1496 });
1497}
1498/**
1499 * @param {?} aApiUrl
1500 * @return {?}
1501 */
1502function _getStoredCredentials(aApiUrl) {
1503 /** @type {?} */
1504 var key = _ensureTrailingSlash(aApiUrl);
1505 // normalize the URL
1506 if (platform() === 'win32') {
1507 // load the credentials module
1508 return _getWindowsCredentials(key).pipe(mergeMap(function (cred) {
1509 return _isValidCredential(cred) ? of(cred) : _loadCredentials(key);
1510 }), catchError(function () { return _loadCredentials(key); }));
1511 }
1512 // linux like fallback
1513 return _loadCredentials(key);
1514}
1515/**
1516 * @param {?} aApiUrl
1517 * @return {?}
1518 */
1519function wchToolsGetCredentials(aApiUrl) {
1520 // return
1521 return _getStoredCredentials(aApiUrl).pipe(map(function (cred) { return _mergeCredentials(_getCredentialsFromEnvironment(), cred); }), catchError(function (err) { return of(_getCredentialsFromEnvironment()); }));
1522}
1523
1524/**
1525 * @fileoverview added by tsickle
1526 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1527 */
1528/** @enum {number} */
1529var DEP_TYPE = {
1530 PEER: 0,
1531 RUNTIME: 1,
1532 DEVELOPMENT: 2,
1533};
1534DEP_TYPE[DEP_TYPE.PEER] = 'PEER';
1535DEP_TYPE[DEP_TYPE.RUNTIME] = 'RUNTIME';
1536DEP_TYPE[DEP_TYPE.DEVELOPMENT] = 'DEVELOPMENT';
1537/**
1538 * @param {?=} aType
1539 * @return {?}
1540 */
1541function getFolderForType(aType) {
1542 return aType === DEP_TYPE.PEER
1543 ? 'peerDependencies'
1544 : aType === DEP_TYPE.DEVELOPMENT
1545 ? 'devDependencies'
1546 : 'dependencies';
1547}
1548/**
1549 * Updates the package JSON to use at least the given version
1550 *
1551 * @param {?} aName name
1552 * @param {?} aMinVersion min version
1553 * @param {?} aPkg package
1554 * @param {?=} aType
1555 * @return {?}
1556 */
1557function updateMinVersion(aName, aMinVersion, aPkg, aType) {
1558 /** @type {?} */
1559 var folder = getFolderForType(aType);
1560 /** @type {?} */
1561 var deps = /** @type {?} */ (assertObject(folder, aPkg));
1562 /** @type {?} */
1563 var oldDep = deps[aName];
1564 if (isNil(oldDep) || !satisfies(aMinVersion, oldDep)) {
1565 // just update
1566 deps[aName] = "^" + aMinVersion;
1567 }
1568 // ok
1569 return aPkg;
1570}
1571/** @type {?} */
1572var rxReadFile$1 = bindNodeCallback(readFile);
1573/**
1574 * @param {?} aDir
1575 * @return {?}
1576 */
1577function findPackageJson(aDir) {
1578 // read
1579 return rxReadFile$1(join$1(aDir, 'package.json'), 'utf-8').pipe(map(function (data) { return JSON.parse(data); }), catchError(function (err) { return findPackageJson(parse(aDir).dir); }));
1580}
1581
1582/**
1583 * @fileoverview added by tsickle
1584 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1585 */
1586
1587/**
1588 * @fileoverview added by tsickle
1589 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1590 */
1591/**
1592 * @param {?} aPassword
1593 * @return {?}
1594 */
1595function _isValidPassword(aPassword) {
1596 return aPassword && aPassword.length > 0;
1597}
1598/**
1599 * @param {?} aApiUrl
1600 * @param {?} aError
1601 * @return {?}
1602 */
1603function _throwInvalidUrl(aApiUrl, aError) {
1604 return throwError(new VError(aError, 'The API URL [%s] is not a valid WCH API URL.', aApiUrl));
1605}
1606/**
1607 * @param {?} aApiUrl
1608 * @return {?}
1609 */
1610function _getCurrentUser(aApiUrl) {
1611 /** @type {?} */
1612 var currentUserUrl = "" + aApiUrl + REL_PATH_CURRENT_USER;
1613 return rxGetJson(currentUserUrl).pipe(catchError(function (error) { return _throwInvalidUrl(aApiUrl, error); }));
1614}
1615/**
1616 * @param {?} aApiUrl
1617 * @return {?}
1618 */
1619function _throwInvalidCredentials(aApiUrl) {
1620 return throwError(new VError('Unable to access credentials for the API URL [%s]. Please follow the directions on https://www.npmjs.com/package/ibm-wch-sdk-cli#credential-management to register credentials.', aApiUrl));
1621}
1622/**
1623 * @param {?} aApiUrl
1624 * @param {?} aCredentials
1625 * @return {?}
1626 */
1627function validateCredentials(aApiUrl, aCredentials) {
1628 var _a;
1629 // check the credentials object
1630 if (!aCredentials ||
1631 !isValidUserName(aCredentials.username) ||
1632 !_isValidPassword(aCredentials.password)) {
1633 return _throwInvalidCredentials(aApiUrl);
1634 }
1635 /** @type {?} */
1636 var loginUrl = "" + aApiUrl + REL_PATH_BASICAUTH_LOGIN;
1637 /** @type {?} */
1638 var body = (_a = {},
1639 _a[KEY_BASICAUTH_LOGIN_USERNAME] = aCredentials.username,
1640 _a[KEY_BASICAUTH_LOGIN_PASSWORD] = aCredentials.password,
1641 _a);
1642 // execute
1643 return rxFormPost(loginUrl, body).pipe(map(function (data) { return JSON.parse(data); }), catchError(function (error) {
1644 return throwError(new VError(error, 'Unable to login to [%s] with user [%s]. Please check your registered password.', loginUrl, aCredentials.username));
1645 }), mapTo(aApiUrl));
1646}
1647/**
1648 * @param {?} aFeed
1649 * @return {?}
1650 */
1651function _validateUser(aFeed) {
1652 // test the feed result
1653 if (!aFeed || !aFeed.externalId) {
1654 return throwError(new VError('Invalid currentuser response'));
1655 }
1656 return of(aFeed);
1657}
1658/**
1659 * Tests if the API URL is valid and if we have sufficient credentials to access the API
1660 *
1661 * @param {?} aUrl the API URL
1662 * @param {?} bValidateWithCredentials
1663 * @return {?} the url
1664 */
1665function validateApiUrl(aUrl, bValidateWithCredentials) {
1666 // check if the URL is valud
1667 if (!isUri(aUrl)) {
1668 return throwError(new VError('Please enter a valid API URL. Copy this URL from the "Hub Information" section of your WCH tenant.'));
1669 }
1670 /** @type {?} */
1671 var normUrl = _ensureTrailingSlash(aUrl);
1672 if (bValidateWithCredentials) {
1673 /** @type {?} */
1674 var onCredentials = wchToolsGetCredentials(normUrl).pipe(catchError(function (error) { return _throwInvalidCredentials(normUrl); }));
1675 /** @type {?} */
1676 var onValidUrl = _getCurrentUser(normUrl).pipe(switchMap(_validateUser), switchMapTo(onCredentials), switchMap(function (cred) { return validateCredentials(normUrl, cred); }));
1677 // ok
1678 return onValidUrl;
1679 }
1680 else {
1681 /** @type {?} */
1682 var onValidUrl = _getCurrentUser(normUrl).pipe(switchMap(_validateUser), mapTo(normUrl));
1683 // ok
1684 return onValidUrl;
1685 }
1686}
1687/** @type {?} */
1688var PACKAGE_JSON = /** @type {?} */ ('/package.json');
1689/** @type {?} */
1690var FALLBACK = /** @type {?} */ ('/data');
1691/** @type {?} */
1692var OPTIONS = /** @type {?} */ ('.wchtoolsoptions.json');
1693/** @type {?} */
1694var SDK_IMPORT = '@ibm-wch-sdk/ng';
1695/** @type {?} */
1696var CLI_IMPORT = '@ibm-wch-sdk/cli';
1697/** @type {?} */
1698var WCHTOOLS_DEPENDENCIES = 'wchtools-dependencies';
1699/**
1700 * @return {?}
1701 */
1702function _findBuildVersion() {
1703 // find the package
1704 return findPackageJson(__dirname).pipe(pluck('version'));
1705}
1706/**
1707 * Decode the version from the dependency
1708 *
1709 * @param {?} aVersion the version
1710 *
1711 * @return {?} observable of the version
1712 */
1713function _fromDependency(aVersion) {
1714 /** @type {?} */
1715 var parsed = coerce(aVersion);
1716 return !!parsed ? of(parsed.version) : _findBuildVersion();
1717}
1718/**
1719 * @param {?} host
1720 * @return {?}
1721 */
1722function findSdkVersion(host) {
1723 /** @type {?} */
1724 var buf = host.read(PACKAGE_JSON);
1725 if (isNil(buf)) {
1726 return _findBuildVersion();
1727 }
1728 /** @type {?} */
1729 var pkg = JSON.parse(buf.toString());
1730 /** @type {?} */
1731 var deps = pkg.dependencies || {};
1732 /** @type {?} */
1733 var devDeps = pkg.devDependencies || {};
1734 /** @type {?} */
1735 var fromPkg = deps[SDK_IMPORT] || devDeps[CLI_IMPORT];
1736 return isNotNil(fromPkg) ? _fromDependency(fromPkg) : _findBuildVersion();
1737}
1738/**
1739 * @param {?} host
1740 * @return {?}
1741 */
1742function findDataDir(host) {
1743 /** @type {?} */
1744 var buf = host.read(PACKAGE_JSON);
1745 if (isNil(buf)) {
1746 return FALLBACK;
1747 }
1748 /** @type {?} */
1749 var pkg = JSON.parse(buf.toString());
1750 /** @type {?} */
1751 var cfg = pkg.config || {};
1752 /** @type {?} */
1753 var data = cfg.data || FALLBACK;
1754 return resolve(/** @type {?} */ ('/'), data);
1755}
1756/**
1757 * @param {?} host
1758 * @return {?}
1759 */
1760function findWchToolsOptions(host) {
1761 return resolve(findDataDir(host), OPTIONS);
1762}
1763/**
1764 * @param {?} aDeps
1765 * @param {?} aPkg
1766 * @return {?}
1767 */
1768function addToWchToolsDependencies(aDeps, aPkg) {
1769 /** @type {?} */
1770 var deps = assertArray(WCHTOOLS_DEPENDENCIES, aPkg);
1771 // filter
1772 deps.push.apply(deps, __spread(aDeps.filter(function (dep) { return deps.indexOf(dep) < 0; })));
1773}
1774
1775/**
1776 * @fileoverview added by tsickle
1777 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1778 */
1779/** @type {?} */
1780var _keys = Object.keys;
1781/** @type {?} */
1782var KEY_WEIGHTS = {
1783 name: 1,
1784 description: 2,
1785 id: 3,
1786 classification: 4
1787};
1788/**
1789 * @param {?} aLeft
1790 * @param {?} aRight
1791 * @return {?}
1792 */
1793function _compareNumber(aLeft, aRight) {
1794 return aLeft < aRight ? -1 : aLeft > aRight ? +1 : 0;
1795}
1796/**
1797 * @param {?} aName
1798 * @return {?}
1799 */
1800function _getKey(aName) {
1801 return KEY_WEIGHTS[aName] || Number.MAX_SAFE_INTEGER;
1802}
1803/**
1804 * @param {?} aLeft
1805 * @param {?} aRight
1806 * @return {?}
1807 */
1808function _compareName(aLeft, aRight) {
1809 /** @type {?} */
1810 var c = _compareNumber(_getKey(aLeft), _getKey(aRight));
1811 if (c === 0) {
1812 c = aLeft.localeCompare(aRight);
1813 }
1814 // ok
1815 return c;
1816}
1817/**
1818 * @param {?} aData
1819 * @return {?}
1820 */
1821function _canonicalize(aData) {
1822 // handle
1823 if (isArray(aData)) {
1824 /** @type {?} */
1825 var copy_1 = [];
1826 aData.forEach(function (v) { return copy_1.push(_canonicalize(v)); });
1827 return copy_1;
1828 }
1829 if (isPlainObject(aData)) {
1830 /** @type {?} */
1831 var copy_2 = {};
1832 _keys(aData)
1833 .sort(_compareName)
1834 .forEach(function (k) { return (copy_2[k] = _canonicalize(aData[k])); });
1835 return copy_2;
1836 }
1837 // nothing to do
1838 return aData;
1839}
1840/**
1841 * @param {?} aData
1842 * @return {?}
1843 */
1844function serializeJson(aData) {
1845 return aData ? JSON.stringify(aData, undefined, 2) : undefined;
1846}
1847/**
1848 * @param {?} aName
1849 * @param {?} aGenerator
1850 * @param {?} aObj
1851 * @return {?}
1852 */
1853function updateField(aName, aGenerator, aObj) {
1854 /** @type {?} */
1855 var oldValue = aObj[aName];
1856 if (isNil(oldValue)) {
1857 // update with the generated value
1858 aObj[aName] = aGenerator();
1859 }
1860 return aObj;
1861}
1862
1863/**
1864 * @fileoverview added by tsickle
1865 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1866 */
1867/**
1868 * @param {?=} aSource
1869 * @return {?}
1870 */
1871function serializeLines(aSource) {
1872 return aSource ? aSource.join('\n') : undefined;
1873}
1874/**
1875 * @param {?=} aSource
1876 * @return {?}
1877 */
1878function parseLines(aSource) {
1879 return aSource ? aSource.split('\n') : [];
1880}
1881/**
1882 * @param {?} aSource
1883 * @param {?} aInsert
1884 * @return {?}
1885 */
1886function insertLines(aSource, aInsert) {
1887 if (aSource) {
1888 /** @type {?} */
1889 var existing_1 = new Set(aSource);
1890 return __spread(aSource, aInsert.filter(function (line) { return !existing_1.has(line); }));
1891 }
1892 else {
1893 // just insert into the empty file
1894 return __spread(aInsert);
1895 }
1896}
1897
1898/**
1899 * @fileoverview added by tsickle
1900 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1901 */
1902/**
1903 * Reads a text file from the tree and then transforms it using the given function. If the result
1904 * is null or undefined, the file will be deleted, else replaced or created.
1905 *
1906 * @param {?} aName name of the file
1907 * @param {?} aOp the operator
1908 * @param {?} aTree the tree to work in
1909 * @return {?}
1910 */
1911function rxTransformTextFile(aName, aOp, aTree) {
1912 /** @type {?} */
1913 var buffer = aTree.read(aName);
1914 /** @type {?} */
1915 var value = isNotNil(buffer) ? buffer.toString() : null;
1916 /** @type {?} */
1917 var op = /** @type {?} */ (aOp);
1918 // replace
1919 return op(value, aName).pipe(first(), map(function (result) {
1920 return isNotNil(result)
1921 ? isNotNil(buffer)
1922 ? aTree.overwrite(aName, result)
1923 : aTree.create(aName, result)
1924 : isNotNil(buffer)
1925 ? aTree.delete(aName)
1926 : undefined;
1927 }), mapTo(aName));
1928}
1929/**
1930 * Reads a JSON file from the tree and then transforms it using the given function. If the result
1931 * is null or undefined, the file will be deleted, else replaced or created.
1932 *
1933 * @param {?} aName name of the file
1934 * @param {?} aOp the operator
1935 * @param {?} aTree the tree to work in
1936 * @return {?}
1937 */
1938function rxTransformJsonFile(aName, aOp, aTree) {
1939 /** @type {?} */
1940 var op = /** @type {?} */ (aOp);
1941 // dispatch
1942 return rxTransformTextFile(aName, function (textContent, path) {
1943 return op(textContent ? JSON.parse(textContent) : undefined, path).pipe(map(_canonicalize), map(serializeJson));
1944 }, aTree);
1945}
1946/**
1947 * Reads a line based file from the tree and then transforms it using the given function. If the result
1948 * is null or undefined, the file will be deleted, else replaced or created.
1949 *
1950 * @param {?} aName name of the file
1951 * @param {?} aOp the operator
1952 * @param {?} aTree the tree to work in
1953 * @return {?}
1954 */
1955function rxTransformLinesFile(aName, aOp, aTree) {
1956 /** @type {?} */
1957 var op = /** @type {?} */ (aOp);
1958 // dispatch
1959 return rxTransformTextFile(aName, function (textContent, path) {
1960 return op(textContent ? parseLines(textContent) : undefined, path).pipe(map(serializeLines));
1961 }, aTree);
1962}
1963
1964/**
1965 * @fileoverview added by tsickle
1966 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1967 */
1968/**
1969 * @param {?} aName
1970 * @param {?} aCount
1971 * @return {?}
1972 */
1973function _skipPrefix(aName, aCount) {
1974 /** @type {?} */
1975 var idx = 0;
1976 for (var i = 0; i < aCount; ++i) {
1977 /** @type {?} */
1978 var nextIdx = aName.indexOf('/', idx);
1979 if (nextIdx >= idx) {
1980 idx = nextIdx + 1;
1981 }
1982 else {
1983 return null;
1984 }
1985 }
1986 // split
1987 return aName.substring(idx);
1988}
1989var StreamOnBuffer = /** @class */ (function (_super) {
1990 __extends(StreamOnBuffer, _super);
1991 function StreamOnBuffer() {
1992 var _this = _super !== null && _super.apply(this, arguments) || this;
1993 _this.buffers = [];
1994 return _this;
1995 }
1996 /**
1997 * @param {?} chunk
1998 * @param {?} encoding
1999 * @param {?} callback
2000 * @return {?}
2001 */
2002 StreamOnBuffer.prototype._write = /**
2003 * @param {?} chunk
2004 * @param {?} encoding
2005 * @param {?} callback
2006 * @return {?}
2007 */
2008 function (chunk, encoding, callback) {
2009 this.buffers.push(chunk);
2010 callback();
2011 };
2012 /**
2013 * @param {?} callback
2014 * @return {?}
2015 */
2016 StreamOnBuffer.prototype._final = /**
2017 * @param {?} callback
2018 * @return {?}
2019 */
2020 function (callback) {
2021 callback();
2022 this.emit('close');
2023 };
2024 return StreamOnBuffer;
2025}(Writable));
2026/**
2027 * @param {?} aTree
2028 * @param {?} aEntry
2029 * @param {?} aDstDir
2030 * @param {?} aSkip
2031 * @return {?}
2032 */
2033function _rxExtractEntry(aTree, aEntry, aDstDir, aSkip) {
2034 /** @type {?} */
2035 var path = _skipPrefix(aEntry.path, aSkip);
2036 if (!path) {
2037 // nothing
2038 return of('').pipe(tap(function () { return aEntry.autodrain(); }), filter(function () { return false; }));
2039 }
2040 /** @type {?} */
2041 var fileName = normalize$1(join$1(aDstDir, path));
2042 // handle directories
2043 if (aEntry.type === 'Directory') {
2044 // create the directory
2045 return of('').pipe(tap(function () { return aEntry.autodrain(); }), filter(function () { return false; }));
2046 }
2047 else {
2048 /** @type {?} */
2049 var stream_1 = aEntry.pipe(new StreamOnBuffer());
2050 // attach
2051 return fromEvent(stream_1, 'close').pipe(
2052 // just take one
2053 first(),
2054 // copy into the tree
2055 map(function () { return aTree.create(fileName, Buffer.concat(stream_1.buffers)); }),
2056 // map to the target name
2057 mapTo(fileName));
2058 }
2059}
2060/**
2061 * @param {?} aTree
2062 * @param {?} aSrcUrl
2063 * @param {?} aDstDir
2064 * @param {?=} aSkip
2065 * @return {?}
2066 */
2067function rxUnzipFromUrl(aTree, aSrcUrl, aDstDir, aSkip) {
2068 if (aSkip === void 0) { aSkip = 0; }
2069 // defer
2070 return defer(function () {
2071 /** @type {?} */
2072 var stream = get(aSrcUrl).pipe(Parse());
2073 /** @type {?} */
2074 var onEntry = fromEvent(stream, 'entry');
2075 /** @type {?} */
2076 var onClose = fromEvent(stream, 'close');
2077 // return the full stream
2078 return onEntry.pipe(takeUntil(onClose), mergeMap(function (entry) { return _rxExtractEntry(aTree, entry, aDstDir, aSkip); }));
2079 });
2080}
2081
2082/**
2083 * @fileoverview added by tsickle
2084 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2085 */
2086/**
2087 * @param {?=} aString
2088 * @return {?}
2089 */
2090function _parseHtml(aString) {
2091 return of(load(isNotNil(aString) ? /** @type {?} */ ((aString)) : ''));
2092}
2093/**
2094 * @param {?} aHtml
2095 * @return {?}
2096 */
2097function _serializeHtml(aHtml) {
2098 return of(/** @type {?} */ ((aHtml)).html());
2099}
2100/**
2101 * Reads an HMTL from the tree and then transforms it using the given function. If the result
2102 * is null or undefined, the file will be deleted, else replaced or created.
2103 *
2104 * @param {?} aName name of the file
2105 * @param {?} aOp the operator
2106 * @param {?} aTree the tree to work in
2107 * @return {?}
2108 */
2109function rxTransformHtmlFile(aName, aOp, aTree) {
2110 /** @type {?} */
2111 var op = /** @type {?} */ (aOp);
2112 // dispatch
2113 return rxTransformTextFile(aName, function (textContent, path) {
2114 return _parseHtml(textContent).pipe(switchMap(function (html) { return op(html, path); }), switchMap(_serializeHtml));
2115 }, aTree);
2116}
2117
2118/**
2119 * @fileoverview added by tsickle
2120 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2121 */
2122
2123/**
2124 * @fileoverview added by tsickle
2125 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2126 */
2127/**
2128 * @param {?} host
2129 * @param {?} path
2130 * @return {?}
2131 */
2132function getSourceFile(host, path) {
2133 /** @type {?} */
2134 var buffer = host.read(path);
2135 if (!buffer) {
2136 throw new SchematicsException("Could not find " + path + ".");
2137 }
2138 /** @type {?} */
2139 var content = buffer.toString();
2140 /** @type {?} */
2141 var source = createSourceFile(path, content, ScriptTarget.Latest, true);
2142 return source;
2143}
2144
2145/**
2146 * @fileoverview added by tsickle
2147 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2148 */
2149/**
2150 * @param {?} aChanges
2151 * @param {?} aRecorder
2152 * @return {?}
2153 */
2154function insertChanges(aChanges, aRecorder) {
2155 aChanges.forEach(function (change) {
2156 // delete
2157 if (change instanceof InsertChange) {
2158 aRecorder.insertLeft(change.pos, change.toAdd);
2159 }
2160 else if (change instanceof RemoveChange) ;
2161 else if (change instanceof ReplaceChange) {
2162 /** @type {?} */
2163 var anyChange = /** @type {?} */ (change);
2164 aRecorder.remove(anyChange.pos, anyChange.oldText.length);
2165 aRecorder.insertLeft(anyChange.pos, anyChange.newText);
2166 }
2167 });
2168}
2169/**
2170 * @param {?} aFile
2171 * @param {?} aOp
2172 * @param {?} aHost
2173 * @return {?}
2174 */
2175function changeSourceFile(aFile, aOp, aHost) {
2176 // make sure at least an empty file exists
2177 if (!aHost.exists(aFile)) {
2178 aHost.create(aFile, '');
2179 }
2180 /** @type {?} */
2181 var recorder = aHost.beginUpdate(aFile);
2182 insertChanges(aOp(aFile, getSourceFile(aHost, aFile)), recorder);
2183 aHost.commitUpdate(recorder);
2184}
2185/**
2186 * Changes the identified module by adding a couple of imports
2187 *
2188 * @param {?} aFile the filename
2189 * @param {?} aModules the modules to be added
2190 * @param {?} aHost the tree
2191 * @return {?}
2192 */
2193function addImportsToModule(aFile, aModules, aHost) {
2194 // iterate
2195 Object.keys(aModules).forEach(function (name) {
2196 return changeSourceFile(aFile, function (file, content) { return addImportToModule(content, file, name, aModules[name]); }, aHost);
2197 });
2198}
2199
2200/**
2201 * @fileoverview added by tsickle
2202 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2203 */
2204/**
2205 * @param {?} aType
2206 * @return {?}
2207 */
2208function byType(aType) {
2209 return function (node) { return node && node.kind === aType; };
2210}
2211/**
2212 * @param {?} aText
2213 * @return {?}
2214 */
2215function byText(aText) {
2216 return function (node) { return node && node.getText() === aText; };
2217}
2218/**
2219 * @param {?} aText
2220 * @return {?}
2221 */
2222function byName(aText) {
2223 return function (node) { return !!(node && node.name && node.name.getText() === aText); };
2224}
2225/**
2226 * @param {?} aType
2227 * @param {?} aName
2228 * @return {?}
2229 */
2230function byTypeAndName(aType, aName) {
2231 return function (node) { return node && node.kind === aType && node.getText() === aName; };
2232}
2233/**
2234 * @param {?} aName
2235 * @return {?}
2236 */
2237function byIdentifier(aName) {
2238 return byTypeAndName(SyntaxKind.Identifier, aName);
2239}
2240
2241/**
2242 * @fileoverview added by tsickle
2243 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2244 */
2245
2246/**
2247 * @fileoverview added by tsickle
2248 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2249 */
2250
2251/**
2252 * @fileoverview added by tsickle
2253 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2254 */
2255
2256/**
2257 * @fileoverview added by tsickle
2258 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2259 */
2260
2261export { findModuleFromOptions, findModule, buildRelativePath, insertImport, findNodes, getSourceNodes, findNode, insertAfterLastOccurrence, getContentOfKeyLiteral, getDecoratorMetadata, getFirstNgModuleName, addSymbolToNgModuleMetadata, addDeclarationToModule, addImportToModule, addProviderToModule, addExportToModule, addBootstrapToModule, addEntryComponentToModule, isImported, getWorkspacePath, getWorkspace, addProjectToWorkspace, getConfig, getAppFromConfig, configPath, findBootstrapModuleCall, findBootstrapModulePath, getAppModulePath, parseName, validateName, validateHtmlSelector, validateProjectName, htmlSelectorRe, NoopChange, InsertChange, RemoveChange, ReplaceChange, assertNotNull, assertParameter, isValidUrl, assertIsUrl, isValidEmail, isValidUserName, assertIsEmail, assertIsValidUserName, assertHasTrailingSlash, TENANT_BASED_URL_REGEXP, _ensureTrailingSlash as ensureTrailingSlash, _hasTrailingSlash as hasTrailingSlash, rxGet, rxGetJson, rxFormPost, wchToolsGetCredentials, validateCredentials, validateApiUrl, findSdkVersion, findDataDir, findWchToolsOptions, addToWchToolsDependencies, WCHTOOLS_DEPENDENCIES, rxReadFile, rxTransformTextFile, rxTransformJsonFile, rxTransformLinesFile, serializeJson, updateField, _canonicalize as canonicalizeJSON, rxUnzipFromUrl, rxTransformHtmlFile, getSourceFile, insertChanges, changeSourceFile, addImportsToModule, byType, byText, byName, byTypeAndName, byIdentifier, serializeLines, parseLines, insertLines, getFolderForType, updateMinVersion, findPackageJson, DEP_TYPE };
2262
2263//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWJtLXdjaC1zZGstc2NoZW1hdGljcy11dGlscy5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS9maW5kLW1vZHVsZS50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS9jaGFuZ2UudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3V0aWxpdHkvYXN0LXV0aWxzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy91dGlsaXR5L2NvbmZpZy50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS9uZy1hc3QtdXRpbHMudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3V0aWxpdHkvcGFyc2UtbmFtZS50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdXRpbGl0eS92YWxpZGF0aW9uLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvdXJsLnV0aWxzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvYXNzZXJ0LnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvdGVuYW50LnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvcngucmVxdWVzdC50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvd2NoL3J4LmZpbGUudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3djaC93Y2h0b29scy50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvcGFja2FnZS9wYWNrYWdlLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvd2NoLnV0aWxzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy93Y2gvanNvbi50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdGV4dC9saW5lcy50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvd2NoL3J4LnRyZWUudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3djaC9yeC56aXAudHMiLCJuZzovL0BpYm0td2NoLXNkay9zY2hlbWF0aWNzLXV0aWxzL3djaC9yeC5odG1sLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy90eXBlc2NyaXB0L3NvdXJjZS50cyIsIm5nOi8vQGlibS13Y2gtc2RrL3NjaGVtYXRpY3MtdXRpbHMvdHlwZXNjcmlwdC9jaGFuZ2VzLnRzIiwibmc6Ly9AaWJtLXdjaC1zZGsvc2NoZW1hdGljcy11dGlscy90eXBlc2NyaXB0L2ZpbmRlcnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgUGF0aCwgam9pbiwgbm9ybWFsaXplLCByZWxhdGl2ZSwgc3RyaW5ncyB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IERpckVudHJ5LCBUcmVlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L3NjaGVtYXRpY3MnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9kdWxlT3B0aW9ucyB7XG4gIG1vZHVsZT86IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBmbGF0PzogYm9vbGVhbjtcbiAgcGF0aD86IHN0cmluZztcbiAgc2tpcEltcG9ydD86IGJvb2xlYW47XG59XG5cblxuLyoqXG4gKiBGaW5kIHRoZSBtb2R1bGUgcmVmZXJyZWQgYnkgYSBzZXQgb2Ygb3B0aW9ucyBwYXNzZWQgdG8gdGhlIHNjaGVtYXRpY3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTW9kdWxlRnJvbU9wdGlvbnMoaG9zdDogVHJlZSwgb3B0aW9uczogTW9kdWxlT3B0aW9ucyk6IFBhdGggfCB1bmRlZmluZWQge1xuICBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnc2tpcEltcG9ydCcpICYmIG9wdGlvbnMuc2tpcEltcG9ydCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoIW9wdGlvbnMubW9kdWxlKSB7XG4gICAgY29uc3QgcGF0aFRvQ2hlY2sgPSAob3B0aW9ucy5wYXRoIHx8ICcnKVxuICAgICAgICAgICAgICAgICAgICAgICsgKG9wdGlvbnMuZmxhdCA/ICcnIDogJy8nICsgc3RyaW5ncy5kYXNoZXJpemUob3B0aW9ucy5uYW1lKSk7XG5cbiAgICByZXR1cm4gbm9ybWFsaXplKGZpbmRNb2R1bGUoaG9zdCwgcGF0aFRvQ2hlY2spKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBtb2R1bGVQYXRoID0gbm9ybWFsaXplKFxuICAgICAgJy8nICsgKG9wdGlvbnMucGF0aCkgKyAnLycgKyBvcHRpb25zLm1vZHVsZSk7XG4gICAgY29uc3QgbW9kdWxlQmFzZU5hbWUgPSBub3JtYWxpemUobW9kdWxlUGF0aCkuc3BsaXQoJy8nKS5wb3AoKTtcblxuICAgIGlmIChob3N0LmV4aXN0cyhtb2R1bGVQYXRoKSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZShtb2R1bGVQYXRoKTtcbiAgICB9IGVsc2UgaWYgKGhvc3QuZXhpc3RzKG1vZHVsZVBhdGggKyAnLnRzJykpIHtcbiAgICAgIHJldHVybiBub3JtYWxpemUobW9kdWxlUGF0aCArICcudHMnKTtcbiAgICB9IGVsc2UgaWYgKGhvc3QuZXhpc3RzKG1vZHVsZVBhdGggKyAnLm1vZHVsZS50cycpKSB7XG4gICAgICByZXR1cm4gbm9ybWFsaXplKG1vZHVsZVBhdGggKyAnLm1vZHVsZS50cycpO1xuICAgIH0gZWxzZSBpZiAoaG9zdC5leGlzdHMobW9kdWxlUGF0aCArICcvJyArIG1vZHVsZUJhc2VOYW1lICsgJy5tb2R1bGUudHMnKSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZShtb2R1bGVQYXRoICsgJy8nICsgbW9kdWxlQmFzZU5hbWUgKyAnLm1vZHVsZS50cycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NwZWNpZmllZCBtb2R1bGUgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGdW5jdGlvbiB0byBmaW5kIHRoZSBcImNsb3Nlc3RcIiBtb2R1bGUgdG8gYSBnZW5lcmF0ZWQgZmlsZSdzIHBhdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTW9kdWxlKGhvc3Q6IFRyZWUsIGdlbmVyYXRlRGlyOiBzdHJpbmcpOiBQYXRoIHtcbiAgbGV0IGRpcjogRGlyRW50cnkgfCBudWxsID0gaG9zdC5nZXREaXIoJy8nICsgZ2VuZXJhdGVEaXIpO1xuXG4gIGNvbnN0IG1vZHVsZVJlID0gL1xcLm1vZHVsZVxcLnRzJC87XG4gIGNvbnN0IHJvdXRpbmdNb2R1bGVSZSA9IC8tcm91dGluZ1xcLm1vZHVsZVxcLnRzLztcblxuICB3aGlsZSAoZGlyKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IGRpci5zdWJmaWxlcy5maWx0ZXIocCA9PiBtb2R1bGVSZS50ZXN0KHApICYmICFyb3V0aW5nTW9kdWxlUmUudGVzdChwKSk7XG5cbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT0gMSkge1xuICAgICAgcmV0dXJuIGpvaW4oZGlyLnBhdGgsIG1hdGNoZXNbMF0pO1xuICAgIH0gZWxzZSBpZiAobWF0Y2hlcy5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vcmUgdGhhbiBvbmUgbW9kdWxlIG1hdGNoZXMuIFVzZSBza2lwLWltcG9ydCBvcHRpb24gdG8gc2tpcCBpbXBvcnRpbmcgJ1xuICAgICAgICArICd0aGUgY29tcG9uZW50IGludG8gdGhlIGNsb3Nlc3QgbW9kdWxlLicpO1xuICAgIH1cblxuICAgIGRpciA9IGRpci5wYXJlbnQ7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIGFuIE5nTW9kdWxlLiBVc2UgdGhlIHNraXAtaW1wb3J0ICdcbiAgICArICdvcHRpb24gdG8gc2tpcCBpbXBvcnRpbmcgaW4gTmdNb2R1bGUuJyk7XG59XG5cbi8qKlxuICogQnVpbGQgYSByZWxhdGl2ZSBwYXRoIGZyb20gb25lIGZpbGUgcGF0aCB0byBhbm90aGVyIGZpbGUgcGF0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUmVsYXRpdmVQYXRoKGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IHN0cmluZyB7XG4gIGZyb20gPSBub3JtYWxpemUoZnJvbSk7XG4gIHRvID0gbm9ybWFsaXplKHRvKTtcblxuICAvLyBDb252ZXJ0IHRvIGFycmF5cy5cbiAgY29uc3QgZnJvbVBhcnRzID0gZnJvbS5zcGxpdCgnLycpO1xuICBjb25zdCB0b1BhcnRzID0gdG8uc3BsaXQoJy8nKTtcblxuICAvLyBSZW1vdmUgZmlsZSBuYW1lcyAocHJlc2VydmluZyBkZXN0aW5hdGlvbilcbiAgZnJvbVBhcnRzLnBvcCgpO1xuICBjb25zdCB0b0ZpbGVOYW1lID0gdG9QYXJ0cy5wb3AoKTtcblxuICBjb25zdCByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZShub3JtYWxpemUoZnJvbVBhcnRzLmpvaW4oJy8nKSksIG5vcm1hbGl6ZSh0b1BhcnRzLmpvaW4oJy8nKSkpO1xuICBsZXQgcGF0aFByZWZpeCA9ICcnO1xuXG4gIC8vIFNldCB0aGUgcGF0aCBwcmVmaXggZm9yIHNhbWUgZGlyIG9yIGNoaWxkIGRpciwgcGFyZW50IGRpciBzdGFydHMgd2l0aCBgLi5gXG4gIGlmICghcmVsYXRpdmVQYXRoKSB7XG4gICAgcGF0aFByZWZpeCA9ICcuJztcbiAgfSBlbHNlIGlmICghcmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgIHBhdGhQcmVmaXggPSBgLi9gO1xuICB9XG4gIGlmIChwYXRoUHJlZml4ICYmICFwYXRoUHJlZml4LmVuZHNXaXRoKCcvJykpIHtcbiAgICBwYXRoUHJlZml4ICs9ICcvJztcbiAgfVxuXG4gIHJldHVybiBwYXRoUHJlZml4ICsgKHJlbGF0aXZlUGF0aCA/IHJlbGF0aXZlUGF0aCArICcvJyA6ICcnKSArIHRvRmlsZU5hbWU7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvc3Qge1xuICB3cml0ZShwYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIHJlYWQocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xufVxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlIHtcbiAgYXBwbHkoaG9zdDogSG9zdCk6IFByb21pc2U8dm9pZD47XG5cbiAgLy8gVGhlIGZpbGUgdGhpcyBjaGFuZ2Ugc2hvdWxkIGJlIGFwcGxpZWQgdG8uIFNvbWUgY2hhbmdlcyBtaWdodCBub3QgYXBwbHkgdG9cbiAgLy8gYSBmaWxlIChtYXliZSB0aGUgY29uZmlnKS5cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nIHwgbnVsbDtcblxuICAvLyBUaGUgb3JkZXIgdGhpcyBjaGFuZ2Ugc2hvdWxkIGJlIGFwcGxpZWQuIE5vcm1hbGx5IHRoZSBwb3NpdGlvbiBpbnNpZGUgdGhlIGZpbGUuXG4gIC8vIENoYW5nZXMgYXJlIGFwcGxpZWQgZnJvbSB0aGUgYm90dG9tIG9mIGEgZmlsZSB0byB0aGUgdG9wLlxuICByZWFkb25seSBvcmRlcjogbnVtYmVyO1xuXG4gIC8vIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGlzIGNoYW5nZS4gVGhpcyB3aWxsIGJlIG91dHB1dHRlZCBpbiBhIGRyeSBvciB2ZXJib3NlIHJ1bi5cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb246IHN0cmluZztcbn1cblxuXG4vKipcbiAqIEFuIG9wZXJhdGlvbiB0aGF0IGRvZXMgbm90aGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vb3BDaGFuZ2UgaW1wbGVtZW50cyBDaGFuZ2Uge1xuICBkZXNjcmlwdGlvbiA9ICdObyBvcGVyYXRpb24uJztcbiAgb3JkZXIgPSBJbmZpbml0eTtcbiAgcGF0aCA9IG51bGw7XG4gIGFwcGx5KCkgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7IH1cbn1cblxuXG4vKipcbiAqIFdpbGwgYWRkIHRleHQgdG8gdGhlIHNvdXJjZSBjb2RlLlxuICovXG5leHBvcnQgY2xhc3MgSW5zZXJ0Q2hhbmdlIGltcGxlbWVudHMgQ2hhbmdlIHtcblxuICBvcmRlcjogbnVtYmVyO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcsIHB1YmxpYyBwb3M6IG51bWJlciwgcHVibGljIHRvQWRkOiBzdHJpbmcpIHtcbiAgICBpZiAocG9zIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOZWdhdGl2ZSBwb3NpdGlvbnMgYXJlIGludmFsaWQnKTtcbiAgICB9XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGBJbnNlcnRlZCAke3RvQWRkfSBpbnRvIHBvc2l0aW9uICR7cG9zfSBvZiAke3BhdGh9YDtcbiAgICB0aGlzLm9yZGVyID0gcG9zO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IGluc2VydCBzcGFjZXMgaWYgdGhlcmUgaXMgbm9uZSBpbiB0aGUgb3JpZ2luYWwgc3RyaW5nLlxuICAgKi9cbiAgYXBwbHkoaG9zdDogSG9zdCkge1xuICAgIHJldHVybiBob3N0LnJlYWQodGhpcy5wYXRoKS50aGVuKGNvbnRlbnQgPT4ge1xuICAgICAgY29uc3QgcHJlZml4ID0gY29udGVudC5zdWJzdHJpbmcoMCwgdGhpcy5wb3MpO1xuICAgICAgY29uc3Qgc3VmZml4ID0gY29udGVudC5zdWJzdHJpbmcodGhpcy5wb3MpO1xuXG4gICAgICByZXR1cm4gaG9zdC53cml0ZSh0aGlzLnBhdGgsIGAke3ByZWZpeH0ke3RoaXMudG9BZGR9JHtzdWZmaXh9YCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaWxsIHJlbW92ZSB0ZXh0IGZyb20gdGhlIHNvdXJjZSBjb2RlLlxuICovXG5leHBvcnQgY2xhc3MgUmVtb3ZlQ2hhbmdlIGltcGxlbWVudHMgQ2hhbmdlIHtcblxuICBvcmRlcjogbnVtYmVyO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcsIHByaXZhdGUgcG9zOiBudW1iZXIsIHByaXZhdGUgdG9SZW1vdmU6IHN0cmluZykge1xuICAgIGlmIChwb3MgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05lZ2F0aXZlIHBvc2l0aW9ucyBhcmUgaW52YWxpZCcpO1xuICAgIH1cbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gYFJlbW92ZWQgJHt0b1JlbW92ZX0gaW50byBwb3NpdGlvbiAke3Bvc30gb2YgJHtwYXRofWA7XG4gICAgdGhpcy5vcmRlciA9IHBvcztcbiAgfVxuXG4gIGFwcGx5KGhvc3Q6IEhvc3QpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gaG9zdC5yZWFkKHRoaXMucGF0aCkudGhlbihjb250ZW50ID0+IHtcbiAgICAgIGNvbnN0IHByZWZpeCA9IGNvbnRlbnQuc3Vic3RyaW5nKDAsIHRoaXMucG9zKTtcbiAgICAgIGNvbnN0IHN1ZmZpeCA9IGNvbnRlbnQuc3Vic3RyaW5nKHRoaXMucG9zICsgdGhpcy50b1JlbW92ZS5sZW5ndGgpO1xuXG4gICAgICAvLyBUT0RPOiB0aHJvdyBlcnJvciBpZiB0b1JlbW92ZSBkb2Vzbid0IG1hdGNoIHJlbW92ZWQgc3RyaW5nLlxuICAgICAgcmV0dXJuIGhvc3Qud3JpdGUodGhpcy5wYXRoLCBgJHtwcmVmaXh9JHtzdWZmaXh9YCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaWxsIHJlcGxhY2UgdGV4dCBmcm9tIHRoZSBzb3VyY2UgY29kZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlcGxhY2VDaGFuZ2UgaW1wbGVtZW50cyBDaGFuZ2Uge1xuICBvcmRlcjogbnVtYmVyO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcsIHByaXZhdGUgcG9zOiBudW1iZXIsIHByaXZhdGUgb2xkVGV4dDogc3RyaW5nLFxuICAgICAgICAgICAgICBwcml2YXRlIG5ld1RleHQ6IHN0cmluZykge1xuICAgIGlmIChwb3MgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05lZ2F0aXZlIHBvc2l0aW9ucyBhcmUgaW52YWxpZCcpO1xuICAgIH1cbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gYFJlcGxhY2VkICR7b2xkVGV4dH0gaW50byBwb3NpdGlvbiAke3Bvc30gb2YgJHtwYXRofSB3aXRoICR7bmV3VGV4dH1gO1xuICAgIHRoaXMub3JkZXIgPSBwb3M7XG4gIH1cblxuICBhcHBseShob3N0OiBIb3N0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGhvc3QucmVhZCh0aGlzLnBhdGgpLnRoZW4oY29udGVudCA9PiB7XG4gICAgICBjb25zdCBwcmVmaXggPSBjb250ZW50LnN1YnN0cmluZygwLCB0aGlzLnBvcyk7XG4gICAgICBjb25zdCBzdWZmaXggPSBjb250ZW50LnN1YnN0cmluZyh0aGlzLnBvcyArIHRoaXMub2xkVGV4dC5sZW5ndGgpO1xuICAgICAgY29uc3QgdGV4dCA9IGNvbnRlbnQuc3Vic3RyaW5nKHRoaXMucG9zLCB0aGlzLnBvcyArIHRoaXMub2xkVGV4dC5sZW5ndGgpO1xuXG4gICAgICBpZiAodGV4dCAhPT0gdGhpcy5vbGRUZXh0KSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYEludmFsaWQgcmVwbGFjZTogXCIke3RleHR9XCIgIT0gXCIke3RoaXMub2xkVGV4dH1cIi5gKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFRPRE86IHRocm93IGVycm9yIGlmIG9sZFRleHQgZG9lc24ndCBtYXRjaCByZW1vdmVkIHN0cmluZy5cbiAgICAgIHJldHVybiBob3N0LndyaXRlKHRoaXMucGF0aCwgYCR7cHJlZml4fSR7dGhpcy5uZXdUZXh0fSR7c3VmZml4fWApO1xuICAgIH0pO1xuICB9XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IENoYW5nZSwgSW5zZXJ0Q2hhbmdlLCBOb29wQ2hhbmdlIH0gZnJvbSAnLi9jaGFuZ2UnO1xuXG4vKipcbiAqIEFkZCBJbXBvcnQgYGltcG9ydCB7IHN5bWJvbE5hbWUgfSBmcm9tIGZpbGVOYW1lYCBpZiB0aGUgaW1wb3J0IGRvZXNuJ3QgZXhpdFxuICogYWxyZWFkeS4gQXNzdW1lcyBmaWxlVG9FZGl0IGNhbiBiZSByZXNvbHZlZCBhbmQgYWNjZXNzZWQuXG4gKiBAcGFyYW0gZmlsZVRvRWRpdCAoZmlsZSB3ZSB3YW50IHRvIGFkZCBpbXBvcnQgdG8pXG4gKiBAcGFyYW0gc3ltYm9sTmFtZSAoaXRlbSB0byBpbXBvcnQpXG4gKiBAcGFyYW0gZmlsZU5hbWUgKHBhdGggdG8gdGhlIGZpbGUpXG4gKiBAcGFyYW0gaXNEZWZhdWx0IChpZiB0cnVlLCBpbXBvcnQgZm9sbG93cyBzdHlsZSBmb3IgaW1wb3J0aW5nIGRlZmF1bHQgZXhwb3J0cylcbiAqIEByZXR1cm4gQ2hhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRJbXBvcnQoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZSxcbiAgZmlsZVRvRWRpdDogc3RyaW5nLFxuICBzeW1ib2xOYW1lOiBzdHJpbmcsXG4gIGZpbGVOYW1lOiBzdHJpbmcsXG4gIGlzRGVmYXVsdCA9IGZhbHNlXG4pOiBDaGFuZ2Uge1xuICBjb25zdCByb290Tm9kZSA9IHNvdXJjZTtcbiAgY29uc3QgYWxsSW1wb3J0cyA9IGZpbmROb2Rlcyhyb290Tm9kZSwgdHMuU3ludGF4S2luZC5JbXBvcnREZWNsYXJhdGlvbik7XG5cbiAgLy8gZ2V0IG5vZGVzIHRoYXQgbWFwIHRvIGltcG9ydCBzdGF0ZW1lbnRzIGZyb20gdGhlIGZpbGUgZmlsZU5hbWVcbiAgY29uc3QgcmVsZXZhbnRJbXBvcnRzID0gYWxsSW1wb3J0cy5maWx0ZXIobm9kZSA9PiB7XG4gICAgLy8gU3RyaW5nTGl0ZXJhbCBvZiB0aGUgSW1wb3J0RGVjbGFyYXRpb24gaXMgdGhlIGltcG9ydCBmaWxlIChmaWxlTmFtZSBpbiB0aGlzIGNhc2UpLlxuICAgIGNvbnN0IGltcG9ydEZpbGVzID0gbm9kZVxuICAgICAgLmdldENoaWxkcmVuKClcbiAgICAgIC5maWx0ZXIoY2hpbGQgPT4gY2hpbGQua2luZCA9PT0gdHMuU3ludGF4S2luZC5TdHJpbmdMaXRlcmFsKVxuICAgICAgLm1hcChuID0+IChuIGFzIHRzLlN0cmluZ0xpdGVyYWwpLnRleHQpO1xuXG4gICAgcmV0dXJuIGltcG9ydEZpbGVzLmZpbHRlcihmaWxlID0+IGZpbGUgPT09IGZpbGVOYW1lKS5sZW5ndGggPT09IDE7XG4gIH0pO1xuXG4gIGlmIChyZWxldmFudEltcG9ydHMubGVuZ3RoID4gMCkge1xuICAgIGxldCBpbXBvcnRzQXN0ZXJpc2sgPSBmYWxzZTtcbiAgICAvLyBpbXBvcnRzIGZyb20gaW1wb3J0IGZpbGVcbiAgICBjb25zdCBpbXBvcnRzOiB0cy5Ob2RlW10gPSBbXTtcbiAgICByZWxldmFudEltcG9ydHMuZm9yRWFjaChuID0+IHtcbiAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KFxuICAgICAgICBpbXBvcnRzLFxuICAgICAgICBmaW5kTm9kZXMobiwgdHMuU3ludGF4S2luZC5JZGVudGlmaWVyKVxuICAgICAgKTtcbiAgICAgIGlmIChmaW5kTm9kZXMobiwgdHMuU3ludGF4S2luZC5Bc3Rlcmlza1Rva2VuKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGltcG9ydHNBc3RlcmlzayA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBpZiBpbXBvcnRzICogZnJvbSBmaWxlTmFtZSwgZG9uJ3QgYWRkIHN5bWJvbE5hbWVcbiAgICBpZiAoaW1wb3J0c0FzdGVyaXNrKSB7XG4gICAgICByZXR1cm4gbmV3IE5vb3BDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbXBvcnRUZXh0Tm9kZXMgPSBpbXBvcnRzLmZpbHRlcihcbiAgICAgIG4gPT4gKG4gYXMgdHMuSWRlbnRpZmllcikudGV4dCA9PT0gc3ltYm9sTmFtZVxuICAgICk7XG5cbiAgICAvLyBpbnNlcnQgaW1wb3J0IGlmIGl0J3Mgbm90IHRoZXJlXG4gICAgaWYgKGltcG9ydFRleHROb2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IGZhbGxiYWNrUG9zID1cbiAgICAgICAgZmluZE5vZGVzKFxuICAgICAgICAgIHJlbGV2YW50SW1wb3J0c1swXSxcbiAgICAgICAgICB0cy5TeW50YXhLaW5kLkNsb3NlQnJhY2VUb2tlblxuICAgICAgICApWzBdLmdldFN0YXJ0KCkgfHxcbiAgICAgICAgZmluZE5vZGVzKHJlbGV2YW50SW1wb3J0c1swXSwgdHMuU3ludGF4S2luZC5Gcm9tS2V5d29yZClbMF0uZ2V0U3RhcnQoKTtcblxuICAgICAgcmV0dXJuIGluc2VydEFmdGVyTGFzdE9jY3VycmVuY2UoXG4gICAgICAgIGltcG9ydHMsXG4gICAgICAgIGAsICR7c3ltYm9sTmFtZX1gLFxuICAgICAgICBmaWxlVG9FZGl0LFxuICAgICAgICBmYWxsYmFja1Bvc1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5vb3BDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIG5vIHN1Y2ggaW1wb3J0IGRlY2xhcmF0aW9uIGV4aXN0c1xuICBjb25zdCB1c2VTdHJpY3QgPSBmaW5kTm9kZXMocm9vdE5vZGUsIHRzLlN5bnRheEtpbmQuU3RyaW5nTGl0ZXJhbCkuZmlsdGVyKFxuICAgIChuOiB0cy5TdHJpbmdMaXRlcmFsKSA9PiBuLnRleHQgPT09ICd1c2Ugc3RyaWN0J1xuICApO1xuICBsZXQgZmFsbGJhY2tQb3MgPSAwO1xuICBpZiAodXNlU3RyaWN0Lmxlbmd0aCA+IDApIHtcbiAgICBmYWxsYmFja1BvcyA9IHVzZVN0cmljdFswXS5lbmQ7XG4gIH1cbiAgY29uc3Qgb3BlbiA9IGlzRGVmYXVsdCA/ICcnIDogJ3sgJztcbiAgY29uc3QgY2xvc2UgPSBpc0RlZmF1bHQgPyAnJyA6ICcgfSc7XG4gIC8vIGlmIHRoZXJlIGFyZSBubyBpbXBvcnRzIG9yICd1c2Ugc3RyaWN0JyBzdGF0ZW1lbnQsIGluc2VydCBpbXBvcnQgYXQgYmVnaW5uaW5nIG9mIGZpbGVcbiAgY29uc3QgaW5zZXJ0QXRCZWdpbm5pbmcgPSBhbGxJbXBvcnRzLmxlbmd0aCA9PT0gMCAmJiB1c2VTdHJpY3QubGVuZ3RoID09PSAwO1xuICBjb25zdCBzZXBhcmF0b3IgPSBpbnNlcnRBdEJlZ2lubmluZyA/ICcnIDogJztcXG4nO1xuICBjb25zdCB0b0luc2VydCA9XG4gICAgYCR7c2VwYXJhdG9yfWltcG9ydCAke29wZW59JHtzeW1ib2xOYW1lfSR7Y2xvc2V9YCArXG4gICAgYCBmcm9tICcke2ZpbGVOYW1lfScke2luc2VydEF0QmVnaW5uaW5nID8gJztcXG4nIDogJyd9YDtcblxuICByZXR1cm4gaW5zZXJ0QWZ0ZXJMYXN0T2NjdXJyZW5jZShcbiAgICBhbGxJbXBvcnRzLFxuICAgIHRvSW5zZXJ0LFxuICAgIGZpbGVUb0VkaXQsXG4gICAgZmFsbGJhY2tQb3MsXG4gICAgdHMuU3ludGF4S2luZC5TdHJpbmdMaXRlcmFsXG4gICk7XG59XG5cbi8qKlxuICogRmluZCBhbGwgbm9kZXMgZnJvbSB0aGUgQVNUIGluIHRoZSBzdWJ0cmVlIG9mIG5vZGUgb2YgU3ludGF4S2luZCBraW5kLlxuICogQHBhcmFtIG5vZGVcbiAqIEBwYXJhbSBraW5kXG4gKiBAcGFyYW0gbWF4IFRoZSBtYXhpbXVtIG51bWJlciBvZiBpdGVtcyB0byByZXR1cm4uXG4gKiBAcmV0dXJuIGFsbCBub2RlcyBvZiBraW5kLCBvciBbXSBpZiBub25lIGlzIGZvdW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTm9kZXMoXG4gIG5vZGU6IHRzLk5vZGUsXG4gIGtpbmQ6IHRzLlN5bnRheEtpbmQsXG4gIG1heCA9IEluZmluaXR5XG4pOiB0cy5Ob2RlW10ge1xuICBpZiAoIW5vZGUgfHwgbWF4ID09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBhcnI6IHRzLk5vZGVbXSA9IFtdO1xuICBpZiAobm9kZS5raW5kID09PSBraW5kKSB7XG4gICAgYXJyLnB1c2gobm9kZSk7XG4gICAgbWF4LS07XG4gIH1cbiAgaWYgKG1heCA+IDApIHtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuZ2V0Q2hpbGRyZW4oKSkge1xuICAgICAgZmluZE5vZGVzKGNoaWxkLCBraW5kLCBtYXgpLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgIGlmIChtYXggPiAwKSB7XG4gICAgICAgICAgYXJyLnB1c2gobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgbWF4LS07XG4gICAgICB9KTtcblxuICAgICAgaWYgKG1heCA8PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhcnI7XG59XG5cbi8qKlxuICogR2V0IGFsbCB0aGUgbm9kZXMgZnJvbSBhIHNvdXJjZS5cbiAqIEBwYXJhbSBzb3VyY2VGaWxlIFRoZSBzb3VyY2UgZmlsZSBvYmplY3QuXG4gKiBAcmV0dXJucyBBbiBvYnNlcnZhYmxlIG9mIGFsbCB0aGUgbm9kZXMgaW4gdGhlIHNvdXJjZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNvdXJjZU5vZGVzKHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUpOiB0cy5Ob2RlW10ge1xuICBjb25zdCBub2RlczogdHMuTm9kZVtdID0gW3NvdXJjZUZpbGVdO1xuICBjb25zdCByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAobm9kZXMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IG5vZGUgPSBub2Rlcy5zaGlmdCgpO1xuXG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHJlc3VsdC5wdXNoKG5vZGUpO1xuICAgICAgaWYgKG5vZGUuZ2V0Q2hpbGRDb3VudChzb3VyY2VGaWxlKSA+PSAwKSB7XG4gICAgICAgIG5vZGVzLnVuc2hpZnQoLi4ubm9kZS5nZXRDaGlsZHJlbigpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZE5vZGUoXG4gIG5vZGU6IHRzLk5vZGUsXG4gIGtpbmQ6IHRzLlN5bnRheEtpbmQsXG4gIHRleHQ6IHN0cmluZ1xuKTogdHMuTm9kZSB8IG51bGwge1xuICBpZiAobm9kZS5raW5kID09PSBraW5kICYmIG5vZGUuZ2V0VGV4dCgpID09PSB0ZXh0KSB7XG4gICAgLy8gdGhyb3cgbmV3IEVycm9yKG5vZGUuZ2V0VGV4dCgpKTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIGxldCBmb3VuZE5vZGU6IHRzLk5vZGUgfCBudWxsID0gbnVsbDtcbiAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIGNoaWxkTm9kZSA9PiB7XG4gICAgZm91bmROb2RlID0gZm91bmROb2RlIHx8IGZpbmROb2RlKGNoaWxkTm9kZSwga2luZCwgdGV4dCk7XG4gIH0pO1xuXG4gIHJldHVybiBmb3VuZE5vZGU7XG59XG5cbi8qKlxuICogSGVscGVyIGZvciBzb3J0aW5nIG5vZGVzLlxuICogQHJldHVybiBmdW5jdGlvbiB0byBzb3J0IG5vZGVzIGluIGluY3JlYXNpbmcgb3JkZXIgb2YgcG9zaXRpb24gaW4gc291cmNlRmlsZVxuICovXG5mdW5jdGlvbiBub2Rlc0J5UG9zaXRpb24oZmlyc3Q6IHRzLk5vZGUsIHNlY29uZDogdHMuTm9kZSk6IG51bWJlciB7XG4gIHJldHVybiBmaXJzdC5nZXRTdGFydCgpIC0gc2Vjb25kLmdldFN0YXJ0KCk7XG59XG5cbi8qKlxuICogSW5zZXJ0IGB0b0luc2VydGAgYWZ0ZXIgdGhlIGxhc3Qgb2NjdXJlbmNlIG9mIGB0cy5TeW50YXhLaW5kW25vZGVzW2ldLmtpbmRdYFxuICogb3IgYWZ0ZXIgdGhlIGxhc3Qgb2Ygb2NjdXJlbmNlIG9mIGBzeW50YXhLaW5kYCBpZiB0aGUgbGFzdCBvY2N1cmVuY2UgaXMgYSBzdWIgY2hpbGRcbiAqIG9mIHRzLlN5bnRheEtpbmRbbm9kZXNbaV0ua2luZF0gYW5kIHNhdmUgdGhlIGNoYW5nZXMgaW4gZmlsZS5cbiAqXG4gKiBAcGFyYW0gbm9kZXMgaW5zZXJ0IGFmdGVyIHRoZSBsYXN0IG9jY3VyZW5jZSBvZiBub2Rlc1xuICogQHBhcmFtIHRvSW5zZXJ0IHN0cmluZyB0byBpbnNlcnRcbiAqIEBwYXJhbSBmaWxlIGZpbGUgdG8gaW5zZXJ0IGNoYW5nZXMgaW50b1xuICogQHBhcmFtIGZhbGxiYWNrUG9zIHBvc2l0aW9uIHRvIGluc2VydCBpZiB0b0luc2VydCBoYXBwZW5zIHRvIGJlIHRoZSBmaXJzdCBvY2N1cmVuY2VcbiAqIEBwYXJhbSBzeW50YXhLaW5kIHRoZSB0cy5TeW50YXhLaW5kIG9mIHRoZSBzdWJjaGlsZHJlbiB0byBpbnNlcnQgYWZ0ZXJcbiAqIEByZXR1cm4gQ2hhbmdlIGluc3RhbmNlXG4gKiBAdGhyb3cgRXJyb3IgaWYgdG9JbnNlcnQgaXMgZmlyc3Qgb2NjdXJlbmNlIGJ1dCBmYWxsIGJhY2sgaXMgbm90IHNldFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0QWZ0ZXJMYXN0T2NjdXJyZW5jZShcbiAgbm9kZXM6IHRzLk5vZGVbXSxcbiAgdG9JbnNlcnQ6IHN0cmluZyxcbiAgZmlsZTogc3RyaW5nLFxuICBmYWxsYmFja1BvczogbnVtYmVyLFxuICBzeW50YXhLaW5kPzogdHMuU3ludGF4S2luZFxuKTogQ2hhbmdlIHtcbiAgLy8gc29ydCgpIGhhcyBhIHNpZGUgZWZmZWN0LCBzbyBtYWtlIGEgY29weSBzbyB0aGF0IHdlIHdvbid0IG92ZXJ3cml0ZSB0aGUgcGFyZW50J3Mgb2JqZWN0LlxuICBsZXQgbGFzdEl0ZW0gPSBbLi4ubm9kZXNdLnNvcnQobm9kZXNCeVBvc2l0aW9uKS5wb3AoKTtcbiAgaWYgKCFsYXN0SXRlbSkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xuICB9XG4gIGlmIChzeW50YXhLaW5kKSB7XG4gICAgbGFzdEl0ZW0gPSBmaW5kTm9kZXMobGFzdEl0ZW0sIHN5bnRheEtpbmQpXG4gICAgICAuc29ydChub2Rlc0J5UG9zaXRpb24pXG4gICAgICAucG9wKCk7XG4gIH1cbiAgaWYgKCFsYXN0SXRlbSAmJiBmYWxsYmFja1BvcyA9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgdHJpZWQgdG8gaW5zZXJ0ICR7dG9JbnNlcnR9IGFzIGZpcnN0IG9jY3VyZW5jZSB3aXRoIG5vIGZhbGxiYWNrIHBvc2l0aW9uYFxuICAgICk7XG4gIH1cbiAgY29uc3QgbGFzdEl0ZW1Qb3NpdGlvbjogbnVtYmVyID0gbGFzdEl0ZW0gPyBsYXN0SXRlbS5nZXRFbmQoKSA6IGZhbGxiYWNrUG9zO1xuXG4gIHJldHVybiBuZXcgSW5zZXJ0Q2hhbmdlKGZpbGUsIGxhc3RJdGVtUG9zaXRpb24sIHRvSW5zZXJ0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbnRlbnRPZktleUxpdGVyYWwoXG4gIF9zb3VyY2U6IHRzLlNvdXJjZUZpbGUsXG4gIG5vZGU6IHRzLk5vZGVcbik6IHN0cmluZyB8IG51bGwge1xuICBpZiAobm9kZS5raW5kID09IHRzLlN5bnRheEtpbmQuSWRlbnRpZmllcikge1xuICAgIHJldHVybiAobm9kZSBhcyB0cy5JZGVudGlmaWVyKS50ZXh0O1xuICB9IGVsc2UgaWYgKG5vZGUua2luZCA9PSB0cy5TeW50YXhLaW5kLlN0cmluZ0xpdGVyYWwpIHtcbiAgICByZXR1cm4gKG5vZGUgYXMgdHMuU3RyaW5nTGl0ZXJhbCkudGV4dDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBfYW5ndWxhckltcG9ydHNGcm9tTm9kZShcbiAgbm9kZTogdHMuSW1wb3J0RGVjbGFyYXRpb24sXG4gIF9zb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlXG4pOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gIGNvbnN0IG1zID0gbm9kZS5tb2R1bGVTcGVjaWZpZXI7XG4gIGxldCBtb2R1bGVQYXRoOiBzdHJpbmc7XG4gIHN3aXRjaCAobXMua2luZCkge1xuICAgIGNhc2UgdHMuU3ludGF4S2luZC5TdHJpbmdMaXRlcmFsOlxuICAgICAgbW9kdWxlUGF0aCA9IChtcyBhcyB0cy5TdHJpbmdMaXRlcmFsKS50ZXh0O1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGlmICghbW9kdWxlUGF0aC5zdGFydHNXaXRoKCdAYW5ndWxhci8nKSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGlmIChub2RlLmltcG9ydENsYXVzZSkge1xuICAgIGlmIChub2RlLmltcG9ydENsYXVzZS5uYW1lKSB7XG4gICAgICAvLyBUaGlzIGlzIG9mIHRoZSBmb3JtIGBpbXBvcnQgTmFtZSBmcm9tICdwYXRoJ2AuIElnbm9yZS5cbiAgICAgIHJldHVybiB7fTtcbiAgICB9IGVsc2UgaWYgKG5vZGUuaW1wb3J0Q2xhdXNlLm5hbWVkQmluZGluZ3MpIHtcbiAgICAgIGNvbnN0IG5iID0gbm9kZS5pbXBvcnRDbGF1c2UubmFtZWRCaW5kaW5ncztcbiAgICAgIGlmIChuYi5raW5kID09IHRzLlN5bnRheEtpbmQuTmFtZXNwYWNlSW1wb3J0KSB7XG4gICAgICAgIC8vIFRoaXMgaXMgb2YgdGhlIGZvcm0gYGltcG9ydCAqIGFzIG5hbWUgZnJvbSAncGF0aCdgLiBSZXR1cm4gYG5hbWUuYC5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBbKG5iIGFzIHRzLk5hbWVzcGFjZUltcG9ydCkubmFtZS50ZXh0ICsgJy4nXTogbW9kdWxlUGF0aFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyBpcyBvZiB0aGUgZm9ybSBgaW1wb3J0IHthLGIsY30gZnJvbSAncGF0aCdgXG4gICAgICAgIGNvbnN0IG5hbWVkSW1wb3J0cyA9IG5iIGFzIHRzLk5hbWVkSW1wb3J0cztcblxuICAgICAgICByZXR1cm4gbmFtZWRJbXBvcnRzLmVsZW1lbnRzXG4gICAgICAgICAgLm1hcChcbiAgICAgICAgICAgIChpczogdHMuSW1wb3J0U3BlY2lmaWVyKSA9PlxuICAgICAgICAgICAgICBpcy5wcm9wZXJ0eU5hbWUgPyBpcy5wcm9wZXJ0eU5hbWUudGV4dCA6IGlzLm5hbWUudGV4dFxuICAgICAgICAgIClcbiAgICAgICAgICAucmVkdWNlKChhY2M6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9LCBjdXJyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGFjY1tjdXJyXSA9IG1vZHVsZVBhdGg7XG5cbiAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgfSwge30pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7fTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIGlzIG9mIHRoZSBmb3JtIGBpbXBvcnQgJ3BhdGgnO2AuIE5vdGhpbmcgdG8gZG8uXG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWNvcmF0b3JNZXRhZGF0YShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBpZGVudGlmaWVyOiBzdHJpbmcsXG4gIG1vZHVsZTogc3RyaW5nXG4pOiB0cy5Ob2RlW10ge1xuICBjb25zdCBhbmd1bGFySW1wb3J0czogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0gPSBmaW5kTm9kZXMoXG4gICAgc291cmNlLFxuICAgIHRzLlN5bnRheEtpbmQuSW1wb3J0RGVjbGFyYXRpb25cbiAgKVxuICAgIC5tYXAoKG5vZGU6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiBfYW5ndWxhckltcG9ydHNGcm9tTm9kZShub2RlLCBzb3VyY2UpKVxuICAgIC5yZWR1Y2UoXG4gICAgICAoXG4gICAgICAgIGFjYzogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICAgICAgIGN1cnJlbnQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9XG4gICAgICApID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoY3VycmVudCkpIHtcbiAgICAgICAgICBhY2Nba2V5XSA9IGN1cnJlbnRba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuXG4gIHJldHVybiBnZXRTb3VyY2VOb2Rlcyhzb3VyY2UpXG4gICAgLmZpbHRlcihub2RlID0+IHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIG5vZGUua2luZCA9PSB0cy5TeW50YXhLaW5kLkRlY29yYXRvciAmJlxuICAgICAgICAobm9kZSBhcyB0cy5EZWNvcmF0b3IpLmV4cHJlc3Npb24ua2luZCA9PSB0cy5TeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uXG4gICAgICApO1xuICAgIH0pXG4gICAgLm1hcChub2RlID0+IChub2RlIGFzIHRzLkRlY29yYXRvcikuZXhwcmVzc2lvbiBhcyB0cy5DYWxsRXhwcmVzc2lvbilcbiAgICAuZmlsdGVyKGV4cHIgPT4ge1xuICAgICAgaWYgKGV4cHIuZXhwcmVzc2lvbi5raW5kID09IHRzLlN5bnRheEtpbmQuSWRlbnRpZmllcikge1xuICAgICAgICBjb25zdCBpZCA9IGV4cHIuZXhwcmVzc2lvbiBhcyB0cy5JZGVudGlmaWVyO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgaWQuZ2V0RnVsbFRleHQoc291cmNlKSA9PSBpZGVudGlmaWVyICYmXG4gICAgICAgICAgYW5ndWxhckltcG9ydHNbaWQuZ2V0RnVsbFRleHQoc291cmNlKV0gPT09IG1vZHVsZVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXhwci5leHByZXNzaW9uLmtpbmQgPT0gdHMuU3ludGF4S2luZC5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb25cbiAgICAgICkge1xuICAgICAgICAvLyBUaGlzIGNvdmVycyBmb28uTmdNb2R1bGUgd2hlbiBpbXBvcnRpbmcgKiBhcyBmb28uXG4gICAgICAgIGNvbnN0IHBhRXhwciA9IGV4cHIuZXhwcmVzc2lvbiBhcyB0cy5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb247XG4gICAgICAgIC8vIElmIHRoZSBsZWZ0IGV4cHJlc3Npb24gaXMgbm90IGFuIGlkZW50aWZpZXIsIGp1c3QgZ2l2ZSB1cCBhdCB0aGF0IHBvaW50LlxuICAgICAgICBpZiAocGFFeHByLmV4cHJlc3Npb24ua2luZCAhPT0gdHMuU3ludGF4S2luZC5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaWQgPSBwYUV4cHIubmFtZS50ZXh0O1xuICAgICAgICBjb25zdCBtb2R1bGVJZCA9IChwYUV4cHIuZXhwcmVzc2lvbiBhcyB0cy5JZGVudGlmaWVyKS5nZXRUZXh0KHNvdXJjZSk7XG5cbiAgICAgICAgcmV0dXJuIGlkID09PSBpZGVudGlmaWVyICYmIGFuZ3VsYXJJbXBvcnRzW21vZHVsZUlkICsgJy4nXSA9PT0gbW9kdWxlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSlcbiAgICAuZmlsdGVyKFxuICAgICAgZXhwciA9PlxuICAgICAgICBleHByLmFyZ3VtZW50c1swXSAmJlxuICAgICAgICBleHByLmFyZ3VtZW50c1swXS5raW5kID09IHRzLlN5bnRheEtpbmQuT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb25cbiAgICApXG4gICAgLm1hcChleHByID0+IGV4cHIuYXJndW1lbnRzWzBdIGFzIHRzLk9iamVjdExpdGVyYWxFeHByZXNzaW9uKTtcbn1cblxuZnVuY3Rpb24gZmluZENsYXNzRGVjbGFyYXRpb25QYXJlbnQoXG4gIG5vZGU6IHRzLk5vZGVcbik6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB1bmRlZmluZWQge1xuICBpZiAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICByZXR1cm4gbm9kZS5wYXJlbnQgJiYgZmluZENsYXNzRGVjbGFyYXRpb25QYXJlbnQobm9kZS5wYXJlbnQpO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgc291cmNlIGZpbGUgd2l0aCBATmdNb2R1bGUgY2xhc3MoZXMpLCBmaW5kIHRoZSBuYW1lIG9mIHRoZSBmaXJzdCBATmdNb2R1bGUgY2xhc3MuXG4gKlxuICogQHBhcmFtIHNvdXJjZSBzb3VyY2UgZmlsZSBjb250YWluaW5nIG9uZSBvciBtb3JlIEBOZ01vZHVsZVxuICogQHJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGZpcnN0IEBOZ01vZHVsZSwgb3IgYHVuZGVmaW5lZGAgaWYgbm9uZSBpcyBmb3VuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3ROZ01vZHVsZU5hbWUoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZVxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgLy8gRmlyc3QsIGZpbmQgdGhlIEBOZ01vZHVsZSBkZWNvcmF0b3JzLlxuICBjb25zdCBuZ01vZHVsZXNNZXRhZGF0YSA9IGdldERlY29yYXRvck1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICAnTmdNb2R1bGUnLFxuICAgICdAYW5ndWxhci9jb3JlJ1xuICApO1xuICBpZiAobmdNb2R1bGVzTWV0YWRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIFRoZW4gd2FsayBwYXJlbnQgcG9pbnRlcnMgdXAgdGhlIEFTVCwgbG9va2luZyBmb3IgdGhlIENsYXNzRGVjbGFyYXRpb24gcGFyZW50IG9mIHRoZSBOZ01vZHVsZVxuICAvLyBtZXRhZGF0YS5cbiAgY29uc3QgbW9kdWxlQ2xhc3MgPSBmaW5kQ2xhc3NEZWNsYXJhdGlvblBhcmVudChuZ01vZHVsZXNNZXRhZGF0YVswXSk7XG4gIGlmICghbW9kdWxlQ2xhc3MgfHwgIW1vZHVsZUNsYXNzLm5hbWUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBtb2R1bGUgQ2xhc3NEZWNsYXJhdGlvbi5cbiAgcmV0dXJuIG1vZHVsZUNsYXNzLm5hbWUudGV4dDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFN5bWJvbFRvTmdNb2R1bGVNZXRhZGF0YShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBuZ01vZHVsZVBhdGg6IHN0cmluZyxcbiAgbWV0YWRhdGFGaWVsZDogc3RyaW5nLFxuICBzeW1ib2xOYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZyB8IG51bGwgPSBudWxsXG4pOiBDaGFuZ2VbXSB7XG4gIGNvbnN0IG5vZGVzID0gZ2V0RGVjb3JhdG9yTWV0YWRhdGEoc291cmNlLCAnTmdNb2R1bGUnLCAnQGFuZ3VsYXIvY29yZScpO1xuICBsZXQgbm9kZTogYW55ID0gbm9kZXNbMF07IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG5cbiAgLy8gRmluZCB0aGUgZGVjb3JhdG9yIGRlY2xhcmF0aW9uLlxuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBHZXQgYWxsIHRoZSBjaGlsZHJlbiBwcm9wZXJ0eSBhc3NpZ25tZW50IG9mIG9iamVjdCBsaXRlcmFscy5cbiAgY29uc3QgbWF0Y2hpbmdQcm9wZXJ0aWVzOiB0cy5PYmplY3RMaXRlcmFsRWxlbWVudFtdID0gKG5vZGUgYXMgdHMuT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24pLnByb3BlcnRpZXNcbiAgICAuZmlsdGVyKHByb3AgPT4gcHJvcC5raW5kID09IHRzLlN5bnRheEtpbmQuUHJvcGVydHlBc3NpZ25tZW50KVxuICAgIC8vIEZpbHRlciBvdXQgZXZlcnkgZmllbGRzIHRoYXQncyBub3QgXCJtZXRhZGF0YUZpZWxkXCIuIEFsc28gaGFuZGxlcyBzdHJpbmcgbGl0ZXJhbHNcbiAgICAvLyAoYnV0IG5vdCBleHByZXNzaW9ucykuXG4gICAgLmZpbHRlcigocHJvcDogdHMuUHJvcGVydHlBc3NpZ25tZW50KSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gcHJvcC5uYW1lO1xuICAgICAgc3dpdGNoIChuYW1lLmtpbmQpIHtcbiAgICAgICAgY2FzZSB0cy5TeW50YXhLaW5kLklkZW50aWZpZXI6XG4gICAgICAgICAgcmV0dXJuIChuYW1lIGFzIHRzLklkZW50aWZpZXIpLmdldFRleHQoc291cmNlKSA9PSBtZXRhZGF0YUZpZWxkO1xuICAgICAgICBjYXNlIHRzLlN5bnRheEtpbmQuU3RyaW5nTGl0ZXJhbDpcbiAgICAgICAgICByZXR1cm4gKG5hbWUgYXMgdHMuU3RyaW5nTGl0ZXJhbCkudGV4dCA9PSBtZXRhZGF0YUZpZWxkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSk7XG5cbiAgLy8gR2V0IHRoZSBsYXN0IG5vZGUgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gIGlmICghbWF0Y2hpbmdQcm9wZXJ0aWVzKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmIChtYXRjaGluZ1Byb3BlcnRpZXMubGVuZ3RoID09IDApIHtcbiAgICAvLyBXZSBoYXZlbid0IGZvdW5kIHRoZSBmaWVsZCBpbiB0aGUgbWV0YWRhdGEgZGVjbGFyYXRpb24uIEluc2VydCBhIG5ldyBmaWVsZC5cbiAgICBjb25zdCBleHByID0gbm9kZSBhcyB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbjtcbiAgICBsZXQgcG9zaXRpb246IG51bWJlcjtcbiAgICBsZXQgdG9JbnNlcnQ6IHN0cmluZztcbiAgICBpZiAoZXhwci5wcm9wZXJ0aWVzLmxlbmd0aCA9PSAwKSB7XG4gICAgICBwb3NpdGlvbiA9IGV4cHIuZ2V0RW5kKCkgLSAxO1xuICAgICAgdG9JbnNlcnQgPSBgICAke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1cXG5gO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlID0gZXhwci5wcm9wZXJ0aWVzW2V4cHIucHJvcGVydGllcy5sZW5ndGggLSAxXTtcbiAgICAgIHBvc2l0aW9uID0gbm9kZS5nZXRFbmQoKTtcbiAgICAgIC8vIEdldCB0aGUgaW5kZW50YXRpb24gb2YgdGhlIGxhc3QgZWxlbWVudCwgaWYgYW55LlxuICAgICAgY29uc3QgdGV4dCA9IG5vZGUuZ2V0RnVsbFRleHQoc291cmNlKTtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0ZXh0Lm1hdGNoKC9eXFxyP1xcblxccyovKTtcbiAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdG9JbnNlcnQgPSBgLCR7bWF0Y2hlc1swXX0ke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9JbnNlcnQgPSBgLCAke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1gO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaW1wb3J0UGF0aCAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgbmV3IEluc2VydENoYW5nZShuZ01vZHVsZVBhdGgsIHBvc2l0aW9uLCB0b0luc2VydCksXG4gICAgICAgIGluc2VydEltcG9ydChcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgbmdNb2R1bGVQYXRoLFxuICAgICAgICAgIHN5bWJvbE5hbWUucmVwbGFjZSgvXFwuLiokLywgJycpLFxuICAgICAgICAgIGltcG9ydFBhdGhcbiAgICAgICAgKVxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFtuZXcgSW5zZXJ0Q2hhbmdlKG5nTW9kdWxlUGF0aCwgcG9zaXRpb24sIHRvSW5zZXJ0KV07XG4gICAgfVxuICB9XG4gIGNvbnN0IGFzc2lnbm1lbnQgPSBtYXRjaGluZ1Byb3BlcnRpZXNbMF0gYXMgdHMuUHJvcGVydHlBc3NpZ25tZW50O1xuXG4gIC8vIElmIGl0J3Mgbm90IGFuIGFycmF5LCBub3RoaW5nIHdlIGNhbiBkbyByZWFsbHkuXG4gIGlmIChhc3NpZ25tZW50LmluaXRpYWxpemVyLmtpbmQgIT09IHRzLlN5bnRheEtpbmQuQXJyYXlMaXRlcmFsRXhwcmVzc2lvbikge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGFyckxpdGVyYWwgPSBhc3NpZ25tZW50LmluaXRpYWxpemVyIGFzIHRzLkFycmF5TGl0ZXJhbEV4cHJlc3Npb247XG4gIGlmIChhcnJMaXRlcmFsLmVsZW1lbnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gRm9yd2FyZCB0aGUgcHJvcGVydHkuXG4gICAgbm9kZSA9IGFyckxpdGVyYWw7XG4gIH0gZWxzZSB7XG4gICAgbm9kZSA9IGFyckxpdGVyYWwuZWxlbWVudHM7XG4gIH1cblxuICBpZiAoIW5vZGUpIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICdObyBhcHAgbW9kdWxlIGZvdW5kLiBQbGVhc2UgYWRkIHlvdXIgbmV3IGNsYXNzIHRvIHlvdXIgY29tcG9uZW50LidcbiAgICApO1xuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkobm9kZSkpIHtcbiAgICBjb25zdCBub2RlQXJyYXkgPSAobm9kZSBhcyB7fSkgYXMgQXJyYXk8dHMuTm9kZT47XG4gICAgY29uc3Qgc3ltYm9sc0FycmF5ID0gbm9kZUFycmF5Lm1hcChub2RlID0+IG5vZGUuZ2V0VGV4dCgpKTtcbiAgICBpZiAoc3ltYm9sc0FycmF5LmluZGV4T2Yoc3ltYm9sTmFtZSkgPj0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIG5vZGUgPSBub2RlW25vZGUubGVuZ3RoIC0gMV07XG4gIH1cblxuICBsZXQgdG9JbnNlcnQ6IHN0cmluZztcbiAgbGV0IHBvc2l0aW9uID0gbm9kZS5nZXRFbmQoKTtcbiAgaWYgKG5vZGUua2luZCA9PSB0cy5TeW50YXhLaW5kLk9iamVjdExpdGVyYWxFeHByZXNzaW9uKSB7XG4gICAgLy8gV2UgaGF2ZW4ndCBmb3VuZCB0aGUgZmllbGQgaW4gdGhlIG1ldGFkYXRhIGRlY2xhcmF0aW9uLiBJbnNlcnQgYSBuZXdcbiAgICAvLyBmaWVsZC5cbiAgICBjb25zdCBleHByID0gbm9kZSBhcyB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbjtcbiAgICBpZiAoZXhwci5wcm9wZXJ0aWVzLmxlbmd0aCA9PSAwKSB7XG4gICAgICBwb3NpdGlvbiA9IGV4cHIuZ2V0RW5kKCkgLSAxO1xuICAgICAgdG9JbnNlcnQgPSBgICAke21ldGFkYXRhRmllbGR9OiBbJHtzeW1ib2xOYW1lfV1cXG5gO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlID0gZXhwci5wcm9wZXJ0aWVzW2V4cHIucHJvcGVydGllcy5sZW5ndGggLSAxXTtcbiAgICAgIHBvc2l0aW9uID0gbm9kZS5nZXRFbmQoKTtcbiAgICAgIC8vIEdldCB0aGUgaW5kZW50YXRpb24gb2YgdGhlIGxhc3QgZWxlbWVudCwgaWYgYW55LlxuICAgICAgY29uc3QgdGV4dCA9IG5vZGUuZ2V0RnVsbFRleHQoc291cmNlKTtcbiAgICAgIGlmICh0ZXh0Lm1hdGNoKCdeXFxyP1xccj9cXG4nKSkge1xuICAgICAgICB0b0luc2VydCA9IGAsJHtcbiAgICAgICAgICB0ZXh0Lm1hdGNoKC9eXFxyP1xcblxccysvKVswXVxuICAgICAgICB9JHttZXRhZGF0YUZpZWxkfTogWyR7c3ltYm9sTmFtZX1dYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvSW5zZXJ0ID0gYCwgJHttZXRhZGF0YUZpZWxkfTogWyR7c3ltYm9sTmFtZX1dYDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAobm9kZS5raW5kID09IHRzLlN5bnRheEtpbmQuQXJyYXlMaXRlcmFsRXhwcmVzc2lvbikge1xuICAgIC8vIFdlIGZvdW5kIHRoZSBmaWVsZCBidXQgaXQncyBlbXB0eS4gSW5zZXJ0IGl0IGp1c3QgYmVmb3JlIHRoZSBgXWAuXG4gICAgcG9zaXRpb24tLTtcbiAgICB0b0luc2VydCA9IGAke3N5bWJvbE5hbWV9YDtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIGluZGVudGF0aW9uIG9mIHRoZSBsYXN0IGVsZW1lbnQsIGlmIGFueS5cbiAgICBjb25zdCB0ZXh0ID0gbm9kZS5nZXRGdWxsVGV4dChzb3VyY2UpO1xuICAgIGlmICh0ZXh0Lm1hdGNoKC9eXFxyP1xcbi8pKSB7XG4gICAgICB0b0luc2VydCA9IGAsJHt0ZXh0Lm1hdGNoKC9eXFxyP1xcbihcXHI/KVxccysvKVswXX0ke3N5bWJvbE5hbWV9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgdG9JbnNlcnQgPSBgLCAke3N5bWJvbE5hbWV9YDtcbiAgICB9XG4gIH1cbiAgaWYgKGltcG9ydFBhdGggIT09IG51bGwpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IEluc2VydENoYW5nZShuZ01vZHVsZVBhdGgsIHBvc2l0aW9uLCB0b0luc2VydCksXG4gICAgICBpbnNlcnRJbXBvcnQoXG4gICAgICAgIHNvdXJjZSxcbiAgICAgICAgbmdNb2R1bGVQYXRoLFxuICAgICAgICBzeW1ib2xOYW1lLnJlcGxhY2UoL1xcLi4qJC8sICcnKSxcbiAgICAgICAgaW1wb3J0UGF0aFxuICAgICAgKVxuICAgIF07XG4gIH1cblxuICByZXR1cm4gW25ldyBJbnNlcnRDaGFuZ2UobmdNb2R1bGVQYXRoLCBwb3NpdGlvbiwgdG9JbnNlcnQpXTtcbn1cblxuLyoqXG4gKiBDdXN0b20gZnVuY3Rpb24gdG8gaW5zZXJ0IGEgZGVjbGFyYXRpb24gKGNvbXBvbmVudCwgcGlwZSwgZGlyZWN0aXZlKVxuICogaW50byBOZ01vZHVsZSBkZWNsYXJhdGlvbnMuIEl0IGFsc28gaW1wb3J0cyB0aGUgY29tcG9uZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRGVjbGFyYXRpb25Ub01vZHVsZShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gIGNsYXNzaWZpZWROYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZ1xuKTogQ2hhbmdlW10ge1xuICByZXR1cm4gYWRkU3ltYm9sVG9OZ01vZHVsZU1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICBtb2R1bGVQYXRoLFxuICAgICdkZWNsYXJhdGlvbnMnLFxuICAgIGNsYXNzaWZpZWROYW1lLFxuICAgIGltcG9ydFBhdGhcbiAgKTtcbn1cblxuLyoqXG4gKiBDdXN0b20gZnVuY3Rpb24gdG8gaW5zZXJ0IGFuIE5nTW9kdWxlIGludG8gTmdNb2R1bGUgaW1wb3J0cy4gSXQgYWxzbyBpbXBvcnRzIHRoZSBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRJbXBvcnRUb01vZHVsZShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gIGNsYXNzaWZpZWROYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZ1xuKTogQ2hhbmdlW10ge1xuICByZXR1cm4gYWRkU3ltYm9sVG9OZ01vZHVsZU1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICBtb2R1bGVQYXRoLFxuICAgICdpbXBvcnRzJyxcbiAgICBjbGFzc2lmaWVkTmFtZSxcbiAgICBpbXBvcnRQYXRoXG4gICk7XG59XG5cbi8qKlxuICogQ3VzdG9tIGZ1bmN0aW9uIHRvIGluc2VydCBhIHByb3ZpZGVyIGludG8gTmdNb2R1bGUuIEl0IGFsc28gaW1wb3J0cyBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFByb3ZpZGVyVG9Nb2R1bGUoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZSxcbiAgbW9kdWxlUGF0aDogc3RyaW5nLFxuICBjbGFzc2lmaWVkTmFtZTogc3RyaW5nLFxuICBpbXBvcnRQYXRoOiBzdHJpbmdcbik6IENoYW5nZVtdIHtcbiAgcmV0dXJuIGFkZFN5bWJvbFRvTmdNb2R1bGVNZXRhZGF0YShcbiAgICBzb3VyY2UsXG4gICAgbW9kdWxlUGF0aCxcbiAgICAncHJvdmlkZXJzJyxcbiAgICBjbGFzc2lmaWVkTmFtZSxcbiAgICBpbXBvcnRQYXRoXG4gICk7XG59XG5cbi8qKlxuICogQ3VzdG9tIGZ1bmN0aW9uIHRvIGluc2VydCBhbiBleHBvcnQgaW50byBOZ01vZHVsZS4gSXQgYWxzbyBpbXBvcnRzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRXhwb3J0VG9Nb2R1bGUoXG4gIHNvdXJjZTogdHMuU291cmNlRmlsZSxcbiAgbW9kdWxlUGF0aDogc3RyaW5nLFxuICBjbGFzc2lmaWVkTmFtZTogc3RyaW5nLFxuICBpbXBvcnRQYXRoOiBzdHJpbmdcbik6IENoYW5nZVtdIHtcbiAgcmV0dXJuIGFkZFN5bWJvbFRvTmdNb2R1bGVNZXRhZGF0YShcbiAgICBzb3VyY2UsXG4gICAgbW9kdWxlUGF0aCxcbiAgICAnZXhwb3J0cycsXG4gICAgY2xhc3NpZmllZE5hbWUsXG4gICAgaW1wb3J0UGF0aFxuICApO1xufVxuXG4vKipcbiAqIEN1c3RvbSBmdW5jdGlvbiB0byBpbnNlcnQgYW4gZXhwb3J0IGludG8gTmdNb2R1bGUuIEl0IGFsc28gaW1wb3J0cyBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZEJvb3RzdHJhcFRvTW9kdWxlKFxuICBzb3VyY2U6IHRzLlNvdXJjZUZpbGUsXG4gIG1vZHVsZVBhdGg6IHN0cmluZyxcbiAgY2xhc3NpZmllZE5hbWU6IHN0cmluZyxcbiAgaW1wb3J0UGF0aDogc3RyaW5nXG4pOiBDaGFuZ2VbXSB7XG4gIHJldHVybiBhZGRTeW1ib2xUb05nTW9kdWxlTWV0YWRhdGEoXG4gICAgc291cmNlLFxuICAgIG1vZHVsZVBhdGgsXG4gICAgJ2Jvb3RzdHJhcCcsXG4gICAgY2xhc3NpZmllZE5hbWUsXG4gICAgaW1wb3J0UGF0aFxuICApO1xufVxuXG4vKipcbiAqIEN1c3RvbSBmdW5jdGlvbiB0byBpbnNlcnQgYW4gZW50cnlDb21wb25lbnQgaW50byBOZ01vZHVsZS4gSXQgYWxzbyBpbXBvcnRzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRW50cnlDb21wb25lbnRUb01vZHVsZShcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBtb2R1bGVQYXRoOiBzdHJpbmcsXG4gIGNsYXNzaWZpZWROYW1lOiBzdHJpbmcsXG4gIGltcG9ydFBhdGg6IHN0cmluZ1xuKTogQ2hhbmdlW10ge1xuICByZXR1cm4gYWRkU3ltYm9sVG9OZ01vZHVsZU1ldGFkYXRhKFxuICAgIHNvdXJjZSxcbiAgICBtb2R1bGVQYXRoLFxuICAgICdlbnRyeUNvbXBvbmVudHMnLFxuICAgIGNsYXNzaWZpZWROYW1lLFxuICAgIGltcG9ydFBhdGhcbiAgKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYW4gaW1wb3J0IGFscmVhZHkgZXhpc3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNJbXBvcnRlZChcbiAgc291cmNlOiB0cy5Tb3VyY2VGaWxlLFxuICBjbGFzc2lmaWVkTmFtZTogc3RyaW5nLFxuICBpbXBvcnRQYXRoOiBzdHJpbmdcbik6IGJvb2xlYW4ge1xuICBjb25zdCBhbGxOb2RlcyA9IGdldFNvdXJjZU5vZGVzKHNvdXJjZSk7XG4gIGNvbnN0IG1hdGNoaW5nTm9kZXMgPSBhbGxOb2Rlc1xuICAgIC5maWx0ZXIobm9kZSA9PiBub2RlLmtpbmQgPT09IHRzLlN5bnRheEtpbmQuSW1wb3J0RGVjbGFyYXRpb24pXG4gICAgLmZpbHRlcihcbiAgICAgIChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PlxuICAgICAgICBpbXAubW9kdWxlU3BlY2lmaWVyLmtpbmQgPT09IHRzLlN5bnRheEtpbmQuU3RyaW5nTGl0ZXJhbFxuICAgIClcbiAgICAuZmlsdGVyKChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiB7XG4gICAgICByZXR1cm4gKDx0cy5TdHJpbmdMaXRlcmFsPmltcC5tb2R1bGVTcGVjaWZpZXIpLnRleHQgPT09IGltcG9ydFBhdGg7XG4gICAgfSlcbiAgICAuZmlsdGVyKChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBpZiAoIWltcC5pbXBvcnRDbGF1c2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3Qgbm9kZXMgPSBmaW5kTm9kZXMoXG4gICAgICAgIGltcC5pbXBvcnRDbGF1c2UsXG4gICAgICAgIHRzLlN5bnRheEtpbmQuSW1wb3J0U3BlY2lmaWVyXG4gICAgICApLmZpbHRlcihuID0+IG4uZ2V0VGV4dCgpID09PSBjbGFzc2lmaWVkTmFtZSk7XG5cbiAgICAgIHJldHVybiBub2Rlcy5sZW5ndGggPiAwO1xuICAgIH0pO1xuXG4gIHJldHVybiBtYXRjaGluZ05vZGVzLmxlbmd0aCA+IDA7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQgeyBKc29uUGFyc2VNb2RlLCBleHBlcmltZW50YWwsIHBhcnNlSnNvbiB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IFJ1bGUsIFNjaGVtYXRpY0NvbnRleHQsIFNjaGVtYXRpY3NFeGNlcHRpb24sIFRyZWUgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvc2NoZW1hdGljcyc7XG5cblxuLy8gVGhlIGludGVyZmFjZXMgYmVsb3cgYXJlIGdlbmVyYXRlZCBmcm9tIHRoZSBBbmd1bGFyIENMSSBjb25maWd1cmF0aW9uIHNjaGVtYVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci1jbGkvYmxvYi9tYXN0ZXIvcGFja2FnZXMvQGFuZ3VsYXIvY2xpL2xpYi9jb25maWcvc2NoZW1hLmpzb25cbmV4cG9ydCBpbnRlcmZhY2UgQXBwQ29uZmlnIHtcbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIGFwcC5cbiAgICovXG4gIG5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBEaXJlY3Rvcnkgd2hlcmUgYXBwIGZpbGVzIGFyZSBwbGFjZWQuXG4gICAqL1xuICBhcHBSb290Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoZSBhcHAuXG4gICAqL1xuICByb290Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG91dHB1dCBkaXJlY3RvcnkgZm9yIGJ1aWxkIHJlc3VsdHMuXG4gICAqL1xuICBvdXREaXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBMaXN0IG9mIGFwcGxpY2F0aW9uIGFzc2V0cy5cbiAgICovXG4gIGFzc2V0cz86IChzdHJpbmcgfCB7XG4gICAgICAvKipcbiAgICAgICAqIFRoZSBwYXR0ZXJuIHRvIG1hdGNoLlxuICAgICAgICovXG4gICAgICBnbG9iPzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgZGlyIHRvIHNlYXJjaCB3aXRoaW4uXG4gICAgICAgKi9cbiAgICAgIGlucHV0Pzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgb3V0cHV0IHBhdGggKHJlbGF0aXZlIHRvIHRoZSBvdXREaXIpLlxuICAgICAgICovXG4gICAgICBvdXRwdXQ/OiBzdHJpbmc7XG4gIH0pW107XG4gIC8qKlxuICAgKiBVUkwgd2hlcmUgZmlsZXMgd2lsbCBiZSBkZXBsb3llZC5cbiAgICovXG4gIGRlcGxveVVybD86IHN0cmluZztcbiAgLyoqXG4gICAqIEJhc2UgdXJsIGZvciB0aGUgYXBwbGljYXRpb24gYmVpbmcgYnVpbHQuXG4gICAqL1xuICBiYXNlSHJlZj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBydW50aW1lIHBsYXRmb3JtIG9mIHRoZSBhcHAuXG4gICAqL1xuICBwbGF0Zm9ybT86ICgnYnJvd3NlcicgfCAnc2VydmVyJyk7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgc3RhcnQgSFRNTCBmaWxlLlxuICAgKi9cbiAgaW5kZXg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgbWFpbiBlbnRyeS1wb2ludCBmaWxlLlxuICAgKi9cbiAgbWFpbj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBwb2x5ZmlsbHMgZmlsZS5cbiAgICovXG4gIHBvbHlmaWxscz86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB0ZXN0IGVudHJ5LXBvaW50IGZpbGUuXG4gICAqL1xuICB0ZXN0Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIFR5cGVTY3JpcHQgY29uZmlndXJhdGlvbiBmaWxlLlxuICAgKi9cbiAgdHNjb25maWc/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgVHlwZVNjcmlwdCBjb25maWd1cmF0aW9uIGZpbGUgZm9yIHVuaXQgdGVzdHMuXG4gICAqL1xuICB0ZXN0VHNjb25maWc/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgcHJlZml4IHRvIGFwcGx5IHRvIGdlbmVyYXRlZCBzZWxlY3RvcnMuXG4gICAqL1xuICBwcmVmaXg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFeHBlcmltZW50YWwgc3VwcG9ydCBmb3IgYSBzZXJ2aWNlIHdvcmtlciBmcm9tIEBhbmd1bGFyL3NlcnZpY2Utd29ya2VyLlxuICAgKi9cbiAgc2VydmljZVdvcmtlcj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBHbG9iYWwgc3R5bGVzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBidWlsZC5cbiAgICovXG4gIHN0eWxlcz86IChzdHJpbmcgfCB7XG4gICAgICBpbnB1dD86IHN0cmluZztcbiAgICAgIFtuYW1lOiBzdHJpbmddOiBhbnk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG4gIH0pW107XG4gIC8qKlxuICAgKiBPcHRpb25zIHRvIHBhc3MgdG8gc3R5bGUgcHJlcHJvY2Vzc29yc1xuICAgKi9cbiAgc3R5bGVQcmVwcm9jZXNzb3JPcHRpb25zPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBQYXRocyB0byBpbmNsdWRlLiBQYXRocyB3aWxsIGJlIHJlc29sdmVkIHRvIHByb2plY3Qgcm9vdC5cbiAgICAgICAqL1xuICAgICAgaW5jbHVkZVBhdGhzPzogc3RyaW5nW107XG4gIH07XG4gIC8qKlxuICAgKiBHbG9iYWwgc2NyaXB0cyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gICAqL1xuICBzY3JpcHRzPzogKHN0cmluZyB8IHtcbiAgICAgIGlucHV0OiBzdHJpbmc7XG4gICAgICBbbmFtZTogc3RyaW5nXTogYW55OyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWFueVxuICB9KVtdO1xuICAvKipcbiAgICogU291cmNlIGZpbGUgZm9yIGVudmlyb25tZW50IGNvbmZpZy5cbiAgICovXG4gIGVudmlyb25tZW50U291cmNlPzogc3RyaW5nO1xuICAvKipcbiAgICogTmFtZSBhbmQgY29ycmVzcG9uZGluZyBmaWxlIGZvciBlbnZpcm9ubWVudCBjb25maWcuXG4gICAqL1xuICBlbnZpcm9ubWVudHM/OiB7XG4gICAgICBbbmFtZTogc3RyaW5nXTogYW55OyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWFueVxuICB9O1xuICBhcHBTaGVsbD86IHtcbiAgICBhcHA6IHN0cmluZztcbiAgICByb3V0ZTogc3RyaW5nO1xuICB9O1xuICBidWRnZXRzPzoge1xuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGJ1ZGdldFxuICAgICAqL1xuICAgIHR5cGU/OiAoJ2J1bmRsZScgfCAnaW5pdGlhbCcgfCAnYWxsU2NyaXB0JyB8ICdhbGwnIHwgJ2FueVNjcmlwdCcgfCAnYW55Jyk7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJ1bmRsZVxuICAgICAqL1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2VsaW5lIHNpemUgZm9yIGNvbXBhcmlzb24uXG4gICAgICovXG4gICAgYmFzZWxpbmU/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdGhyZXNob2xkIGZvciB3YXJuaW5nIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtYXhpbXVtV2FybmluZz86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB0aHJlc2hvbGQgZm9yIGVycm9yIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtYXhpbXVtRXJyb3I/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdGhyZXNob2xkIGZvciB3YXJuaW5nIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtaW5pbXVtV2FybmluZz86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB0aHJlc2hvbGQgZm9yIGVycm9yIHJlbGF0aXZlIHRvIHRoZSBiYXNlbGluZS5cbiAgICAgKi9cbiAgICBtaW5pbXVtRXJyb3I/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIHRocmVzaG9sZCBmb3Igd2FybmluZyByZWxhdGl2ZSB0byB0aGUgYmFzZWxpbmUgKG1pbiAmIG1heCkuXG4gICAgICovXG4gICAgd2FybmluZz86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgdGhyZXNob2xkIGZvciBlcnJvciByZWxhdGl2ZSB0byB0aGUgYmFzZWxpbmUgKG1pbiAmIG1heCkuXG4gICAgICovXG4gICAgZXJyb3I/OiBzdHJpbmc7XG4gIH1bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDbGlDb25maWcge1xuICAkc2NoZW1hPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGdsb2JhbCBjb25maWd1cmF0aW9uIG9mIHRoZSBwcm9qZWN0LlxuICAgKi9cbiAgcHJvamVjdD86IHtcbiAgICAgIC8qKlxuICAgICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2plY3QuXG4gICAgICAgKi9cbiAgICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgICAvKipcbiAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoaXMgcHJvamVjdCB3YXMgZWplY3RlZC5cbiAgICAgICAqL1xuICAgICAgZWplY3RlZD86IGJvb2xlYW47XG4gIH07XG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIG9mIHRoZSBkaWZmZXJlbnQgYXBwbGljYXRpb25zIGluIHRoaXMgcHJvamVjdC5cbiAgICovXG4gIGFwcHM/OiBBcHBDb25maWdbXTtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIGVuZC10by1lbmQgdGVzdHMuXG4gICAqL1xuICBlMmU/OiB7XG4gICAgICBwcm90cmFjdG9yPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFBhdGggdG8gdGhlIGNvbmZpZyBmaWxlLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGNvbmZpZz86IHN0cmluZztcbiAgICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIHRvIGJlIHBhc3NlZCB0byBUU0xpbnQuXG4gICAqL1xuICBsaW50Pzoge1xuICAgICAgLyoqXG4gICAgICAgKiBGaWxlIGdsb2IocykgdG8gbGludC5cbiAgICAgICAqL1xuICAgICAgZmlsZXM/OiAoc3RyaW5nIHwgc3RyaW5nW10pO1xuICAgICAgLyoqXG4gICAgICAgKiBMb2NhdGlvbiBvZiB0aGUgdHNjb25maWcuanNvbiBwcm9qZWN0IGZpbGUuXG4gICAgICAgKiBXaWxsIGFsc28gdXNlIGFzIGZpbGVzIHRvIGxpbnQgaWYgJ2ZpbGVzJyBwcm9wZXJ0eSBub3QgcHJlc2VudC5cbiAgICAgICAqL1xuICAgICAgcHJvamVjdDogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBMb2NhdGlvbiBvZiB0aGUgdHNsaW50Lmpzb24gY29uZmlndXJhdGlvbi5cbiAgICAgICAqL1xuICAgICAgdHNsaW50Q29uZmlnPzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBGaWxlIGdsb2IocykgdG8gaWdub3JlLlxuICAgICAgICovXG4gICAgICBleGNsdWRlPzogKHN0cmluZyB8IHN0cmluZ1tdKTtcbiAgfVtdO1xuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBmb3IgdW5pdCB0ZXN0cy5cbiAgICovXG4gIHRlc3Q/OiB7XG4gICAgICBrYXJtYT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBQYXRoIHRvIHRoZSBrYXJtYSBjb25maWcgZmlsZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb25maWc/OiBzdHJpbmc7XG4gICAgICB9O1xuICAgICAgY29kZUNvdmVyYWdlPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEdsb2JzIHRvIGV4Y2x1ZGUgZnJvbSBjb2RlIGNvdmVyYWdlLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGV4Y2x1ZGU/OiBzdHJpbmdbXTtcbiAgICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBkZWZhdWx0IHZhbHVlcyBmb3IgZ2VuZXJhdGluZy5cbiAgICovXG4gIGRlZmF1bHRzPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgZmlsZSBleHRlbnNpb24gdG8gYmUgdXNlZCBmb3Igc3R5bGUgZmlsZXMuXG4gICAgICAgKi9cbiAgICAgIHN0eWxlRXh0Pzogc3RyaW5nO1xuICAgICAgLyoqXG4gICAgICAgKiBIb3cgb2Z0ZW4gdG8gY2hlY2sgZm9yIGZpbGUgdXBkYXRlcy5cbiAgICAgICAqL1xuICAgICAgcG9sbD86IG51bWJlcjtcbiAgICAgIC8qKlxuICAgICAgICogVXNlIGxpbnQgdG8gZml4IGZpbGVzIGFmdGVyIGdlbmVyYXRpb25cbiAgICAgICAqL1xuICAgICAgbGludEZpeD86IGJvb2xlYW47XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBjbGFzcy5cbiAgICAgICAqL1xuICAgICAgY2xhc3M/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBjb21wb25lbnQuXG4gICAgICAgKi9cbiAgICAgIGNvbXBvbmVudD86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGEgZGlyIGlzIGNyZWF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZmxhdD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBTcGVjaWZpZXMgaWYgdGhlIHN0eWxlIHdpbGwgYmUgaW4gdGhlIHRzIGZpbGUuXG4gICAgICAgICAgICovXG4gICAgICAgICAgaW5saW5lU3R5bGU/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNwZWNpZmllcyBpZiB0aGUgdGVtcGxhdGUgd2lsbCBiZSBpbiB0aGUgdHMgZmlsZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBpbmxpbmVUZW1wbGF0ZT86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIHRoZSB2aWV3IGVuY2Fwc3VsYXRpb24gc3RyYXRlZ3kuXG4gICAgICAgICAgICovXG4gICAgICAgICAgdmlld0VuY2Fwc3VsYXRpb24/OiAoJ0VtdWxhdGVkJyB8ICdOYXRpdmUnIHwgJ05vbmUnKTtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBTcGVjaWZpZXMgdGhlIGNoYW5nZSBkZXRlY3Rpb24gc3RyYXRlZ3kuXG4gICAgICAgICAgICovXG4gICAgICAgICAgY2hhbmdlRGV0ZWN0aW9uPzogKCdEZWZhdWx0JyB8ICdPblB1c2gnKTtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBkaXJlY3RpdmUuXG4gICAgICAgKi9cbiAgICAgIGRpcmVjdGl2ZT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGEgZGlyIGlzIGNyZWF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZmxhdD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgYSBndWFyZC5cbiAgICAgICAqL1xuICAgICAgZ3VhcmQ/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRmxhZyB0byBpbmRpY2F0ZSBpZiBhIGRpciBpcyBjcmVhdGVkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGZsYXQ/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNwZWNpZmllcyBpZiBhIHNwZWMgZmlsZSBpcyBnZW5lcmF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgc3BlYz86IGJvb2xlYW47XG4gICAgICB9O1xuICAgICAgLyoqXG4gICAgICAgKiBPcHRpb25zIGZvciBnZW5lcmF0aW5nIGFuIGludGVyZmFjZS5cbiAgICAgICAqL1xuICAgICAgaW50ZXJmYWNlPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFByZWZpeCB0byBhcHBseSB0byBpbnRlcmZhY2UgbmFtZXMuIChpLmUuIEkpXG4gICAgICAgICAgICovXG4gICAgICAgICAgcHJlZml4Pzogc3RyaW5nO1xuICAgICAgfTtcbiAgICAgIC8qKlxuICAgICAgICogT3B0aW9ucyBmb3IgZ2VuZXJhdGluZyBhIG1vZHVsZS5cbiAgICAgICAqL1xuICAgICAgbW9kdWxlPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEZsYWcgdG8gaW5kaWNhdGUgaWYgYSBkaXIgaXMgY3JlYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBmbGF0PzogYm9vbGVhbjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBTcGVjaWZpZXMgaWYgYSBzcGVjIGZpbGUgaXMgZ2VuZXJhdGVkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHNwZWM/OiBib29sZWFuO1xuICAgICAgfTtcbiAgICAgIC8qKlxuICAgICAgICogT3B0aW9ucyBmb3IgZ2VuZXJhdGluZyBhIHBpcGUuXG4gICAgICAgKi9cbiAgICAgIHBpcGU/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRmxhZyB0byBpbmRpY2F0ZSBpZiBhIGRpciBpcyBjcmVhdGVkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGZsYXQ/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNwZWNpZmllcyBpZiBhIHNwZWMgZmlsZSBpcyBnZW5lcmF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgc3BlYz86IGJvb2xlYW47XG4gICAgICB9O1xuICAgICAgLyoqXG4gICAgICAgKiBPcHRpb25zIGZvciBnZW5lcmF0aW5nIGEgc2VydmljZS5cbiAgICAgICAqL1xuICAgICAgc2VydmljZT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGEgZGlyIGlzIGNyZWF0ZWQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZmxhdD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU3BlY2lmaWVzIGlmIGEgc3BlYyBmaWxlIGlzIGdlbmVyYXRlZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzcGVjPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgdG8gYmUgcGFzc2VkIHRvIHRoZSBidWlsZCBjb21tYW5kLlxuICAgICAgICovXG4gICAgICBidWlsZD86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBPdXRwdXQgc291cmNlbWFwcy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzb3VyY2VtYXBzPzogYm9vbGVhbjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBCYXNlIHVybCBmb3IgdGhlIGFwcGxpY2F0aW9uIGJlaW5nIGJ1aWx0LlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGJhc2VIcmVmPzogc3RyaW5nO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFRoZSBzc2wga2V5IHVzZWQgYnkgdGhlIHNlcnZlci5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwcm9ncmVzcz86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRW5hYmxlIGFuZCBkZWZpbmUgdGhlIGZpbGUgd2F0Y2hpbmcgcG9sbCB0aW1lIHBlcmlvZCAobWlsbGlzZWNvbmRzKS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwb2xsPzogbnVtYmVyO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIERlbGV0ZSBvdXRwdXQgcGF0aCBiZWZvcmUgYnVpbGQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZGVsZXRlT3V0cHV0UGF0aD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRG8gbm90IHVzZSB0aGUgcmVhbCBwYXRoIHdoZW4gcmVzb2x2aW5nIG1vZHVsZXMuXG4gICAgICAgICAgICovXG4gICAgICAgICAgcHJlc2VydmVTeW1saW5rcz86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU2hvdyBjaXJjdWxhciBkZXBlbmRlbmN5IHdhcm5pbmdzIG9uIGJ1aWxkcy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzaG93Q2lyY3VsYXJEZXBlbmRlbmNpZXM/OiBib29sZWFuO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFVzZSBhIHNlcGFyYXRlIGJ1bmRsZSBjb250YWluaW5nIGNvZGUgdXNlZCBhY3Jvc3MgbXVsdGlwbGUgYnVuZGxlcy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb21tb25DaHVuaz86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogVXNlIGZpbGUgbmFtZSBmb3IgbGF6eSBsb2FkZWQgY2h1bmtzLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIG5hbWVkQ2h1bmtzPzogYm9vbGVhbjtcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgdG8gYmUgcGFzc2VkIHRvIHRoZSBzZXJ2ZSBjb21tYW5kLlxuICAgICAgICovXG4gICAgICBzZXJ2ZT86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgcG9ydCB0aGUgYXBwbGljYXRpb24gd2lsbCBiZSBzZXJ2ZWQgb24uXG4gICAgICAgICAgICovXG4gICAgICAgICAgcG9ydD86IG51bWJlcjtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgaG9zdCB0aGUgYXBwbGljYXRpb24gd2lsbCBiZSBzZXJ2ZWQgb24uXG4gICAgICAgICAgICovXG4gICAgICAgICAgaG9zdD86IHN0cmluZztcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBFbmFibGVzIHNzbCBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHNzbD86IGJvb2xlYW47XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogVGhlIHNzbCBrZXkgdXNlZCBieSB0aGUgc2VydmVyLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHNzbEtleT86IHN0cmluZztcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgc3NsIGNlcnRpZmljYXRlIHVzZWQgYnkgdGhlIHNlcnZlci5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBzc2xDZXJ0Pzogc3RyaW5nO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFByb3h5IGNvbmZpZ3VyYXRpb24gZmlsZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwcm94eUNvbmZpZz86IHN0cmluZztcbiAgICAgIH07XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgYWJvdXQgc2NoZW1hdGljcy5cbiAgICAgICAqL1xuICAgICAgc2NoZW1hdGljcz86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBUaGUgc2NoZW1hdGljcyBjb2xsZWN0aW9uIHRvIHVzZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb2xsZWN0aW9uPzogc3RyaW5nO1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFRoZSBuZXcgYXBwIHNjaGVtYXRpYy5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBuZXdBcHA/OiBzdHJpbmc7XG4gICAgICB9O1xuICB9O1xuICAvKipcbiAgICogU3BlY2lmeSB3aGljaCBwYWNrYWdlIG1hbmFnZXIgdG9vbCB0byB1c2UuXG4gICAqL1xuICBwYWNrYWdlTWFuYWdlcj86ICgnbnBtJyB8ICdjbnBtJyB8ICd5YXJuJyB8ICdkZWZhdWx0Jyk7XG4gIC8qKlxuICAgKiBBbGxvdyBwZW9wbGUgdG8gZGlzYWJsZSBjb25zb2xlIHdhcm5pbmdzLlxuICAgKi9cbiAgd2FybmluZ3M/OiB7XG4gICAgICAvKipcbiAgICAgICAqIFNob3cgYSB3YXJuaW5nIHdoZW4gdGhlIHVzZXIgZW5hYmxlZCB0aGUgLS1obXIgb3B0aW9uLlxuICAgICAgICovXG4gICAgICBobXJXYXJuaW5nPzogYm9vbGVhbjtcbiAgICAgIC8qKlxuICAgICAgICogU2hvdyBhIHdhcm5pbmcgd2hlbiB0aGUgbm9kZSB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZS5cbiAgICAgICAqL1xuICAgICAgbm9kZURlcHJlY2F0aW9uPzogYm9vbGVhbjtcbiAgICAgIC8qKlxuICAgICAgICogU2hvdyBhIHdhcm5pbmcgd2hlbiB0aGUgdXNlciBpbnN0YWxsZWQgYW5ndWxhci1jbGkuXG4gICAgICAgKi9cbiAgICAgIHBhY2thZ2VEZXByZWNhdGlvbj86IGJvb2xlYW47XG4gICAgICAvKipcbiAgICAgICAqIFNob3cgYSB3YXJuaW5nIHdoZW4gdGhlIGdsb2JhbCB2ZXJzaW9uIGlzIG5ld2VyIHRoYW4gdGhlIGxvY2FsIG9uZS5cbiAgICAgICAqL1xuICAgICAgdmVyc2lvbk1pc21hdGNoPzogYm9vbGVhbjtcbiAgICAgIC8qKlxuICAgICAgICogU2hvdyBhIHdhcm5pbmcgd2hlbiB0aGUgVHlwZVNjcmlwdCB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZVxuICAgICAgICovXG4gICAgICB0eXBlc2NyaXB0TWlzbWF0Y2g/OiBib29sZWFuO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VTY2hlbWEgPSBleHBlcmltZW50YWwud29ya3NwYWNlLldvcmtzcGFjZVNjaGVtYTtcbmV4cG9ydCB0eXBlIFdvcmtzcGFjZVByb2plY3QgPSBleHBlcmltZW50YWwud29ya3NwYWNlLldvcmtzcGFjZVByb2plY3Q7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtzcGFjZVBhdGgoaG9zdDogVHJlZSk6IHN0cmluZyB7XG4gIGNvbnN0IHBvc3NpYmxlRmlsZXMgPSBbICcvYW5ndWxhci5qc29uJywgJy8uYW5ndWxhci5qc29uJyBdO1xuICBjb25zdCBwYXRoID0gcG9zc2libGVGaWxlcy5maWx0ZXIocGF0aCA9PiBob3N0LmV4aXN0cyhwYXRoKSlbMF07XG5cbiAgcmV0dXJuIHBhdGg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3Jrc3BhY2UoaG9zdDogVHJlZSk6IFdvcmtzcGFjZVNjaGVtYSB7XG4gIGNvbnN0IHBhdGggPSBnZXRXb3Jrc3BhY2VQYXRoKGhvc3QpO1xuICBjb25zdCBjb25maWdCdWZmZXIgPSBob3N0LnJlYWQocGF0aCk7XG4gIGlmIChjb25maWdCdWZmZXIgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgU2NoZW1hdGljc0V4Y2VwdGlvbihgQ291bGQgbm90IGZpbmQgKCR7cGF0aH0pYCk7XG4gIH1cbiAgY29uc3QgY29udGVudCA9IGNvbmZpZ0J1ZmZlci50b1N0cmluZygpO1xuXG4gIHJldHVybiBwYXJzZUpzb24oY29udGVudCwgSnNvblBhcnNlTW9kZS5Mb29zZSkgYXMge30gYXMgV29ya3NwYWNlU2NoZW1hO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkUHJvamVjdFRvV29ya3NwYWNlKFxuICB3b3Jrc3BhY2U6IFdvcmtzcGFjZVNjaGVtYSxcbiAgbmFtZTogc3RyaW5nLFxuICBwcm9qZWN0OiBXb3Jrc3BhY2VQcm9qZWN0LFxuKTogUnVsZSB7XG4gIHJldHVybiAoaG9zdDogVHJlZSwgY29udGV4dDogU2NoZW1hdGljQ29udGV4dCkgPT4ge1xuXG4gICAgaWYgKHdvcmtzcGFjZS5wcm9qZWN0c1tuYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm9qZWN0ICcke25hbWV9JyBhbHJlYWR5IGV4aXN0cyBpbiB3b3Jrc3BhY2UuYCk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHByb2plY3QgdG8gd29ya3NwYWNlLlxuICAgIHdvcmtzcGFjZS5wcm9qZWN0c1tuYW1lXSA9IHByb2plY3Q7XG5cbiAgICBpZiAoIXdvcmtzcGFjZS5kZWZhdWx0UHJvamVjdCAmJiBPYmplY3Qua2V5cyh3b3Jrc3BhY2UucHJvamVjdHMpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgLy8gTWFrZSB0aGUgbmV3IHByb2plY3QgdGhlIGRlZmF1bHQgb25lLlxuICAgICAgd29ya3NwYWNlLmRlZmF1bHRQcm9qZWN0ID0gbmFtZTtcbiAgICB9XG5cbiAgICBob3N0Lm92ZXJ3cml0ZShnZXRXb3Jrc3BhY2VQYXRoKGhvc3QpLCBKU09OLnN0cmluZ2lmeSh3b3Jrc3BhY2UsIG51bGwsIDIpKTtcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbmZpZ1BhdGggPSAnLy5hbmd1bGFyLWNsaS5qc29uJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbmZpZyhob3N0OiBUcmVlKTogQ2xpQ29uZmlnIHtcbiAgY29uc3QgY29uZmlnQnVmZmVyID0gaG9zdC5yZWFkKGNvbmZpZ1BhdGgpO1xuICBpZiAoY29uZmlnQnVmZmVyID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oJ0NvdWxkIG5vdCBmaW5kIC5hbmd1bGFyLWNsaS5qc29uJyk7XG4gIH1cblxuICBjb25zdCBjb25maWcgPSBwYXJzZUpzb24oY29uZmlnQnVmZmVyLnRvU3RyaW5nKCksIEpzb25QYXJzZU1vZGUuTG9vc2UpIGFzIHt9IGFzIENsaUNvbmZpZztcblxuICByZXR1cm4gY29uZmlnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBwRnJvbUNvbmZpZyhjb25maWc6IENsaUNvbmZpZywgYXBwSW5kZXhPck5hbWU6IHN0cmluZyk6IEFwcENvbmZpZyB8IG51bGwge1xuICBpZiAoIWNvbmZpZy5hcHBzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAocGFyc2VJbnQoYXBwSW5kZXhPck5hbWUpID49IDApIHtcbiAgICByZXR1cm4gY29uZmlnLmFwcHNbcGFyc2VJbnQoYXBwSW5kZXhPck5hbWUpXTtcbiAgfVxuXG4gIHJldHVybiBjb25maWcuYXBwcy5maWx0ZXIoKGFwcCkgPT4gYXBwLm5hbWUgPT09IGFwcEluZGV4T3JOYW1lKVswXTtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IFNjaGVtYXRpY3NFeGNlcHRpb24sIFRyZWUgfSBmcm9tICdAYW5ndWxhci1kZXZraXQvc2NoZW1hdGljcyc7XG5pbXBvcnQgeyBkaXJuYW1lIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IGZpbmROb2RlLCBnZXRTb3VyY2VOb2RlcyB9IGZyb20gJy4uL3V0aWxpdHkvYXN0LXV0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRCb290c3RyYXBNb2R1bGVDYWxsKGhvc3Q6IFRyZWUsIG1haW5QYXRoOiBzdHJpbmcpOiB0cy5DYWxsRXhwcmVzc2lvbiB8IG51bGwge1xuICBjb25zdCBtYWluQnVmZmVyID0gaG9zdC5yZWFkKG1haW5QYXRoKTtcbiAgaWYgKCFtYWluQnVmZmVyKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oYE1haW4gZmlsZSAoJHttYWluUGF0aH0pIG5vdCBmb3VuZGApO1xuICB9XG4gIGNvbnN0IG1haW5UZXh0ID0gbWFpbkJ1ZmZlci50b1N0cmluZygndXRmLTgnKTtcbiAgY29uc3Qgc291cmNlID0gdHMuY3JlYXRlU291cmNlRmlsZShtYWluUGF0aCwgbWFpblRleHQsIHRzLlNjcmlwdFRhcmdldC5MYXRlc3QsIHRydWUpO1xuXG4gIGNvbnN0IGFsbE5vZGVzID0gZ2V0U291cmNlTm9kZXMoc291cmNlKTtcblxuICBsZXQgYm9vdHN0cmFwQ2FsbDogdHMuQ2FsbEV4cHJlc3Npb24gfCBudWxsID0gbnVsbDtcblxuICBmb3IgKGNvbnN0IG5vZGUgb2YgYWxsTm9kZXMpIHtcblxuICAgIGxldCBib290c3RyYXBDYWxsTm9kZTogdHMuTm9kZSB8IG51bGwgPSBudWxsO1xuICAgIGJvb3RzdHJhcENhbGxOb2RlID0gZmluZE5vZGUobm9kZSwgdHMuU3ludGF4S2luZC5JZGVudGlmaWVyLCAnYm9vdHN0cmFwTW9kdWxlJyk7XG5cbiAgICAvLyBXYWxrIHVwIHRoZSBwYXJlbnQgdW50aWwgQ2FsbEV4cHJlc3Npb24gaXMgZm91bmQuXG4gICAgd2hpbGUgKGJvb3RzdHJhcENhbGxOb2RlICYmIGJvb3RzdHJhcENhbGxOb2RlLnBhcmVudFxuICAgICAgJiYgYm9vdHN0cmFwQ2FsbE5vZGUucGFyZW50LmtpbmQgIT09IHRzLlN5bnRheEtpbmQuQ2FsbEV4cHJlc3Npb24pIHtcblxuICAgICAgYm9vdHN0cmFwQ2FsbE5vZGUgPSBib290c3RyYXBDYWxsTm9kZS5wYXJlbnQ7XG4gICAgfVxuXG4gICAgaWYgKGJvb3RzdHJhcENhbGxOb2RlICE9PSBudWxsICYmXG4gICAgICBib290c3RyYXBDYWxsTm9kZS5wYXJlbnQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgYm9vdHN0cmFwQ2FsbE5vZGUucGFyZW50LmtpbmQgPT09IHRzLlN5bnRheEtpbmQuQ2FsbEV4cHJlc3Npb24pIHtcbiAgICAgIGJvb3RzdHJhcENhbGwgPSBib290c3RyYXBDYWxsTm9kZS5wYXJlbnQgYXMgdHMuQ2FsbEV4cHJlc3Npb247XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYm9vdHN0cmFwQ2FsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRCb290c3RyYXBNb2R1bGVQYXRoKGhvc3Q6IFRyZWUsIG1haW5QYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBib290c3RyYXBDYWxsID0gZmluZEJvb3RzdHJhcE1vZHVsZUNhbGwoaG9zdCwgbWFpblBhdGgpO1xuICBpZiAoIWJvb3RzdHJhcENhbGwpIHtcbiAgICB0aHJvdyBuZXcgU2NoZW1hdGljc0V4Y2VwdGlvbignQm9vdHN0cmFwIGNhbGwgbm90IGZvdW5kJyk7XG4gIH1cblxuICBjb25zdCBib290c3RyYXBNb2R1bGUgPSBib290c3RyYXBDYWxsLmFyZ3VtZW50c1swXTtcblxuICBjb25zdCBtYWluQnVmZmVyID0gaG9zdC5yZWFkKG1haW5QYXRoKTtcbiAgaWYgKCFtYWluQnVmZmVyKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oYENsaWVudCBhcHAgbWFpbiBmaWxlICgke21haW5QYXRofSkgbm90IGZvdW5kYCk7XG4gIH1cbiAgY29uc3QgbWFpblRleHQgPSBtYWluQnVmZmVyLnRvU3RyaW5nKCd1dGYtOCcpO1xuICBjb25zdCBzb3VyY2UgPSB0cy5jcmVhdGVTb3VyY2VGaWxlKG1haW5QYXRoLCBtYWluVGV4dCwgdHMuU2NyaXB0VGFyZ2V0LkxhdGVzdCwgdHJ1ZSk7XG4gIGNvbnN0IGFsbE5vZGVzID0gZ2V0U291cmNlTm9kZXMoc291cmNlKTtcbiAgY29uc3QgYm9vdHN0cmFwTW9kdWxlUmVsYXRpdmVQYXRoID0gYWxsTm9kZXNcbiAgICAuZmlsdGVyKG5vZGUgPT4gbm9kZS5raW5kID09PSB0cy5TeW50YXhLaW5kLkltcG9ydERlY2xhcmF0aW9uKVxuICAgIC5maWx0ZXIoaW1wID0+IHtcbiAgICAgIHJldHVybiBmaW5kTm9kZShpbXAsIHRzLlN5bnRheEtpbmQuSWRlbnRpZmllciwgYm9vdHN0cmFwTW9kdWxlLmdldFRleHQoKSk7XG4gICAgfSlcbiAgICAubWFwKChpbXA6IHRzLkltcG9ydERlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBtb2R1bGVQYXRoU3RyaW5nTGl0ZXJhbCA9IDx0cy5TdHJpbmdMaXRlcmFsPiBpbXAubW9kdWxlU3BlY2lmaWVyO1xuXG4gICAgICByZXR1cm4gbW9kdWxlUGF0aFN0cmluZ0xpdGVyYWwudGV4dDtcbiAgICB9KVswXTtcblxuICByZXR1cm4gYm9vdHN0cmFwTW9kdWxlUmVsYXRpdmVQYXRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBwTW9kdWxlUGF0aChob3N0OiBUcmVlLCBtYWluUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbW9kdWxlUmVsYXRpdmVQYXRoID0gZmluZEJvb3RzdHJhcE1vZHVsZVBhdGgoaG9zdCwgbWFpblBhdGgpO1xuICBjb25zdCBtYWluRGlyID0gZGlybmFtZShtYWluUGF0aCk7XG4gIGNvbnN0IG1vZHVsZVBhdGggPSBub3JtYWxpemUoYC8ke21haW5EaXJ9LyR7bW9kdWxlUmVsYXRpdmVQYXRofS50c2ApO1xuXG4gIHJldHVybiBtb2R1bGVQYXRoO1xufVxuIiwiXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG4vLyBpbXBvcnQgeyByZWxhdGl2ZSwgUGF0aCB9IGZyb20gXCIuLi8uLi8uLi9hbmd1bGFyX2RldmtpdC9jb3JlL3NyYy92aXJ0dWFsLWZzXCI7XG5pbXBvcnQgeyBQYXRoLCBiYXNlbmFtZSwgZGlybmFtZSwgbm9ybWFsaXplIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIExvY2F0aW9uIHtcbiAgbmFtZTogc3RyaW5nO1xuICBwYXRoOiBQYXRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VOYW1lKHBhdGg6IHN0cmluZywgbmFtZTogc3RyaW5nKTogTG9jYXRpb24ge1xuICBjb25zdCBuYW1lV2l0aG91dFBhdGggPSBiYXNlbmFtZShuYW1lIGFzIFBhdGgpO1xuICBjb25zdCBuYW1lUGF0aCA9IGRpcm5hbWUoKHBhdGggKyAnLycgKyBuYW1lKSBhcyBQYXRoKTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6IG5hbWVXaXRob3V0UGF0aCxcbiAgICBwYXRoOiBub3JtYWxpemUoJy8nICsgbmFtZVBhdGgpLFxuICB9O1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgdGFncyB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IFNjaGVtYXRpY3NFeGNlcHRpb24gfSBmcm9tICdAYW5ndWxhci1kZXZraXQvc2NoZW1hdGljcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZU5hbWUobmFtZTogc3RyaW5nKTogdm9pZCB7XG4gIGlmIChuYW1lICYmIC9eXFxkLy50ZXN0KG5hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24odGFncy5vbmVMaW5lYG5hbWUgKCR7bmFtZX0pXG4gICAgICAgIGNhbiBub3Qgc3RhcnQgd2l0aCBhIGRpZ2l0LmApO1xuICB9XG59XG5cbi8vIE11c3Qgc3RhcnQgd2l0aCBhIGxldHRlciwgYW5kIG11c3QgY29udGFpbiBvbmx5IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIG9yIGRhc2hlcy5cbi8vIFdoZW4gYWRkaW5nIGEgZGFzaCB0aGUgc2VnbWVudCBhZnRlciB0aGUgZGFzaCBtdXN0IGFsc28gc3RhcnQgd2l0aCBhIGxldHRlci5cbmV4cG9ydCBjb25zdCBodG1sU2VsZWN0b3JSZSA9IC9eW2EtekEtWl1bLjAtOWEtekEtWl0qKDo/LVthLXpBLVpdWy4wLTlhLXpBLVpdKikqJC87XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUh0bWxTZWxlY3RvcihzZWxlY3Rvcjogc3RyaW5nKTogdm9pZCB7XG4gIGlmIChzZWxlY3RvciAmJiAhaHRtbFNlbGVjdG9yUmUudGVzdChzZWxlY3RvcikpIHtcbiAgICB0aHJvdyBuZXcgU2NoZW1hdGljc0V4Y2VwdGlvbih0YWdzLm9uZUxpbmVgU2VsZWN0b3IgKCR7c2VsZWN0b3J9KVxuICAgICAgICBpcyBpbnZhbGlkLmApO1xuICB9XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUHJvamVjdE5hbWUocHJvamVjdE5hbWU6IHN0cmluZykge1xuICBjb25zdCBlcnJvckluZGV4ID0gZ2V0UmVnRXhwRmFpbFBvc2l0aW9uKHByb2plY3ROYW1lKTtcbiAgY29uc3QgdW5zdXBwb3J0ZWRQcm9qZWN0TmFtZXMgPSBbJ3Rlc3QnLCAnZW1iZXInLCAnZW1iZXItY2xpJywgJ3ZlbmRvcicsICdhcHAnXTtcbiAgY29uc3QgcGFja2FnZU5hbWVSZWdleCA9IC9eKD86QFthLXpBLVowLTlfLV0rXFwvKT9bYS16QS1aMC05Xy1dKyQvO1xuICBpZiAoZXJyb3JJbmRleCAhPT0gbnVsbCkge1xuICAgIGNvbnN0IGZpcnN0TWVzc2FnZSA9IHRhZ3Mub25lTGluZWBcbiAgICBQcm9qZWN0IG5hbWUgXCIke3Byb2plY3ROYW1lfVwiIGlzIG5vdCB2YWxpZC4gTmV3IHByb2plY3QgbmFtZXMgbXVzdFxuICAgIHN0YXJ0IHdpdGggYSBsZXR0ZXIsIGFuZCBtdXN0IGNvbnRhaW4gb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBvciBkYXNoZXMuXG4gICAgV2hlbiBhZGRpbmcgYSBkYXNoIHRoZSBzZWdtZW50IGFmdGVyIHRoZSBkYXNoIG11c3QgYWxzbyBzdGFydCB3aXRoIGEgbGV0dGVyLlxuICAgIGA7XG4gICAgY29uc3QgbXNnID0gdGFncy5zdHJpcEluZGVudGBcbiAgICAke2ZpcnN0TWVzc2FnZX1cbiAgICAke3Byb2plY3ROYW1lfVxuICAgICR7QXJyYXkoZXJyb3JJbmRleCArIDEpLmpvaW4oJyAnKSArICdeJ31cbiAgICBgO1xuICAgIHRocm93IG5ldyBTY2hlbWF0aWNzRXhjZXB0aW9uKG1zZyk7XG4gIH0gZWxzZSBpZiAodW5zdXBwb3J0ZWRQcm9qZWN0TmFtZXMuaW5kZXhPZihwcm9qZWN0TmFtZSkgIT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oXG4gICAgICBgUHJvamVjdCBuYW1lICR7SlNPTi5zdHJpbmdpZnkocHJvamVjdE5hbWUpfSBpcyBub3QgYSBzdXBwb3J0ZWQgbmFtZS5gKTtcbiAgfSBlbHNlIGlmICghcGFja2FnZU5hbWVSZWdleC50ZXN0KHByb2plY3ROYW1lKSkge1xuICAgIHRocm93IG5ldyBTY2hlbWF0aWNzRXhjZXB0aW9uKGBQcm9qZWN0IG5hbWUgJHtKU09OLnN0cmluZ2lmeShwcm9qZWN0TmFtZSl9IGlzIGludmFsaWQuYCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0UmVnRXhwRmFpbFBvc2l0aW9uKHN0cjogc3RyaW5nKTogbnVtYmVyIHwgbnVsbCB7XG4gIGNvbnN0IGlzU2NvcGUgPSAvXkAuKlxcLy4qLy50ZXN0KHN0cik7XG4gIGlmIChpc1Njb3BlKSB7XG4gICAgLy8gUmVtb3ZlIHN0YXJ0aW5nIEBcbiAgICBzdHIgPSBzdHIucmVwbGFjZSgvXkAvLCAnJyk7XG4gICAgLy8gQ2hhbmdlIC8gdG8gLSBmb3IgdmFsaWRhdGlvblxuICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXC8vZywgJy0nKTtcbiAgfVxuXG4gIGNvbnN0IHBhcnRzID0gc3RyLmluZGV4T2YoJy0nKSA+PSAwID8gc3RyLnNwbGl0KCctJykgOiBbc3RyXTtcbiAgY29uc3QgbWF0Y2hlZDogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdCBwcm9qZWN0TmFtZVJlZ2V4cCA9IC9eW2EtekEtWl1bLjAtOWEtekEtWl0qKC1bLjAtOWEtekEtWl0qKSokLztcblxuICBwYXJ0cy5mb3JFYWNoKHBhcnQgPT4ge1xuICAgIGlmIChwYXJ0Lm1hdGNoKHByb2plY3ROYW1lUmVnZXhwKSkge1xuICAgICAgbWF0Y2hlZC5wdXNoKHBhcnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgY29tcGFyZSA9IG1hdGNoZWQuam9pbignLScpO1xuXG4gIHJldHVybiAoc3RyICE9PSBjb21wYXJlKSA/IGNvbXBhcmUubGVuZ3RoIDogbnVsbDtcbn1cbiIsIi8qIENvcHlyaWdodCBJQk0gQ29ycC4gMjAxNyAqL1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuXG4vKlxuICogTWFrZXMgc3VyZSBvdXIgcGF0aCBlbmRzIHdpdGggYSBwcm9wZXIgdHJhaWxpbmcgc2xhc2hcbiAqL1xuZnVuY3Rpb24gX2Vuc3VyZVRyYWlsaW5nU2xhc2goYVVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGFVcmwuZW5kc1dpdGgoJy8nKSA/IGFVcmwgOiBhVXJsICsgJy8nO1xufVxuXG5mdW5jdGlvbiBfaGFzVHJhaWxpbmdTbGFzaChhVXJsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuICEhKGFVcmwgJiYgaXNTdHJpbmcoYVVybCkgJiYgYVVybC5lbmRzV2l0aCgnLycpKTtcbn1cblxuZXhwb3J0IHtcbiAgX2Vuc3VyZVRyYWlsaW5nU2xhc2ggYXMgZW5zdXJlVHJhaWxpbmdTbGFzaCxcbiAgX2hhc1RyYWlsaW5nU2xhc2ggYXMgaGFzVHJhaWxpbmdTbGFzaFxufTtcbiIsImltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcbmltcG9ydCAqIGFzIEFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgdmFsaWRhdGUgYXMgdmFsaWRhdGVFbWFpbCB9IGZyb20gJ2VtYWlsLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBpc1dlYlVyaSB9IGZyb20gJ3ZhbGlkLXVybCc7XG5cbmltcG9ydCB7IGhhc1RyYWlsaW5nU2xhc2ggfSBmcm9tICcuL3VybC51dGlscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnROb3ROdWxsKGFWYWx1ZTogYW55LCBhTmFtZT86IHN0cmluZykge1xuICBBc3NlcnQub2soXG4gICAgYVZhbHVlICE9IG51bGwsXG4gICAgYU5hbWVcbiAgICAgID8gYFZhbHVlIFske2FOYW1lfV0gbXVzdCBub3QgYmUgbnVsbCBvciB1bmRlZmluZWQuYFxuICAgICAgOiAnVmFsdWUgbXVzdCBub3QgYmUgbnVsbCBvciB1bmRlZmluZWQuJ1xuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UGFyYW1ldGVyKGFWYWx1ZTogYW55LCBhUGFyYW1ldGVyTmFtZTogc3RyaW5nKSB7XG4gIEFzc2VydC5vayghIWFWYWx1ZSwgYFBsZWFzZSBzcGVjaWZ5IHRoZSAnLS0ke2FQYXJhbWV0ZXJOYW1lfScgcGFyYW1ldGVyLmApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFVybChhVmFsdWU6IGFueSk6IGFWYWx1ZSBpcyBzdHJpbmcge1xuICByZXR1cm4gaXNTdHJpbmcoYVZhbHVlKSAmJiAhIWlzV2ViVXJpKGFWYWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRJc1VybChhVmFsdWU6IGFueSwgYU5hbWU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBBc3NlcnQub2soXG4gICAgaXNWYWxpZFVybChhVmFsdWUpLFxuICAgIGFOYW1lXG4gICAgICA/IGBWYWx1ZSBbJHthTmFtZX1dIG11c3QgYmUgYSB2YWxpZCBVUkwuYFxuICAgICAgOiAnVmFsdWUgbXVzdCBiZSBhIHZhbGlkIFVSTC4nXG4gICk7XG4gIHJldHVybiBhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkRW1haWwoYVZhbHVlOiBhbnkpOiBhVmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIGlzU3RyaW5nKGFWYWx1ZSkgJiYgISF2YWxpZGF0ZUVtYWlsKGFWYWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkVXNlck5hbWUoYVZhbHVlOiBhbnkpOiBhVmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIGlzU3RyaW5nKGFWYWx1ZSkgJiYgKCEhdmFsaWRhdGVFbWFpbChhVmFsdWUpIHx8IGFWYWx1ZSA9PT0gJ2FwaWtleScpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0SXNFbWFpbChhVmFsdWU6IGFueSwgYU5hbWU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBBc3NlcnQub2soXG4gICAgaXNWYWxpZEVtYWlsKGFWYWx1ZSksXG4gICAgYU5hbWVcbiAgICAgID8gYFZhbHVlIFske2FOYW1lfV0gbXVzdCBiZSBhIHZhbGlkIGUtbWFpbCBhZGRyZXNzLmBcbiAgICAgIDogJ1ZhbHVlIG11c3QgYmUgYSB2YWxpZCBlLW1haWwgYWRkcmVzcy4nXG4gICk7XG4gIHJldHVybiBhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRJc1ZhbGlkVXNlck5hbWUoYVZhbHVlOiBhbnksIGFOYW1lPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgQXNzZXJ0Lm9rKFxuICAgIGlzVmFsaWRVc2VyTmFtZShhVmFsdWUpLFxuICAgIGFOYW1lXG4gICAgICA/IGBWYWx1ZSBbJHthTmFtZX1dIG11c3QgYmUgYSB2YWxpZCBlLW1haWwgYWRkcmVzcyBvciB0aGUgdGVybSAnYXBpa2V5Jy5gXG4gICAgICA6IFwiVmFsdWUgbXVzdCBiZSBhIHZhbGlkIGUtbWFpbCBhZGRyZXNzIG9yIHRoZSB0ZXJtICdhcGlrZXknLlwiXG4gICk7XG4gIHJldHVybiBhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRIYXNUcmFpbGluZ1NsYXNoKGFWYWx1ZTogYW55KTogc3RyaW5nIHtcbiAgQXNzZXJ0Lm9rKFxuICAgIGlzVmFsaWRVcmwoYVZhbHVlKSAmJiBoYXNUcmFpbGluZ1NsYXNoKGFWYWx1ZSksXG4gICAgJ1VSTCBbJHthVmFsdWV9XSBtdXN0IGVuZCB3aXRoIGEgc2xhc2guJ1xuICApO1xuICByZXR1cm4gYVZhbHVlO1xufVxuIiwiLyogQ29weXJpZ2h0IElCTSBDb3JwLiAyMDE4ICovXG5cbi8vIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBkZXRlY3QgdXVpZC52NCBzdHJpbmdzXG5jb25zdCBIRVhfUkVHRVhQX1NUUklORyA9ICdbMC05YS1mQS1GXSc7XG5jb25zdCBIT1NUX1JFR0VYUF9TVFJJTkcgPSAnW15cXFxcLlxcXFw6XSc7XG5jb25zdCBVVUlEX1Y0X1JFR0VYUF9TVFJJTkcgPVxuICAgIGAke0hFWF9SRUdFWFBfU1RSSU5HfXs4fS0ke0hFWF9SRUdFWFBfU1RSSU5HfXs0fS00JHtIRVhfUkVHRVhQX1NUUklOR317M30tWzg5YWJBQl0ke0hFWF9SRUdFWFBfU1RSSU5HfXszfS0ke0hFWF9SRUdFWFBfU1RSSU5HfXsxMn1gO1xuY29uc3QgVEVOQU5UX0JBU0VEX1VSTCA9IGBeKD86XFxcXC9hcGkpP1xcXFwvKCR7VVVJRF9WNF9SRUdFWFBfU1RSSU5HfSkoPzpcXFxcLyk/KD86LiopJGA7XG5leHBvcnQgY29uc3QgVEVOQU5UX0JBU0VEX1VSTF9SRUdFWFAgPSBuZXcgUmVnRXhwKFRFTkFOVF9CQVNFRF9VUkwpO1xuIiwiLyogQ29weXJpZ2h0IElCTSBDb3JwLiAyMDE3ICovXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBkZWZlciwgZnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgYWpheCwgQWpheFJlcXVlc3QgfSBmcm9tICdyeGpzL2FqYXgnO1xuaW1wb3J0IHsgcGx1Y2ssIG1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCBjcmVhdGVYSFIgPSAoKSA9PiB7XG4gIGNvbnN0IFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneGhyMicpO1xuICByZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG59O1xuXG5jb25zdCBhamF4UmVxdWVzdCA9IChyZXE6IEFqYXhSZXF1ZXN0KSA9PlxuICBhamF4KHsgLi4ucmVxLCByZXNwb25zZVR5cGU6ICd0ZXh0JywgY3JlYXRlWEhSIH0pLnBpcGUoXG4gICAgbWFwKHJlc3AgPT4gcmVzcC5yZXNwb25zZSBhcyBzdHJpbmcpXG4gICk7XG5cbmV4cG9ydCBmdW5jdGlvbiByeEdldChhVXJpOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBzZXR1cCB0aGUgcmVxdWVzdFxuICByZXR1cm4gYWpheFJlcXVlc3Qoe1xuICAgIHVybDogYVVyaVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ4R2V0SnNvbihhVXJpOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICByZXR1cm4gcnhHZXQoYVVyaSkucGlwZShtYXAoZGF0YSA9PiBKU09OLnBhcnNlKGRhdGEpKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByeEZvcm1Qb3N0KGFVcmk6IHN0cmluZywgYURhdGE6IGFueSk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIHNldHVwIHRoZSByZXF1ZXN0XG4gIHJldHVybiBhamF4UmVxdWVzdCh7XG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgdXJsOiBhVXJpLFxuICAgIGJvZHk6IGFEYXRhXG4gIH0pO1xufVxuIiwiaW1wb3J0IHsgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnZnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gcnhSZWFkRmlsZShhUGF0aDogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgcmV0dXJuIE9ic2VydmFibGUuY3JlYXRlKChvYnNlcnZlcjogT2JzZXJ2ZXI8c3RyaW5nPikgPT4ge1xuICAgIHJlYWRGaWxlKGFQYXRoLCAndXRmLTgnLCAoZXJyLCBkYXRhKSA9PiB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYnNlcnZlci5uZXh0KGRhdGEpO1xuICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cbiIsImltcG9ydCB7IGV4ZWMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IFJTQV9QS0NTMV9QQURESU5HIH0gZnJvbSAnY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIHByaXZhdGVEZWNyeXB0LFxuICBwdWJsaWNFbmNyeXB0LFxuICBSc2FQcml2YXRlS2V5LFxuICBSc2FQdWJsaWNLZXlcbn0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IGNsb25lRGVlcCwgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgaG9tZWRpciwgcGxhdGZvcm0gfSBmcm9tICdvcyc7XG5pbXBvcnQgeyBqb2luLCBub3JtYWxpemUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGVudiB9IGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIG1lcmdlTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgcGFyc2VLZXkgfSBmcm9tICdzc2hwayc7XG5cbmltcG9ydCB7IGFzc2VydEhhc1RyYWlsaW5nU2xhc2gsIGlzVmFsaWRVc2VyTmFtZSB9IGZyb20gJy4vYXNzZXJ0JztcbmltcG9ydCB7IHJ4UmVhZEZpbGUgfSBmcm9tICcuL3J4LmZpbGUnO1xuaW1wb3J0IHsgZW5zdXJlVHJhaWxpbmdTbGFzaCB9IGZyb20gJy4vdXJsLnV0aWxzJztcblxuZXhwb3J0IHsgd2NoR2V0RGVsaXZlcnlVcmxGcm9tQXBpVVJMIH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBDcmVkZW50aWFscyB7XG4gIHVzZXJuYW1lOiBzdHJpbmc7XG4gIHBhc3N3b3JkOiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIF9pc1ZhbGlkQ3JlZGVudGlhbChhQ3JlZD86IENyZWRlbnRpYWxzKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIShcbiAgICBhQ3JlZCAmJlxuICAgIGlzVmFsaWRVc2VyTmFtZShhQ3JlZC51c2VybmFtZSkgJiZcbiAgICBpc1N0cmluZyhhQ3JlZC5wYXNzd29yZClcbiAgKTtcbn1cblxuZnVuY3Rpb24gX2VtcHR5Q3JlZGVudGlhbHMoKTogQ3JlZGVudGlhbHMge1xuICByZXR1cm4ge1xuICAgIHVzZXJuYW1lOiAnJyxcbiAgICBwYXNzd29yZDogJydcbiAgfTtcbn1cblxuZnVuY3Rpb24gX2NyZWF0ZUNyZWRlbnRpYWxzKGFVc2VyTmFtZTogc3RyaW5nLCBhUGFzc3dvcmQ6IHN0cmluZyk6IENyZWRlbnRpYWxzIHtcbiAgcmV0dXJuIHtcbiAgICB1c2VybmFtZTogYVVzZXJOYW1lLFxuICAgIHBhc3N3b3JkOiBhUGFzc3dvcmRcbiAgfTtcbn1cblxuZnVuY3Rpb24gX2dldENyZWRlbnRpYWxzRnJvbUVudmlyb25tZW50KCk6IENyZWRlbnRpYWxzIHtcbiAgLy8gYWNjZXNzIHRoZSBjcmVkZW50aWFscyBmcm9tIHRoZSBlbnZpcm9ubWVudFxuICBjb25zdCB1c2VybmFtZSA9IGVudlsnaWJtX3djaF9zZGtfY2xpX3VzZXJuYW1lJ10gfHwgJyc7XG4gIGNvbnN0IHBhc3N3b3JkID0gZW52WydpYm1fd2NoX3Nka19jbGlfcGFzc3dvcmQnXSB8fCAnJztcbiAgLy8gY29uc3RydWN0XG4gIHJldHVybiB7IHVzZXJuYW1lLCBwYXNzd29yZCB9O1xufVxuXG4vKipcbiAqIE1lcmdlIGRpZmZlcmVudCBjcmVkZW50aWFscyBsYXllcnNcbiAqXG4gKiBAcGFyYW0gYUJhc2UgICAgICAgICBiYXNlIGxheWVyXG4gKiBAcGFyYW0gYU92ZXJyaWRlICAgICBvdmVycmlkZSBsYXllclxuICpcbiAqIEByZXR1cm4gdGhlIG1lcmdlZCBjcmVkZW50aWFsc1xuICovXG5mdW5jdGlvbiBfbWVyZ2VDcmVkZW50aWFscyhcbiAgYUJhc2U6IENyZWRlbnRpYWxzLFxuICBhT3ZlcnJpZGU/OiBDcmVkZW50aWFsc1xuKTogQ3JlZGVudGlhbHMge1xuICAvLyB0YXJnZXRcbiAgaWYgKCFhT3ZlcnJpZGUpIHtcbiAgICByZXR1cm4gYUJhc2U7XG4gIH1cbiAgLy8gY2xvbmVcbiAgY29uc3QgY3JlZCA9IGNsb25lRGVlcChhQmFzZSk7XG4gIC8vIG92ZXJyaWRlXG4gIGlmICghIWFPdmVycmlkZS51c2VybmFtZSkge1xuICAgIGNyZWQudXNlcm5hbWUgPSBhT3ZlcnJpZGUudXNlcm5hbWU7XG4gIH1cbiAgaWYgKCEhYU92ZXJyaWRlLnBhc3N3b3JkKSB7XG4gICAgY3JlZC5wYXNzd29yZCA9IGFPdmVycmlkZS5wYXNzd29yZDtcbiAgfVxuICAvLyBva1xuICByZXR1cm4gY3JlZDtcbn1cblxuY29uc3QgUEFERElOR19NT0RFID0gUlNBX1BLQ1MxX1BBRERJTkc7XG5cbmZ1bmN0aW9uIF9sb2FkUHJpdmF0ZUtleSgpOiBPYnNlcnZhYmxlPFJzYVByaXZhdGVLZXk+IHtcbiAgLy8gZmlsZW5hbWVcbiAgY29uc3QgbmFtZSA9IGpvaW4oaG9tZWRpcigpLCAnLnNzaCcsICdpZF9yc2EnKTtcbiAgcmV0dXJuIHJ4UmVhZEZpbGUobmFtZSkucGlwZShtYXAoa2V5ID0+ICh7IGtleSwgcGFkZGluZzogUEFERElOR19NT0RFIH0pKSk7XG59XG5cbmZ1bmN0aW9uIF9sb2FkUHVibGljS2V5KCk6IE9ic2VydmFibGU8UnNhUHVibGljS2V5PiB7XG4gIC8vIGZpbGVuYW1lXG4gIGNvbnN0IG5hbWUgPSBqb2luKGhvbWVkaXIoKSwgJy5zc2gnLCAnaWRfcnNhLnB1YicpO1xuICByZXR1cm4gcnhSZWFkRmlsZShuYW1lKS5waXBlKFxuICAgIG1hcChrZXkgPT4gcGFyc2VLZXkoa2V5LCAnYXV0bycpLnRvU3RyaW5nKCdwa2NzMScpKSxcbiAgICBtYXAoa2V5ID0+ICh7IGtleSwgcGFkZGluZzogUEFERElOR19NT0RFIH0pKVxuICApO1xufVxuXG5jb25zdCBFTkNSWVBURURfRU5DT0RJTkcgPSAnYmFzZTY0JztcbmNvbnN0IERFQ1RZUFRFRF9FTkNPRElORyA9ICd1dGY4JztcblxuZnVuY3Rpb24gX2VuY3J5cHRQYXNzd29yZChhUGFzc3dvcmQ6IHN0cmluZywgYUtleTogUnNhUHVibGljS2V5KTogc3RyaW5nIHtcbiAgLy8gZW5jcnlwdFxuICByZXR1cm4gcHVibGljRW5jcnlwdChcbiAgICBhS2V5LFxuICAgIEJ1ZmZlci5mcm9tKGFQYXNzd29yZCwgREVDVFlQVEVEX0VOQ09ESU5HKVxuICApLnRvU3RyaW5nKEVOQ1JZUFRFRF9FTkNPRElORyk7XG59XG5cbmZ1bmN0aW9uIF9kZWNyeXB0UGFzc3dvcmQoYUhhc2g6IHN0cmluZywgYUtleTogUnNhUHJpdmF0ZUtleSk6IHN0cmluZyB7XG4gIHJldHVybiBwcml2YXRlRGVjcnlwdChhS2V5LCBCdWZmZXIuZnJvbShhSGFzaCwgRU5DUllQVEVEX0VOQ09ESU5HKSkudG9TdHJpbmcoXG4gICAgREVDVFlQVEVEX0VOQ09ESU5HXG4gICk7XG59XG5cbmZ1bmN0aW9uIF9sb2FkQ3JlZGVudGlhbHMoYUFwaUJhc2U6IHN0cmluZyk6IE9ic2VydmFibGU8Q3JlZGVudGlhbHM+IHtcbiAgLy8gdmFsaWRhdGUgdGhlIFVSTFxuICBhc3NlcnRIYXNUcmFpbGluZ1NsYXNoKGFBcGlCYXNlKTtcbiAgLy8gY3JlZGVudGlhbCBmaWxlIG5hbWVcbiAgY29uc3QgZmlsZW5hbWUgPSBqb2luKGhvbWVkaXIoKSwgJy5pYm0td2NoLXNkay1jbGknLCAnLmNyZWRlbnRpYWxzJyk7XG4gIC8vIHJlYWQgdGhlIGNyZWRlbnRpYWxcbiAgY29uc3Qga2V5ID0gX2xvYWRQcml2YXRlS2V5KCk7XG4gIC8vIGxvYWQgdGhlIGZpbGVcbiAgcmV0dXJuIHJ4UmVhZEZpbGUoZmlsZW5hbWUpLnBpcGUoXG4gICAgbWFwKGRhdGEgPT4gSlNPTi5wYXJzZShkYXRhKSksXG4gICAgbWFwKGRhdGEgPT4gZGF0YVthQXBpQmFzZV0pLFxuICAgIG1lcmdlTWFwKGNyZWQgPT5cbiAgICAgIGtleS5waXBlKFxuICAgICAgICBtYXAoayA9PiBfZGVjcnlwdFBhc3N3b3JkKGNyZWQucGFzc3dvcmQsIGspKSxcbiAgICAgICAgbWFwKHAgPT4ge1xuICAgICAgICAgIGNyZWQucGFzc3dvcmQgPSBwO1xuICAgICAgICAgIHJldHVybiBjcmVkO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICksXG4gICAgY2F0Y2hFcnJvcigoKSA9PiBvZihfZW1wdHlDcmVkZW50aWFscygpKSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gX2dldFdpbmRvd3NDcmVkZW50aWFscyhhQXBpVXJsOiBzdHJpbmcpOiBPYnNlcnZhYmxlPENyZWRlbnRpYWxzPiB7XG4gIC8vIHZhbGlkYXRlIHRoZSBVUkxcbiAgYXNzZXJ0SGFzVHJhaWxpbmdTbGFzaChhQXBpVXJsKTtcbiAgLy8gdGhlIGV4ZWN1dGFibGVcbiAgY29uc3QgcGF0aCA9IG5vcm1hbGl6ZShcbiAgICBqb2luKFxuICAgICAgX19kaXJuYW1lLFxuICAgICAgJy4uJyxcbiAgICAgICcuLicsXG4gICAgICAnLi4nLFxuICAgICAgJ2Fzc2V0cycsXG4gICAgICAnY3JlZG1hbicsXG4gICAgICBwcm9jZXNzLmFyY2gsXG4gICAgICAnV2NoQ3JlZE1hbi5leGUnXG4gICAgKVxuICApO1xuICAvLyBleGVjdXRlXG4gIGNvbnN0IGNtZCA9IGBcXFwiJHtwYXRofVxcXCIgXFxcIiR7YUFwaVVybH1cXFwiYDtcbiAgLy8gY29uc3RydWN0IHRoZSBvYnNlcnZhYmxlXG4gIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZSgob2JzZXJ2ZXI6IE9ic2VydmVyPENyZWRlbnRpYWxzPikgPT4ge1xuICAgIC8vIGV4ZWN1dGUgdGhlIGNvbW1hbmRcbiAgICBleGVjKFxuICAgICAgY21kLFxuICAgICAge1xuICAgICAgICBlbmNvZGluZzogJ3V0ZjgnXG4gICAgICB9LFxuICAgICAgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIHBhcnNlXG4gICAgICAgICAgICBvYnNlcnZlci5uZXh0KEpTT04ucGFyc2Uoc3Rkb3V0KSk7XG4gICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBfZ2V0U3RvcmVkQ3JlZGVudGlhbHMoYUFwaVVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxDcmVkZW50aWFscz4ge1xuICAvLyB0aGUga2V5XG4gIGNvbnN0IGtleSA9IGVuc3VyZVRyYWlsaW5nU2xhc2goYUFwaVVybCk7XG4gIC8vIG5vcm1hbGl6ZSB0aGUgVVJMXG4gIGlmIChwbGF0Zm9ybSgpID09PSAnd2luMzInKSB7XG4gICAgLy8gbG9hZCB0aGUgY3JlZGVudGlhbHMgbW9kdWxlXG4gICAgcmV0dXJuIF9nZXRXaW5kb3dzQ3JlZGVudGlhbHMoa2V5KS5waXBlKFxuICAgICAgbWVyZ2VNYXAoXG4gICAgICAgIChjcmVkOiBDcmVkZW50aWFscykgPT5cbiAgICAgICAgICBfaXNWYWxpZENyZWRlbnRpYWwoY3JlZCkgPyBvZihjcmVkKSA6IF9sb2FkQ3JlZGVudGlhbHMoa2V5KVxuICAgICAgKSxcbiAgICAgIGNhdGNoRXJyb3IoKCkgPT4gX2xvYWRDcmVkZW50aWFscyhrZXkpKVxuICAgICk7XG4gIH1cbiAgLy8gbGludXggbGlrZSBmYWxsYmFja1xuICByZXR1cm4gX2xvYWRDcmVkZW50aWFscyhrZXkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2NoVG9vbHNHZXRDcmVkZW50aWFscyhcbiAgYUFwaVVybDogc3RyaW5nXG4pOiBPYnNlcnZhYmxlPENyZWRlbnRpYWxzPiB7XG4gIC8vIHJldHVyblxuICByZXR1cm4gX2dldFN0b3JlZENyZWRlbnRpYWxzKGFBcGlVcmwpLnBpcGUoXG4gICAgbWFwKGNyZWQgPT4gX21lcmdlQ3JlZGVudGlhbHMoX2dldENyZWRlbnRpYWxzRnJvbUVudmlyb25tZW50KCksIGNyZWQpKSxcbiAgICBjYXRjaEVycm9yKGVyciA9PiBvZihfZ2V0Q3JlZGVudGlhbHNGcm9tRW52aXJvbm1lbnQoKSkpXG4gICk7XG59XG4iLCJpbXBvcnQgeyBhc3NlcnRPYmplY3QsIGlzTmlsIH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcbmltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiwgcGFyc2UgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGJpbmROb2RlQ2FsbGJhY2ssIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IHNhdGlzZmllcyB9IGZyb20gJ3NlbXZlcic7XG5cbmV4cG9ydCBlbnVtIERFUF9UWVBFIHtcbiAgUEVFUixcbiAgUlVOVElNRSxcbiAgREVWRUxPUE1FTlRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlckZvclR5cGUoYVR5cGU/OiBERVBfVFlQRSk6IHN0cmluZyB7XG4gIHJldHVybiBhVHlwZSA9PT0gREVQX1RZUEUuUEVFUlxuICAgID8gJ3BlZXJEZXBlbmRlbmNpZXMnXG4gICAgOiBhVHlwZSA9PT0gREVQX1RZUEUuREVWRUxPUE1FTlRcbiAgICAgID8gJ2RldkRlcGVuZGVuY2llcydcbiAgICAgIDogJ2RlcGVuZGVuY2llcyc7XG59XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgcGFja2FnZSBKU09OIHRvIHVzZSBhdCBsZWFzdCB0aGUgZ2l2ZW4gdmVyc2lvblxuICpcbiAqIEBwYXJhbSBhTmFtZSAgICAgbmFtZVxuICogQHBhcmFtIGFNaW5WZXJzaW9uICAgbWluIHZlcnNpb25cbiAqIEBwYXJhbSBhUGtnICBwYWNrYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVNaW5WZXJzaW9uKFxuICBhTmFtZTogc3RyaW5nLFxuICBhTWluVmVyc2lvbjogc3RyaW5nLFxuICBhUGtnOiBhbnksXG4gIGFUeXBlPzogREVQX1RZUEVcbik6IGFueSB7XG4gIC8vIGNoZWNrIGlmIHdlIGhhdmUgYSB2ZXJzaW9uIGlkZW50aWZpZXJcbiAgY29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyRm9yVHlwZShhVHlwZSk7XG4gIC8vIGFjY2Vzc1xuICBjb25zdCBkZXBzID0gYXNzZXJ0T2JqZWN0KGZvbGRlciwgYVBrZykgYXMgYW55O1xuICBjb25zdCBvbGREZXAgPSBkZXBzW2FOYW1lXTtcbiAgaWYgKGlzTmlsKG9sZERlcCkgfHwgIXNhdGlzZmllcyhhTWluVmVyc2lvbiwgb2xkRGVwKSkge1xuICAgIC8vIGp1c3QgdXBkYXRlXG4gICAgZGVwc1thTmFtZV0gPSBgXiR7YU1pblZlcnNpb259YDtcbiAgfVxuICAvLyBva1xuICByZXR1cm4gYVBrZztcbn1cblxuY29uc3QgcnhSZWFkRmlsZSA9IGJpbmROb2RlQ2FsbGJhY2s8c3RyaW5nLCBzdHJpbmcsIHN0cmluZz4ocmVhZEZpbGUpO1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZFBhY2thZ2VKc29uKGFEaXI6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gIC8vIHJlYWRcbiAgcmV0dXJuIHJ4UmVhZEZpbGUoam9pbihhRGlyLCAncGFja2FnZS5qc29uJyksICd1dGYtOCcpLnBpcGUoXG4gICAgbWFwKGRhdGEgPT4gSlNPTi5wYXJzZShkYXRhKSksXG4gICAgY2F0Y2hFcnJvcihlcnIgPT4gZmluZFBhY2thZ2VKc29uKHBhcnNlKGFEaXIpLmRpcikpXG4gICk7XG59XG4iLCJpbXBvcnQgeyBQYXRoLCByZXNvbHZlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2NvcmUnO1xuaW1wb3J0IHsgVHJlZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzJztcbmltcG9ydCB7IGNvZXJjZSB9IGZyb20gJ3NlbXZlcic7XG5pbXBvcnQge1xuICBLRVlfQkFTSUNBVVRIX0xPR0lOX1BBU1NXT1JELFxuICBLRVlfQkFTSUNBVVRIX0xPR0lOX1VTRVJOQU1FLFxuICBSRUxfUEFUSF9CQVNJQ0FVVEhfTE9HSU4sXG4gIFJFTF9QQVRIX0NVUlJFTlRfVVNFUlxufSBmcm9tICdAaWJtLXdjaC1zZGsvYXBpJztcbmltcG9ydCB7IGlzTmlsLCBpc05vdE5pbCwgYXNzZXJ0QXJyYXkgfSBmcm9tICdAaWJtLXdjaC1zZGsvdXRpbHMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGNhdGNoRXJyb3IsXG4gIG1hcCxcbiAgbWFwVG8sXG4gIHBsdWNrLFxuICBzd2l0Y2hNYXAsXG4gIHN3aXRjaE1hcFRvXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IGlzVXJpIH0gZnJvbSAndmFsaWQtdXJsJztcbmltcG9ydCB7IFZFcnJvciB9IGZyb20gJ3ZlcnJvcic7XG5cbmltcG9ydCB7IGZpbmRQYWNrYWdlSnNvbiB9IGZyb20gJy4vLi4vcGFja2FnZSc7XG5pbXBvcnQgeyBpc1ZhbGlkVXNlck5hbWUgfSBmcm9tICcuL2Fzc2VydCc7XG5pbXBvcnQgeyByeEZvcm1Qb3N0LCByeEdldEpzb24gfSBmcm9tICcuL3J4LnJlcXVlc3QnO1xuaW1wb3J0IHsgZW5zdXJlVHJhaWxpbmdTbGFzaCB9IGZyb20gJy4vdXJsLnV0aWxzJztcbmltcG9ydCB7IENyZWRlbnRpYWxzLCB3Y2hUb29sc0dldENyZWRlbnRpYWxzIH0gZnJvbSAnLi93Y2h0b29scyc7XG5cbmZ1bmN0aW9uIF9pc0FwaUtleShhTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBhTmFtZSA9PT0gJ2FwaWtleSc7XG59XG5cbmZ1bmN0aW9uIF9pc1ZhbGlkUGFzc3dvcmQoYVBhc3N3b3JkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGFQYXNzd29yZCAmJiBhUGFzc3dvcmQubGVuZ3RoID4gMDtcbn1cblxuZnVuY3Rpb24gX3Rocm93SW52YWxpZFVybChhQXBpVXJsOiBzdHJpbmcsIGFFcnJvcjogRXJyb3IpOiBPYnNlcnZhYmxlPG5ldmVyPiB7XG4gIHJldHVybiB0aHJvd0Vycm9yKFxuICAgIG5ldyBWRXJyb3IoYUVycm9yLCAnVGhlIEFQSSBVUkwgWyVzXSBpcyBub3QgYSB2YWxpZCBXQ0ggQVBJIFVSTC4nLCBhQXBpVXJsKVxuICApO1xufVxuXG5mdW5jdGlvbiBfZ2V0Q3VycmVudFVzZXIoYUFwaVVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgLy8gdGhlIFVSTFxuICBjb25zdCBjdXJyZW50VXNlclVybCA9IGAke2FBcGlVcmx9JHtSRUxfUEFUSF9DVVJSRU5UX1VTRVJ9YDtcbiAgcmV0dXJuIHJ4R2V0SnNvbihjdXJyZW50VXNlclVybCkucGlwZShcbiAgICBjYXRjaEVycm9yKGVycm9yID0+IF90aHJvd0ludmFsaWRVcmwoYUFwaVVybCwgZXJyb3IpKVxuICApO1xufVxuXG5mdW5jdGlvbiBfdGhyb3dJbnZhbGlkQ3JlZGVudGlhbHMoYUFwaVVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxuZXZlcj4ge1xuICByZXR1cm4gdGhyb3dFcnJvcihcbiAgICBuZXcgVkVycm9yKFxuICAgICAgJ1VuYWJsZSB0byBhY2Nlc3MgY3JlZGVudGlhbHMgZm9yIHRoZSBBUEkgVVJMIFslc10uIFBsZWFzZSBmb2xsb3cgdGhlIGRpcmVjdGlvbnMgb24gaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvaWJtLXdjaC1zZGstY2xpI2NyZWRlbnRpYWwtbWFuYWdlbWVudCB0byByZWdpc3RlciBjcmVkZW50aWFscy4nLFxuICAgICAgYUFwaVVybFxuICAgIClcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ3JlZGVudGlhbHMoXG4gIGFBcGlVcmw6IHN0cmluZyxcbiAgYUNyZWRlbnRpYWxzOiBDcmVkZW50aWFsc1xuKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgLy8gY2hlY2sgdGhlIGNyZWRlbnRpYWxzIG9iamVjdFxuICBpZiAoXG4gICAgIWFDcmVkZW50aWFscyB8fFxuICAgICFpc1ZhbGlkVXNlck5hbWUoYUNyZWRlbnRpYWxzLnVzZXJuYW1lKSB8fFxuICAgICFfaXNWYWxpZFBhc3N3b3JkKGFDcmVkZW50aWFscy5wYXNzd29yZClcbiAgKSB7XG4gICAgcmV0dXJuIF90aHJvd0ludmFsaWRDcmVkZW50aWFscyhhQXBpVXJsKTtcbiAgfVxuICAvLyB0ZXN0IGlmIHdlIGNhbiBsb2dpblxuICBjb25zdCBsb2dpblVybCA9IGAke2FBcGlVcmx9JHtSRUxfUEFUSF9CQVNJQ0FVVEhfTE9HSU59YDtcbiAgY29uc3QgYm9keSA9IHtcbiAgICBbS0VZX0JBU0lDQVVUSF9MT0dJTl9VU0VSTkFNRV06IGFDcmVkZW50aWFscy51c2VybmFtZSxcbiAgICBbS0VZX0JBU0lDQVVUSF9MT0dJTl9QQVNTV09SRF06IGFDcmVkZW50aWFscy5wYXNzd29yZFxuICB9O1xuICAvLyBleGVjdXRlXG4gIHJldHVybiByeEZvcm1Qb3N0KGxvZ2luVXJsLCBib2R5KS5waXBlKFxuICAgIG1hcChkYXRhID0+IEpTT04ucGFyc2UoZGF0YSkpLFxuICAgIGNhdGNoRXJyb3IoZXJyb3IgPT5cbiAgICAgIHRocm93RXJyb3IoXG4gICAgICAgIG5ldyBWRXJyb3IoXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgJ1VuYWJsZSB0byBsb2dpbiB0byBbJXNdIHdpdGggdXNlciBbJXNdLiBQbGVhc2UgY2hlY2sgeW91ciByZWdpc3RlcmVkIHBhc3N3b3JkLicsXG4gICAgICAgICAgbG9naW5VcmwsXG4gICAgICAgICAgYUNyZWRlbnRpYWxzLnVzZXJuYW1lXG4gICAgICAgIClcbiAgICAgIClcbiAgICApLFxuICAgIG1hcFRvKGFBcGlVcmwpXG4gICk7XG59XG5cbmZ1bmN0aW9uIF92YWxpZGF0ZVVzZXIoYUZlZWQ6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gIC8vIHRlc3QgdGhlIGZlZWQgcmVzdWx0XG4gIGlmICghYUZlZWQgfHwgIWFGZWVkLmV4dGVybmFsSWQpIHtcbiAgICByZXR1cm4gdGhyb3dFcnJvcihuZXcgVkVycm9yKCdJbnZhbGlkIGN1cnJlbnR1c2VyIHJlc3BvbnNlJykpO1xuICB9XG4gIHJldHVybiBvZihhRmVlZCk7XG59XG5cbi8qKlxuICogVGVzdHMgaWYgIHRoZSBBUEkgVVJMIGlzIHZhbGlkIGFuZCBpZiB3ZSBoYXZlIHN1ZmZpY2llbnQgY3JlZGVudGlhbHMgdG8gYWNjZXNzIHRoZSBBUElcbiAqXG4gKiBAcGFyYW0gYVVybCAgdGhlIEFQSSBVUkxcbiAqIEByZXR1cm4gdGhlIHVybFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVBcGlVcmwoXG4gIGFVcmw6IHN0cmluZyxcbiAgYlZhbGlkYXRlV2l0aENyZWRlbnRpYWxzOiBib29sZWFuXG4pOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBjaGVjayBpZiB0aGUgVVJMIGlzIHZhbHVkXG4gIGlmICghaXNVcmkoYVVybCkpIHtcbiAgICByZXR1cm4gdGhyb3dFcnJvcihcbiAgICAgIG5ldyBWRXJyb3IoXG4gICAgICAgICdQbGVhc2UgZW50ZXIgYSB2YWxpZCBBUEkgVVJMLiBDb3B5IHRoaXMgVVJMIGZyb20gdGhlIFwiSHViIEluZm9ybWF0aW9uXCIgc2VjdGlvbiBvZiB5b3VyIFdDSCB0ZW5hbnQuJ1xuICAgICAgKVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgaWYgdGhlIFVSTCBpcyB2YWxpZFxuICBjb25zdCBub3JtVXJsID0gZW5zdXJlVHJhaWxpbmdTbGFzaChhVXJsKTtcblxuICBpZiAoYlZhbGlkYXRlV2l0aENyZWRlbnRpYWxzKSB7XG4gICAgLy8gbG9hZCB0aGUgY3JlZGVudGlhbHNcbiAgICBjb25zdCBvbkNyZWRlbnRpYWxzID0gd2NoVG9vbHNHZXRDcmVkZW50aWFscyhub3JtVXJsKS5waXBlKFxuICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiBfdGhyb3dJbnZhbGlkQ3JlZGVudGlhbHMobm9ybVVybCkpXG4gICAgKTtcblxuICAgIC8vIGNoZWNrIGlmIHRoZSBVUkwgZXhpc3RzXG4gICAgY29uc3Qgb25WYWxpZFVybDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gX2dldEN1cnJlbnRVc2VyKG5vcm1VcmwpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoX3ZhbGlkYXRlVXNlciksXG4gICAgICBzd2l0Y2hNYXBUbyhvbkNyZWRlbnRpYWxzKSxcbiAgICAgIHN3aXRjaE1hcChjcmVkID0+IHZhbGlkYXRlQ3JlZGVudGlhbHMobm9ybVVybCwgY3JlZCkpXG4gICAgKTtcbiAgICAvLyBva1xuICAgIHJldHVybiBvblZhbGlkVXJsO1xuICB9IGVsc2Uge1xuICAgIC8vIGNoZWNrIGlmIHRoZSBVUkwgZXhpc3RzXG4gICAgY29uc3Qgb25WYWxpZFVybDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gX2dldEN1cnJlbnRVc2VyKG5vcm1VcmwpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoX3ZhbGlkYXRlVXNlciksXG4gICAgICBtYXBUbyhub3JtVXJsKVxuICAgICk7XG4gICAgLy8gb2tcbiAgICByZXR1cm4gb25WYWxpZFVybDtcbiAgfVxufVxuXG5jb25zdCBQQUNLQUdFX0pTT04gPSAnL3BhY2thZ2UuanNvbicgYXMgUGF0aDtcbmNvbnN0IEZBTExCQUNLID0gJy9kYXRhJyBhcyBQYXRoO1xuXG5jb25zdCBPUFRJT05TID0gJy53Y2h0b29sc29wdGlvbnMuanNvbicgYXMgUGF0aDtcblxuY29uc3QgU0RLX0lNUE9SVCA9ICdAaWJtLXdjaC1zZGsvbmcnO1xuY29uc3QgQ0xJX0lNUE9SVCA9ICdAaWJtLXdjaC1zZGsvY2xpJztcblxuZXhwb3J0IGNvbnN0IFdDSFRPT0xTX0RFUEVOREVOQ0lFUyA9ICd3Y2h0b29scy1kZXBlbmRlbmNpZXMnO1xuXG5mdW5jdGlvbiBfZmluZEJ1aWxkVmVyc2lvbigpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBmaW5kIHRoZSBwYWNrYWdlXG4gIHJldHVybiBmaW5kUGFja2FnZUpzb24oX19kaXJuYW1lKS5waXBlKHBsdWNrPGFueSwgc3RyaW5nPigndmVyc2lvbicpKTtcbn1cblxuLyoqXG4gKiBEZWNvZGUgdGhlIHZlcnNpb24gZnJvbSB0aGUgZGVwZW5kZW5jeVxuICpcbiAqIEBwYXJhbSBhVmVyc2lvbiAgdGhlIHZlcnNpb25cbiAqXG4gKiBAcmV0dXJuIG9ic2VydmFibGUgb2YgdGhlIHZlcnNpb25cbiAqL1xuZnVuY3Rpb24gX2Zyb21EZXBlbmRlbmN5KGFWZXJzaW9uOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICBjb25zdCBwYXJzZWQgPSBjb2VyY2UoYVZlcnNpb24pO1xuICByZXR1cm4gISFwYXJzZWQgPyBvZihwYXJzZWQudmVyc2lvbikgOiBfZmluZEJ1aWxkVmVyc2lvbigpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZFNka1ZlcnNpb24oaG9zdDogVHJlZSk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIHRyeSB0byBsb2NhdGUgdGhlIHBhY2thZ2UganNvblxuICBjb25zdCBidWYgPSBob3N0LnJlYWQoUEFDS0FHRV9KU09OKTtcbiAgaWYgKGlzTmlsKGJ1ZikpIHtcbiAgICByZXR1cm4gX2ZpbmRCdWlsZFZlcnNpb24oKTtcbiAgfVxuICAvLyBzb3VyY2UgcGFja2FnZVxuICBjb25zdCBwa2cgPSBKU09OLnBhcnNlKGJ1Zi50b1N0cmluZygpKTtcbiAgLy8gY2hlY2sgaWYgd2UgaGF2ZSBpbXBvcnRzXG4gIGNvbnN0IGRlcHMgPSBwa2cuZGVwZW5kZW5jaWVzIHx8IHt9O1xuICBjb25zdCBkZXZEZXBzID0gcGtnLmRldkRlcGVuZGVuY2llcyB8fCB7fTtcblxuICBjb25zdCBmcm9tUGtnID0gZGVwc1tTREtfSU1QT1JUXSB8fCBkZXZEZXBzW0NMSV9JTVBPUlRdO1xuXG4gIHJldHVybiBpc05vdE5pbChmcm9tUGtnKSA/IF9mcm9tRGVwZW5kZW5jeShmcm9tUGtnKSA6IF9maW5kQnVpbGRWZXJzaW9uKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRGF0YURpcihob3N0OiBUcmVlKTogUGF0aCB7XG4gIGNvbnN0IGJ1ZiA9IGhvc3QucmVhZChQQUNLQUdFX0pTT04pO1xuICBpZiAoaXNOaWwoYnVmKSkge1xuICAgIHJldHVybiBGQUxMQkFDSztcbiAgfVxuXG4gIGNvbnN0IHBrZyA9IEpTT04ucGFyc2UoYnVmLnRvU3RyaW5nKCkpO1xuICBjb25zdCBjZmcgPSBwa2cuY29uZmlnIHx8IHt9O1xuXG4gIGNvbnN0IGRhdGEgPSBjZmcuZGF0YSB8fCBGQUxMQkFDSztcblxuICByZXR1cm4gcmVzb2x2ZSgnLycgYXMgUGF0aCwgZGF0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kV2NoVG9vbHNPcHRpb25zKGhvc3Q6IFRyZWUpOiBQYXRoIHtcbiAgcmV0dXJuIHJlc29sdmUoZmluZERhdGFEaXIoaG9zdCksIE9QVElPTlMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkVG9XY2hUb29sc0RlcGVuZGVuY2llcyhhRGVwczogc3RyaW5nW10sIGFQa2c6IGFueSkge1xuICAvLyBhZGQgdGhlIGtleVxuICBjb25zdCBkZXBzID0gYXNzZXJ0QXJyYXk8c3RyaW5nPihXQ0hUT09MU19ERVBFTkRFTkNJRVMsIGFQa2cpO1xuICAvLyBmaWx0ZXJcbiAgZGVwcy5wdXNoKC4uLmFEZXBzLmZpbHRlcihkZXAgPT4gZGVwcy5pbmRleE9mKGRlcCkgPCAwKSk7XG59XG4iLCJpbXBvcnQgeyBHZW5lcmF0b3IsIGlzQXJyYXksIGlzTmlsLCBpc1BsYWluT2JqZWN0IH0gZnJvbSAnQGlibS13Y2gtc2RrL3V0aWxzJztcblxuY29uc3QgX2tleXMgPSBPYmplY3Qua2V5cztcblxuY29uc3QgS0VZX1dFSUdIVFM6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7XG4gIG5hbWU6IDEsXG4gIGRlc2NyaXB0aW9uOiAyLFxuICBpZDogMyxcbiAgY2xhc3NpZmljYXRpb246IDRcbn07XG5cbmZ1bmN0aW9uIF9jb21wYXJlTnVtYmVyKGFMZWZ0OiBudW1iZXIsIGFSaWdodDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGFMZWZ0IDwgYVJpZ2h0ID8gLTEgOiBhTGVmdCA+IGFSaWdodCA/ICsxIDogMDtcbn1cblxuZnVuY3Rpb24gX2dldEtleShhTmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIEtFWV9XRUlHSFRTW2FOYW1lXSB8fCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbn1cblxuZnVuY3Rpb24gX2NvbXBhcmVOYW1lKGFMZWZ0OiBzdHJpbmcsIGFSaWdodDogc3RyaW5nKTogbnVtYmVyIHtcbiAgLy8gZmlyc3QgYnkga2V5XG4gIGxldCBjID0gX2NvbXBhcmVOdW1iZXIoX2dldEtleShhTGVmdCksIF9nZXRLZXkoYVJpZ2h0KSk7XG4gIGlmIChjID09PSAwKSB7XG4gICAgYyA9IGFMZWZ0LmxvY2FsZUNvbXBhcmUoYVJpZ2h0KTtcbiAgfVxuICAvLyBva1xuICByZXR1cm4gYztcbn1cblxuZnVuY3Rpb24gX2Nhbm9uaWNhbGl6ZShhRGF0YTogYW55KTogYW55IHtcbiAgLy8gaGFuZGxlXG4gIGlmIChpc0FycmF5KGFEYXRhKSkge1xuICAgIGNvbnN0IGNvcHk6IGFueVtdID0gW107XG4gICAgYURhdGEuZm9yRWFjaCh2ID0+IGNvcHkucHVzaChfY2Fub25pY2FsaXplKHYpKSk7XG4gICAgcmV0dXJuIGNvcHk7XG4gIH1cbiAgaWYgKGlzUGxhaW5PYmplY3QoYURhdGEpKSB7XG4gICAgLy8gc29ydCB0aGUga2V5c1xuICAgIGNvbnN0IGNvcHk6IGFueSA9IHt9O1xuICAgIF9rZXlzKGFEYXRhKVxuICAgICAgLnNvcnQoX2NvbXBhcmVOYW1lKVxuICAgICAgLmZvckVhY2goayA9PiAoY29weVtrXSA9IF9jYW5vbmljYWxpemUoYURhdGFba10pKSk7XG4gICAgcmV0dXJuIGNvcHk7XG4gIH1cbiAgLy8gbm90aGluZyB0byBkb1xuICByZXR1cm4gYURhdGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVKc29uKGFEYXRhOiBhbnkpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gYURhdGEgPyBKU09OLnN0cmluZ2lmeShhRGF0YSwgdW5kZWZpbmVkLCAyKSA6IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUZpZWxkKFxuICBhTmFtZTogc3RyaW5nLFxuICBhR2VuZXJhdG9yOiBHZW5lcmF0b3I8c3RyaW5nPixcbiAgYU9iajogYW55XG4pOiBhbnkge1xuICBjb25zdCBvbGRWYWx1ZSA9IGFPYmpbYU5hbWVdO1xuICBpZiAoaXNOaWwob2xkVmFsdWUpKSB7XG4gICAgLy8gdXBkYXRlIHdpdGggdGhlIGdlbmVyYXRlZCB2YWx1ZVxuICAgIGFPYmpbYU5hbWVdID0gYUdlbmVyYXRvcigpO1xuICB9XG4gIHJldHVybiBhT2JqO1xufVxuXG5leHBvcnQgeyBfY2Fub25pY2FsaXplIGFzIGNhbm9uaWNhbGl6ZUpTT04gfTtcbiIsImV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVMaW5lcyhhU291cmNlPzogc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gYVNvdXJjZSA/IGFTb3VyY2Uuam9pbignXFxuJykgOiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpbmVzKGFTb3VyY2U/OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBhU291cmNlID8gYVNvdXJjZS5zcGxpdCgnXFxuJykgOiBbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExpbmVzKFxuICBhU291cmNlOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCxcbiAgYUluc2VydDogc3RyaW5nW11cbik6IHN0cmluZ1tdIHtcbiAgaWYgKGFTb3VyY2UpIHtcbiAgICAvLyBidWlsZCB0aGUgc2V0XG4gICAgY29uc3QgZXhpc3RpbmcgPSBuZXcgU2V0PHN0cmluZz4oYVNvdXJjZSk7XG5cbiAgICByZXR1cm4gWy4uLmFTb3VyY2UsIC4uLmFJbnNlcnQuZmlsdGVyKGxpbmUgPT4gIWV4aXN0aW5nLmhhcyhsaW5lKSldO1xuICB9IGVsc2Uge1xuICAgIC8vIGp1c3QgaW5zZXJ0IGludG8gdGhlIGVtcHR5IGZpbGVcbiAgICByZXR1cm4gWy4uLmFJbnNlcnRdO1xuICB9XG59XG4iLCJpbXBvcnQgeyBUcmVlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L3NjaGVtYXRpY3MnO1xuaW1wb3J0IHsgaXNOb3ROaWwgfSBmcm9tICdAaWJtLXdjaC1zZGsvdXRpbHMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgVW5hcnlGdW5jdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlyc3QsIG1hcCwgbWFwVG8gfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGNhbm9uaWNhbGl6ZUpTT04sIHNlcmlhbGl6ZUpzb24gfSBmcm9tICcuL2pzb24nO1xuaW1wb3J0IHsgcGFyc2VMaW5lcywgc2VyaWFsaXplTGluZXMgfSBmcm9tICcuLy4uL3RleHQvbGluZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybVdpdGhQYXRoPFQ+IHtcbiAgKGFTb3VyY2U6IFQgfCB1bmRlZmluZWQsIGFQYXRoOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybVdpdGhvdXRQYXRoPFQ+IHtcbiAgKGFTb3VyY2U6IFQgfCB1bmRlZmluZWQpOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xufVxuXG5leHBvcnQgdHlwZSBUcmFuc2Zvcm1DYWxsYmFjazxUPiA9XG4gIHwgVHJhbnNmb3JtV2l0aFBhdGg8VD5cbiAgfCBUcmFuc2Zvcm1XaXRob3V0UGF0aDxUPjtcblxuLyoqXG4gKiBSZWFkcyBhIHRleHQgZmlsZSBmcm9tIHRoZSB0cmVlIGFuZCB0aGVuIHRyYW5zZm9ybXMgaXQgdXNpbmcgdGhlIGdpdmVuIGZ1bmN0aW9uLiBJZiB0aGUgcmVzdWx0XG4gKiBpcyBudWxsIG9yIHVuZGVmaW5lZCwgdGhlIGZpbGUgd2lsbCBiZSBkZWxldGVkLCBlbHNlIHJlcGxhY2VkIG9yIGNyZWF0ZWQuXG4gKlxuICogQHBhcmFtIGFOYW1lICAgbmFtZSBvZiB0aGUgZmlsZVxuICogQHBhcmFtIGFPcCAgICAgdGhlIG9wZXJhdG9yXG4gKiBAcGFyYW0gYVRyZWUgICB0aGUgdHJlZSB0byB3b3JrIGluXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByeFRyYW5zZm9ybVRleHRGaWxlKFxuICBhTmFtZTogc3RyaW5nLFxuICBhT3A6IFRyYW5zZm9ybUNhbGxiYWNrPHN0cmluZz4sXG4gIGFUcmVlOiBUcmVlXG4pOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAvLyBsb2FkIHRoZSBmaWxlIGlmIGl0IGV4aXN0c1xuICBjb25zdCBidWZmZXIgPSBhVHJlZS5yZWFkKGFOYW1lKTtcbiAgY29uc3QgdmFsdWUgPSBpc05vdE5pbChidWZmZXIpID8gYnVmZmVyLnRvU3RyaW5nKCkgOiBudWxsO1xuICBjb25zdCBvcDogVHJhbnNmb3JtV2l0aFBhdGg8c3RyaW5nPiA9IGFPcCBhcyBhbnk7XG4gIC8vIHJlcGxhY2VcbiAgcmV0dXJuIG9wKHZhbHVlLCBhTmFtZSkucGlwZShcbiAgICBmaXJzdCgpLFxuICAgIG1hcChcbiAgICAgIHJlc3VsdCA9PlxuICAgICAgICBpc05vdE5pbChyZXN1bHQpXG4gICAgICAgICAgPyBpc05vdE5pbChidWZmZXIpXG4gICAgICAgICAgICA/IGFUcmVlLm92ZXJ3cml0ZShhTmFtZSwgcmVzdWx0KVxuICAgICAgICAgICAgOiBhVHJlZS5jcmVhdGUoYU5hbWUsIHJlc3VsdClcbiAgICAgICAgICA6IGlzTm90TmlsKGJ1ZmZlcilcbiAgICAgICAgICAgID8gYVRyZWUuZGVsZXRlKGFOYW1lKVxuICAgICAgICAgICAgOiB1bmRlZmluZWRcbiAgICApLFxuICAgIG1hcFRvKGFOYW1lKVxuICApO1xufVxuXG4vKipcbiAqIFJlYWRzIGEgSlNPTiBmaWxlIGZyb20gdGhlIHRyZWUgYW5kIHRoZW4gdHJhbnNmb3JtcyBpdCB1c2luZyB0aGUgZ2l2ZW4gZnVuY3Rpb24uIElmIHRoZSByZXN1bHRcbiAqIGlzIG51bGwgb3IgdW5kZWZpbmVkLCB0aGUgZmlsZSB3aWxsIGJlIGRlbGV0ZWQsIGVsc2UgcmVwbGFjZWQgb3IgY3JlYXRlZC5cbiAqXG4gKiBAcGFyYW0gYU5hbWUgICBuYW1lIG9mIHRoZSBmaWxlXG4gKiBAcGFyYW0gYU9wICAgICB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSBhVHJlZSAgIHRoZSB0cmVlIHRvIHdvcmsgaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ4VHJhbnNmb3JtSnNvbkZpbGUoXG4gIGFOYW1lOiBzdHJpbmcsXG4gIGFPcDogVHJhbnNmb3JtQ2FsbGJhY2s8YW55PixcbiAgYVRyZWU6IFRyZWVcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIGNhc3RcbiAgY29uc3Qgb3A6IFRyYW5zZm9ybVdpdGhQYXRoPGFueT4gPSBhT3AgYXMgYW55O1xuICAvLyBkaXNwYXRjaFxuICByZXR1cm4gcnhUcmFuc2Zvcm1UZXh0RmlsZShcbiAgICBhTmFtZSxcbiAgICAodGV4dENvbnRlbnQsIHBhdGgpID0+XG4gICAgICBvcCh0ZXh0Q29udGVudCA/IEpTT04ucGFyc2UodGV4dENvbnRlbnQpIDogdW5kZWZpbmVkLCBwYXRoKS5waXBlKFxuICAgICAgICBtYXAoY2Fub25pY2FsaXplSlNPTiksXG4gICAgICAgIG1hcChzZXJpYWxpemVKc29uKVxuICAgICAgKSxcbiAgICBhVHJlZVxuICApO1xufVxuXG4vKipcbiAqIFJlYWRzIGEgbGluZSBiYXNlZCBmaWxlIGZyb20gdGhlIHRyZWUgYW5kIHRoZW4gdHJhbnNmb3JtcyBpdCB1c2luZyB0aGUgZ2l2ZW4gZnVuY3Rpb24uIElmIHRoZSByZXN1bHRcbiAqIGlzIG51bGwgb3IgdW5kZWZpbmVkLCB0aGUgZmlsZSB3aWxsIGJlIGRlbGV0ZWQsIGVsc2UgcmVwbGFjZWQgb3IgY3JlYXRlZC5cbiAqXG4gKiBAcGFyYW0gYU5hbWUgICBuYW1lIG9mIHRoZSBmaWxlXG4gKiBAcGFyYW0gYU9wICAgICB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSBhVHJlZSAgIHRoZSB0cmVlIHRvIHdvcmsgaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ4VHJhbnNmb3JtTGluZXNGaWxlKFxuICBhTmFtZTogc3RyaW5nLFxuICBhT3A6IFRyYW5zZm9ybUNhbGxiYWNrPHN0cmluZ1tdPixcbiAgYVRyZWU6IFRyZWVcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIGNhc3RcbiAgY29uc3Qgb3A6IFRyYW5zZm9ybVdpdGhQYXRoPHN0cmluZ1tdPiA9IGFPcCBhcyBhbnk7XG4gIC8vIGRpc3BhdGNoXG4gIHJldHVybiByeFRyYW5zZm9ybVRleHRGaWxlKFxuICAgIGFOYW1lLFxuICAgICh0ZXh0Q29udGVudCwgcGF0aCkgPT5cbiAgICAgIG9wKHRleHRDb250ZW50ID8gcGFyc2VMaW5lcyh0ZXh0Q29udGVudCkgOiB1bmRlZmluZWQsIHBhdGgpLnBpcGUoXG4gICAgICAgIG1hcChzZXJpYWxpemVMaW5lcylcbiAgICAgICksXG4gICAgYVRyZWVcbiAgKTtcbn1cbiIsIi8qIENvcHlyaWdodCBJQk0gQ29ycC4gMjAxOCAqL1xuaW1wb3J0IHsgVHJlZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzJztcbmltcG9ydCB7IGpvaW4sIG5vcm1hbGl6ZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgZ2V0IH0gZnJvbSAncmVxdWVzdCc7XG5pbXBvcnQgeyBkZWZlciwgZnJvbUV2ZW50LCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmaXJzdCxcbiAgbWFwLFxuICBtYXBUbyxcbiAgbWVyZ2VNYXAsXG4gIHRha2VVbnRpbCxcbiAgdGFwXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFdyaXRhYmxlIH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCB7IEVudHJ5LCBQYXJzZSB9IGZyb20gJ3VuemlwJztcblxuZnVuY3Rpb24gX3NraXBQcmVmaXgoYU5hbWU6IHN0cmluZywgYUNvdW50OiBudW1iZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgLy8gY3VycmVudCBuYW1lXG4gIGxldCBpZHggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFDb3VudDsgKytpKSB7XG4gICAgLy8gZmluZCB0aGUgbmV4dCBzZXBhcmF0b3JcbiAgICBjb25zdCBuZXh0SWR4ID0gYU5hbWUuaW5kZXhPZignLycsIGlkeCk7XG4gICAgaWYgKG5leHRJZHggPj0gaWR4KSB7XG4gICAgICBpZHggPSBuZXh0SWR4ICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIC8vIHNwbGl0XG4gIHJldHVybiBhTmFtZS5zdWJzdHJpbmcoaWR4KTtcbn1cblxuY2xhc3MgU3RyZWFtT25CdWZmZXIgZXh0ZW5kcyBXcml0YWJsZSB7XG4gIGJ1ZmZlcnM6IEJ1ZmZlcltdID0gW107XG5cbiAgX3dyaXRlKGNodW5rOiBhbnksIGVuY29kaW5nOiBzdHJpbmcsIGNhbGxiYWNrOiAoZXJyPzogRXJyb3IpID0+IHZvaWQpIHtcbiAgICB0aGlzLmJ1ZmZlcnMucHVzaChjaHVuayk7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIF9maW5hbChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgICBjYWxsYmFjaygpO1xuICAgIHRoaXMuZW1pdCgnY2xvc2UnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfcnhFeHRyYWN0RW50cnkoXG4gIGFUcmVlOiBUcmVlLFxuICBhRW50cnk6IEVudHJ5LFxuICBhRHN0RGlyOiBzdHJpbmcsXG4gIGFTa2lwOiBudW1iZXJcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIHNraXAgdGhlIHByZWZpeFxuICBjb25zdCBwYXRoID0gX3NraXBQcmVmaXgoYUVudHJ5LnBhdGgsIGFTa2lwKTtcbiAgaWYgKCFwYXRoKSB7XG4gICAgLy8gbm90aGluZ1xuICAgIHJldHVybiBvZignJykucGlwZShcbiAgICAgIHRhcCgoKSA9PiBhRW50cnkuYXV0b2RyYWluKCkpLFxuICAgICAgZmlsdGVyKCgpID0+IGZhbHNlKVxuICAgICk7XG4gIH1cbiAgLy8gY3JlYXRlIGZpbGVuYW1lXG4gIGNvbnN0IGZpbGVOYW1lID0gbm9ybWFsaXplKGpvaW4oYURzdERpciwgcGF0aCkpO1xuICAvLyBoYW5kbGUgZGlyZWN0b3JpZXNcbiAgaWYgKGFFbnRyeS50eXBlID09PSAnRGlyZWN0b3J5Jykge1xuICAgIC8vIGNyZWF0ZSB0aGUgZGlyZWN0b3J5XG4gICAgcmV0dXJuIG9mKCcnKS5waXBlKFxuICAgICAgdGFwKCgpID0+IGFFbnRyeS5hdXRvZHJhaW4oKSksXG4gICAgICBmaWx0ZXIoKCkgPT4gZmFsc2UpXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHN0cmVhbVxuICAgIGNvbnN0IHN0cmVhbSA9IGFFbnRyeS5waXBlKG5ldyBTdHJlYW1PbkJ1ZmZlcigpKTtcbiAgICAvLyBhdHRhY2hcbiAgICByZXR1cm4gZnJvbUV2ZW50KHN0cmVhbSwgJ2Nsb3NlJykucGlwZShcbiAgICAgIC8vIGp1c3QgdGFrZSBvbmVcbiAgICAgIGZpcnN0KCksXG4gICAgICAvLyBjb3B5IGludG8gdGhlIHRyZWVcbiAgICAgIG1hcCgoKSA9PiBhVHJlZS5jcmVhdGUoZmlsZU5hbWUsIEJ1ZmZlci5jb25jYXQoc3RyZWFtLmJ1ZmZlcnMpKSksXG4gICAgICAvLyBtYXAgdG8gdGhlIHRhcmdldCBuYW1lXG4gICAgICBtYXBUbyhmaWxlTmFtZSlcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByeFVuemlwRnJvbVVybChcbiAgYVRyZWU6IFRyZWUsXG4gIGFTcmNVcmw6IHN0cmluZyxcbiAgYURzdERpcjogc3RyaW5nLFxuICBhU2tpcDogbnVtYmVyID0gMFxuKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgLy8gZGVmZXJcbiAgcmV0dXJuIGRlZmVyKCgpID0+IHtcbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHN0cmVhbVxuICAgIGNvbnN0IHN0cmVhbSA9IGdldChhU3JjVXJsKS5waXBlKFBhcnNlKCkpO1xuICAgIC8vIGhhbmRsZVxuICAgIGNvbnN0IG9uRW50cnkgPSBmcm9tRXZlbnQ8RW50cnk+KHN0cmVhbSwgJ2VudHJ5Jyk7XG4gICAgY29uc3Qgb25DbG9zZSA9IGZyb21FdmVudChzdHJlYW0sICdjbG9zZScpO1xuICAgIC8vIHJldHVybiB0aGUgZnVsbCBzdHJlYW1cbiAgICByZXR1cm4gb25FbnRyeS5waXBlKFxuICAgICAgdGFrZVVudGlsKG9uQ2xvc2UpLFxuICAgICAgbWVyZ2VNYXAoZW50cnkgPT4gX3J4RXh0cmFjdEVudHJ5KGFUcmVlLCBlbnRyeSwgYURzdERpciwgYVNraXApKVxuICAgICk7XG4gIH0pO1xufVxuIiwiaW1wb3J0IHsgVHJlZSB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzL3NyYy90cmVlL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBpc05vdE5pbCB9IGZyb20gJ0BpYm0td2NoLXNkay91dGlscyc7XG5pbXBvcnQgeyBsb2FkIH0gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyByeFRyYW5zZm9ybVRleHRGaWxlLCBUcmFuc2Zvcm1DYWxsYmFjaywgVHJhbnNmb3JtV2l0aFBhdGggfSBmcm9tICcuL3J4LnRyZWUnO1xuXG5mdW5jdGlvbiBfcGFyc2VIdG1sKGFTdHJpbmc/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPENoZWVyaW9TdGF0aWM+IHtcbiAgcmV0dXJuIG9mKGxvYWQoaXNOb3ROaWwoYVN0cmluZykgPyBhU3RyaW5nISA6ICcnKSk7XG59XG5cbmZ1bmN0aW9uIF9zZXJpYWxpemVIdG1sKGFIdG1sOiBDaGVlcmlvU3RhdGljKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG9mKGFIdG1sIS5odG1sKCkpO1xufVxuXG4vKipcbiAqIFJlYWRzIGFuIEhNVEwgZnJvbSB0aGUgdHJlZSBhbmQgdGhlbiB0cmFuc2Zvcm1zIGl0IHVzaW5nIHRoZSBnaXZlbiBmdW5jdGlvbi4gSWYgdGhlIHJlc3VsdFxuICogaXMgbnVsbCBvciB1bmRlZmluZWQsIHRoZSBmaWxlIHdpbGwgYmUgZGVsZXRlZCwgZWxzZSByZXBsYWNlZCBvciBjcmVhdGVkLlxuICpcbiAqIEBwYXJhbSBhTmFtZSAgIG5hbWUgb2YgdGhlIGZpbGVcbiAqIEBwYXJhbSBhT3AgICAgIHRoZSBvcGVyYXRvclxuICogQHBhcmFtIGFUcmVlICAgdGhlIHRyZWUgdG8gd29yayBpblxuICovXG5leHBvcnQgZnVuY3Rpb24gcnhUcmFuc2Zvcm1IdG1sRmlsZShcbiAgYU5hbWU6IHN0cmluZyxcbiAgYU9wOiBUcmFuc2Zvcm1DYWxsYmFjazxDaGVlcmlvU3RhdGljPixcbiAgYVRyZWU6IFRyZWVcbik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gIC8vIGNhc3RcbiAgY29uc3Qgb3A6IFRyYW5zZm9ybVdpdGhQYXRoPENoZWVyaW9TdGF0aWM+ID0gYU9wIGFzIGFueTtcbiAgLy8gZGlzcGF0Y2hcbiAgcmV0dXJuIHJ4VHJhbnNmb3JtVGV4dEZpbGUoXG4gICAgYU5hbWUsXG4gICAgKHRleHRDb250ZW50LCBwYXRoKSA9PlxuICAgICAgX3BhcnNlSHRtbCh0ZXh0Q29udGVudCkucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKGh0bWwgPT4gb3AoaHRtbCwgcGF0aCkpLFxuICAgICAgICBzd2l0Y2hNYXAoX3NlcmlhbGl6ZUh0bWwpXG4gICAgICApLFxuICAgIGFUcmVlXG4gICk7XG59XG4iLCJpbXBvcnQgeyBTY2hlbWF0aWNzRXhjZXB0aW9uLCBUcmVlIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L3NjaGVtYXRpY3MnO1xuaW1wb3J0IHsgY3JlYXRlU291cmNlRmlsZSwgU2NyaXB0VGFyZ2V0LCBTb3VyY2VGaWxlIH0gZnJvbSAndHlwZXNjcmlwdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTb3VyY2VGaWxlKGhvc3Q6IFRyZWUsIHBhdGg6IHN0cmluZyk6IFNvdXJjZUZpbGUge1xuICBjb25zdCBidWZmZXIgPSBob3N0LnJlYWQocGF0aCk7XG4gIGlmICghYnVmZmVyKSB7XG4gICAgdGhyb3cgbmV3IFNjaGVtYXRpY3NFeGNlcHRpb24oYENvdWxkIG5vdCBmaW5kICR7cGF0aH0uYCk7XG4gIH1cbiAgY29uc3QgY29udGVudCA9IGJ1ZmZlci50b1N0cmluZygpO1xuICBjb25zdCBzb3VyY2UgPSBjcmVhdGVTb3VyY2VGaWxlKHBhdGgsIGNvbnRlbnQsIFNjcmlwdFRhcmdldC5MYXRlc3QsIHRydWUpO1xuXG4gIHJldHVybiBzb3VyY2U7XG59XG4iLCJpbXBvcnQgeyBUcmVlLCBVcGRhdGVSZWNvcmRlciB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9zY2hlbWF0aWNzJztcbmltcG9ydCB7IFNvdXJjZUZpbGUgfSBmcm9tICd0eXBlc2NyaXB0JztcblxuaW1wb3J0IHtcbiAgYWRkSW1wb3J0VG9Nb2R1bGUsXG4gIENoYW5nZSxcbiAgSW5zZXJ0Q2hhbmdlLFxuICBSZW1vdmVDaGFuZ2UsXG4gIFJlcGxhY2VDaGFuZ2Vcbn0gZnJvbSAnLi8uLi91dGlsaXR5JztcbmltcG9ydCB7IGdldFNvdXJjZUZpbGUgfSBmcm9tICcuL3NvdXJjZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRDaGFuZ2VzKGFDaGFuZ2VzOiBDaGFuZ2VbXSwgYVJlY29yZGVyOiBVcGRhdGVSZWNvcmRlcikge1xuICBhQ2hhbmdlcy5mb3JFYWNoKChjaGFuZ2U6IENoYW5nZSkgPT4ge1xuICAgIC8vIGRlbGV0ZVxuICAgIGlmIChjaGFuZ2UgaW5zdGFuY2VvZiBJbnNlcnRDaGFuZ2UpIHtcbiAgICAgIGFSZWNvcmRlci5pbnNlcnRMZWZ0KGNoYW5nZS5wb3MsIGNoYW5nZS50b0FkZCk7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UgaW5zdGFuY2VvZiBSZW1vdmVDaGFuZ2UpIHtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZSBpbnN0YW5jZW9mIFJlcGxhY2VDaGFuZ2UpIHtcbiAgICAgIC8vIHJlbW92ZSBvbGQgY2h1bmtcbiAgICAgIGNvbnN0IGFueUNoYW5nZSA9IGNoYW5nZSBhcyBhbnk7XG4gICAgICBhUmVjb3JkZXIucmVtb3ZlKGFueUNoYW5nZS5wb3MsIGFueUNoYW5nZS5vbGRUZXh0Lmxlbmd0aCk7XG4gICAgICBhUmVjb3JkZXIuaW5zZXJ0TGVmdChhbnlDaGFuZ2UucG9zLCBhbnlDaGFuZ2UubmV3VGV4dCk7XG4gICAgfVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoYW5nZVNvdXJjZUZpbGUoXG4gIGFGaWxlOiBzdHJpbmcsXG4gIGFPcDogKGFGaWxlOiBzdHJpbmcsIGFDb250ZW50OiBTb3VyY2VGaWxlKSA9PiBDaGFuZ2VbXSxcbiAgYUhvc3Q6IFRyZWVcbikge1xuICAvLyBtYWtlIHN1cmUgYXQgbGVhc3QgYW4gZW1wdHkgZmlsZSBleGlzdHNcbiAgaWYgKCFhSG9zdC5leGlzdHMoYUZpbGUpKSB7XG4gICAgYUhvc3QuY3JlYXRlKGFGaWxlLCAnJyk7XG4gIH1cblxuICAvLyB1cGRhdGVcbiAgY29uc3QgcmVjb3JkZXIgPSBhSG9zdC5iZWdpblVwZGF0ZShhRmlsZSk7XG4gIGluc2VydENoYW5nZXMoYU9wKGFGaWxlLCBnZXRTb3VyY2VGaWxlKGFIb3N0LCBhRmlsZSkpLCByZWNvcmRlcik7XG5cbiAgYUhvc3QuY29tbWl0VXBkYXRlKHJlY29yZGVyKTtcbn1cblxuLyoqXG4gKiBDaGFuZ2VzIHRoZSBpZGVudGlmaWVkIG1vZHVsZSBieSBhZGRpbmcgYSBjb3VwbGUgb2YgaW1wb3J0c1xuICpcbiAqIEBwYXJhbSBhRmlsZSB0aGUgZmlsZW5hbWVcbiAqIEBwYXJhbSBhTW9kdWxlcyB0aGUgbW9kdWxlcyB0byBiZSBhZGRlZFxuICogQHBhcmFtIGFIb3N0IHRoZSB0cmVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRJbXBvcnRzVG9Nb2R1bGUoXG4gIGFGaWxlOiBzdHJpbmcsXG4gIGFNb2R1bGVzOiB7IFtpZGVudGlmaWVyOiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgYUhvc3Q6IFRyZWVcbikge1xuICAvLyBpdGVyYXRlXG4gIE9iamVjdC5rZXlzKGFNb2R1bGVzKS5mb3JFYWNoKG5hbWUgPT5cbiAgICBjaGFuZ2VTb3VyY2VGaWxlKFxuICAgICAgYUZpbGUsXG4gICAgICAoZmlsZSwgY29udGVudCkgPT4gYWRkSW1wb3J0VG9Nb2R1bGUoY29udGVudCwgZmlsZSwgbmFtZSwgYU1vZHVsZXNbbmFtZV0pLFxuICAgICAgYUhvc3RcbiAgICApXG4gICk7XG59XG4iLCJpbXBvcnQgeyBQcmVkaWNhdGUgfSBmcm9tICdAaWJtLXdjaC1zZGsvdXRpbHMnO1xuaW1wb3J0IHsgTmFtZWREZWNsYXJhdGlvbiwgTm9kZSwgU3ludGF4S2luZCB9IGZyb20gJ3R5cGVzY3JpcHQnO1xuXG5leHBvcnQgZnVuY3Rpb24gYnlUeXBlKGFUeXBlOiBTeW50YXhLaW5kKTogUHJlZGljYXRlPE5vZGU+IHtcbiAgcmV0dXJuIG5vZGUgPT4gbm9kZSAmJiBub2RlLmtpbmQgPT09IGFUeXBlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnlUZXh0KGFUZXh0OiBzdHJpbmcpOiBQcmVkaWNhdGU8Tm9kZT4ge1xuICByZXR1cm4gbm9kZSA9PiBub2RlICYmIG5vZGUuZ2V0VGV4dCgpID09PSBhVGV4dDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ5TmFtZShhVGV4dDogc3RyaW5nKTogUHJlZGljYXRlPE5hbWVkRGVjbGFyYXRpb24+IHtcbiAgcmV0dXJuIG5vZGUgPT4gISEobm9kZSAmJiBub2RlLm5hbWUgJiYgbm9kZS5uYW1lLmdldFRleHQoKSA9PT0gYVRleHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnlUeXBlQW5kTmFtZShcbiAgYVR5cGU6IFN5bnRheEtpbmQsXG4gIGFOYW1lOiBzdHJpbmdcbik6IFByZWRpY2F0ZTxOb2RlPiB7XG4gIHJldHVybiBub2RlID0+IG5vZGUgJiYgbm9kZS5raW5kID09PSBhVHlwZSAmJiBub2RlLmdldFRleHQoKSA9PT0gYU5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBieUlkZW50aWZpZXIoYU5hbWU6IHN0cmluZyk6IFByZWRpY2F0ZTxOb2RlPiB7XG4gIHJldHVybiBieVR5cGVBbmROYW1lKFN5bnRheEtpbmQuSWRlbnRpZmllciwgYU5hbWUpO1xufVxuIl0sIm5hbWVzIjpbInRzLlN5bnRheEtpbmQiLCJ0c2xpYl8xLl9fdmFsdWVzIiwidHMuZm9yRWFjaENoaWxkIiwiZmlyc3QiLCJ0c2xpYl8xLl9fc3ByZWFkIiwidHMuaXNDbGFzc0RlY2xhcmF0aW9uIiwidHMuY3JlYXRlU291cmNlRmlsZSIsInRzLlNjcmlwdFRhcmdldCIsImRpcm5hbWUiLCJBc3NlcnQub2siLCJpc1N0cmluZyIsInZhbGlkYXRlRW1haWwiLCJoYXNUcmFpbGluZ1NsYXNoIiwiam9pbiIsIm5vcm1hbGl6ZSIsImVuc3VyZVRyYWlsaW5nU2xhc2giLCJyeFJlYWRGaWxlIiwiY2Fub25pY2FsaXplSlNPTiIsInRzbGliXzEuX19leHRlbmRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPQTs7Ozs7O0FBZ0JBLCtCQUFzQyxJQUFVLEVBQUUsT0FBc0I7SUFDdEUsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUU7UUFDOUQsT0FBTyxTQUFT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
\No newline at end of file