aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
270 lines • 36.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StackCollection = exports.CloudAssembly = exports.ExtendedStackSelection = exports.DefaultSelection = void 0;
exports.sanitizePatterns = sanitizePatterns;
const cxapi = require("@aws-cdk/cx-api");
const chalk = require("chalk");
const minimatch_1 = require("minimatch");
const semver = require("semver");
const logging_1 = require("../../logging");
const error_1 = require("../../toolkit/error");
const util_1 = require("../../util");
var DefaultSelection;
(function (DefaultSelection) {
/**
* Returns an empty selection in case there are no selectors.
*/
DefaultSelection["None"] = "none";
/**
* If the app includes a single stack, returns it. Otherwise throws an exception.
* This behavior is used by "deploy".
*/
DefaultSelection["OnlySingle"] = "single";
/**
* Returns all stacks in the main (top level) assembly only.
*/
DefaultSelection["MainAssembly"] = "main";
/**
* If no selectors are provided, returns all stacks in the app,
* including stacks inside nested assemblies.
*/
DefaultSelection["AllStacks"] = "all";
})(DefaultSelection || (exports.DefaultSelection = DefaultSelection = {}));
/**
* When selecting stacks, what other stacks to include because of dependencies
*/
var ExtendedStackSelection;
(function (ExtendedStackSelection) {
/**
* Don't select any extra stacks
*/
ExtendedStackSelection[ExtendedStackSelection["None"] = 0] = "None";
/**
* Include stacks that this stack depends on
*/
ExtendedStackSelection[ExtendedStackSelection["Upstream"] = 1] = "Upstream";
/**
* Include stacks that depend on this stack
*/
ExtendedStackSelection[ExtendedStackSelection["Downstream"] = 2] = "Downstream";
})(ExtendedStackSelection || (exports.ExtendedStackSelection = ExtendedStackSelection = {}));
/**
* A single Cloud Assembly and the operations we do on it to deploy the artifacts inside
*/
class CloudAssembly {
constructor(assembly) {
this.assembly = assembly;
this.directory = assembly.directory;
}
async selectStacks(selector, options) {
const asm = this.assembly;
const topLevelStacks = asm.stacks;
const stacks = semver.major(asm.version) < 10 ? asm.stacks : asm.stacksRecursively;
const allTopLevel = selector.allTopLevel ?? false;
const patterns = sanitizePatterns(selector.patterns);
if (stacks.length === 0) {
if (options.ignoreNoStacks) {
return new StackCollection(this, []);
}
throw new error_1.ToolkitError('This app contains no stacks');
}
if (allTopLevel) {
return this.selectTopLevelStacks(stacks, topLevelStacks, options.extend);
}
else if (patterns.length > 0) {
return this.selectMatchingStacks(stacks, patterns, options.extend);
}
else {
return this.selectDefaultStacks(stacks, topLevelStacks, options.defaultBehavior);
}
}
selectTopLevelStacks(stacks, topLevelStacks, extend = ExtendedStackSelection.None) {
if (topLevelStacks.length > 0) {
return this.extendStacks(topLevelStacks, stacks, extend);
}
else {
throw new error_1.ToolkitError('No stack found in the main cloud assembly. Use "list" to print manifest');
}
}
selectMatchingStacks(stacks, patterns, extend = ExtendedStackSelection.None) {
const matchingPattern = (pattern) => (stack) => (0, minimatch_1.minimatch)(stack.hierarchicalId, pattern);
const matchedStacks = (0, util_1.flatten)(patterns.map(pattern => stacks.filter(matchingPattern(pattern))));
return this.extendStacks(matchedStacks, stacks, extend);
}
selectDefaultStacks(stacks, topLevelStacks, defaultSelection) {
switch (defaultSelection) {
case DefaultSelection.MainAssembly:
return new StackCollection(this, topLevelStacks);
case DefaultSelection.AllStacks:
return new StackCollection(this, stacks);
case DefaultSelection.None:
return new StackCollection(this, []);
case DefaultSelection.OnlySingle:
if (topLevelStacks.length === 1) {
return new StackCollection(this, topLevelStacks);
}
else {
throw new error_1.ToolkitError('Since this app includes more than a single stack, specify which stacks to use (wildcards are supported) or specify `--all`\n' +
`Stacks: ${stacks.map(x => x.hierarchicalId).join(' · ')}`);
}
default:
throw new error_1.ToolkitError(`invalid default behavior: ${defaultSelection}`);
}
}
extendStacks(matched, all, extend = ExtendedStackSelection.None) {
const allStacks = new Map();
for (const stack of all) {
allStacks.set(stack.hierarchicalId, stack);
}
const index = indexByHierarchicalId(matched);
switch (extend) {
case ExtendedStackSelection.Downstream:
includeDownstreamStacks(index, allStacks);
break;
case ExtendedStackSelection.Upstream:
includeUpstreamStacks(index, allStacks);
break;
}
// Filter original array because it is in the right order
const selectedList = all.filter(s => index.has(s.hierarchicalId));
return new StackCollection(this, selectedList);
}
/**
* Select a single stack by its ID
*/
stackById(stackId) {
return new StackCollection(this, [this.assembly.getStackArtifact(stackId)]);
}
}
exports.CloudAssembly = CloudAssembly;
/**
* A collection of stacks and related artifacts
*
* In practice, not all artifacts in the CloudAssembly are created equal;
* stacks can be selected independently, but other artifacts such as asset
* bundles cannot.
*/
class StackCollection {
constructor(assembly, stackArtifacts) {
this.assembly = assembly;
this.stackArtifacts = stackArtifacts;
}
get stackCount() {
return this.stackArtifacts.length;
}
get firstStack() {
if (this.stackCount < 1) {
throw new error_1.ToolkitError('StackCollection contains no stack artifacts (trying to access the first one)');
}
return this.stackArtifacts[0];
}
get stackIds() {
return this.stackArtifacts.map(s => s.id);
}
get hierarchicalIds() {
return this.stackArtifacts.map(s => s.hierarchicalId);
}
reversed() {
const arts = [...this.stackArtifacts];
arts.reverse();
return new StackCollection(this.assembly, arts);
}
filter(predicate) {
return new StackCollection(this.assembly, this.stackArtifacts.filter(predicate));
}
concat(...others) {
return new StackCollection(this.assembly, this.stackArtifacts.concat(...others.map(o => o.stackArtifacts)));
}
/**
* Extracts 'aws:cdk:warning|info|error' metadata entries from the stack synthesis
*/
async validateMetadata(failAt = 'error', logger = async () => { }) {
let warnings = false;
let errors = false;
for (const stack of this.stackArtifacts) {
for (const message of stack.messages) {
switch (message.level) {
case cxapi.SynthesisMessageLevel.WARNING:
warnings = true;
await logger('warn', message);
break;
case cxapi.SynthesisMessageLevel.ERROR:
errors = true;
await logger('error', message);
break;
case cxapi.SynthesisMessageLevel.INFO:
await logger('info', message);
break;
}
}
}
if (errors && failAt != 'none') {
throw new error_1.AssemblyError('Found errors');
}
if (warnings && failAt === 'warn') {
throw new error_1.AssemblyError('Found warnings (--strict mode)');
}
}
}
exports.StackCollection = StackCollection;
function indexByHierarchicalId(stacks) {
const result = new Map();
for (const stack of stacks) {
result.set(stack.hierarchicalId, stack);
}
return result;
}
/**
* Calculate the transitive closure of stack dependents.
*
* Modifies `selectedStacks` in-place.
*/
function includeDownstreamStacks(selectedStacks, allStacks) {
const added = new Array();
let madeProgress;
do {
madeProgress = false;
for (const [id, stack] of allStacks) {
// Select this stack if it's not selected yet AND it depends on a stack that's in the selected set
if (!selectedStacks.has(id) && (stack.dependencies || []).some(dep => selectedStacks.has(dep.id))) {
selectedStacks.set(id, stack);
added.push(id);
madeProgress = true;
}
}
} while (madeProgress);
if (added.length > 0) {
(0, logging_1.info)('Including depending stacks: %s', chalk.bold(added.join(', ')));
}
}
/**
* Calculate the transitive closure of stack dependencies.
*
* Modifies `selectedStacks` in-place.
*/
function includeUpstreamStacks(selectedStacks, allStacks) {
const added = new Array();
let madeProgress = true;
while (madeProgress) {
madeProgress = false;
for (const stack of selectedStacks.values()) {
// Select an additional stack if it's not selected yet and a dependency of a selected stack (and exists, obviously)
for (const dependencyId of stack.dependencies.map(x => x.manifest.displayName ?? x.id)) {
if (!selectedStacks.has(dependencyId) && allStacks.has(dependencyId)) {
added.push(dependencyId);
selectedStacks.set(dependencyId, allStacks.get(dependencyId));
madeProgress = true;
}
}
}
}
if (added.length > 0) {
(0, logging_1.info)('Including dependency stacks: %s', chalk.bold(added.join(', ')));
}
}
function sanitizePatterns(patterns) {
let sanitized = patterns.filter(s => s != null); // filter null/undefined
sanitized = [...new Set(sanitized)]; // make them unique
return sanitized;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWQtYXNzZW1ibHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjbG91ZC1hc3NlbWJseS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2WEEsNENBSUM7QUFqWUQseUNBQXlDO0FBQ3pDLCtCQUErQjtBQUMvQix5Q0FBc0M7QUFDdEMsaUNBQWlDO0FBQ2pDLDJDQUFxQztBQUNyQywrQ0FBa0U7QUFDbEUscUNBQXFDO0FBRXJDLElBQVksZ0JBc0JYO0FBdEJELFdBQVksZ0JBQWdCO0lBQzFCOztPQUVHO0lBQ0gsaUNBQWEsQ0FBQTtJQUViOzs7T0FHRztJQUNILHlDQUFxQixDQUFBO0lBRXJCOztPQUVHO0lBQ0gseUNBQXFCLENBQUE7SUFFckI7OztPQUdHO0lBQ0gscUNBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQXRCVyxnQkFBZ0IsZ0NBQWhCLGdCQUFnQixRQXNCM0I7QUFzQkQ7O0dBRUc7QUFDSCxJQUFZLHNCQWVYO0FBZkQsV0FBWSxzQkFBc0I7SUFDaEM7O09BRUc7SUFDSCxtRUFBSSxDQUFBO0lBRUo7O09BRUc7SUFDSCwyRUFBUSxDQUFBO0lBRVI7O09BRUc7SUFDSCwrRUFBVSxDQUFBO0FBQ1osQ0FBQyxFQWZXLHNCQUFzQixzQ0FBdEIsc0JBQXNCLFFBZWpDO0FBa0JEOztHQUVHO0FBQ0gsTUFBYSxhQUFhO0lBTXhCLFlBQTRCLFFBQTZCO1FBQTdCLGFBQVEsR0FBUixRQUFRLENBQXFCO1FBQ3ZELElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztJQUN0QyxDQUFDO0lBRU0sS0FBSyxDQUFDLFlBQVksQ0FBQyxRQUF1QixFQUFFLE9BQTRCO1FBQzdFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDMUIsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztRQUNsQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FB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QyxFQUFFLENBQUM7b0JBQ3JFLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3pCLGNBQWMsQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFFLENBQUMsQ0FBQztvQkFDL0QsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDdEIsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNyQixJQUFBLGNBQUksRUFBQyxpQ0FBaUMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBZ0IsZ0JBQWdCLENBQUMsUUFBa0I7SUFDakQsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLHdCQUF3QjtJQUN6RSxTQUFTLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7SUFDeEQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgeyBtaW5pbWF0Y2ggfSBmcm9tICdtaW5pbWF0Y2gnO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gJ3NlbXZlcic7XG5pbXBvcnQgeyBpbmZvIH0gZnJvbSAnLi4vLi4vbG9nZ2luZyc7XG5pbXBvcnQgeyBBc3NlbWJseUVycm9yLCBUb29sa2l0RXJyb3IgfSBmcm9tICcuLi8uLi90b29sa2l0L2Vycm9yJztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICcuLi8uLi91dGlsJztcblxuZXhwb3J0IGVudW0gRGVmYXVsdFNlbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGVtcHR5IHNlbGVjdGlvbiBpbiBjYXNlIHRoZXJlIGFyZSBubyBzZWxlY3RvcnMuXG4gICAqL1xuICBOb25lID0gJ25vbmUnLFxuXG4gIC8qKlxuICAgKiBJZiB0aGUgYXBwIGluY2x1ZGVzIGEgc2luZ2xlIHN0YWNrLCByZXR1cm5zIGl0LiBPdGhlcndpc2UgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgICogVGhpcyBiZWhhdmlvciBpcyB1c2VkIGJ5IFwiZGVwbG95XCIuXG4gICAqL1xuICBPbmx5U2luZ2xlID0gJ3NpbmdsZScsXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYWxsIHN0YWNrcyBpbiB0aGUgbWFpbiAodG9wIGxldmVsKSBhc3NlbWJseSBvbmx5LlxuICAgKi9cbiAgTWFpbkFzc2VtYmx5ID0gJ21haW4nLFxuXG4gIC8qKlxuICAgKiBJZiBubyBzZWxlY3RvcnMgYXJlIHByb3ZpZGVkLCByZXR1cm5zIGFsbCBzdGFja3MgaW4gdGhlIGFwcCxcbiAgICogaW5jbHVkaW5nIHN0YWNrcyBpbnNpZGUgbmVzdGVkIGFzc2VtYmxpZXMuXG4gICAqL1xuICBBbGxTdGFja3MgPSAnYWxsJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZWxlY3RTdGFja3NPcHRpb25zIHtcbiAgLyoqXG4gICAqIEV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIHVwc3RyZWFkL2Rvd25zdHJlYW0gc3RhY2tzXG4gICAqIEBkZWZhdWx0IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSBvbmx5IHNlbGVjdCB0aGUgc3BlY2lmaWVkIHN0YWNrcy5cbiAgICovXG4gIGV4dGVuZD86IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIFRoZSBiZWhhdmlvciBpZiBubyBzZWxlY3RvcnMgYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGRlcGxveSBpZiB0aGUgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcy5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGlnbm9yZU5vU3RhY2tzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXaGVuIHNlbGVjdGluZyBzdGFja3MsIHdoYXQgb3RoZXIgc3RhY2tzIHRvIGluY2x1ZGUgYmVjYXVzZSBvZiBkZXBlbmRlbmNpZXNcbiAqL1xuZXhwb3J0IGVudW0gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBEb24ndCBzZWxlY3QgYW55IGV4dHJhIHN0YWNrc1xuICAgKi9cbiAgTm9uZSxcblxuICAvKipcbiAgICogSW5jbHVkZSBzdGFja3MgdGhhdCB0aGlzIHN0YWNrIGRlcGVuZHMgb25cbiAgICovXG4gIFVwc3RyZWFtLFxuXG4gIC8qKlxuICAgKiBJbmNsdWRlIHN0YWNrcyB0aGF0IGRlcGVuZCBvbiB0aGlzIHN0YWNrXG4gICAqL1xuICBEb3duc3RyZWFtLFxufVxuXG4vKipcbiAqIEEgc3BlY2lmaWNhdGlvbiBvZiB3aGljaCBzdGFja3Mgc2hvdWxkIGJlIHNlbGVjdGVkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tTZWxlY3RvciB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIGFsbCBzdGFja3MgYXQgdGhlIHRvcCBsZXZlbCBhc3NlbWJseSBzaG91bGRcbiAgICogYmUgc2VsZWN0ZWQgYW5kIG5vdGhpbmcgZWxzZVxuICAgKi9cbiAgYWxsVG9wTGV2ZWw/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgcGF0dGVybnMgdG8gbWF0Y2ggdGhlIHN0YWNrIGhpZXJhcmNoaWNhbCBpZHNcbiAgICovXG4gIHBhdHRlcm5zOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBDbG91ZCBBc3NlbWJseSBhbmQgdGhlIG9wZXJhdGlvbnMgd2UgZG8gb24gaXQgdG8gZGVwbG95IHRoZSBhcnRpZmFjdHMgaW5zaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZEFzc2VtYmx5IHtcbiAgLyoqXG4gICAqIFRoZSBkaXJlY3RvcnkgdGhpcyBDbG91ZEFzc2VtYmx5IHdhcyByZWFkIGZyb21cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkaXJlY3Rvcnk6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgYXNzZW1ibHk6IGN4YXBpLkNsb3VkQXNzZW1ibHkpIHtcbiAgICB0aGlzLmRpcmVjdG9yeSA9IGFzc2VtYmx5LmRpcmVjdG9yeTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZWxlY3RTdGFja3Moc2VsZWN0b3I6IFN0YWNrU2VsZWN0b3IsIG9wdGlvbnM6IFNlbGVjdFN0YWNrc09wdGlvbnMpOiBQcm9taXNlPFN0YWNrQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IGFzbSA9IHRoaXMuYXNzZW1ibHk7XG4gICAgY29uc3QgdG9wTGV2ZWxTdGFja3MgPSBhc20uc3RhY2tzO1xuICAgIGNvbnN0IHN0YWNrcyA9IHNlbXZlci5tYWpvcihhc20udmVyc2lvbikgPCAxMCA/IGFzbS5zdGFja3MgOiBhc20uc3RhY2tzUmVjdXJzaXZlbHk7XG4gICAgY29uc3QgYWxsVG9wTGV2ZWwgPSBzZWxlY3Rvci5hbGxUb3BMZXZlbCA/PyBmYWxzZTtcbiAgICBjb25zdCBwYXR0ZXJucyA9IHNhbml0aXplUGF0dGVybnMoc2VsZWN0b3IucGF0dGVybnMpO1xuXG4gICAgaWYgKHN0YWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvcHRpb25zLmlnbm9yZU5vU3RhY2tzKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIFtdKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycpO1xuICAgIH1cblxuICAgIGlmIChhbGxUb3BMZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0VG9wTGV2ZWxTdGFja3Moc3RhY2tzLCB0b3BMZXZlbFN0YWNrcywgb3B0aW9ucy5leHRlbmQpO1xuICAgIH0gZWxzZSBpZiAocGF0dGVybnMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0TWF0Y2hpbmdTdGFja3Moc3RhY2tzLCBwYXR0ZXJucywgb3B0aW9ucy5leHRlbmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5zZWxlY3REZWZhdWx0U3RhY2tzKHN0YWNrcywgdG9wTGV2ZWxTdGFja3MsIG9wdGlvbnMuZGVmYXVsdEJlaGF2aW9yKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdFRvcExldmVsU3RhY2tzKFxuICAgIHN0YWNrczogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10sXG4gICAgdG9wTGV2ZWxTdGFja3M6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGV4dGVuZDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiA9IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSxcbiAgKTogU3RhY2tDb2xsZWN0aW9uIHtcbiAgICBpZiAodG9wTGV2ZWxTdGFja3MubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW5kU3RhY2tzKHRvcExldmVsU3RhY2tzLCBzdGFja3MsIGV4dGVuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ05vIHN0YWNrIGZvdW5kIGluIHRoZSBtYWluIGNsb3VkIGFzc2VtYmx5LiBVc2UgXCJsaXN0XCIgdG8gcHJpbnQgbWFuaWZlc3QnKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VsZWN0TWF0Y2hpbmdTdGFja3MoXG4gICAgc3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBwYXR0ZXJuczogc3RyaW5nW10sXG4gICAgZXh0ZW5kOiBFeHRlbmRlZFN0YWNrU2VsZWN0aW9uID0gRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Ob25lLFxuICApOiBTdGFja0NvbGxlY3Rpb24ge1xuXG4gICAgY29uc3QgbWF0Y2hpbmdQYXR0ZXJuID0gKHBhdHRlcm46IHN0cmluZykgPT4gKHN0YWNrOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpID0+IG1pbmltYXRjaChzdGFjay5oaWVyYXJjaGljYWxJZCwgcGF0dGVybik7XG4gICAgY29uc3QgbWF0Y2hlZFN0YWNrcyA9IGZsYXR0ZW4ocGF0dGVybnMubWFwKHBhdHRlcm4gPT4gc3RhY2tzLmZpbHRlcihtYXRjaGluZ1BhdHRlcm4ocGF0dGVybikpKSk7XG5cbiAgICByZXR1cm4gdGhpcy5leHRlbmRTdGFja3MobWF0Y2hlZFN0YWNrcywgc3RhY2tzLCBleHRlbmQpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3REZWZhdWx0U3RhY2tzKFxuICAgIHN0YWNrczogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10sXG4gICAgdG9wTGV2ZWxTdGFja3M6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGRlZmF1bHRTZWxlY3Rpb246IERlZmF1bHRTZWxlY3Rpb24sXG4gICkge1xuICAgIHN3aXRjaCAoZGVmYXVsdFNlbGVjdGlvbikge1xuICAgICAgY2FzZSBEZWZhdWx0U2VsZWN0aW9uLk1haW5Bc3NlbWJseTpcbiAgICAgICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgdG9wTGV2ZWxTdGFja3MpO1xuICAgICAgY2FzZSBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrczpcbiAgICAgICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgc3RhY2tzKTtcbiAgICAgIGNhc2UgRGVmYXVsdFNlbGVjdGlvbi5Ob25lOlxuICAgICAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLCBbXSk7XG4gICAgICBjYXNlIERlZmF1bHRTZWxlY3Rpb24uT25seVNpbmdsZTpcbiAgICAgICAgaWYgKHRvcExldmVsU3RhY2tzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMsIHRvcExldmVsU3RhY2tzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdTaW5jZSB0aGlzIGFwcCBpbmNsdWRlcyBtb3JlIHRoYW4gYSBzaW5nbGUgc3RhY2ssIHNwZWNpZnkgd2hpY2ggc3RhY2tzIHRvIHVzZSAod2lsZGNhcmRzIGFyZSBzdXBwb3J0ZWQpIG9yIHNwZWNpZnkgYC0tYWxsYFxcbicgK1xuICAgICAgICAgIGBTdGFja3M6ICR7c3RhY2tzLm1hcCh4ID0+IHguaGllcmFyY2hpY2FsSWQpLmpvaW4oJyDCtyAnKX1gKTtcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihgaW52YWxpZCBkZWZhdWx0IGJlaGF2aW9yOiAke2RlZmF1bHRTZWxlY3Rpb259YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGV4dGVuZFN0YWNrcyhcbiAgICBtYXRjaGVkOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSxcbiAgICBhbGw6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdFtdLFxuICAgIGV4dGVuZDogRXh0ZW5kZWRTdGFja1NlbGVjdGlvbiA9IEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uTm9uZSxcbiAgKSB7XG4gICAgY29uc3QgYWxsU3RhY2tzID0gbmV3IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4oKTtcbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIGFsbCkge1xuICAgICAgYWxsU3RhY2tzLnNldChzdGFjay5oaWVyYXJjaGljYWxJZCwgc3RhY2spO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gaW5kZXhCeUhpZXJhcmNoaWNhbElkKG1hdGNoZWQpO1xuXG4gICAgc3dpdGNoIChleHRlbmQpIHtcbiAgICAgIGNhc2UgRXh0ZW5kZWRTdGFja1NlbGVjdGlvbi5Eb3duc3RyZWFtOlxuICAgICAgICBpbmNsdWRlRG93bnN0cmVhbVN0YWNrcyhpbmRleCwgYWxsU3RhY2tzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEV4dGVuZGVkU3RhY2tTZWxlY3Rpb24uVXBzdHJlYW06XG4gICAgICAgIGluY2x1ZGVVcHN0cmVhbVN0YWNrcyhpbmRleCwgYWxsU3RhY2tzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gRmlsdGVyIG9yaWdpbmFsIGFycmF5IGJlY2F1c2UgaXQgaXMgaW4gdGhlIHJpZ2h0IG9yZGVyXG4gICAgY29uc3Qgc2VsZWN0ZWRMaXN0ID0gYWxsLmZpbHRlcihzID0+IGluZGV4LmhhcyhzLmhpZXJhcmNoaWNhbElkKSk7XG5cbiAgICByZXR1cm4gbmV3IFN0YWNrQ29sbGVjdGlvbih0aGlzLCBzZWxlY3RlZExpc3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCBhIHNpbmdsZSBzdGFjayBieSBpdHMgSURcbiAgICovXG4gIHB1YmxpYyBzdGFja0J5SWQoc3RhY2tJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcywgW3RoaXMuYXNzZW1ibHkuZ2V0U3RhY2tBcnRpZmFjdChzdGFja0lkKV0pO1xuICB9XG59XG5cbi8qKlxuICogQSBjb2xsZWN0aW9uIG9mIHN0YWNrcyBhbmQgcmVsYXRlZCBhcnRpZmFjdHNcbiAqXG4gKiBJbiBwcmFjdGljZSwgbm90IGFsbCBhcnRpZmFjdHMgaW4gdGhlIENsb3VkQXNzZW1ibHkgYXJlIGNyZWF0ZWQgZXF1YWw7XG4gKiBzdGFja3MgY2FuIGJlIHNlbGVjdGVkIGluZGVwZW5kZW50bHksIGJ1dCBvdGhlciBhcnRpZmFjdHMgc3VjaCBhcyBhc3NldFxuICogYnVuZGxlcyBjYW5ub3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGFja0NvbGxlY3Rpb24ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgYXNzZW1ibHk6IENsb3VkQXNzZW1ibHksIHB1YmxpYyByZWFkb25seSBzdGFja0FydGlmYWN0czogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0W10pIHtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc3RhY2tDb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0FydGlmYWN0cy5sZW5ndGg7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZpcnN0U3RhY2soKSB7XG4gICAgaWYgKHRoaXMuc3RhY2tDb3VudCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1N0YWNrQ29sbGVjdGlvbiBjb250YWlucyBubyBzdGFjayBhcnRpZmFjdHMgKHRyeWluZyB0byBhY2Nlc3MgdGhlIGZpcnN0IG9uZSknKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tBcnRpZmFjdHNbMF07XG4gIH1cblxuICBwdWJsaWMgZ2V0IHN0YWNrSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0FydGlmYWN0cy5tYXAocyA9PiBzLmlkKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaGllcmFyY2hpY2FsSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0FydGlmYWN0cy5tYXAocyA9PiBzLmhpZXJhcmNoaWNhbElkKTtcbiAgfVxuXG4gIHB1YmxpYyByZXZlcnNlZCgpIHtcbiAgICBjb25zdCBhcnRzID0gWy4uLnRoaXMuc3RhY2tBcnRpZmFjdHNdO1xuICAgIGFydHMucmV2ZXJzZSgpO1xuICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMuYXNzZW1ibHksIGFydHMpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlcihwcmVkaWNhdGU6IChhcnQ6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCkgPT4gYm9vbGVhbik6IFN0YWNrQ29sbGVjdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBTdGFja0NvbGxlY3Rpb24odGhpcy5hc3NlbWJseSwgdGhpcy5zdGFja0FydGlmYWN0cy5maWx0ZXIocHJlZGljYXRlKSk7XG4gIH1cblxuICBwdWJsaWMgY29uY2F0KC4uLm90aGVyczogU3RhY2tDb2xsZWN0aW9uW10pOiBTdGFja0NvbGxlY3Rpb24ge1xuICAgIHJldHVybiBuZXcgU3RhY2tDb2xsZWN0aW9uKHRoaXMuYXNzZW1ibHksIHRoaXMuc3RhY2tBcnRpZmFjdHMuY29uY2F0KC4uLm90aGVycy5tYXAobyA9PiBvLnN0YWNrQXJ0aWZhY3RzKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzICdhd3M6Y2RrOndhcm5pbmd8aW5mb3xlcnJvcicgbWV0YWRhdGEgZW50cmllcyBmcm9tIHRoZSBzdGFjayBzeW50aGVzaXNcbiAgICovXG4gIHB1YmxpYyBhc3luYyB2YWxpZGF0ZU1ldGFkYXRhKFxuICAgIGZhaWxBdDogJ3dhcm4nIHwgJ2Vycm9yJyB8ICdub25lJyA9ICdlcnJvcicsXG4gICAgbG9nZ2VyOiAobGV2ZWw6ICdpbmZvJyB8ICdlcnJvcicgfCAnd2FybicsIG1zZzogY3hhcGkuU3ludGhlc2lzTWVzc2FnZSkgPT4gUHJvbWlzZTx2b2lkPiA9IGFzeW5jICgpID0+IHt9LFxuICApIHtcbiAgICBsZXQgd2FybmluZ3MgPSBmYWxzZTtcbiAgICBsZXQgZXJyb3JzID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIHRoaXMuc3RhY2tBcnRpZmFjdHMpIHtcbiAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBzdGFjay5tZXNzYWdlcykge1xuICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UubGV2ZWwpIHtcbiAgICAgICAgICBjYXNlIGN4YXBpLlN5bnRoZXNpc01lc3NhZ2VMZXZlbC5XQVJOSU5HOlxuICAgICAgICAgICAgd2FybmluZ3MgPSB0cnVlO1xuICAgICAgICAgICAgYXdhaXQgbG9nZ2VyKCd3YXJuJywgbWVzc2FnZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGN4YXBpLlN5bnRoZXNpc01lc3NhZ2VMZXZlbC5FUlJPUjpcbiAgICAgICAgICAgIGVycm9ycyA9IHRydWU7XG4gICAgICAgICAgICBhd2FpdCBsb2dnZXIoJ2Vycm9yJywgbWVzc2FnZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGN4YXBpLlN5bnRoZXNpc01lc3NhZ2VMZXZlbC5JTkZPOlxuICAgICAgICAgICAgYXdhaXQgbG9nZ2VyKCdpbmZvJywgbWVzc2FnZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlcnJvcnMgJiYgZmFpbEF0ICE9ICdub25lJykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VtYmx5RXJyb3IoJ0ZvdW5kIGVycm9ycycpO1xuICAgIH1cblxuICAgIGlmICh3YXJuaW5ncyAmJiBmYWlsQXQgPT09ICd3YXJuJykge1xuICAgICAgdGhyb3cgbmV3IEFzc2VtYmx5RXJyb3IoJ0ZvdW5kIHdhcm5pbmdzICgtLXN0cmljdCBtb2RlKScpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1ldGFkYXRhTWVzc2FnZU9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciB0byBiZSB2ZXJib3NlXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICB2ZXJib3NlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRG9uJ3Qgc3RvcCBvbiBlcnJvciBtZXRhZGF0YVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgaWdub3JlRXJyb3JzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVHJlYXQgd2FybmluZ3MgaW4gbWV0YWRhdGEgYXMgZXJyb3JzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBzdHJpY3Q/OiBib29sZWFuO1xufVxuXG5mdW5jdGlvbiBpbmRleEJ5SGllcmFyY2hpY2FsSWQoc3RhY2tzOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3RbXSk6IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4ge1xuICBjb25zdCByZXN1bHQgPSBuZXcgTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0PigpO1xuXG4gIGZvciAoY29uc3Qgc3RhY2sgb2Ygc3RhY2tzKSB7XG4gICAgcmVzdWx0LnNldChzdGFjay5oaWVyYXJjaGljYWxJZCwgc3RhY2spO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHRyYW5zaXRpdmUgY2xvc3VyZSBvZiBzdGFjayBkZXBlbmRlbnRzLlxuICpcbiAqIE1vZGlmaWVzIGBzZWxlY3RlZFN0YWNrc2AgaW4tcGxhY2UuXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVEb3duc3RyZWFtU3RhY2tzKFxuICBzZWxlY3RlZFN0YWNrczogTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0PixcbiAgYWxsU3RhY2tzOiBNYXA8c3RyaW5nLCBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q+KSB7XG4gIGNvbnN0IGFkZGVkID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICBsZXQgbWFkZVByb2dyZXNzO1xuICBkbyB7XG4gICAgbWFkZVByb2dyZXNzID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IFtpZCwgc3RhY2tdIG9mIGFsbFN0YWNrcykge1xuICAgICAgLy8gU2VsZWN0IHRoaXMgc3RhY2sgaWYgaXQncyBub3Qgc2VsZWN0ZWQgeWV0IEFORCBpdCBkZXBlbmRzIG9uIGEgc3RhY2sgdGhhdCdzIGluIHRoZSBzZWxlY3RlZCBzZXRcbiAgICAgIGlmICghc2VsZWN0ZWRTdGFja3MuaGFzKGlkKSAmJiAoc3RhY2suZGVwZW5kZW5jaWVzIHx8IFtdKS5zb21lKGRlcCA9PiBzZWxlY3RlZFN0YWNrcy5oYXMoZGVwLmlkKSkpIHtcbiAgICAgICAgc2VsZWN0ZWRTdGFja3Muc2V0KGlkLCBzdGFjayk7XG4gICAgICAgIGFkZGVkLnB1c2goaWQpO1xuICAgICAgICBtYWRlUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSB3aGlsZSAobWFkZVByb2dyZXNzKTtcblxuICBpZiAoYWRkZWQubGVuZ3RoID4gMCkge1xuICAgIGluZm8oJ0luY2x1ZGluZyBkZXBlbmRpbmcgc3RhY2tzOiAlcycsIGNoYWxrLmJvbGQoYWRkZWQuam9pbignLCAnKSkpO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSB0cmFuc2l0aXZlIGNsb3N1cmUgb2Ygc3RhY2sgZGVwZW5kZW5jaWVzLlxuICpcbiAqIE1vZGlmaWVzIGBzZWxlY3RlZFN0YWNrc2AgaW4tcGxhY2UuXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVVcHN0cmVhbVN0YWNrcyhcbiAgc2VsZWN0ZWRTdGFja3M6IE1hcDxzdHJpbmcsIGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdD4sXG4gIGFsbFN0YWNrczogTWFwPHN0cmluZywgY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0Pikge1xuICBjb25zdCBhZGRlZCA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG4gIGxldCBtYWRlUHJvZ3Jlc3MgPSB0cnVlO1xuICB3aGlsZSAobWFkZVByb2dyZXNzKSB7XG4gICAgbWFkZVByb2dyZXNzID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IHN0YWNrIG9mIHNlbGVjdGVkU3RhY2tzLnZhbHVlcygpKSB7XG4gICAgICAvLyBTZWxlY3QgYW4gYWRkaXRpb25hbCBzdGFjayBpZiBpdCdzIG5vdCBzZWxlY3RlZCB5ZXQgYW5kIGEgZGVwZW5kZW5jeSBvZiBhIHNlbGVjdGVkIHN0YWNrIChhbmQgZXhpc3RzLCBvYnZpb3VzbHkpXG4gICAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3lJZCBvZiBzdGFjay5kZXBlbmRlbmNpZXMubWFwKHggPT4geC5tYW5pZmVzdC5kaXNwbGF5TmFtZSA/PyB4LmlkKSkge1xuICAgICAgICBpZiAoIXNlbGVjdGVkU3RhY2tzLmhhcyhkZXBlbmRlbmN5SWQpICYmIGFsbFN0YWNrcy5oYXMoZGVwZW5kZW5jeUlkKSkge1xuICAgICAgICAgIGFkZGVkLnB1c2goZGVwZW5kZW5jeUlkKTtcbiAgICAgICAgICBzZWxlY3RlZFN0YWNrcy5zZXQoZGVwZW5kZW5jeUlkLCBhbGxTdGFja3MuZ2V0KGRlcGVuZGVuY3lJZCkhKTtcbiAgICAgICAgICBtYWRlUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGFkZGVkLmxlbmd0aCA+IDApIHtcbiAgICBpbmZvKCdJbmNsdWRpbmcgZGVwZW5kZW5jeSBzdGFja3M6ICVzJywgY2hhbGsuYm9sZChhZGRlZC5qb2luKCcsICcpKSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbml0aXplUGF0dGVybnMocGF0dGVybnM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICBsZXQgc2FuaXRpemVkID0gcGF0dGVybnMuZmlsdGVyKHMgPT4gcyAhPSBudWxsKTsgLy8gZmlsdGVyIG51bGwvdW5kZWZpbmVkXG4gIHNhbml0aXplZCA9IFsuLi5uZXcgU2V0KHNhbml0aXplZCldOyAvLyBtYWtlIHRoZW0gdW5pcXVlXG4gIHJldHVybiBzYW5pdGl6ZWQ7XG59XG4iXX0=