@aws-cdk/cloudformation-diff
Version:
Utilities to diff CDK stacks against CloudFormation templates
99 lines • 16.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecurityGroupChanges = void 0;
const chalk = require("chalk");
const security_group_rule_1 = require("./security-group-rule");
const diffable_1 = require("../diffable");
const render_intrinsics_1 = require("../render-intrinsics");
const util_1 = require("../util");
/**
* Changes to IAM statements
*/
class SecurityGroupChanges {
constructor(props) {
this.ingress = new diffable_1.DiffableCollection();
this.egress = new diffable_1.DiffableCollection();
// Group rules
for (const ingressProp of props.ingressRulePropertyChanges) {
this.ingress.addOld(...this.readInlineRules(ingressProp.oldValue, ingressProp.resourceLogicalId));
this.ingress.addNew(...this.readInlineRules(ingressProp.newValue, ingressProp.resourceLogicalId));
}
for (const egressProp of props.egressRulePropertyChanges) {
this.egress.addOld(...this.readInlineRules(egressProp.oldValue, egressProp.resourceLogicalId));
this.egress.addNew(...this.readInlineRules(egressProp.newValue, egressProp.resourceLogicalId));
}
// Rule resources
for (const ingressRes of props.ingressRuleResourceChanges) {
this.ingress.addOld(...this.readRuleResource(ingressRes.oldProperties));
this.ingress.addNew(...this.readRuleResource(ingressRes.newProperties));
}
for (const egressRes of props.egressRuleResourceChanges) {
this.egress.addOld(...this.readRuleResource(egressRes.oldProperties));
this.egress.addNew(...this.readRuleResource(egressRes.newProperties));
}
this.ingress.calculateDiff();
this.egress.calculateDiff();
}
get hasChanges() {
return this.ingress.hasChanges || this.egress.hasChanges;
}
/**
* Return a summary table of changes
*/
summarize() {
const ret = [];
const header = ['', 'Group', 'Dir', 'Protocol', 'Peer'];
const inWord = 'In';
const outWord = 'Out';
// Render a single rule to the table (curried function so we can map it across rules easily--thank you JavaScript!)
const renderRule = (plusMin, inOut) => (rule) => [
plusMin,
rule.groupId,
inOut,
rule.describeProtocol(),
rule.describePeer(),
].map(s => plusMin === '+' ? chalk.green(s) : chalk.red(s));
// First generate all lines, sort later
ret.push(...this.ingress.additions.map(renderRule('+', inWord)));
ret.push(...this.egress.additions.map(renderRule('+', outWord)));
ret.push(...this.ingress.removals.map(renderRule('-', inWord)));
ret.push(...this.egress.removals.map(renderRule('-', outWord)));
// Sort by group name then ingress/egress (ingress first)
ret.sort((0, util_1.makeComparator)((row) => [row[1], row[2].indexOf(inWord) > -1 ? 0 : 1]));
ret.splice(0, 0, header);
return ret;
}
toJson() {
return (0, util_1.deepRemoveUndefined)({
ingressRuleAdditions: (0, util_1.dropIfEmpty)(this.ingress.additions.map(s => s.toJson())),
ingressRuleRemovals: (0, util_1.dropIfEmpty)(this.ingress.removals.map(s => s.toJson())),
egressRuleAdditions: (0, util_1.dropIfEmpty)(this.egress.additions.map(s => s.toJson())),
egressRuleRemovals: (0, util_1.dropIfEmpty)(this.egress.removals.map(s => s.toJson())),
});
}
get rulesAdded() {
return this.ingress.hasAdditions
|| this.egress.hasAdditions;
}
readInlineRules(rules, logicalId) {
if (!rules || !Array.isArray(rules)) {
return [];
}
// UnCloudFormation so the parser works in an easier domain
const ref = '${' + logicalId + '.GroupId}';
return rules.flatMap((r) => {
const rendered = (0, render_intrinsics_1.renderIntrinsics)(r);
// SecurityGroupRule is not robust against unparsed objects
return typeof rendered === 'object' ? [new security_group_rule_1.SecurityGroupRule(rendered, ref)] : [];
});
}
readRuleResource(resource) {
if (!resource) {
return [];
}
// UnCloudFormation so the parser works in an easier domain
return [new security_group_rule_1.SecurityGroupRule((0, render_intrinsics_1.renderIntrinsics)(resource))];
}
}
exports.SecurityGroupChanges = SecurityGroupChanges;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHktZ3JvdXAtY2hhbmdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNlY3VyaXR5LWdyb3VwLWNoYW5nZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0JBQStCO0FBRS9CLCtEQUEwRDtBQUUxRCwwQ0FBaUQ7QUFDakQsNERBQXdEO0FBQ3hELGtDQUEyRTtBQVMzRTs7R0FFRztBQUNILE1BQWEsb0JBQW9CO0lBSS9CLFlBQVksS0FBZ0M7UUFINUIsWUFBTyxHQUFHLElBQUksNkJBQWtCLEVBQXFCLENBQUM7UUFDdEQsV0FBTSxHQUFHLElBQUksNkJBQWtCLEVBQXFCLENBQUM7UUFHbkUsY0FBYztRQUNkLEtBQUssTUFBTSxXQUFXLElBQUksS0FBSyxDQUFDLDBCQUEwQixFQUFFLENBQUM7WUFDM0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztZQUNsRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1FBQ3BHLENBQUM7UUFDRCxLQUFLLE1BQU0sVUFBVSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7WUFDL0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztRQUNqRyxDQUFDO1FBRUQsaUJBQWlCO1FBQ2pCLEtBQUssTUFBTSxVQUFVLElBQUksS0FBSyxDQUFDLDBCQUEwQixFQUFFLENBQUM7WUFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDeEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELEtBQUssTUFBTSxTQUFTLElBQUksS0FBSyxDQUFDLHlCQUF5QixFQUFFLENBQUM7WUFDeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQsSUFBVyxVQUFVO1FBQ25CLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7SUFDM0QsQ0FBQztJQUVEOztPQUVHO0lBQ0ksU0FBUztRQUNkLE1BQU0sR0FBRyxHQUFlLEVBQUUsQ0FBQztRQUUzQixNQUFNLE1BQU0sR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV4RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDcEIsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBRXRCLG1IQUFtSDtRQUNuSCxNQUFNLFVBQVUsR0FBRyxDQUFDLE9BQWUsRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBdUIsRUFBRSxFQUFFLENBQUM7WUFDbEYsT0FBTztZQUNQLElBQUksQ0FBQyxPQUFPO1lBQ1osS0FBSztZQUNMLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN2QixJQUFJLENBQUMsWUFBWSxFQUFFO1NBQ3BCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTVELHVDQUF1QztRQUN2QyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakUsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWhFLHlEQUF5RDtRQUN6RCxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUEscUJBQWMsRUFBQyxDQUFDLEdBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFM0YsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRXpCLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVNLE1BQU07UUFDWCxPQUFPLElBQUEsMEJBQW1CLEVBQUM7WUFDekIsb0JBQW9CLEVBQUUsSUFBQSxrQkFBVyxFQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQzlFLG1CQUFtQixFQUFFLElBQUEsa0JBQVcsRUFBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM1RSxtQkFBbUIsRUFBRSxJQUFBLGtCQUFXLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDNUUsa0JBQWtCLEVBQUUsSUFBQSxrQkFBVyxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1NBQzNFLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFXLFVBQVU7UUFDbkIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVk7ZUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7SUFDbEMsQ0FBQztJQUVPLGVBQWUsQ0FBQyxLQUFVLEVBQUUsU0FBaUI7UUFDbkQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwQyxPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7UUFFRCwyREFBMkQ7UUFFM0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLFNBQVMsR0FBRyxXQUFXLENBQUM7UUFDM0MsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUU7WUFDOUIsTUFBTSxRQUFRLEdBQUcsSUFBQSxvQ0FBZ0IsRUFBQyxDQUFDLENBQUMsQ0FBQztZQUNyQywyREFBMkQ7WUFDM0QsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSx1Q0FBaUIsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3BGLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGdCQUFnQixDQUFDLFFBQWE7UUFDcEMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2QsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsMkRBQTJEO1FBRTNELE9BQU8sQ0FBQyxJQUFJLHVDQUFpQixDQUFDLElBQUEsb0NBQWdCLEVBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdELENBQUM7Q0FDRjtBQXpHRCxvREF5R0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgdHlwZSB7IFJ1bGVKc29uIH0gZnJvbSAnLi9zZWN1cml0eS1ncm91cC1ydWxlJztcbmltcG9ydCB7IFNlY3VyaXR5R3JvdXBSdWxlIH0gZnJvbSAnLi9zZWN1cml0eS1ncm91cC1ydWxlJztcbmltcG9ydCB0eXBlIHsgUHJvcGVydHlDaGFuZ2UsIFJlc291cmNlQ2hhbmdlIH0gZnJvbSAnLi4vZGlmZi90eXBlcyc7XG5pbXBvcnQgeyBEaWZmYWJsZUNvbGxlY3Rpb24gfSBmcm9tICcuLi9kaWZmYWJsZSc7XG5pbXBvcnQgeyByZW5kZXJJbnRyaW5zaWNzIH0gZnJvbSAnLi4vcmVuZGVyLWludHJpbnNpY3MnO1xuaW1wb3J0IHsgZGVlcFJlbW92ZVVuZGVmaW5lZCwgZHJvcElmRW1wdHksIG1ha2VDb21wYXJhdG9yIH0gZnJvbSAnLi4vdXRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VjdXJpdHlHcm91cENoYW5nZXNQcm9wcyB7XG4gIGluZ3Jlc3NSdWxlUHJvcGVydHlDaGFuZ2VzOiBQcm9wZXJ0eUNoYW5nZVtdO1xuICBpbmdyZXNzUnVsZVJlc291cmNlQ2hhbmdlczogUmVzb3VyY2VDaGFuZ2VbXTtcbiAgZWdyZXNzUnVsZVJlc291cmNlQ2hhbmdlczogUmVzb3VyY2VDaGFuZ2VbXTtcbiAgZWdyZXNzUnVsZVByb3BlcnR5Q2hhbmdlczogUHJvcGVydHlDaGFuZ2VbXTtcbn1cblxuLyoqXG4gKiBDaGFuZ2VzIHRvIElBTSBzdGF0ZW1lbnRzXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWN1cml0eUdyb3VwQ2hhbmdlcyB7XG4gIHB1YmxpYyByZWFkb25seSBpbmdyZXNzID0gbmV3IERpZmZhYmxlQ29sbGVjdGlvbjxTZWN1cml0eUdyb3VwUnVsZT4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGVncmVzcyA9IG5ldyBEaWZmYWJsZUNvbGxlY3Rpb248U2VjdXJpdHlHcm91cFJ1bGU+KCk7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IFNlY3VyaXR5R3JvdXBDaGFuZ2VzUHJvcHMpIHtcbiAgICAvLyBHcm91cCBydWxlc1xuICAgIGZvciAoY29uc3QgaW5ncmVzc1Byb3Agb2YgcHJvcHMuaW5ncmVzc1J1bGVQcm9wZXJ0eUNoYW5nZXMpIHtcbiAgICAgIHRoaXMuaW5ncmVzcy5hZGRPbGQoLi4udGhpcy5yZWFkSW5saW5lUnVsZXMoaW5ncmVzc1Byb3Aub2xkVmFsdWUsIGluZ3Jlc3NQcm9wLnJlc291cmNlTG9naWNhbElkKSk7XG4gICAgICB0aGlzLmluZ3Jlc3MuYWRkTmV3KC4uLnRoaXMucmVhZElubGluZVJ1bGVzKGluZ3Jlc3NQcm9wLm5ld1ZhbHVlLCBpbmdyZXNzUHJvcC5yZXNvdXJjZUxvZ2ljYWxJZCkpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGVncmVzc1Byb3Agb2YgcHJvcHMuZWdyZXNzUnVsZVByb3BlcnR5Q2hhbmdlcykge1xuICAgICAgdGhpcy5lZ3Jlc3MuYWRkT2xkKC4uLnRoaXMucmVhZElubGluZVJ1bGVzKGVncmVzc1Byb3Aub2xkVmFsdWUsIGVncmVzc1Byb3AucmVzb3VyY2VMb2dpY2FsSWQpKTtcbiAgICAgIHRoaXMuZWdyZXNzLmFkZE5ldyguLi50aGlzLnJlYWRJbmxpbmVSdWxlcyhlZ3Jlc3NQcm9wLm5ld1ZhbHVlLCBlZ3Jlc3NQcm9wLnJlc291cmNlTG9naWNhbElkKSk7XG4gICAgfVxuXG4gICAgLy8gUnVsZSByZXNvdXJjZXNcbiAgICBmb3IgKGNvbnN0IGluZ3Jlc3NSZXMgb2YgcHJvcHMuaW5ncmVzc1J1bGVSZXNvdXJjZUNoYW5nZXMpIHtcbiAgICAgIHRoaXMuaW5ncmVzcy5hZGRPbGQoLi4udGhpcy5yZWFkUnVsZVJlc291cmNlKGluZ3Jlc3NSZXMub2xkUHJvcGVydGllcykpO1xuICAgICAgdGhpcy5pbmdyZXNzLmFkZE5ldyguLi50aGlzLnJlYWRSdWxlUmVzb3VyY2UoaW5ncmVzc1Jlcy5uZXdQcm9wZXJ0aWVzKSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZWdyZXNzUmVzIG9mIHByb3BzLmVncmVzc1J1bGVSZXNvdXJjZUNoYW5nZXMpIHtcbiAgICAgIHRoaXMuZWdyZXNzLmFkZE9sZCguLi50aGlzLnJlYWRSdWxlUmVzb3VyY2UoZWdyZXNzUmVzLm9sZFByb3BlcnRpZXMpKTtcbiAgICAgIHRoaXMuZWdyZXNzLmFkZE5ldyguLi50aGlzLnJlYWRSdWxlUmVzb3VyY2UoZWdyZXNzUmVzLm5ld1Byb3BlcnRpZXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLmluZ3Jlc3MuY2FsY3VsYXRlRGlmZigpO1xuICAgIHRoaXMuZWdyZXNzLmNhbGN1bGF0ZURpZmYoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaGFzQ2hhbmdlcygpIHtcbiAgICByZXR1cm4gdGhpcy5pbmdyZXNzLmhhc0NoYW5nZXMgfHwgdGhpcy5lZ3Jlc3MuaGFzQ2hhbmdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBzdW1tYXJ5IHRhYmxlIG9mIGNoYW5nZXNcbiAgICovXG4gIHB1YmxpYyBzdW1tYXJpemUoKTogc3RyaW5nW11bXSB7XG4gICAgY29uc3QgcmV0OiBzdHJpbmdbXVtdID0gW107XG5cbiAgICBjb25zdCBoZWFkZXIgPSBbJycsICdHcm91cCcsICdEaXInLCAnUHJvdG9jb2wnLCAnUGVlciddO1xuXG4gICAgY29uc3QgaW5Xb3JkID0gJ0luJztcbiAgICBjb25zdCBvdXRXb3JkID0gJ091dCc7XG5cbiAgICAvLyBSZW5kZXIgYSBzaW5nbGUgcnVsZSB0byB0aGUgdGFibGUgKGN1cnJpZWQgZnVuY3Rpb24gc28gd2UgY2FuIG1hcCBpdCBhY3Jvc3MgcnVsZXMgZWFzaWx5LS10aGFuayB5b3UgSmF2YVNjcmlwdCEpXG4gICAgY29uc3QgcmVuZGVyUnVsZSA9IChwbHVzTWluOiBzdHJpbmcsIGluT3V0OiBzdHJpbmcpID0+IChydWxlOiBTZWN1cml0eUdyb3VwUnVsZSkgPT4gW1xuICAgICAgcGx1c01pbixcbiAgICAgIHJ1bGUuZ3JvdXBJZCxcbiAgICAgIGluT3V0LFxuICAgICAgcnVsZS5kZXNjcmliZVByb3RvY29sKCksXG4gICAgICBydWxlLmRlc2NyaWJlUGVlcigpLFxuICAgIF0ubWFwKHMgPT4gcGx1c01pbiA9PT0gJysnID8gY2hhbGsuZ3JlZW4ocykgOiBjaGFsay5yZWQocykpO1xuXG4gICAgLy8gRmlyc3QgZ2VuZXJhdGUgYWxsIGxpbmVzLCBzb3J0IGxhdGVyXG4gICAgcmV0LnB1c2goLi4udGhpcy5pbmdyZXNzLmFkZGl0aW9ucy5tYXAocmVuZGVyUnVsZSgnKycsIGluV29yZCkpKTtcbiAgICByZXQucHVzaCguLi50aGlzLmVncmVzcy5hZGRpdGlvbnMubWFwKHJlbmRlclJ1bGUoJysnLCBvdXRXb3JkKSkpO1xuICAgIHJldC5wdXNoKC4uLnRoaXMuaW5ncmVzcy5yZW1vdmFscy5tYXAocmVuZGVyUnVsZSgnLScsIGluV29yZCkpKTtcbiAgICByZXQucHVzaCguLi50aGlzLmVncmVzcy5yZW1vdmFscy5tYXAocmVuZGVyUnVsZSgnLScsIG91dFdvcmQpKSk7XG5cbiAgICAvLyBTb3J0IGJ5IGdyb3VwIG5hbWUgdGhlbiBpbmdyZXNzL2VncmVzcyAoaW5ncmVzcyBmaXJzdClcbiAgICByZXQuc29ydChtYWtlQ29tcGFyYXRvcigocm93OiBzdHJpbmdbXSkgPT4gW3Jvd1sxXSwgcm93WzJdLmluZGV4T2YoaW5Xb3JkKSA+IC0xID8gMCA6IDFdKSk7XG5cbiAgICByZXQuc3BsaWNlKDAsIDAsIGhlYWRlcik7XG5cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgcHVibGljIHRvSnNvbigpOiBTZWN1cml0eUdyb3VwQ2hhbmdlc0pzb24ge1xuICAgIHJldHVybiBkZWVwUmVtb3ZlVW5kZWZpbmVkKHtcbiAgICAgIGluZ3Jlc3NSdWxlQWRkaXRpb25zOiBkcm9wSWZFbXB0eSh0aGlzLmluZ3Jlc3MuYWRkaXRpb25zLm1hcChzID0+IHMudG9Kc29uKCkpKSxcbiAgICAgIGluZ3Jlc3NSdWxlUmVtb3ZhbHM6IGRyb3BJZkVtcHR5KHRoaXMuaW5ncmVzcy5yZW1vdmFscy5tYXAocyA9PiBzLnRvSnNvbigpKSksXG4gICAgICBlZ3Jlc3NSdWxlQWRkaXRpb25zOiBkcm9wSWZFbXB0eSh0aGlzLmVncmVzcy5hZGRpdGlvbnMubWFwKHMgPT4gcy50b0pzb24oKSkpLFxuICAgICAgZWdyZXNzUnVsZVJlbW92YWxzOiBkcm9wSWZFbXB0eSh0aGlzLmVncmVzcy5yZW1vdmFscy5tYXAocyA9PiBzLnRvSnNvbigpKSksXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHJ1bGVzQWRkZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW5ncmVzcy5oYXNBZGRpdGlvbnNcbiAgICAgICAgfHwgdGhpcy5lZ3Jlc3MuaGFzQWRkaXRpb25zO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkSW5saW5lUnVsZXMocnVsZXM6IGFueSwgbG9naWNhbElkOiBzdHJpbmcpOiBTZWN1cml0eUdyb3VwUnVsZVtdIHtcbiAgICBpZiAoIXJ1bGVzIHx8ICFBcnJheS5pc0FycmF5KHJ1bGVzKSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIFVuQ2xvdWRGb3JtYXRpb24gc28gdGhlIHBhcnNlciB3b3JrcyBpbiBhbiBlYXNpZXIgZG9tYWluXG5cbiAgICBjb25zdCByZWYgPSAnJHsnICsgbG9naWNhbElkICsgJy5Hcm91cElkfSc7XG4gICAgcmV0dXJuIHJ1bGVzLmZsYXRNYXAoKHI6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmVuZGVyZWQgPSByZW5kZXJJbnRyaW5zaWNzKHIpO1xuICAgICAgLy8gU2VjdXJpdHlHcm91cFJ1bGUgaXMgbm90IHJvYnVzdCBhZ2FpbnN0IHVucGFyc2VkIG9iamVjdHNcbiAgICAgIHJldHVybiB0eXBlb2YgcmVuZGVyZWQgPT09ICdvYmplY3QnID8gW25ldyBTZWN1cml0eUdyb3VwUnVsZShyZW5kZXJlZCwgcmVmKV0gOiBbXTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZFJ1bGVSZXNvdXJjZShyZXNvdXJjZTogYW55KTogU2VjdXJpdHlHcm91cFJ1bGVbXSB7XG4gICAgaWYgKCFyZXNvdXJjZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIFVuQ2xvdWRGb3JtYXRpb24gc28gdGhlIHBhcnNlciB3b3JrcyBpbiBhbiBlYXNpZXIgZG9tYWluXG5cbiAgICByZXR1cm4gW25ldyBTZWN1cml0eUdyb3VwUnVsZShyZW5kZXJJbnRyaW5zaWNzKHJlc291cmNlKSldO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VjdXJpdHlHcm91cENoYW5nZXNKc29uIHtcbiAgaW5ncmVzc1J1bGVBZGRpdGlvbnM/OiBSdWxlSnNvbltdO1xuICBpbmdyZXNzUnVsZVJlbW92YWxzPzogUnVsZUpzb25bXTtcbiAgZWdyZXNzUnVsZUFkZGl0aW9ucz86IFJ1bGVKc29uW107XG4gIGVncmVzc1J1bGVSZW1vdmFscz86IFJ1bGVKc29uW107XG59XG4iXX0=