@angular/core
Version:
Angular - the core framework
239 lines • 60.8 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define("@angular/core/schematics/migrations/renderer-to-renderer2/helpers", ["require", "exports", "typescript"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHelper = void 0;
const ts = require("typescript");
/** Gets the string representation of a helper function. */
function getHelper(name, sourceFile, printer) {
const helperDeclaration = getHelperDeclaration(name);
return '\n' + printer.printNode(ts.EmitHint.Unspecified, helperDeclaration, sourceFile) + '\n';
}
exports.getHelper = getHelper;
/** Creates a function declaration for the specified helper name. */
function getHelperDeclaration(name) {
switch (name) {
case "AnyDuringRendererMigration" /* any */:
return createAnyTypeHelper();
case "__ngRendererCreateElementHelper" /* createElement */:
return getCreateElementHelper();
case "__ngRendererCreateTextHelper" /* createText */:
return getCreateTextHelper();
case "__ngRendererCreateTemplateAnchorHelper" /* createTemplateAnchor */:
return getCreateTemplateAnchorHelper();
case "__ngRendererProjectNodesHelper" /* projectNodes */:
return getProjectNodesHelper();
case "__ngRendererAnimateHelper" /* animate */:
return getAnimateHelper();
case "__ngRendererDestroyViewHelper" /* destroyView */:
return getDestroyViewHelper();
case "__ngRendererDetachViewHelper" /* detachView */:
return getDetachViewHelper();
case "__ngRendererAttachViewAfterHelper" /* attachViewAfter */:
return getAttachViewAfterHelper();
case "__ngRendererSetElementAttributeHelper" /* setElementAttribute */:
return getSetElementAttributeHelper();
case "__ngRendererSplitNamespaceHelper" /* splitNamespace */:
return getSplitNamespaceHelper();
}
throw new Error(`Unsupported helper called "${name}".`);
}
/** Creates a helper for a custom `any` type during the migration. */
function createAnyTypeHelper() {
// type AnyDuringRendererMigration = any;
return ts.createTypeAliasDeclaration([], [], "AnyDuringRendererMigration" /* any */, [], ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
}
/** Creates a function parameter that is typed as `any`. */
function getAnyTypedParameter(parameterName, isRequired = true) {
// Declare the parameter as `any` so we don't have to add extra logic to ensure that the
// generated code will pass type checking. Use our custom `any` type so people have an incentive
// to clean it up afterwards and to avoid potentially introducing lint warnings in G3.
const type = ts.createTypeReferenceNode("AnyDuringRendererMigration" /* any */, []);
return ts.createParameter([], [], undefined, parameterName, isRequired ? undefined : ts.createToken(ts.SyntaxKind.QuestionToken), type);
}
/** Creates a helper for `createElement`. */
function getCreateElementHelper() {
const renderer = ts.createIdentifier('renderer');
const parent = ts.createIdentifier('parent');
const namespaceAndName = ts.createIdentifier('namespaceAndName');
const name = ts.createIdentifier('name');
const namespace = ts.createIdentifier('namespace');
// [namespace, name] = splitNamespace(namespaceAndName);
const namespaceAndNameVariable = ts.createVariableDeclaration(ts.createArrayBindingPattern([namespace, name].map(id => ts.createBindingElement(undefined, undefined, id))), undefined, ts.createCall(ts.createIdentifier("__ngRendererSplitNamespaceHelper" /* splitNamespace */), [], [namespaceAndName]));
// `renderer.createElement(name, namespace)`.
const creationCall = ts.createCall(ts.createPropertyAccess(renderer, 'createElement'), [], [name, namespace]);
return getCreationHelper("__ngRendererCreateElementHelper" /* createElement */, creationCall, renderer, parent, [namespaceAndName], [ts.createVariableStatement(undefined, ts.createVariableDeclarationList([namespaceAndNameVariable], ts.NodeFlags.Const))]);
}
/** Creates a helper for `createText`. */
function getCreateTextHelper() {
const renderer = ts.createIdentifier('renderer');
const parent = ts.createIdentifier('parent');
const value = ts.createIdentifier('value');
// `renderer.createText(value)`.
const creationCall = ts.createCall(ts.createPropertyAccess(renderer, 'createText'), [], [value]);
return getCreationHelper("__ngRendererCreateTextHelper" /* createText */, creationCall, renderer, parent, [value]);
}
/** Creates a helper for `createTemplateAnchor`. */
function getCreateTemplateAnchorHelper() {
const renderer = ts.createIdentifier('renderer');
const parent = ts.createIdentifier('parent');
// `renderer.createComment('')`.
const creationCall = ts.createCall(ts.createPropertyAccess(renderer, 'createComment'), [], [ts.createStringLiteral('')]);
return getCreationHelper("__ngRendererCreateTemplateAnchorHelper" /* createTemplateAnchor */, creationCall, renderer, parent);
}
/**
* Gets the function declaration for a creation helper. This is reused between `createElement`,
* `createText` and `createTemplateAnchor` which follow a very similar pattern.
* @param functionName Function that the helper should have.
* @param creationCall Expression that is used to create a node inside the function.
* @param rendererParameter Parameter for the `renderer`.
* @param parentParameter Parameter for the `parent` inside the function.
* @param extraParameters Extra parameters to be added to the end.
* @param precedingVariables Extra variables to be added before the one that creates the `node`.
*/
function getCreationHelper(functionName, creationCall, renderer, parent, extraParameters = [], precedingVariables = []) {
const node = ts.createIdentifier('node');
// `const node = {{creationCall}}`.
const nodeVariableStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(node, undefined, creationCall)], ts.NodeFlags.Const));
// `if (parent) { renderer.appendChild(parent, node) }`.
const guardedAppendChildCall = ts.createIf(parent, ts.createBlock([ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(renderer, 'appendChild'), [], [parent, node]))], true));
return ts.createFunctionDeclaration([], [], undefined, functionName, [], [renderer, parent, ...extraParameters].map(name => getAnyTypedParameter(name)), undefined, ts.createBlock([
...precedingVariables, nodeVariableStatement, guardedAppendChildCall,
ts.createReturn(node)
], true));
}
/** Creates a helper for `projectNodes`. */
function getProjectNodesHelper() {
const renderer = ts.createIdentifier('renderer');
const parent = ts.createIdentifier('parent');
const nodes = ts.createIdentifier('nodes');
const incrementor = ts.createIdentifier('i');
// for (let i = 0; i < nodes.length; i++) {
// renderer.appendChild(parent, nodes[i]);
// }
const loopInitializer = ts.createVariableDeclarationList([ts.createVariableDeclaration(incrementor, undefined, ts.createNumericLiteral('0'))], ts.NodeFlags.Let);
const loopCondition = ts.createBinary(incrementor, ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(nodes, ts.createIdentifier('length')));
const appendStatement = ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(renderer, 'appendChild'), [], [parent, ts.createElementAccess(nodes, incrementor)]));
const loop = ts.createFor(loopInitializer, loopCondition, ts.createPostfix(incrementor, ts.SyntaxKind.PlusPlusToken), ts.createBlock([appendStatement]));
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererProjectNodesHelper" /* projectNodes */, [], [renderer, parent, nodes].map(name => getAnyTypedParameter(name)), undefined, ts.createBlock([loop], true));
}
/** Creates a helper for `animate`. */
function getAnimateHelper() {
// throw new Error('...');
const throwStatement = ts.createThrow(ts.createNew(ts.createIdentifier('Error'), [], [ts.createStringLiteral('Renderer.animate is no longer supported!')]));
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererAnimateHelper" /* animate */, [], [], undefined, ts.createBlock([throwStatement], true));
}
/** Creates a helper for `destroyView`. */
function getDestroyViewHelper() {
const renderer = ts.createIdentifier('renderer');
const allNodes = ts.createIdentifier('allNodes');
const incrementor = ts.createIdentifier('i');
// for (let i = 0; i < allNodes.length; i++) {
// renderer.destroyNode(allNodes[i]);
// }
const loopInitializer = ts.createVariableDeclarationList([ts.createVariableDeclaration(incrementor, undefined, ts.createNumericLiteral('0'))], ts.NodeFlags.Let);
const loopCondition = ts.createBinary(incrementor, ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(allNodes, ts.createIdentifier('length')));
const destroyStatement = ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(renderer, 'destroyNode'), [], [ts.createElementAccess(allNodes, incrementor)]));
const loop = ts.createFor(loopInitializer, loopCondition, ts.createPostfix(incrementor, ts.SyntaxKind.PlusPlusToken), ts.createBlock([destroyStatement]));
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererDestroyViewHelper" /* destroyView */, [], [renderer, allNodes].map(name => getAnyTypedParameter(name)), undefined, ts.createBlock([loop], true));
}
/** Creates a helper for `detachView`. */
function getDetachViewHelper() {
const renderer = ts.createIdentifier('renderer');
const rootNodes = ts.createIdentifier('rootNodes');
const incrementor = ts.createIdentifier('i');
const node = ts.createIdentifier('node');
// for (let i = 0; i < rootNodes.length; i++) {
// const node = rootNodes[i];
// renderer.removeChild(renderer.parentNode(node), node);
// }
const loopInitializer = ts.createVariableDeclarationList([ts.createVariableDeclaration(incrementor, undefined, ts.createNumericLiteral('0'))], ts.NodeFlags.Let);
const loopCondition = ts.createBinary(incrementor, ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(rootNodes, ts.createIdentifier('length')));
// const node = rootNodes[i];
const nodeVariableStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(node, undefined, ts.createElementAccess(rootNodes, incrementor))], ts.NodeFlags.Const));
// renderer.removeChild(renderer.parentNode(node), node);
const removeCall = ts.createCall(ts.createPropertyAccess(renderer, 'removeChild'), [], [ts.createCall(ts.createPropertyAccess(renderer, 'parentNode'), [], [node]), node]);
const loop = ts.createFor(loopInitializer, loopCondition, ts.createPostfix(incrementor, ts.SyntaxKind.PlusPlusToken), ts.createBlock([nodeVariableStatement, ts.createExpressionStatement(removeCall)]));
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererDetachViewHelper" /* detachView */, [], [renderer, rootNodes].map(name => getAnyTypedParameter(name)), undefined, ts.createBlock([loop], true));
}
/** Creates a helper for `attachViewAfter` */
function getAttachViewAfterHelper() {
const renderer = ts.createIdentifier('renderer');
const node = ts.createIdentifier('node');
const rootNodes = ts.createIdentifier('rootNodes');
const parent = ts.createIdentifier('parent');
const nextSibling = ts.createIdentifier('nextSibling');
const incrementor = ts.createIdentifier('i');
const createConstWithMethodCallInitializer = (constName, methodToCall) => {
return ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(constName, undefined, ts.createCall(ts.createPropertyAccess(renderer, methodToCall), [], [node]))], ts.NodeFlags.Const));
};
// const parent = renderer.parentNode(node);
const parentVariableStatement = createConstWithMethodCallInitializer(parent, 'parentNode');
// const nextSibling = renderer.nextSibling(node);
const nextSiblingVariableStatement = createConstWithMethodCallInitializer(nextSibling, 'nextSibling');
// for (let i = 0; i < rootNodes.length; i++) {
// renderer.insertBefore(parentElement, rootNodes[i], nextSibling);
// }
const loopInitializer = ts.createVariableDeclarationList([ts.createVariableDeclaration(incrementor, undefined, ts.createNumericLiteral('0'))], ts.NodeFlags.Let);
const loopCondition = ts.createBinary(incrementor, ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(rootNodes, ts.createIdentifier('length')));
const insertBeforeCall = ts.createCall(ts.createPropertyAccess(renderer, 'insertBefore'), [], [parent, ts.createElementAccess(rootNodes, incrementor), nextSibling]);
const loop = ts.createFor(loopInitializer, loopCondition, ts.createPostfix(incrementor, ts.SyntaxKind.PlusPlusToken), ts.createBlock([ts.createExpressionStatement(insertBeforeCall)]));
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererAttachViewAfterHelper" /* attachViewAfter */, [], [renderer, node, rootNodes].map(name => getAnyTypedParameter(name)), undefined, ts.createBlock([parentVariableStatement, nextSiblingVariableStatement, loop], true));
}
/** Creates a helper for `setElementAttribute` */
function getSetElementAttributeHelper() {
const renderer = ts.createIdentifier('renderer');
const element = ts.createIdentifier('element');
const namespaceAndName = ts.createIdentifier('namespaceAndName');
const value = ts.createIdentifier('value');
const name = ts.createIdentifier('name');
const namespace = ts.createIdentifier('namespace');
// [namespace, name] = splitNamespace(namespaceAndName);
const namespaceAndNameVariable = ts.createVariableDeclaration(ts.createArrayBindingPattern([namespace, name].map(id => ts.createBindingElement(undefined, undefined, id))), undefined, ts.createCall(ts.createIdentifier("__ngRendererSplitNamespaceHelper" /* splitNamespace */), [], [namespaceAndName]));
// renderer.setAttribute(element, name, value, namespace);
const setCall = ts.createCall(ts.createPropertyAccess(renderer, 'setAttribute'), [], [element, name, value, namespace]);
// renderer.removeAttribute(element, name, namespace);
const removeCall = ts.createCall(ts.createPropertyAccess(renderer, 'removeAttribute'), [], [element, name, namespace]);
// if (value != null) { setCall() } else { removeCall }
const ifStatement = ts.createIf(ts.createBinary(value, ts.SyntaxKind.ExclamationEqualsToken, ts.createNull()), ts.createBlock([ts.createExpressionStatement(setCall)], true), ts.createBlock([ts.createExpressionStatement(removeCall)], true));
const functionBody = ts.createBlock([
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([namespaceAndNameVariable], ts.NodeFlags.Const)),
ifStatement
], true);
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererSetElementAttributeHelper" /* setElementAttribute */, [], [
getAnyTypedParameter(renderer), getAnyTypedParameter(element),
getAnyTypedParameter(namespaceAndName), getAnyTypedParameter(value, false)
], undefined, functionBody);
}
/** Creates a helper for splitting a name that might contain a namespace. */
function getSplitNamespaceHelper() {
const name = ts.createIdentifier('name');
const match = ts.createIdentifier('match');
const regex = ts.createRegularExpressionLiteral('/^:([^:]+):(.+)$/');
const matchCall = ts.createCall(ts.createPropertyAccess(name, 'match'), [], [regex]);
// const match = name.split(regex);
const matchVariable = ts.createVariableDeclarationList([ts.createVariableDeclaration(match, undefined, matchCall)], ts.NodeFlags.Const);
// return [match[1], match[2]];
const matchReturn = ts.createReturn(ts.createArrayLiteral([ts.createElementAccess(match, 1), ts.createElementAccess(match, 2)]));
// if (name[0] === ':') { const match = ...; return ...; }
const ifStatement = ts.createIf(ts.createBinary(ts.createElementAccess(name, 0), ts.SyntaxKind.EqualsEqualsEqualsToken, ts.createStringLiteral(':')), ts.createBlock([ts.createVariableStatement([], matchVariable), matchReturn], true));
// return ['', name];
const elseReturn = ts.createReturn(ts.createArrayLiteral([ts.createStringLiteral(''), name]));
return ts.createFunctionDeclaration([], [], undefined, "__ngRendererSplitNamespaceHelper" /* splitNamespace */, [], [getAnyTypedParameter(name)], undefined, ts.createBlock([ifStatement, elseReturn], true));
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc2NoZW1hdGljcy9taWdyYXRpb25zL3JlbmRlcmVyLXRvLXJlbmRlcmVyMi9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7Ozs7Ozs7Ozs7OztJQUVILGlDQUFpQztJQWlCakMsMkRBQTJEO0lBQzNELFNBQWdCLFNBQVMsQ0FDckIsSUFBb0IsRUFBRSxVQUF5QixFQUFFLE9BQW1CO1FBQ3RFLE1BQU0saUJBQWlCLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckQsT0FBTyxJQUFJLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDakcsQ0FBQztJQUpELDhCQUlDO0lBRUQsb0VBQW9FO0lBQ3BFLFNBQVMsb0JBQW9CLENBQUMsSUFBb0I7UUFDaEQsUUFBUSxJQUFJLEVBQUU7WUFDWjtnQkFDRSxPQUFPLG1CQUFtQixFQUFFLENBQUM7WUFDL0I7Z0JBQ0UsT0FBTyxzQkFBc0IsRUFBRSxDQUFDO1lBQ2xDO2dCQUNFLE9BQU8sbUJBQW1CLEVBQUUsQ0FBQztZQUMvQjtnQkFDRSxPQUFPLDZCQUE2QixFQUFFLENBQUM7WUFDekM7Z0JBQ0UsT0FBTyxxQkFBcUIsRUFBRSxDQUFDO1lBQ2pDO2dCQUNFLE9BQU8sZ0JBQWdCLEVBQUUsQ0FBQztZQUM1QjtnQkFDRSxPQUFPLG9CQUFvQixFQUFFLENBQUM7WUFDaEM7Z0JBQ0UsT0FBTyxtQkFBbUIsRUFBRSxDQUFDO1lBQy9CO2dCQUNFLE9BQU8sd0JBQXdCLEVBQUUsQ0FBQztZQUNwQztnQkFDRSxPQUFPLDRCQUE0QixFQUFFLENBQUM7WUFDeEM7Z0JBQ0UsT0FBTyx1QkFBdUIsRUFBRSxDQUFDO1NB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QixDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU5RixPQUFPLEVBQUUsQ0FBQyx5QkFBeUIsQ0FDL0IsRUFBRSxFQUFFLEVBQUUsRUFBRSxTQUFTLDJEQUFpQyxFQUFFLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFDN0YsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgdHMgZnJvbSAndHlwZXNjcmlwdCc7XG5cbi8qKiBOYW1lcyBvZiB0aGUgaGVscGVyIGZ1bmN0aW9ucyB0aGF0IGFyZSBzdXBwb3J0ZWQgZm9yIHRoaXMgbWlncmF0aW9uLiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gSGVscGVyRnVuY3Rpb24ge1xuICBhbnkgPSAnQW55RHVyaW5nUmVuZGVyZXJNaWdyYXRpb24nLFxuICBjcmVhdGVFbGVtZW50ID0gJ19fbmdSZW5kZXJlckNyZWF0ZUVsZW1lbnRIZWxwZXInLFxuICBjcmVhdGVUZXh0ID0gJ19fbmdSZW5kZXJlckNyZWF0ZVRleHRIZWxwZXInLFxuICBjcmVhdGVUZW1wbGF0ZUFuY2hvciA9ICdfX25nUmVuZGVyZXJDcmVhdGVUZW1wbGF0ZUFuY2hvckhlbHBlcicsXG4gIHByb2plY3ROb2RlcyA9ICdfX25nUmVuZGVyZXJQcm9qZWN0Tm9kZXNIZWxwZXInLFxuICBhbmltYXRlID0gJ19fbmdSZW5kZXJlckFuaW1hdGVIZWxwZXInLFxuICBkZXN0cm95VmlldyA9ICdfX25nUmVuZGVyZXJEZXN0cm95Vmlld0hlbHBlcicsXG4gIGRldGFjaFZpZXcgPSAnX19uZ1JlbmRlcmVyRGV0YWNoVmlld0hlbHBlcicsXG4gIGF0dGFjaFZpZXdBZnRlciA9ICdfX25nUmVuZGVyZXJBdHRhY2hWaWV3QWZ0ZXJIZWxwZXInLFxuICBzcGxpdE5hbWVzcGFjZSA9ICdfX25nUmVuZGVyZXJTcGxpdE5hbWVzcGFjZUhlbHBlcicsXG4gIHNldEVsZW1lbnRBdHRyaWJ1dGUgPSAnX19uZ1JlbmRlcmVyU2V0RWxlbWVudEF0dHJpYnV0ZUhlbHBlcidcbn1cblxuLyoqIEdldHMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGhlbHBlciBmdW5jdGlvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZWxwZXIoXG4gICAgbmFtZTogSGVscGVyRnVuY3Rpb24sIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsIHByaW50ZXI6IHRzLlByaW50ZXIpOiBzdHJpbmcge1xuICBjb25zdCBoZWxwZXJEZWNsYXJhdGlvbiA9IGdldEhlbHBlckRlY2xhcmF0aW9uKG5hbWUpO1xuICByZXR1cm4gJ1xcbicgKyBwcmludGVyLnByaW50Tm9kZSh0cy5FbWl0SGludC5VbnNwZWNpZmllZCwgaGVscGVyRGVjbGFyYXRpb24sIHNvdXJjZUZpbGUpICsgJ1xcbic7XG59XG5cbi8qKiBDcmVhdGVzIGEgZnVuY3Rpb24gZGVjbGFyYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgaGVscGVyIG5hbWUuICovXG5mdW5jdGlvbiBnZXRIZWxwZXJEZWNsYXJhdGlvbihuYW1lOiBIZWxwZXJGdW5jdGlvbik6IHRzLk5vZGUge1xuICBzd2l0Y2ggKG5hbWUpIHtcbiAgICBjYXNlIEhlbHBlckZ1bmN0aW9uLmFueTpcbiAgICAgIHJldHVybiBjcmVhdGVBbnlUeXBlSGVscGVyKCk7XG4gICAgY2FzZSBIZWxwZXJGdW5jdGlvbi5jcmVhdGVFbGVtZW50OlxuICAgICAgcmV0dXJuIGdldENyZWF0ZUVsZW1lbnRIZWxwZXIoKTtcbiAgICBjYXNlIEhlbHBlckZ1bmN0aW9uLmNyZWF0ZVRleHQ6XG4gICAgICByZXR1cm4gZ2V0Q3JlYXRlVGV4dEhlbHBlcigpO1xuICAgIGNhc2UgSGVscGVyRnVuY3Rpb24uY3JlYXRlVGVtcGxhdGVBbmNob3I6XG4gICAgICByZXR1cm4gZ2V0Q3JlYXRlVGVtcGxhdGVBbmNob3JIZWxwZXIoKTtcbiAgICBjYXNlIEhlbHBlckZ1bmN0aW9uLnByb2plY3ROb2RlczpcbiAgICAgIHJldHVybiBnZXRQcm9qZWN0Tm9kZXNIZWxwZXIoKTtcbiAgICBjYXNlIEhlbHBlckZ1bmN0aW9uLmFuaW1hdGU6XG4gICAgICByZXR1cm4gZ2V0QW5pbWF0ZUhlbHBlcigpO1xuICAgIGNhc2UgSGVscGVyRnVuY3Rpb24uZGVzdHJveVZpZXc6XG4gICAgICByZXR1cm4gZ2V0RGVzdHJveVZpZXdIZWxwZXIoKTtcbiAgICBjYXNlIEhlbHBlckZ1bmN0aW9uLmRldGFjaFZpZXc6XG4gICAgICByZXR1cm4gZ2V0RGV0YWNoVmlld0hlbHBlcigpO1xuICAgIGNhc2UgSGVscGVyRnVuY3Rpb24uYXR0YWNoVmlld0FmdGVyOlxuICAgICAgcmV0dXJuIGdldEF0dGFjaFZpZXdBZnRlckhlbHBlcigpO1xuICAgIGNhc2UgSGVscGVyRnVuY3Rpb24uc2V0RWxlbWVudEF0dHJpYnV0ZTpcbiAgICAgIHJldHVybiBnZXRTZXRFbGVtZW50QXR0cmlidXRlSGVscGVyKCk7XG4gICAgY2FzZSBIZWxwZXJGdW5jdGlvbi5zcGxpdE5hbWVzcGFjZTpcbiAgICAgIHJldHVybiBnZXRTcGxpdE5hbWVzcGFjZUhlbHBlcigpO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBoZWxwZXIgY2FsbGVkIFwiJHtuYW1lfVwiLmApO1xufVxuXG4vKiogQ3JlYXRlcyBhIGhlbHBlciBmb3IgYSBjdXN0b20gYGFueWAgdHlwZSBkdXJpbmcgdGhlIG1pZ3JhdGlvbi4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUFueVR5cGVIZWxwZXIoKTogdHMuVHlwZUFsaWFzRGVjbGFyYXRpb24ge1xuICAvLyB0eXBlIEFueUR1cmluZ1JlbmRlcmVyTWlncmF0aW9uID0gYW55O1xuICByZXR1cm4gdHMuY3JlYXRlVHlwZUFsaWFzRGVjbGFyYXRpb24oXG4gICAgICBbXSwgW10sIEhlbHBlckZ1bmN0aW9uLmFueSwgW10sIHRzLmNyZWF0ZUtleXdvcmRUeXBlTm9kZSh0cy5TeW50YXhLaW5kLkFueUtleXdvcmQpKTtcbn1cblxuLyoqIENyZWF0ZXMgYSBmdW5jdGlvbiBwYXJhbWV0ZXIgdGhhdCBpcyB0eXBlZCBhcyBgYW55YC4gKi9cbmZ1bmN0aW9uIGdldEFueVR5cGVkUGFyYW1ldGVyKFxuICAgIHBhcmFtZXRlck5hbWU6IHN0cmluZ3x0cy5JZGVudGlmaWVyLCBpc1JlcXVpcmVkID0gdHJ1ZSk6IHRzLlBhcmFtZXRlckRlY2xhcmF0aW9uIHtcbiAgLy8gRGVjbGFyZSB0aGUgcGFyYW1ldGVyIGFzIGBhbnlgIHNvIHdlIGRvbid0IGhhdmUgdG8gYWRkIGV4dHJhIGxvZ2ljIHRvIGVuc3VyZSB0aGF0IHRoZVxuICAvLyBnZW5lcmF0ZWQgY29kZSB3aWxsIHBhc3MgdHlwZSBjaGVja2luZy4gVXNlIG91ciBjdXN0b20gYGFueWAgdHlwZSBzbyBwZW9wbGUgaGF2ZSBhbiBpbmNlbnRpdmVcbiAgLy8gdG8gY2xlYW4gaXQgdXAgYWZ0ZXJ3YXJkcyBhbmQgdG8gYXZvaWQgcG90ZW50aWFsbHkgaW50cm9kdWNpbmcgbGludCB3YXJuaW5ncyBpbiBHMy5cbiAgY29uc3QgdHlwZSA9IHRzLmNyZWF0ZVR5cGVSZWZlcmVuY2VOb2RlKEhlbHBlckZ1bmN0aW9uLmFueSwgW10pO1xuICByZXR1cm4gdHMuY3JlYXRlUGFyYW1ldGVyKFxuICAgICAgW10sIFtdLCB1bmRlZmluZWQsIHBhcmFtZXRlck5hbWUsXG4gICAgICBpc1JlcXVpcmVkID8gdW5kZWZpbmVkIDogdHMuY3JlYXRlVG9rZW4odHMuU3ludGF4S2luZC5RdWVzdGlvblRva2VuKSwgdHlwZSk7XG59XG5cbi8qKiBDcmVhdGVzIGEgaGVscGVyIGZvciBgY3JlYXRlRWxlbWVudGAuICovXG5mdW5jdGlvbiBnZXRDcmVhdGVFbGVtZW50SGVscGVyKCk6IHRzLkZ1bmN0aW9uRGVjbGFyYXRpb24ge1xuICBjb25zdCByZW5kZXJlciA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3JlbmRlcmVyJyk7XG4gIGNvbnN0IHBhcmVudCA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3BhcmVudCcpO1xuICBjb25zdCBuYW1lc3BhY2VBbmROYW1lID0gdHMuY3JlYXRlSWRlbnRpZmllcignbmFtZXNwYWNlQW5kTmFtZScpO1xuICBjb25zdCBuYW1lID0gdHMuY3JlYXRlSWRlbnRpZmllcignbmFtZScpO1xuICBjb25zdCBuYW1lc3BhY2UgPSB0cy5jcmVhdGVJZGVudGlmaWVyKCduYW1lc3BhY2UnKTtcblxuICAvLyBbbmFtZXNwYWNlLCBuYW1lXSA9IHNwbGl0TmFtZXNwYWNlKG5hbWVzcGFjZUFuZE5hbWUpO1xuICBjb25zdCBuYW1lc3BhY2VBbmROYW1lVmFyaWFibGUgPSB0cy5jcmVhdGVWYXJpYWJsZURlY2xhcmF0aW9uKFxuICAgICAgdHMuY3JlYXRlQXJyYXlCaW5kaW5nUGF0dGVybihcbiAgICAgICAgICBbbmFtZXNwYWNlLCBuYW1lXS5tYXAoaWQgPT4gdHMuY3JlYXRlQmluZGluZ0VsZW1lbnQodW5kZWZpbmVkLCB1bmRlZmluZWQsIGlkKSkpLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdHMuY3JlYXRlQ2FsbCh0cy5jcmVhdGVJZGVudGlmaWVyKEhlbHBlckZ1bmN0aW9uLnNwbGl0TmFtZXNwYWNlKSwgW10sIFtuYW1lc3BhY2VBbmROYW1lXSkpO1xuXG4gIC8vIGByZW5kZXJlci5jcmVhdGVFbGVtZW50KG5hbWUsIG5hbWVzcGFjZSlgLlxuICBjb25zdCBjcmVhdGlvbkNhbGwgPVxuICAgICAgdHMuY3JlYXRlQ2FsbCh0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhyZW5kZXJlciwgJ2NyZWF0ZUVsZW1lbnQnKSwgW10sIFtuYW1lLCBuYW1lc3BhY2VdKTtcblxuICByZXR1cm4gZ2V0Q3JlYXRpb25IZWxwZXIoXG4gICAgICBIZWxwZXJGdW5jdGlvbi5jcmVhdGVFbGVtZW50LCBjcmVhdGlvbkNhbGwsIHJlbmRlcmVyLCBwYXJlbnQsIFtuYW1lc3BhY2VBbmROYW1lXSxcbiAgICAgIFt0cy5jcmVhdGVWYXJpYWJsZVN0YXRlbWVudChcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdHMuY3JlYXRlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QoW25hbWVzcGFjZUFuZE5hbWVWYXJpYWJsZV0sIHRzLk5vZGVGbGFncy5Db25zdCkpXSk7XG59XG5cbi8qKiBDcmVhdGVzIGEgaGVscGVyIGZvciBgY3JlYXRlVGV4dGAuICovXG5mdW5jdGlvbiBnZXRDcmVhdGVUZXh0SGVscGVyKCk6IHRzLkZ1bmN0aW9uRGVjbGFyYXRpb24ge1xuICBjb25zdCByZW5kZXJlciA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3JlbmRlcmVyJyk7XG4gIGNvbnN0IHBhcmVudCA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3BhcmVudCcpO1xuICBjb25zdCB2YWx1ZSA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3ZhbHVlJyk7XG5cbiAgLy8gYHJlbmRlcmVyLmNyZWF0ZVRleHQodmFsdWUpYC5cbiAgY29uc3QgY3JlYXRpb25DYWxsID0gdHMuY3JlYXRlQ2FsbCh0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhyZW5kZXJlciwgJ2NyZWF0ZVRleHQnKSwgW10sIFt2YWx1ZV0pO1xuXG4gIHJldHVybiBnZXRDcmVhdGlvbkhlbHBlcihIZWxwZXJGdW5jdGlvbi5jcmVhdGVUZXh0LCBjcmVhdGlvbkNhbGwsIHJlbmRlcmVyLCBwYXJlbnQsIFt2YWx1ZV0pO1xufVxuXG4vKiogQ3JlYXRlcyBhIGhlbHBlciBmb3IgYGNyZWF0ZVRlbXBsYXRlQW5jaG9yYC4gKi9cbmZ1bmN0aW9uIGdldENyZWF0ZVRlbXBsYXRlQW5jaG9ySGVscGVyKCk6IHRzLkZ1bmN0aW9uRGVjbGFyYXRpb24ge1xuICBjb25zdCByZW5kZXJlciA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3JlbmRlcmVyJyk7XG4gIGNvbnN0IHBhcmVudCA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3BhcmVudCcpO1xuXG4gIC8vIGByZW5kZXJlci5jcmVhdGVDb21tZW50KCcnKWAuXG4gIGNvbnN0IGNyZWF0aW9uQ2FsbCA9IHRzLmNyZWF0ZUNhbGwoXG4gICAgICB0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhyZW5kZXJlciwgJ2NyZWF0ZUNvbW1lbnQnKSwgW10sIFt0cy5jcmVhdGVTdHJpbmdMaXRlcmFsKCcnKV0pO1xuXG4gIHJldHVybiBnZXRDcmVhdGlvbkhlbHBlcihIZWxwZXJGdW5jdGlvbi5jcmVhdGVUZW1wbGF0ZUFuY2hvciwgY3JlYXRpb25DYWxsLCByZW5kZXJlciwgcGFyZW50KTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBmdW5jdGlvbiBkZWNsYXJhdGlvbiBmb3IgYSBjcmVhdGlvbiBoZWxwZXIuIFRoaXMgaXMgcmV1c2VkIGJldHdlZW4gYGNyZWF0ZUVsZW1lbnRgLFxuICogYGNyZWF0ZVRleHRgIGFuZCBgY3JlYXRlVGVtcGxhdGVBbmNob3JgIHdoaWNoIGZvbGxvdyBhIHZlcnkgc2ltaWxhciBwYXR0ZXJuLlxuICogQHBhcmFtIGZ1bmN0aW9uTmFtZSBGdW5jdGlvbiB0aGF0IHRoZSBoZWxwZXIgc2hvdWxkIGhhdmUuXG4gKiBAcGFyYW0gY3JlYXRpb25DYWxsIEV4cHJlc3Npb24gdGhhdCBpcyB1c2VkIHRvIGNyZWF0ZSBhIG5vZGUgaW5zaWRlIHRoZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSByZW5kZXJlclBhcmFtZXRlciBQYXJhbWV0ZXIgZm9yIHRoZSBgcmVuZGVyZXJgLlxuICogQHBhcmFtIHBhcmVudFBhcmFtZXRlciBQYXJhbWV0ZXIgZm9yIHRoZSBgcGFyZW50YCBpbnNpZGUgdGhlIGZ1bmN0aW9uLlxuICogQHBhcmFtIGV4dHJhUGFyYW1ldGVycyBFeHRyYSBwYXJhbWV0ZXJzIHRvIGJlIGFkZGVkIHRvIHRoZSBlbmQuXG4gKiBAcGFyYW0gcHJlY2VkaW5nVmFyaWFibGVzIEV4dHJhIHZhcmlhYmxlcyB0byBiZSBhZGRlZCBiZWZvcmUgdGhlIG9uZSB0aGF0IGNyZWF0ZXMgdGhlIGBub2RlYC5cbiAqL1xuZnVuY3Rpb24gZ2V0Q3JlYXRpb25IZWxwZXIoXG4gICAgZnVuY3Rpb25OYW1lOiBIZWxwZXJGdW5jdGlvbiwgY3JlYXRpb25DYWxsOiB0cy5DYWxsRXhwcmVzc2lvbiwgcmVuZGVyZXI6IHRzLklkZW50aWZpZXIsXG4gICAgcGFyZW50OiB0cy5JZGVudGlmaWVyLCBleHRyYVBhcmFtZXRlcnM6IHRzLklkZW50aWZpZXJbXSA9IFtdLFxuICAgIHByZWNlZGluZ1ZhcmlhYmxlczogdHMuVmFyaWFibGVTdGF0ZW1lbnRbXSA9IFtdKTogdHMuRnVuY3Rpb25EZWNsYXJhdGlvbiB7XG4gIGNvbnN0IG5vZGUgPSB0cy5jcmVhdGVJZGVudGlmaWVyKCdub2RlJyk7XG5cbiAgLy8gYGNvbnN0IG5vZGUgPSB7e2NyZWF0aW9uQ2FsbH19YC5cbiAgY29uc3Qgbm9kZVZhcmlhYmxlU3RhdGVtZW50ID0gdHMuY3JlYXRlVmFyaWFibGVTdGF0ZW1lbnQoXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB0cy5jcmVhdGVWYXJpYWJsZURlY2xhcmF0aW9uTGlzdChcbiAgICAgICAgICBbdHMuY3JlYXRlVmFyaWFibGVEZWNsYXJhdGlvbihub2RlLCB1bmRlZmluZWQsIGNyZWF0aW9uQ2FsbCldLCB0cy5Ob2RlRmxhZ3MuQ29uc3QpKTtcblxuICAvLyBgaWYgKHBhcmVudCkgeyByZW5kZXJlci5hcHBlbmRDaGlsZChwYXJlbnQsIG5vZGUpIH1gLlxuICBjb25zdCBndWFyZGVkQXBwZW5kQ2hpbGRDYWxsID0gdHMuY3JlYXRlSWYoXG4gICAgICBwYXJlbnQsXG4gICAgICB0cy5jcmVhdGVCbG9jayhcbiAgICAgICAgICBbdHMuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChcbiAgICAgICAgICAgICAgdHMuY3JlYXRlQ2FsbCh0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhyZW5kZXJlciwgJ2FwcGVuZENoaWxkJyksIFtdLCBbcGFyZW50LCBub2RlXSkpXSxcbiAgICAgICAgICB0cnVlKSk7XG5cbiAgcmV0dXJuIHRzLmNyZWF0ZUZ1bmN0aW9uRGVjbGFyYXRpb24oXG4gICAgICBbXSwgW10sIHVuZGVmaW5lZCwgZnVuY3Rpb25OYW1lLCBbXSxcbiAgICAgIFtyZW5kZXJlciwgcGFyZW50LCAuLi5leHRyYVBhcmFtZXRlcnNdLm1hcChuYW1lID0+IGdldEFueVR5cGVkUGFyYW1ldGVyKG5hbWUpKSwgdW5kZWZpbmVkLFxuICAgICAgdHMuY3JlYXRlQmxvY2soXG4gICAgICAgICAgW1xuICAgICAgICAgICAgLi4ucHJlY2VkaW5nVmFyaWFibGVzLCBub2RlVmFyaWFibGVTdGF0ZW1lbnQsIGd1YXJkZWRBcHBlbmRDaGlsZENhbGwsXG4gICAgICAgICAgICB0cy5jcmVhdGVSZXR1cm4obm9kZSlcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRydWUpKTtcbn1cblxuLyoqIENyZWF0ZXMgYSBoZWxwZXIgZm9yIGBwcm9qZWN0Tm9kZXNgLiAqL1xuZnVuY3Rpb24gZ2V0UHJvamVjdE5vZGVzSGVscGVyKCk6IHRzLkZ1bmN0aW9uRGVjbGFyYXRpb24ge1xuICBjb25zdCByZW5kZXJlciA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3JlbmRlcmVyJyk7XG4gIGNvbnN0IHBhcmVudCA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ3BhcmVudCcpO1xuICBjb25zdCBub2RlcyA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ25vZGVzJyk7XG4gIGNvbnN0IGluY3JlbWVudG9yID0gdHMuY3JlYXRlSWRlbnRpZmllcignaScpO1xuXG4gIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgLy8gICByZW5kZXJlci5hcHBlbmRDaGlsZChwYXJlbnQsIG5vZGVzW2ldKTtcbiAgLy8gfVxuICBjb25zdCBsb29wSW5pdGlhbGl6ZXIgPSB0cy5jcmVhdGVWYXJpYWJsZURlY2xhcmF0aW9uTGlzdChcbiAgICAgIFt0cy5jcmVhdGVWYXJpYWJsZURlY2xhcmF0aW9uKGluY3JlbWVudG9yLCB1bmRlZmluZWQsIHRzLmNyZWF0ZU51bWVyaWNMaXRlcmFsKCcwJykpXSxcbiAgICAgIHRzLk5vZGVGbGFncy5MZXQpO1xuICBjb25zdCBsb29wQ29uZGl0aW9uID0gdHMuY3JlYXRlQmluYXJ5KFxuICAgICAgaW5jcmVtZW50b3IsIHRzLlN5bnRheEtpbmQuTGVzc1RoYW5Ub2tlbixcbiAgICAgIHRzLmNyZWF0ZVByb3BlcnR5QWNjZXNzKG5vZGVzLCB0cy5jcmVhdGVJZGVudGlmaWVyKCdsZW5ndGgnKSkpO1xuICBjb25zdCBhcHBlbmRTdGF0ZW1lbnQgPSB0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KHRzLmNyZWF0ZUNhbGwoXG4gICAgICB0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhyZW5kZXJlciwgJ2FwcGVuZENoaWxkJyksIFtdLFxuICAgICAgW3BhcmVudCwgdHMuY3JlYXRlRWxlbWVudEFjY2Vzcyhub2RlcywgaW5jcmVtZW50b3IpXSkpO1xuICBjb25zdCBsb29wID0gdHMuY3JlYXRlRm9yKFxuICAgICAgbG9vcEluaXRpYWxpemVyLCBsb29wQ29uZGl0aW9uLCB0cy5jcmVhdGVQb3N0Zml4KGluY3JlbWVudG9yLCB0cy5TeW50YXhLaW5kLlBsdXNQbHVzVG9rZW4pLFxuICAgICAgdHMuY3JlYXRlQmxvY2soW2FwcGVuZFN0YXRlbWVudF0pKTtcblxuICByZXR1cm4gdHMuY3JlYXRlRnVuY3Rpb25EZWNsYXJhdGlvbihcbiAgICAgIFtdLCBbXSwgdW5kZWZpbmVkLCBIZWxwZXJGdW5jdGlvbi5wcm9qZWN0Tm9kZXMsIFtdLFxuICAgICAgW3JlbmRlcmVyLCBwYXJlbnQsIG5vZGVzXS5tYXAobmFtZSA9PiBnZXRBbnlUeXBlZFBhcmFtZXRlcihuYW1lKSksIHVuZGVmaW5lZCxcbiAgICAgIHRzLmNyZWF0ZUJsb2NrKFtsb29wXSwgdHJ1ZSkpO1xufVxuXG4vKiogQ3JlYXRlcyBhIGhlbHBlciBmb3IgYGFuaW1hdGVgLiAqL1xuZnVuY3Rpb24gZ2V0QW5pbWF0ZUhlbHBlcigpOiB0cy5GdW5jdGlvbkRlY2xhcmF0aW9uIHtcbiAgLy8gdGhyb3cgbmV3IEVycm9yKCcuLi4nKTtcbiAgY29uc3QgdGhyb3dTdGF0ZW1lbnQgPSB0cy5jcmVhdGVUaHJvdyh0cy5jcmVhdGVOZXcoXG4gICAgICB0cy5jcmVhdGVJZGVudGlmaWVyKCdFcnJvcicpLCBbXSxcbiAgICAgIFt0cy5jcmVhdGVTdHJpbmdMaXRlcmFsKCdSZW5kZXJlci5hbmltYXRlIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQhJyldKSk7XG5cbiAgcmV0dXJuIHRzLmNyZWF0ZUZ1bmN0aW9uRGVjbGFyYXRpb24oXG4gICAgICBbXSwgW10sIHVuZGVmaW5lZCwgSGVscGVyRnVuY3Rpb24uYW5pbWF0ZSwgW10sIFtdLCB1bmRlZmluZWQsXG4gICAgICB0cy5jcmVhdGVCbG9jayhbdGhyb3dTdGF0ZW1lbnRdLCB0cnVlKSk7XG59XG5cbi8qKiBDcmVhdGVzIGEgaGVscGVyIGZvciBgZGVzdHJveVZpZXdgLiAqL1xuZnVuY3Rpb24gZ2V0RGVzdHJveVZpZXdIZWxwZXIoKTogdHMuRnVuY3Rpb25EZWNsYXJhdGlvbiB7XG4gIGNvbnN0IHJlbmRlcmVyID0gdHMuY3JlYXRlSWRlbnRpZmllcigncmVuZGVyZXInKTtcbiAgY29uc3QgYWxsTm9kZXMgPSB0cy5jcmVhdGVJZGVudGlmaWVyKCdhbGxOb2RlcycpO1xuICBjb25zdCBpbmNyZW1lbnRvciA9IHRzLmNyZWF0ZUlkZW50aWZpZXIoJ2knKTtcblxuICAvLyBmb3IgKGxldCBpID0gMDsgaSA8IGFsbE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gIC8vICAgcmVuZGVyZXIuZGVzdHJveU5vZGUoYWxsTm9kZXNbaV0pO1xuICAvLyB9XG4gIGNvbnN0IGxvb3BJbml0aWFsaXplciA9IHRzLmNyZWF0ZVZhcmlhYmxlRGVjbGFyYXRpb25MaXN0KFxuICAgICAgW3RzLmNyZWF0ZVZhcmlhYmxlRGVjbGFyYXRpb24oaW5jcmVtZW50b3IsIHVuZGVmaW5lZCwgdHMuY3JlYXRlTnVtZXJpY0xpdGVyYWwoJzAnKSldLFxuICAgICAgdHMuTm9kZUZsYWdzLkxldCk7XG4gIGNvbnN0IGxvb3BDb25kaXRpb24gPSB0cy5jcmVhdGVCaW5hcnkoXG4gICAgICBpbmNyZW1lbnRvciwgdHMuU3ludGF4S2luZC5MZXNzVGhhblRva2VuLFxuICAgICAgdHMuY3JlYXRlUHJvcGVydHlBY2Nlc3MoYWxsTm9kZXMsIHRzLmNyZWF0ZUlkZW50aWZpZXIoJ2xlbmd0aCcpKSk7XG4gIGNvbnN0IGRlc3Ryb3lTdGF0ZW1lbnQgPSB0cy5jcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50KHRzLmNyZWF0ZUNhbGwoXG4gICAgICB0cy5jcmVhdGVQcm9wZXJ0eUFjY2VzcyhyZW5kZXJlciwgJ2Rlc3Ryb3lOb