aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
162 lines • 22.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RequireApproval = void 0;
exports.printStackDiff = printStackDiff;
exports.printSecurityDiff = printSecurityDiff;
const util_1 = require("util");
const cxschema = require("@aws-cdk/cloud-assembly-schema");
const cloudformation_diff_1 = require("@aws-cdk/cloudformation-diff");
const chalk = require("chalk");
const logging_1 = require("./logging");
const error_1 = require("./toolkit/error");
/**
* Pretty-prints the differences between two template states to the console.
*
* @param oldTemplate the old/current state of the stack.
* @param newTemplate the new/target state of the stack.
* @param strict do not filter out AWS::CDK::Metadata or Rules
* @param context lines of context to use in arbitrary JSON diff
* @param quiet silences \'There were no differences\' messages
*
* @returns the number of stacks in this stack tree that have differences, including the top-level root stack
*/
function printStackDiff(oldTemplate, newTemplate, strict, context, quiet, stackName, changeSet, isImport, stream = process.stderr, nestedStackTemplates) {
let diff = (0, cloudformation_diff_1.fullDiff)(oldTemplate, newTemplate.template, changeSet, isImport);
// must output the stack name if there are differences, even if quiet
if (stackName && (!quiet || !diff.isEmpty)) {
stream.write((0, util_1.format)('Stack %s\n', chalk.bold(stackName)));
}
if (!quiet && isImport) {
stream.write('Parameters and rules created during migration do not affect resource configuration.\n');
}
// detect and filter out mangled characters from the diff
let filteredChangesCount = 0;
if (diff.differenceCount && !strict) {
const mangledNewTemplate = JSON.parse((0, cloudformation_diff_1.mangleLikeCloudFormation)(JSON.stringify(newTemplate.template)));
const mangledDiff = (0, cloudformation_diff_1.fullDiff)(oldTemplate, mangledNewTemplate, changeSet);
filteredChangesCount = Math.max(0, diff.differenceCount - mangledDiff.differenceCount);
if (filteredChangesCount > 0) {
diff = mangledDiff;
}
}
// filter out 'AWS::CDK::Metadata' resources from the template
// filter out 'CheckBootstrapVersion' rules from the template
if (!strict) {
obscureDiff(diff);
}
let stackDiffCount = 0;
if (!diff.isEmpty) {
stackDiffCount++;
(0, cloudformation_diff_1.formatDifferences)(stream, diff, {
...logicalIdMapFromTemplate(oldTemplate),
...buildLogicalToPathMap(newTemplate),
}, context);
}
else if (!quiet) {
(0, logging_1.info)(chalk.green('There were no differences'));
}
if (filteredChangesCount > 0) {
(0, logging_1.info)(chalk.yellow(`Omitted ${filteredChangesCount} changes because they are likely mangled non-ASCII characters. Use --strict to print them.`));
}
for (const nestedStackLogicalId of Object.keys(nestedStackTemplates ?? {})) {
if (!nestedStackTemplates) {
break;
}
const nestedStack = nestedStackTemplates[nestedStackLogicalId];
newTemplate._template = nestedStack.generatedTemplate;
stackDiffCount += printStackDiff(nestedStack.deployedTemplate, newTemplate, strict, context, quiet, nestedStack.physicalName ?? nestedStackLogicalId, undefined, isImport, stream, nestedStack.nestedStackTemplates);
}
return stackDiffCount;
}
var RequireApproval;
(function (RequireApproval) {
RequireApproval["Never"] = "never";
RequireApproval["AnyChange"] = "any-change";
RequireApproval["Broadening"] = "broadening";
})(RequireApproval || (exports.RequireApproval = RequireApproval = {}));
/**
* Print the security changes of this diff, if the change is impactful enough according to the approval level
*
* Returns true if the changes are prompt-worthy, false otherwise.
*/
function printSecurityDiff(oldTemplate, newTemplate, requireApproval, _quiet, stackName, changeSet, stream = process.stderr) {
const diff = (0, cloudformation_diff_1.fullDiff)(oldTemplate, newTemplate.template, changeSet);
if (diffRequiresApproval(diff, requireApproval)) {
stream.write((0, util_1.format)('Stack %s\n', chalk.bold(stackName)));
// eslint-disable-next-line max-len
(0, logging_1.warning)(`This deployment will make potentially sensitive changes according to your current security approval level (--require-approval ${requireApproval}).`);
(0, logging_1.warning)('Please confirm you intend to make the following modifications:\n');
(0, cloudformation_diff_1.formatSecurityChanges)(process.stdout, diff, buildLogicalToPathMap(newTemplate));
return true;
}
return false;
}
/**
* Return whether the diff has security-impacting changes that need confirmation
*
* TODO: Filter the security impact determination based off of an enum that allows
* us to pick minimum "severities" to alert on.
*/
function diffRequiresApproval(diff, requireApproval) {
switch (requireApproval) {
case RequireApproval.Never: return false;
case RequireApproval.AnyChange: return diff.permissionsAnyChanges;
case RequireApproval.Broadening: return diff.permissionsBroadened;
default: throw new error_1.ToolkitError(`Unrecognized approval level: ${requireApproval}`);
}
}
function buildLogicalToPathMap(stack) {
const map = {};
for (const md of stack.findMetadataByType(cxschema.ArtifactMetadataEntryType.LOGICAL_ID)) {
map[md.data] = md.path;
}
return map;
}
function logicalIdMapFromTemplate(template) {
const ret = {};
for (const [logicalId, resource] of Object.entries(template.Resources ?? {})) {
const path = resource?.Metadata?.['aws:cdk:path'];
if (path) {
ret[logicalId] = path;
}
}
return ret;
}
/**
* Remove any template elements that we don't want to show users.
* This is currently:
* - AWS::CDK::Metadata resource
* - CheckBootstrapVersion Rule
*/
function obscureDiff(diff) {
if (diff.unknown) {
// see https://github.com/aws/aws-cdk/issues/17942
diff.unknown = diff.unknown.filter(change => {
if (!change) {
return true;
}
if (change.newValue?.CheckBootstrapVersion) {
return false;
}
if (change.oldValue?.CheckBootstrapVersion) {
return false;
}
return true;
});
}
if (diff.resources) {
diff.resources = diff.resources.filter(change => {
if (!change) {
return true;
}
if (change.newResourceType === 'AWS::CDK::Metadata') {
return false;
}
if (change.oldResourceType === 'AWS::CDK::Metadata') {
return false;
}
return true;
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRpZmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBNEJBLHdDQTJFQztBQWVELDhDQXNCQztBQTVJRCwrQkFBOEI7QUFDOUIsMkRBQTJEO0FBQzNELHNFQVFzQztBQUV0QywrQkFBK0I7QUFFL0IsdUNBQTBDO0FBQzFDLDJDQUErQztBQUUvQzs7Ozs7Ozs7OztHQVVHO0FBQ0gsU0FBZ0IsY0FBYyxDQUM1QixXQUFnQixFQUNoQixXQUE4QyxFQUM5QyxNQUFlLEVBQ2YsT0FBZSxFQUNmLEtBQWMsRUFDZCxTQUFrQixFQUNsQixTQUFtQyxFQUNuQyxRQUFrQixFQUNsQixTQUF1QixPQUFPLENBQUMsTUFBTSxFQUNyQyxvQkFBK0U7SUFDL0UsSUFBSSxJQUFJLEdBQUcsSUFBQSw4QkFBUSxFQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUU1RSxxRUFBcUU7SUFDckUsSUFBSSxTQUFTLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQzNDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBQSxhQUFNLEVBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxJQUFJLENBQUMsS0FBSyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxLQUFLLENBQUMsdUZBQXVGLENBQUMsQ0FBQztJQUN4RyxDQUFDO0lBRUQseURBQXlEO0lBQ3pELElBQUksb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3BDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFBLDhDQUF3QixFQUFD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SSxNQUFNLENBQUMsZUFBZSxLQUFLLG9CQUFvQixFQUFFLENBQUM7Z0JBQUMsT0FBTyxLQUFLLENBQUM7WUFBQyxDQUFDO1lBQ3RFLElBQUksTUFBTSxDQUFDLGVBQWUsS0FBSyxvQkFBb0IsRUFBRSxDQUFDO2dCQUFDLE9BQU8sS0FBSyxDQUFDO1lBQUMsQ0FBQztZQUN0RSxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmb3JtYXQgfSBmcm9tICd1dGlsJztcbmltcG9ydCAqIGFzIGN4c2NoZW1hIGZyb20gJ0Bhd3MtY2RrL2Nsb3VkLWFzc2VtYmx5LXNjaGVtYSc7XG5pbXBvcnQge1xuICB0eXBlIERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0LFxuICB0eXBlIEZvcm1hdFN0cmVhbSxcbiAgdHlwZSBUZW1wbGF0ZURpZmYsXG4gIGZvcm1hdERpZmZlcmVuY2VzLFxuICBmb3JtYXRTZWN1cml0eUNoYW5nZXMsXG4gIGZ1bGxEaWZmLFxuICBtYW5nbGVMaWtlQ2xvdWRGb3JtYXRpb24sXG59IGZyb20gJ0Bhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWRpZmYnO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCAqIGFzIGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCB7IHR5cGUgTmVzdGVkU3RhY2tUZW1wbGF0ZXMgfSBmcm9tICcuL2FwaS9kZXBsb3ltZW50cyc7XG5pbXBvcnQgeyBpbmZvLCB3YXJuaW5nIH0gZnJvbSAnLi9sb2dnaW5nJztcbmltcG9ydCB7IFRvb2xraXRFcnJvciB9IGZyb20gJy4vdG9vbGtpdC9lcnJvcic7XG5cbi8qKlxuICogUHJldHR5LXByaW50cyB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0d28gdGVtcGxhdGUgc3RhdGVzIHRvIHRoZSBjb25zb2xlLlxuICpcbiAqIEBwYXJhbSBvbGRUZW1wbGF0ZSB0aGUgb2xkL2N1cnJlbnQgc3RhdGUgb2YgdGhlIHN0YWNrLlxuICogQHBhcmFtIG5ld1RlbXBsYXRlIHRoZSBuZXcvdGFyZ2V0IHN0YXRlIG9mIHRoZSBzdGFjay5cbiAqIEBwYXJhbSBzdHJpY3QgICAgICBkbyBub3QgZmlsdGVyIG91dCBBV1M6OkNESzo6TWV0YWRhdGEgb3IgUnVsZXNcbiAqIEBwYXJhbSBjb250ZXh0ICAgICBsaW5lcyBvZiBjb250ZXh0IHRvIHVzZSBpbiBhcmJpdHJhcnkgSlNPTiBkaWZmXG4gKiBAcGFyYW0gcXVpZXQgICAgICAgc2lsZW5jZXMgXFwnVGhlcmUgd2VyZSBubyBkaWZmZXJlbmNlc1xcJyBtZXNzYWdlc1xuICpcbiAqIEByZXR1cm5zIHRoZSBudW1iZXIgb2Ygc3RhY2tzIGluIHRoaXMgc3RhY2sgdHJlZSB0aGF0IGhhdmUgZGlmZmVyZW5jZXMsIGluY2x1ZGluZyB0aGUgdG9wLWxldmVsIHJvb3Qgc3RhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByaW50U3RhY2tEaWZmKFxuICBvbGRUZW1wbGF0ZTogYW55LFxuICBuZXdUZW1wbGF0ZTogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LFxuICBzdHJpY3Q6IGJvb2xlYW4sXG4gIGNvbnRleHQ6IG51bWJlcixcbiAgcXVpZXQ6IGJvb2xlYW4sXG4gIHN0YWNrTmFtZT86IHN0cmluZyxcbiAgY2hhbmdlU2V0PzogRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQsXG4gIGlzSW1wb3J0PzogYm9vbGVhbixcbiAgc3RyZWFtOiBGb3JtYXRTdHJlYW0gPSBwcm9jZXNzLnN0ZGVycixcbiAgbmVzdGVkU3RhY2tUZW1wbGF0ZXM/OiB7IFtuZXN0ZWRTdGFja0xvZ2ljYWxJZDogc3RyaW5nXTogTmVzdGVkU3RhY2tUZW1wbGF0ZXMgfSk6IG51bWJlciB7XG4gIGxldCBkaWZmID0gZnVsbERpZmYob2xkVGVtcGxhdGUsIG5ld1RlbXBsYXRlLnRlbXBsYXRlLCBjaGFuZ2VTZXQsIGlzSW1wb3J0KTtcblxuICAvLyBtdXN0IG91dHB1dCB0aGUgc3RhY2sgbmFtZSBpZiB0aGVyZSBhcmUgZGlmZmVyZW5jZXMsIGV2ZW4gaWYgcXVpZXRcbiAgaWYgKHN0YWNrTmFtZSAmJiAoIXF1aWV0IHx8ICFkaWZmLmlzRW1wdHkpKSB7XG4gICAgc3RyZWFtLndyaXRlKGZvcm1hdCgnU3RhY2sgJXNcXG4nLCBjaGFsay5ib2xkKHN0YWNrTmFtZSkpKTtcbiAgfVxuXG4gIGlmICghcXVpZXQgJiYgaXNJbXBvcnQpIHtcbiAgICBzdHJlYW0ud3JpdGUoJ1BhcmFtZXRlcnMgYW5kIHJ1bGVzIGNyZWF0ZWQgZHVyaW5nIG1pZ3JhdGlvbiBkbyBub3QgYWZmZWN0IHJlc291cmNlIGNvbmZpZ3VyYXRpb24uXFxuJyk7XG4gIH1cblxuICAvLyBkZXRlY3QgYW5kIGZpbHRlciBvdXQgbWFuZ2xlZCBjaGFyYWN0ZXJzIGZyb20gdGhlIGRpZmZcbiAgbGV0IGZpbHRlcmVkQ2hhbmdlc0NvdW50ID0gMDtcbiAgaWYgKGRpZmYuZGlmZmVyZW5jZUNvdW50ICYmICFzdHJpY3QpIHtcbiAgICBjb25zdCBtYW5nbGVkTmV3VGVtcGxhdGUgPSBKU09OLnBhcnNlKG1hbmdsZUxpa2VDbG91ZEZvcm1hdGlvbihKU09OLnN0cmluZ2lmeShuZXdUZW1wbGF0ZS50ZW1wbGF0ZSkpKTtcbiAgICBjb25zdCBtYW5nbGVkRGlmZiA9IGZ1bGxEaWZmKG9sZFRlbXBsYXRlLCBtYW5nbGVkTmV3VGVtcGxhdGUsIGNoYW5nZVNldCk7XG4gICAgZmlsdGVyZWRDaGFuZ2VzQ291bnQgPSBNYXRoLm1heCgwLCBkaWZmLmRpZmZlcmVuY2VDb3VudCAtIG1hbmdsZWREaWZmLmRpZmZlcmVuY2VDb3VudCk7XG4gICAgaWYgKGZpbHRlcmVkQ2hhbmdlc0NvdW50ID4gMCkge1xuICAgICAgZGlmZiA9IG1hbmdsZWREaWZmO1xuICAgIH1cbiAgfVxuXG4gIC8vIGZpbHRlciBvdXQgJ0FXUzo6Q0RLOjpNZXRhZGF0YScgcmVzb3VyY2VzIGZyb20gdGhlIHRlbXBsYXRlXG4gIC8vIGZpbHRlciBvdXQgJ0NoZWNrQm9vdHN0cmFwVmVyc2lvbicgcnVsZXMgZnJvbSB0aGUgdGVtcGxhdGVcbiAgaWYgKCFzdHJpY3QpIHtcbiAgICBvYnNjdXJlRGlmZihkaWZmKTtcbiAgfVxuXG4gIGxldCBzdGFja0RpZmZDb3VudCA9IDA7XG4gIGlmICghZGlmZi5pc0VtcHR5KSB7XG4gICAgc3RhY2tEaWZmQ291bnQrKztcbiAgICBmb3JtYXREaWZmZXJlbmNlcyhzdHJlYW0sIGRpZmYsIHtcbiAgICAgIC4uLmxvZ2ljYWxJZE1hcEZyb21UZW1wbGF0ZShvbGRUZW1wbGF0ZSksXG4gICAgICAuLi5idWlsZExvZ2ljYWxUb1BhdGhNYXAobmV3VGVtcGxhdGUpLFxuICAgIH0sIGNvbnRleHQpO1xuICB9IGVsc2UgaWYgKCFxdWlldCkge1xuICAgIGluZm8oY2hhbGsuZ3JlZW4oJ1RoZXJlIHdlcmUgbm8gZGlmZmVyZW5jZXMnKSk7XG4gIH1cbiAgaWYgKGZpbHRlcmVkQ2hhbmdlc0NvdW50ID4gMCkge1xuICAgIGluZm8oY2hhbGsueWVsbG93KGBPbWl0dGVkICR7ZmlsdGVyZWRDaGFuZ2VzQ291bnR9IGNoYW5nZXMgYmVjYXVzZSB0aGV5IGFyZSBsaWtlbHkgbWFuZ2xlZCBub24tQVNDSUkgY2hhcmFjdGVycy4gVXNlIC0tc3RyaWN0IHRvIHByaW50IHRoZW0uYCkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBuZXN0ZWRTdGFja0xvZ2ljYWxJZCBvZiBPYmplY3Qua2V5cyhuZXN0ZWRTdGFja1RlbXBsYXRlcyA/PyB7fSkpIHtcbiAgICBpZiAoIW5lc3RlZFN0YWNrVGVtcGxhdGVzKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29uc3QgbmVzdGVkU3RhY2sgPSBuZXN0ZWRTdGFja1RlbXBsYXRlc1tuZXN0ZWRTdGFja0xvZ2ljYWxJZF07XG5cbiAgICAobmV3VGVtcGxhdGUgYXMgYW55KS5fdGVtcGxhdGUgPSBuZXN0ZWRTdGFjay5nZW5lcmF0ZWRUZW1wbGF0ZTtcbiAgICBzdGFja0RpZmZDb3VudCArPSBwcmludFN0YWNrRGlmZihcbiAgICAgIG5lc3RlZFN0YWNrLmRlcGxveWVkVGVtcGxhdGUsXG4gICAgICBuZXdUZW1wbGF0ZSxcbiAgICAgIHN0cmljdCxcbiAgICAgIGNvbnRleHQsXG4gICAgICBxdWlldCxcbiAgICAgIG5lc3RlZFN0YWNrLnBoeXNpY2FsTmFtZSA/PyBuZXN0ZWRTdGFja0xvZ2ljYWxJZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGlzSW1wb3J0LFxuICAgICAgc3RyZWFtLFxuICAgICAgbmVzdGVkU3RhY2submVzdGVkU3RhY2tUZW1wbGF0ZXMsXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBzdGFja0RpZmZDb3VudDtcbn1cblxuZXhwb3J0IGVudW0gUmVxdWlyZUFwcHJvdmFsIHtcbiAgTmV2ZXIgPSAnbmV2ZXInLFxuXG4gIEFueUNoYW5nZSA9ICdhbnktY2hhbmdlJyxcblxuICBCcm9hZGVuaW5nID0gJ2Jyb2FkZW5pbmcnLFxufVxuXG4vKipcbiAqIFByaW50IHRoZSBzZWN1cml0eSBjaGFuZ2VzIG9mIHRoaXMgZGlmZiwgaWYgdGhlIGNoYW5nZSBpcyBpbXBhY3RmdWwgZW5vdWdoIGFjY29yZGluZyB0byB0aGUgYXBwcm92YWwgbGV2ZWxcbiAqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGNoYW5nZXMgYXJlIHByb21wdC13b3J0aHksIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByaW50U2VjdXJpdHlEaWZmKFxuICBvbGRUZW1wbGF0ZTogYW55LFxuICBuZXdUZW1wbGF0ZTogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LFxuICByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbCxcbiAgX3F1aWV0PzogYm9vbGVhbixcbiAgc3RhY2tOYW1lPzogc3RyaW5nLFxuICBjaGFuZ2VTZXQ/OiBEZXNjcmliZUNoYW5nZVNldE91dHB1dCxcbiAgc3RyZWFtOiBGb3JtYXRTdHJlYW0gPSBwcm9jZXNzLnN0ZGVycixcbik6IGJvb2xlYW4ge1xuICBjb25zdCBkaWZmID0gZnVsbERpZmYob2xkVGVtcGxhdGUsIG5ld1RlbXBsYXRlLnRlbXBsYXRlLCBjaGFuZ2VTZXQpO1xuXG4gIGlmIChkaWZmUmVxdWlyZXNBcHByb3ZhbChkaWZmLCByZXF1aXJlQXBwcm92YWwpKSB7XG4gICAgc3RyZWFtLndyaXRlKGZvcm1hdCgnU3RhY2sgJXNcXG4nLCBjaGFsay5ib2xkKHN0YWNrTmFtZSkpKTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgd2FybmluZyhgVGhpcyBkZXBsb3ltZW50IHdpbGwgbWFrZSBwb3RlbnRpYWxseSBzZW5zaXRpdmUgY2hhbmdlcyBhY2NvcmRpbmcgdG8geW91ciBjdXJyZW50IHNlY3VyaXR5IGFwcHJvdmFsIGxldmVsICgtLXJlcXVpcmUtYXBwcm92YWwgJHtyZXF1aXJlQXBwcm92YWx9KS5gKTtcbiAgICB3YXJuaW5nKCdQbGVhc2UgY29uZmlybSB5b3UgaW50ZW5kIHRvIG1ha2UgdGhlIGZvbGxvd2luZyBtb2RpZmljYXRpb25zOlxcbicpO1xuXG4gICAgZm9ybWF0U2VjdXJpdHlDaGFuZ2VzKHByb2Nlc3Muc3Rkb3V0LCBkaWZmLCBidWlsZExvZ2ljYWxUb1BhdGhNYXAobmV3VGVtcGxhdGUpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgdGhlIGRpZmYgaGFzIHNlY3VyaXR5LWltcGFjdGluZyBjaGFuZ2VzIHRoYXQgbmVlZCBjb25maXJtYXRpb25cbiAqXG4gKiBUT0RPOiBGaWx0ZXIgdGhlIHNlY3VyaXR5IGltcGFjdCBkZXRlcm1pbmF0aW9uIGJhc2VkIG9mZiBvZiBhbiBlbnVtIHRoYXQgYWxsb3dzXG4gKiB1cyB0byBwaWNrIG1pbmltdW0gXCJzZXZlcml0aWVzXCIgdG8gYWxlcnQgb24uXG4gKi9cbmZ1bmN0aW9uIGRpZmZSZXF1aXJlc0FwcHJvdmFsKGRpZmY6IFRlbXBsYXRlRGlmZiwgcmVxdWlyZUFwcHJvdmFsOiBSZXF1aXJlQXBwcm92YWwpIHtcbiAgc3dpdGNoIChyZXF1aXJlQXBwcm92YWwpIHtcbiAgICBjYXNlIFJlcXVpcmVBcHByb3ZhbC5OZXZlcjogcmV0dXJuIGZhbHNlO1xuICAgIGNhc2UgUmVxdWlyZUFwcHJvdmFsLkFueUNoYW5nZTogcmV0dXJuIGRpZmYucGVybWlzc2lvbnNBbnlDaGFuZ2VzO1xuICAgIGNhc2UgUmVxdWlyZUFwcHJvdmFsLkJyb2FkZW5pbmc6IHJldHVybiBkaWZmLnBlcm1pc3Npb25zQnJvYWRlbmVkO1xuICAgIGRlZmF1bHQ6IHRocm93IG5ldyBUb29sa2l0RXJyb3IoYFVucmVjb2duaXplZCBhcHByb3ZhbCBsZXZlbDogJHtyZXF1aXJlQXBwcm92YWx9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYnVpbGRMb2dpY2FsVG9QYXRoTWFwKHN0YWNrOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpIHtcbiAgY29uc3QgbWFwOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgZm9yIChjb25zdCBtZCBvZiBzdGFjay5maW5kTWV0YWRhdGFCeVR5cGUoY3hzY2hlbWEuQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZS5MT0dJQ0FMX0lEKSkge1xuICAgIG1hcFttZC5kYXRhIGFzIHN0cmluZ10gPSBtZC5wYXRoO1xuICB9XG4gIHJldHVybiBtYXA7XG59XG5cbmZ1bmN0aW9uIGxvZ2ljYWxJZE1hcEZyb21UZW1wbGF0ZSh0ZW1wbGF0ZTogYW55KSB7XG4gIGNvbnN0IHJldDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gIGZvciAoY29uc3QgW2xvZ2ljYWxJZCwgcmVzb3VyY2VdIG9mIE9iamVjdC5lbnRyaWVzKHRlbXBsYXRlLlJlc291cmNlcyA/PyB7fSkpIHtcbiAgICBjb25zdCBwYXRoID0gKHJlc291cmNlIGFzIGFueSk/Lk1ldGFkYXRhPy5bJ2F3czpjZGs6cGF0aCddO1xuICAgIGlmIChwYXRoKSB7XG4gICAgICByZXRbbG9naWNhbElkXSA9IHBhdGg7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUmVtb3ZlIGFueSB0ZW1wbGF0ZSBlbGVtZW50cyB0aGF0IHdlIGRvbid0IHdhbnQgdG8gc2hvdyB1c2Vycy5cbiAqIFRoaXMgaXMgY3VycmVudGx5OlxuICogLSBBV1M6OkNESzo6TWV0YWRhdGEgcmVzb3VyY2VcbiAqIC0gQ2hlY2tCb290c3RyYXBWZXJzaW9uIFJ1bGVcbiAqL1xuZnVuY3Rpb24gb2JzY3VyZURpZmYoZGlmZjogVGVtcGxhdGVEaWZmKSB7XG4gIGlmIChkaWZmLnVua25vd24pIHtcbiAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8xNzk0MlxuICAgIGRpZmYudW5rbm93biA9IGRpZmYudW5rbm93bi5maWx0ZXIoY2hhbmdlID0+IHtcbiAgICAgIGlmICghY2hhbmdlKSB7IHJldHVybiB0cnVlOyB9XG4gICAgICBpZiAoY2hhbmdlLm5ld1ZhbHVlPy5DaGVja0Jvb3RzdHJhcFZlcnNpb24pIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICBpZiAoY2hhbmdlLm9sZFZhbHVlPy5DaGVja0Jvb3RzdHJhcFZlcnNpb24pIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkaWZmLnJlc291cmNlcykge1xuICAgIGRpZmYucmVzb3VyY2VzID0gZGlmZi5yZXNvdXJjZXMuZmlsdGVyKGNoYW5nZSA9PiB7XG4gICAgICBpZiAoIWNoYW5nZSkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgaWYgKGNoYW5nZS5uZXdSZXNvdXJjZVR5cGUgPT09ICdBV1M6OkNESzo6TWV0YWRhdGEnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgaWYgKGNoYW5nZS5vbGRSZXNvdXJjZVR5cGUgPT09ICdBV1M6OkNESzo6TWV0YWRhdGEnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==