raindancers-network
Version:
Extensions to the ec2.Vpc Constructs
198 lines • 28.2 kB
JavaScript
;
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StatelessRule = exports.FirewallPolicy = exports.WellKnownPorts = exports.Protocol = exports.RuleGroupType = exports.ManagedAwsFirewallRules = exports.StatefulDefaultActions = exports.StatelessActions = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const cdk = require("aws-cdk-lib");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const constructs = require("constructs");
var StatelessActions;
(function (StatelessActions) {
StatelessActions["PASS"] = "aws:pass";
StatelessActions["DROP"] = "aws:drop";
StatelessActions["STATEFUL"] = "aws:forward_to_sfe";
})(StatelessActions = exports.StatelessActions || (exports.StatelessActions = {}));
var StatefulDefaultActions;
(function (StatefulDefaultActions) {
StatefulDefaultActions["DROP_STRICT"] = "aws:drop_strict";
StatefulDefaultActions["DROP_ESTABLISHED"] = "aws:drop_established";
StatefulDefaultActions["ALERT_STRICT"] = "aws:alert_strict";
StatefulDefaultActions["ALERT_ESTABLISHED"] = "aws:alert_established";
})(StatefulDefaultActions = exports.StatefulDefaultActions || (exports.StatefulDefaultActions = {}));
var ManagedAwsFirewallRules;
(function (ManagedAwsFirewallRules) {
ManagedAwsFirewallRules["ABUSED_LEGIT_MALWARE_DOMAINS_ACTION_ORDER"] = "AbusedLegitMalwareDomainsActionOrder";
ManagedAwsFirewallRules["ABUSED_LEGIT_BOTNET_COMMAND_AND_CONTROL_DOMAINS_ACTION_ORDER"] = "AbusedLegitBotNetCommandAndControlDomainsActionOrder";
ManagedAwsFirewallRules["MALWARE_DOMAINS_ACTION_ORDER"] = "MalwareDomainsActionOrder";
ManagedAwsFirewallRules["BOTNET_COMMAND_AND_CONTROL_DOMAINS_ACTION_ORDER"] = "BotNetCommandAndControlDomainsActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_BOTNET_ACTION_ORDER"] = "ThreatSignaturesBotnetActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_BOTNET_WEB_ACTION_ORDER"] = "ThreatSignaturesBotnetWebActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_BOTNET_WINDOWS_ACTION_ODER"] = "ThreatSignaturesBotnetWindowsActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_DOS_ACTION_ORDER"] = "ThreatSignaturesDoSActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_EMERGING_EVENTS_ACTION_ORDER"] = "ThreatSignaturesEmergingEventsActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_EXPLOITS_ACTION_ORDER"] = "ThreatSignaturesExploitsActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_FUP_ACTION_ORDER"] = "ThreatSignaturesFUPActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_IOC_ACTION_ORDER"] = "ThreatSignaturesIOCActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_MALWARE_ACTION_ORDER"] = "ThreatSignaturesMalwareActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_MALWARE_COIN_MINING_ACTION_ORDER"] = "ThreatSignaturesMalwareCoinminingActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_MAWLARE_WEB_ACTION_ORDER"] = "ThreatSignaturesMalwareWebActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_MALWARE_MOBILE_ACTION_ORDER"] = "ThreatSignaturesMalwareMobileActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_PHISHING_ACTION_ORDER"] = "ThreatSignaturesPhishingActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_SCANNERS_ACTION_ORDER"] = "ThreatSignaturesScannersActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_SUSPECT_ACTION_ORDER"] = "ThreatSignaturesSuspectActionOrder";
ManagedAwsFirewallRules["THREAT_SIGNATURES_WEB_ATTACKS_ACTION_ORDER"] = "ThreatSignaturesWebAttacksActionOrder";
})(ManagedAwsFirewallRules = exports.ManagedAwsFirewallRules || (exports.ManagedAwsFirewallRules = {}));
var RuleGroupType;
(function (RuleGroupType) {
RuleGroupType["STATEFUL"] = "STATEFUL";
RuleGroupType["STATELESS"] = "STATELESS";
})(RuleGroupType = exports.RuleGroupType || (exports.RuleGroupType = {}));
var Protocol;
(function (Protocol) {
Protocol[Protocol["ICMP"] = 1] = "ICMP";
Protocol[Protocol["TCP"] = 6] = "TCP";
Protocol[Protocol["UDP"] = 17] = "UDP";
})(Protocol = exports.Protocol || (exports.Protocol = {}));
var WellKnownPorts;
(function (WellKnownPorts) {
WellKnownPorts[WellKnownPorts["SSH"] = 22] = "SSH";
WellKnownPorts[WellKnownPorts["HTTP"] = 80] = "HTTP";
WellKnownPorts[WellKnownPorts["HTTPS"] = 443] = "HTTPS";
WellKnownPorts[WellKnownPorts["RDP"] = 3389] = "RDP";
})(WellKnownPorts = exports.WellKnownPorts || (exports.WellKnownPorts = {}));
class FirewallPolicy extends constructs.Construct {
constructor(scope, id, props) {
super(scope, id);
var policy = {
statelessDefaultActions: props.statelessDefaultActions,
statelessFragmentDefaultActions: props.statelessFragmentDefaultActions,
statefulEngineOptions: props.statefulEngineOptions,
};
this.policy = policy;
this.firewallpolicy = new aws_cdk_lib_1.aws_networkfirewall.CfnFirewallPolicy(this, 'Fwpolicy', {
firewallPolicyName: props.policyName,
firewallPolicy: policy,
});
}
addManagedStatefulRules(props) {
props.awsManagedRules.forEach((rule) => {
if (this.policy.statefulRuleGroupReferences) {
this.policy.statefulRuleGroupReferences.push({
resourceArn: `arn:aws:network-firewall:${cdk.Aws.REGION}:aws-managed:stateful-rulegroup/${rule}`,
});
}
else {
this.policy.statefulRuleGroupReferences = [];
this.policy.statefulRuleGroupReferences.push({
resourceArn: `arn:aws:network-firewall:${cdk.Aws.REGION}:aws-managed:stateful-rulegroup/${rule}`,
});
}
});
}
addStatelessRuleGroup(props) {
var capacity = 1000;
new aws_cdk_lib_1.aws_networkfirewall.CfnRuleGroup(this, props.groupName, {
capacity: capacity,
ruleGroupName: props.groupName,
type: RuleGroupType.STATELESS,
description: props.description,
ruleGroup: {
rulesSource: {
statelessRulesAndCustomActions: {
statelessRules: props.rules,
},
},
},
});
}
}
exports.FirewallPolicy = FirewallPolicy;
_a = JSII_RTTI_SYMBOL_1;
FirewallPolicy[_a] = { fqn: "raindancers-network.firewall.FirewallPolicy", version: "1.29.3" };
class StatelessRule {
constructor(props) {
var destinationPorts;
var sourcePorts;
// validate destinationPorts
if (props.destinationPorts) {
destinationPorts = [];
props.destinationPorts.forEach((port) => {
destinationPorts?.push(checkports(port));
});
}
// validate Source Ports
if (props.sourcePorts) {
if (!(props.protocols)) {
throw new Error('The rule must specify using TCP and/or UDP protocols');
}
if (Protocol.ICMP in props.protocols) {
throw new Error('Only TCP and UDP are supported for rules that specify source ports');
}
sourcePorts = [];
props.sourcePorts.forEach((port) => {
sourcePorts?.push(checkports(port));
});
}
this.statelessRuleProperty = {
priority: props.priority,
ruleDefinition: {
actions: props.actions,
matchAttributes: {
destinationPorts: destinationPorts,
destinations: props.destinations,
protocols: props.protocols,
sourcePorts: sourcePorts,
sources: props.sources,
tcpFlags: props.tcpFlags,
},
},
};
}
}
exports.StatelessRule = StatelessRule;
_b = JSII_RTTI_SYMBOL_1;
StatelessRule[_b] = { fqn: "raindancers-network.firewall.StatelessRule", version: "1.29.3" };
function checkports(port) {
var toPort;
var fromPort;
if (typeof (port) === 'string') {
if (port.split(':').length == 2) {
fromPort = parseInt(port.split(':')[0]);
if (!(fromPort >= 0 && (fromPort <= 65536))) {
throw new Error('from ports must be a integer in the range 0 to 65536');
}
toPort = parseInt(port.split(':')[1]);
if (!(toPort >= 0 && toPort <= 65536)) {
throw new Error('from ports must be a integer in the range 0 to 65536');
}
if (fromPort >= toPort) {
throw new Error('the from port must not be higher than the to port');
}
return {
fromPort: fromPort,
toPort: toPort,
};
}
else {
fromPort = toPort = parseInt(port);
if (!(fromPort >= 0 && fromPort <= 65536)) {
throw new Error('Port must be an integer between 0 and 65536');
}
return {
fromPort: fromPort,
toPort: toPort,
};
}
}
else {
if (!((port >= 0) && (port <= 65536))) {
throw new Error('Port must be between 0 and 65536');
}
fromPort = toPort = port;
return {
fromPort: fromPort,
toPort: toPort,
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlyZXdhbGxQb2xpY3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbndmaXJld2FsbC9maXJld2FsbFBvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG1DQUFtQztBQUNuQyw2Q0FHcUI7QUFDckIseUNBQXlDO0FBRXpDLElBQVksZ0JBSVg7QUFKRCxXQUFZLGdCQUFnQjtJQUMxQixxQ0FBaUIsQ0FBQTtJQUNqQixxQ0FBaUIsQ0FBQTtJQUNqQixtREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBSlcsZ0JBQWdCLEdBQWhCLHdCQUFnQixLQUFoQix3QkFBZ0IsUUFJM0I7QUFFRCxJQUFZLHNCQUtYO0FBTEQsV0FBWSxzQkFBc0I7SUFDaEMseURBQStCLENBQUE7SUFDL0IsbUVBQXlDLENBQUE7SUFDekMsMkRBQWlDLENBQUE7SUFDakMscUVBQTJDLENBQUE7QUFDN0MsQ0FBQyxFQUxXLHNCQUFzQixHQUF0Qiw4QkFBc0IsS0FBdEIsOEJBQXNCLFFBS2pDO0FBR0QsSUFBWSx1QkFxQlg7QUFyQkQsV0FBWSx1QkFBdUI7SUFDakMsNkdBQWtGLENBQUE7SUFDbEYsZ0pBQXFILENBQUE7SUFDckgscUZBQTBELENBQUE7SUFDMUQsd0hBQTZGLENBQUE7SUFDN0Ysc0dBQTJFLENBQUE7SUFDM0UsNkdBQWtGLENBQUE7SUFDbEYsb0hBQXlGLENBQUE7SUFDekYsZ0dBQW9FLENBQUE7SUFDcEUsdUhBQTRGLENBQUE7SUFDNUYsMEdBQStFLENBQUE7SUFDL0UsZ0dBQXFFLENBQUE7SUFDckUsZ0dBQXFFLENBQUE7SUFDckUsd0dBQTZFLENBQUE7SUFDN0UsOEhBQW1HLENBQUE7SUFDbkcsK0dBQW9GLENBQUE7SUFDcEYscUhBQTBGLENBQUE7SUFDMUYsMEdBQStFLENBQUE7SUFDL0UsMEdBQStFLENBQUE7SUFDL0Usd0dBQTZFLENBQUE7SUFDN0UsK0dBQW9GLENBQUE7QUFDdEYsQ0FBQyxFQXJCVyx1QkFBdUIsR0FB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QUU7Z0JBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQzthQUNoRTtZQUNELE9BQU87Z0JBQ0wsUUFBUSxFQUFFLFFBQVE7Z0JBQ2xCLE1BQU0sRUFBRSxNQUFNO2FBQ2YsQ0FBQztTQUNIO0tBQ0Y7U0FBTTtRQUNMLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFHLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFDbkMsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1NBQ3JEO1FBQ0QsUUFBUSxHQUFHLE1BQU0sR0FBRyxJQUFjLENBQUM7UUFDbkMsT0FBTztZQUNMLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLE1BQU0sRUFBRSxNQUFNO1NBQ2YsQ0FBQztLQUNIO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1xuICBhd3NfbmV0d29ya2ZpcmV3YWxsIGFzIGZpcmV3YWxsLFxufVxuICBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5leHBvcnQgZW51bSBTdGF0ZWxlc3NBY3Rpb25zIHtcbiAgUEFTUyA9ICdhd3M6cGFzcycsXG4gIERST1AgPSAnYXdzOmRyb3AnLFxuICBTVEFURUZVTCA9ICdhd3M6Zm9yd2FyZF90b19zZmUnXG59XG5cbmV4cG9ydCBlbnVtIFN0YXRlZnVsRGVmYXVsdEFjdGlvbnMge1xuICBEUk9QX1NUUklDVCA9ICdhd3M6ZHJvcF9zdHJpY3QnLFxuICBEUk9QX0VTVEFCTElTSEVEID0gJ2F3czpkcm9wX2VzdGFibGlzaGVkJyxcbiAgQUxFUlRfU1RSSUNUID0gJ2F3czphbGVydF9zdHJpY3QnLFxuICBBTEVSVF9FU1RBQkxJU0hFRCA9ICdhd3M6YWxlcnRfZXN0YWJsaXNoZWQnXG59XG5cblxuZXhwb3J0IGVudW0gTWFuYWdlZEF3c0ZpcmV3YWxsUnVsZXMge1xuICBBQlVTRURfTEVHSVRfTUFMV0FSRV9ET01BSU5TX0FDVElPTl9PUkRFUiA9ICdBYnVzZWRMZWdpdE1hbHdhcmVEb21haW5zQWN0aW9uT3JkZXInLFxuICBBQlVTRURfTEVHSVRfQk9UTkVUX0NPTU1BTkRfQU5EX0NPTlRST0xfRE9NQUlOU19BQ1RJT05fT1JERVIgPSAnQWJ1c2VkTGVnaXRCb3ROZXRDb21tYW5kQW5kQ29udHJvbERvbWFpbnNBY3Rpb25PcmRlcicsXG4gIE1BTFdBUkVfRE9NQUlOU19BQ1RJT05fT1JERVIgPSAnTWFsd2FyZURvbWFpbnNBY3Rpb25PcmRlcicsXG4gIEJPVE5FVF9DT01NQU5EX0FORF9DT05UUk9MX0RPTUFJTlNfQUNUSU9OX09SREVSID0gJ0JvdE5ldENvbW1hbmRBbmRDb250cm9sRG9tYWluc0FjdGlvbk9yZGVyJyxcbiAgVEhSRUFUX1NJR05BVFVSRVNfQk9UTkVUX0FDVElPTl9PUkRFUiA9ICdUaHJlYXRTaWduYXR1cmVzQm90bmV0QWN0aW9uT3JkZXInLFxuICBUSFJFQVRfU0lHTkFUVVJFU19CT1RORVRfV0VCX0FDVElPTl9PUkRFUiA9ICdUaHJlYXRTaWduYXR1cmVzQm90bmV0V2ViQWN0aW9uT3JkZXInLFxuICBUSFJFQVRfU0lHTkFUVVJFU19CT1RORVRfV0lORE9XU19BQ1RJT05fT0RFUiA9ICdUaHJlYXRTaWduYXR1cmVzQm90bmV0V2luZG93c0FjdGlvbk9yZGVyJyxcbiAgVEhSRUFUX1NJR05BVFVSRVNfRE9TX0FDVElPTl9PUkRFUiA9J1RocmVhdFNpZ25hdHVyZXNEb1NBY3Rpb25PcmRlcicsXG4gIFRIUkVBVF9TSUdOQVRVUkVTX0VNRVJHSU5HX0VWRU5UU19BQ1RJT05fT1JERVIgPSAnVGhyZWF0U2lnbmF0dXJlc0VtZXJnaW5nRXZlbnRzQWN0aW9uT3JkZXInLFxuICBUSFJFQVRfU0lHTkFUVVJFU19FWFBMT0lUU19BQ1RJT05fT1JERVIgPSAnVGhyZWF0U2lnbmF0dXJlc0V4cGxvaXRzQWN0aW9uT3JkZXInLFxuICBUSFJFQVRfU0lHTkFUVVJFU19GVVBfQUNUSU9OX09SREVSID0gJ1RocmVhdFNpZ25hdHVyZXNGVVBBY3Rpb25PcmRlcicsXG4gIFRIUkVBVF9TSUdOQVRVUkVTX0lPQ19BQ1RJT05fT1JERVIgPSAnVGhyZWF0U2lnbmF0dXJlc0lPQ0FjdGlvbk9yZGVyJyxcbiAgVEhSRUFUX1NJR05BVFVSRVNfTUFMV0FSRV9BQ1RJT05fT1JERVIgPSAnVGhyZWF0U2lnbmF0dXJlc01hbHdhcmVBY3Rpb25PcmRlcicsXG4gIFRIUkVBVF9TSUdOQVRVUkVTX01BTFdBUkVfQ09JTl9NSU5JTkdfQUNUSU9OX09SREVSID0gJ1RocmVhdFNpZ25hdHVyZXNNYWx3YXJlQ29pbm1pbmluZ0FjdGlvbk9yZGVyJyxcbiAgVEhSRUFUX1NJR05BVFVSRVNfTUFXTEFSRV9XRUJfQUNUSU9OX09SREVSID0gJ1RocmVhdFNpZ25hdHVyZXNNYWx3YXJlV2ViQWN0aW9uT3JkZXInLFxuICBUSFJFQVRfU0lHTkFUVVJFU19NQUxXQVJFX01PQklMRV9BQ1RJT05fT1JERVIgPSAnVGhyZWF0U2lnbmF0dXJlc01hbHdhcmVNb2JpbGVBY3Rpb25PcmRlcicsXG4gIFRIUkVBVF9TSUdOQVRVUkVTX1BISVNISU5HX0FDVElPTl9PUkRFUiA9ICdUaHJlYXRTaWduYXR1cmVzUGhpc2hpbmdBY3Rpb25PcmRlcicsXG4gIFRIUkVBVF9TSUdOQVRVUkVTX1NDQU5ORVJTX0FDVElPTl9PUkRFUiA9ICdUaHJlYXRTaWduYXR1cmVzU2Nhbm5lcnNBY3Rpb25PcmRlcicsXG4gIFRIUkVBVF9TSUdOQVRVUkVTX1NVU1BFQ1RfQUNUSU9OX09SREVSID0gJ1RocmVhdFNpZ25hdHVyZXNTdXNwZWN0QWN0aW9uT3JkZXInLFxuICBUSFJFQVRfU0lHTkFUVVJFU19XRUJfQVRUQUNLU19BQ1RJT05fT1JERVIgPSAnVGhyZWF0U2lnbmF0dXJlc1dlYkF0dGFja3NBY3Rpb25PcmRlcidcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIEFkZFN0YXRlZnVsUnVsZXNQcm9wcyB7XG4gIHJlYWRvbmx5IGF3c01hbmFnZWRSdWxlczogTWFuYWdlZEF3c0ZpcmV3YWxsUnVsZXNbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRmlyZXdhbGxQb2xpY3lQcm9wZXJ0eSB7XG4gIHN0YXRlZnVsRGVmYXVsdEFjdGlvbnM/OiBzdHJpbmdbXTtcbiAgc3RhdGVmdWxFbmdpbmVPcHRpb25zPzogZmlyZXdhbGwuQ2ZuRmlyZXdhbGxQb2xpY3kuU3RhdGVmdWxFbmdpbmVPcHRpb25zUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gIHN0YXRlZnVsUnVsZUdyb3VwUmVmZXJlbmNlcz86IEFycmF5PGZpcmV3YWxsLkNmbkZpcmV3YWxsUG9saWN5LlN0YXRlZnVsUnVsZUdyb3VwUmVmZXJlbmNlUHJvcGVydHk+O1xuICBzdGF0ZWxlc3NDdXN0b21BY3Rpb25zPzogQXJyYXk8ZmlyZXdhbGwuQ2ZuRmlyZXdhbGxQb2xpY3kuQ3VzdG9tQWN0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuICBzdGF0ZWxlc3NEZWZhdWx0QWN0aW9uczogc3RyaW5nW107XG4gIHN0YXRlbGVzc0ZyYWdtZW50RGVmYXVsdEFjdGlvbnM6IHN0cmluZ1tdO1xuICBzdGF0ZWxlc3NSdWxlR3JvdXBSZWZlcmVuY2VzPzogQXJyYXk8ZmlyZXdhbGwuQ2ZuRmlyZXdhbGxQb2xpY3kuU3RhdGVsZXNzUnVsZUdyb3VwUmVmZXJlbmNlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG5leHBvcnQgZW51bSBSdWxlR3JvdXBUeXBlIHtcbiAgU1RBVEVGVUwgPSAnU1RBVEVGVUwnLFxuICBTVEFURUxFU1MgPSAnU1RBVEVMRVNTJ1xufVxuXG5leHBvcnQgZW51bSBQcm90b2NvbCB7XG4gIElDTVAgPSAxLFxuICBUQ1AgPSA2LFxuICBVRFAgPSAxN1xufVxuXG5leHBvcnQgZW51bSBXZWxsS25vd25Qb3J0cyB7XG4gIFNTSCA9IDIyLFxuICBIVFRQID0gODAsXG4gIEhUVFBTID0gNDQzLFxuICBSRFAgPSAzMzg5XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVsZXNzUnVsZVByb3Bze1xuICByZWFkb25seSBhY3Rpb25zOiBTdGF0ZWxlc3NBY3Rpb25zW107XG4gIHJlYWRvbmx5IHByaW9yaXR5OiBudW1iZXI7XG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uUG9ydHM/OiB1bmRlZmluZWQgfCAoc3RyaW5nfG51bWJlcnxXZWxsS25vd25Qb3J0cylbXTtcbiAgcmVhZG9ubHkgZGVzdGluYXRpb25zPzogdW5kZWZpbmVkIHwgZmlyZXdhbGwuQ2ZuUnVsZUdyb3VwLkFkZHJlc3NQcm9wZXJ0eVtdO1xuICByZWFkb25seSBwcm90b2NvbHM/OiB1bmRlZmluZWQgfCBQcm90b2NvbFtdO1xuICByZWFkb25seSBzb3VyY2VQb3J0cz86IHVuZGVmaW5lZCB8IChzdHJpbmd8bnVtYmVyKVtdO1xuICByZWFkb25seSBzb3VyY2VzPzogdW5kZWZpbmVkIHwgZmlyZXdhbGwuQ2ZuUnVsZUdyb3VwLkFkZHJlc3NQcm9wZXJ0eVtdO1xuICByZWFkb25seSB0Y3BGbGFncz86IHVuZGVmaW5lZCB8IGZpcmV3YWxsLkNmblJ1bGVHcm91cC5UQ1BGbGFnRmllbGRQcm9wZXJ0eVtdO1xufVxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlyZXdhbGxQb2xpY3lQcm9wcyB7XG4gIHJlYWRvbmx5IHBvbGljeU5hbWU6IHN0cmluZztcblxuICByZWFkb25seSBzdGF0ZWxlc3NEZWZhdWx0QWN0aW9uczogU3RhdGVsZXNzQWN0aW9uc1tdO1xuICByZWFkb25seSBzdGF0ZWxlc3NGcmFnbWVudERlZmF1bHRBY3Rpb25zOiBTdGF0ZWxlc3NBY3Rpb25zW107XG4gIHJlYWRvbmx5IHN0YXRlZnVsRW5naW5lT3B0aW9ucz86IHVuZGVmaW5lZCB8IGZpcmV3YWxsLkNmbkZpcmV3YWxsUG9saWN5LlN0YXRlZnVsRW5naW5lT3B0aW9uc1Byb3BlcnR5O1xuXG4gIC8vcmVhZG9ubHkgc3RhdGVmdWxSdWxlR3JvdXBSZWZlcmVuY2VzPyB1bmRlZmluZWRcbiAgLy9yZWFkb25seSBzdGF0ZWxlc3NSdWxlR3JvdXBSZWZlcmVuY2VzP1xuXG5cbiAgLy9UT0RPOnJlYWRvbmx5IHN0YXRlbGVzc0N1c3RvbUFjdGlvbnM/XG5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZGRTdGF0ZWxlc3NSdWxlc1Byb3Bze1xuICByZWFkb25seSBncm91cE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcnVsZXM6IGZpcmV3YWxsLkNmblJ1bGVHcm91cC5TdGF0ZWxlc3NSdWxlUHJvcGVydHlbXTtcbiAgcmVhZG9ubHkgZGVzY3JpcHRpb246IHN0cmluZztcbn1cblxuXG5leHBvcnQgY2xhc3MgRmlyZXdhbGxQb2xpY3kgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCB7XG5cbiAgcG9saWN5OiBJRmlyZXdhbGxQb2xpY3lQcm9wZXJ0eTtcblxuICBwdWJsaWMgcmVhZG9ubHkgZmlyZXdhbGxwb2xpY3k6IGZpcmV3YWxsLkNmbkZpcmV3YWxsUG9saWN5O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEZpcmV3YWxsUG9saWN5UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdmFyIHBvbGljeSA9IHtcbiAgICAgIHN0YXRlbGVzc0RlZmF1bHRBY3Rpb25zOiBwcm9wcy5zdGF0ZWxlc3NEZWZhdWx0QWN0aW9ucyxcbiAgICAgIHN0YXRlbGVzc0ZyYWdtZW50RGVmYXVsdEFjdGlvbnM6IHByb3BzLnN0YXRlbGVzc0ZyYWdtZW50RGVmYXVsdEFjdGlvbnMsXG4gICAgICBzdGF0ZWZ1bEVuZ2luZU9wdGlvbnM6IHByb3BzLnN0YXRlZnVsRW5naW5lT3B0aW9ucyxcbiAgICB9O1xuICAgIHRoaXMucG9saWN5ID0gcG9saWN5O1xuXG4gICAgdGhpcy5maXJld2FsbHBvbGljeSA9IG5ldyBmaXJld2FsbC5DZm5GaXJld2FsbFBvbGljeSh0aGlzLCAnRndwb2xpY3knLCB7XG4gICAgICBmaXJld2FsbFBvbGljeU5hbWU6IHByb3BzLnBvbGljeU5hbWUsXG4gICAgICBmaXJld2FsbFBvbGljeTogcG9saWN5IGFzIGZpcmV3YWxsLkNmbkZpcmV3YWxsUG9saWN5LkZpcmV3YWxsUG9saWN5UHJvcGVydHksXG4gICAgfSk7XG4gIH1cblxuXG4gIHB1YmxpYyBhZGRNYW5hZ2VkU3RhdGVmdWxSdWxlcyhwcm9wczogQWRkU3RhdGVmdWxSdWxlc1Byb3BzKTogdm9pZCB7XG4gICAgcHJvcHMuYXdzTWFuYWdlZFJ1bGVzLmZvckVhY2goKHJ1bGUpID0+IHtcblxuICAgICAgaWYgKHRoaXMucG9saWN5LnN0YXRlZnVsUnVsZUdyb3VwUmVmZXJlbmNlcykge1xuICAgICAgICB0aGlzLnBvbGljeS5zdGF0ZWZ1bFJ1bGVHcm91cFJlZmVyZW5jZXMucHVzaChcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZUFybjogYGFybjphd3M6bmV0d29yay1maXJld2FsbDoke2Nkay5Bd3MuUkVHSU9OfTphd3MtbWFuYWdlZDpzdGF0ZWZ1bC1ydWxlZ3JvdXAvJHtydWxlfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucG9saWN5LnN0YXRlZnVsUnVsZUdyb3VwUmVmZXJlbmNlcyA9IFtdO1xuICAgICAgICB0aGlzLnBvbGljeS5zdGF0ZWZ1bFJ1bGVHcm91cFJlZmVyZW5jZXMucHVzaChcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZUFybjogYGFybjphd3M6bmV0d29yay1maXJld2FsbDoke2Nkay5Bd3MuUkVHSU9OfTphd3MtbWFuYWdlZDpzdGF0ZWZ1bC1ydWxlZ3JvdXAvJHtydWxlfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgYWRkU3RhdGVsZXNzUnVsZUdyb3VwKHByb3BzOiBBZGRTdGF0ZWxlc3NSdWxlc1Byb3BzICk6IHZvaWQge1xuXG4gICAgdmFyIGNhcGFjaXR5OiBudW1iZXIgPSAxMDAwO1xuXG4gICAgbmV3IGZpcmV3YWxsLkNmblJ1bGVHcm91cCh0aGlzLCBwcm9wcy5ncm91cE5hbWUsIHtcbiAgICAgIGNhcGFjaXR5OiBjYXBhY2l0eSxcbiAgICAgIHJ1bGVHcm91cE5hbWU6IHByb3BzLmdyb3VwTmFtZSxcbiAgICAgIHR5cGU6IFJ1bGVHcm91cFR5cGUuU1RBVEVMRVNTLFxuICAgICAgZGVzY3JpcHRpb246IHByb3BzLmRlc2NyaXB0aW9uLFxuICAgICAgcnVsZUdyb3VwOiB7XG4gICAgICAgIHJ1bGVzU291cmNlOiB7XG4gICAgICAgICAgc3RhdGVsZXNzUnVsZXNBbmRDdXN0b21BY3Rpb25zOiB7XG4gICAgICAgICAgICBzdGF0ZWxlc3NSdWxlczogcHJvcHMucnVsZXMsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuXG59XG5cbmV4cG9ydCBjbGFzcyBTdGF0ZWxlc3NSdWxlIHtcblxuICBwdWJsaWMgcmVhZG9ubHkgc3RhdGVsZXNzUnVsZVByb3BlcnR5OiBmaXJld2FsbC5DZm5SdWxlR3JvdXAuU3RhdGVsZXNzUnVsZVByb3BlcnR5O1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBTdGF0ZWxlc3NSdWxlUHJvcHMpIHtcblxuICAgIHZhciBkZXN0aW5hdGlvblBvcnRzOiBmaXJld2FsbC5DZm5SdWxlR3JvdXAuUG9ydFJhbmdlUHJvcGVydHlbXSB8IHVuZGVmaW5lZDtcbiAgICB2YXIgc291cmNlUG9ydHM6IGZpcmV3YWxsLkNmblJ1bGVHcm91cC5Qb3J0UmFuZ2VQcm9wZXJ0eVtdIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gdmFsaWRhdGUgZGVzdGluYXRpb25Qb3J0c1xuICAgIGlmIChwcm9wcy5kZXN0aW5hdGlvblBvcnRzKSB7XG4gICAgICBkZXN0aW5hdGlvblBvcnRzID0gW107XG4gICAgICBwcm9wcy5kZXN0aW5hdGlvblBvcnRzLmZvckVhY2goKHBvcnQpID0+IHtcbiAgICAgICAgZGVzdGluYXRpb25Qb3J0cz8ucHVzaChjaGVja3BvcnRzKHBvcnQpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIFNvdXJjZSBQb3J0c1xuICAgIGlmIChwcm9wcy5zb3VyY2VQb3J0cykge1xuICAgICAgaWYgKCEocHJvcHMucHJvdG9jb2xzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBydWxlIG11c3Qgc3BlY2lmeSB1c2luZyBUQ1AgYW5kL29yIFVEUCBwcm90b2NvbHMnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCBQcm90b2NvbC5JQ01QIGluIHByb3BzLnByb3RvY29scyApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IFRDUCBhbmQgVURQIGFyZSBzdXBwb3J0ZWQgZm9yIHJ1bGVzIHRoYXQgc3BlY2lmeSBzb3VyY2UgcG9ydHMnKTtcbiAgICAgIH1cblxuICAgICAgc291cmNlUG9ydHMgPSBbXTtcbiAgICAgIHByb3BzLnNvdXJjZVBvcnRzLmZvckVhY2goKHBvcnQpID0+IHtcbiAgICAgICAgc291cmNlUG9ydHM/LnB1c2goY2hlY2twb3J0cyhwb3J0KSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlbGVzc1J1bGVQcm9wZXJ0eSA9IHtcbiAgICAgIHByaW9yaXR5OiBwcm9wcy5wcmlvcml0eSxcbiAgICAgIHJ1bGVEZWZpbml0aW9uOiB7XG4gICAgICAgIGFjdGlvbnM6IHByb3BzLmFjdGlvbnMsXG4gICAgICAgIG1hdGNoQXR0cmlidXRlczoge1xuICAgICAgICAgIGRlc3RpbmF0aW9uUG9ydHM6IGRlc3RpbmF0aW9uUG9ydHMsXG4gICAgICAgICAgZGVzdGluYXRpb25zOiBwcm9wcy5kZXN0aW5hdGlvbnMsXG4gICAgICAgICAgcHJvdG9jb2xzOiBwcm9wcy5wcm90b2NvbHMsXG4gICAgICAgICAgc291cmNlUG9ydHM6IHNvdXJjZVBvcnRzLFxuICAgICAgICAgIHNvdXJjZXM6IHByb3BzLnNvdXJjZXMsXG4gICAgICAgICAgdGNwRmxhZ3M6IHByb3BzLnRjcEZsYWdzLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cblxuZnVuY3Rpb24gY2hlY2twb3J0cyhwb3J0OiBzdHJpbmcgfCBudW1iZXIpIHtcblxuICB2YXIgdG9Qb3J0OiBudW1iZXI7XG4gIHZhciBmcm9tUG9ydDogbnVtYmVyO1xuXG4gIGlmICh0eXBlb2YocG9ydCkgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHBvcnQuc3BsaXQoJzonKS5sZW5ndGggPT0gMikge1xuICAgICAgZnJvbVBvcnQgPSBwYXJzZUludChwb3J0LnNwbGl0KCc6JylbMF0pO1xuXG4gICAgICBpZiAoIShmcm9tUG9ydCA+PSAwICYmIChmcm9tUG9ydCA8PSA2NTUzNikpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZnJvbSBwb3J0cyBtdXN0IGJlIGEgaW50ZWdlciBpbiB0aGUgcmFuZ2UgMCB0byA2NTUzNicpO1xuICAgICAgfVxuXG4gICAgICB0b1BvcnQgPSBwYXJzZUludChwb3J0LnNwbGl0KCc6JylbMV0pO1xuICAgICAgaWYgKCEodG9Qb3J0ID49IDAgJiYgdG9Qb3J0IDw9IDY1NTM2KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Zyb20gcG9ydHMgbXVzdCBiZSBhIGludGVnZXIgaW4gdGhlIHJhbmdlIDAgdG8gNjU1MzYnKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcm9tUG9ydCA+PSB0b1BvcnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgZnJvbSBwb3J0IG11c3Qgbm90IGJlIGhpZ2hlciB0aGFuIHRoZSB0byBwb3J0Jyk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmcm9tUG9ydDogZnJvbVBvcnQsXG4gICAgICAgIHRvUG9ydDogdG9Qb3J0LFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnJvbVBvcnQgPSB0b1BvcnQgPSBwYXJzZUludChwb3J0KTtcbiAgICAgIGlmICghKGZyb21Qb3J0ID49IDAgJiYgZnJvbVBvcnQgPD0gNjU1MzYpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUG9ydCBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA2NTUzNicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZnJvbVBvcnQ6IGZyb21Qb3J0LFxuICAgICAgICB0b1BvcnQ6IHRvUG9ydCxcbiAgICAgIH07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICghKChwb3J0ID49MCkgJiYgKHBvcnQgPD02NTUzNikpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvcnQgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDY1NTM2Jyk7XG4gICAgfVxuICAgIGZyb21Qb3J0ID0gdG9Qb3J0ID0gcG9ydCBhcyBudW1iZXI7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb21Qb3J0OiBmcm9tUG9ydCxcbiAgICAgIHRvUG9ydDogdG9Qb3J0LFxuICAgIH07XG4gIH1cbn0iXX0=