cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
221 lines • 43.7 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElastiCacheServerlessMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const ElastiCacheServerlessMetricFactory_1 = require("./ElastiCacheServerlessMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class ElastiCacheServerlessMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
const fallbackConstructName = [props.clusterId ?? "ALL"].join("-");
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
fallbackConstructName,
});
this.title = namingStrategy.resolveHumanReadableName();
const metricFactory = new ElastiCacheServerlessMetricFactory_1.ElastiCacheServerlessMetricFactory(scope.createMetricFactory(), props);
this.metricMaxItemCount = metricFactory.metricMaxItemCount();
this.metricEvictions = metricFactory.metricEvictions();
this.metricAverageCacheSize = metricFactory.metricAverageCacheSize();
this.metricMaxElastiCacheProcessingUnits =
metricFactory.metricMaxElastiCacheProcessingUnits();
this.metricAverageConnections = metricFactory.metricAverageConnections();
this.metricNetworkBytesIn = metricFactory.metricNetworkBytesIn();
this.metricNetworkBytesOut = metricFactory.metricNetworkBytesOut();
this.metricTM99SuccessfulReadRequestLatency =
metricFactory.metricSuccessfulReadRequestLatency(common_1.LatencyType.TM99);
this.metricAverageSuccessfulReadRequestLatency =
metricFactory.metricSuccessfulReadRequestLatency(common_1.LatencyType.AVERAGE);
this.metricTM99SuccessfulWriteRequestLatency =
metricFactory.metricSuccessfulWriteRequestLatency(common_1.LatencyType.TM99);
this.metricAverageSuccessfulWriteRequestLatency =
metricFactory.metricSuccessfulWriteRequestLatency(common_1.LatencyType.AVERAGE);
this.metricTotalThrottledCmds = metricFactory.metricTotalThrottledCmds();
this.metricTotalCmds = metricFactory.metricTotalCmds();
this.metricThrottleRate = metricFactory.metricThrottleRate();
this.metricAverageCacheHitRate = metricFactory.metricAverageCacheHitRate();
this.metricCacheHits = metricFactory.metricCacheHits();
this.metricCacheMisses = metricFactory.metricCacheMisses();
this.tm99SuccessfulReadRequestLatencyAlarmAnnotations = [];
this.averageSuccessfulReadRequestLatencyAlarmAnnotations = [];
this.tm99SuccessfulWriteRequestLatencyAlarmAnnotations = [];
this.averageSuccessfulWriteRequestLatencyAlarmAnnotations = [];
this.throttleRateAlarmAnnotations = [];
this.hitRateAlarmAnnotations = [];
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.elastiCacheAlarmFactory = new common_1.ElastiCacheAlarmFactory(alarmFactory);
this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(alarmFactory);
for (const disambiguator in props.addTM99SuccessfulReadRequestLatencyAlarm) {
const alarmProps = props.addTM99SuccessfulReadRequestLatencyAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.metricTM99SuccessfulReadRequestLatency, common_1.LatencyType.TM99, alarmProps, disambiguator, "SuccessfulReadRequest");
this.tm99SuccessfulReadRequestLatencyAlarmAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addAverageSuccessfulReadRequestLatencyAlarm) {
const alarmProps = props.addAverageSuccessfulReadRequestLatencyAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.metricAverageSuccessfulReadRequestLatency, common_1.LatencyType.AVERAGE, alarmProps, disambiguator, "SuccessfulReadRequest");
this.averageSuccessfulReadRequestLatencyAlarmAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addTM99SuccessfulWriteRequestLatencyAlarm) {
const alarmProps = props.addTM99SuccessfulWriteRequestLatencyAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.metricTM99SuccessfulWriteRequestLatency, common_1.LatencyType.TM99, alarmProps, disambiguator, "SuccessfulWriteRequest");
this.tm99SuccessfulWriteRequestLatencyAlarmAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addAverageSuccessfulWriteRequestLatencyAlarm) {
const alarmProps = props.addAverageSuccessfulWriteRequestLatencyAlarm[disambiguator];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(this.metricAverageSuccessfulWriteRequestLatency, common_1.LatencyType.AVERAGE, alarmProps, disambiguator, "SuccessfulWriteRequest");
this.averageSuccessfulWriteRequestLatencyAlarmAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addThrottleRateAlarm) {
const alarmProps = props.addThrottleRateAlarm[disambiguator];
const createdAlarm = this.elastiCacheAlarmFactory.addMaxThrottleRateAlarm(this.metricThrottleRate, alarmProps, disambiguator);
this.throttleRateAlarmAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addHitRateAlarm) {
const alarmProps = props.addHitRateAlarm[disambiguator];
const createdAlarm = this.elastiCacheAlarmFactory.addMinHitRateAlarm(this.metricAverageCacheHitRate, alarmProps, disambiguator);
this.hitRateAlarmAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
this.createProcessingUnitsWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createCacheHitAndMissWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createSuccessfulReadLatencyWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createSuccessfulWriteLatencyWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createItemCountWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
return [
this.createTitleWidget(),
new aws_cloudwatch_1.Row(this.createCacheSizeWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createCacheHitAndMissWidget(common_1.TwoThirdsWidth, common_1.DefaultGraphWidgetHeight)),
new aws_cloudwatch_1.Row(this.createSuccessfulReadLatencyWidget(common_1.HalfWidth, common_1.DefaultGraphWidgetHeight), this.createSuccessfulWriteLatencyWidget(common_1.HalfWidth, common_1.DefaultGraphWidgetHeight)),
new aws_cloudwatch_1.Row(this.createNetworkWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createCacheCmdsWidget(common_1.TwoThirdsWidth, common_1.DefaultGraphWidgetHeight)),
new aws_cloudwatch_1.Row(this.createProcessingUnitsWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createItemCountWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight), this.createConnectionsWidget(common_1.ThirdWidth, common_1.DefaultGraphWidgetHeight)),
];
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "Serverless ElastiCache",
title: this.title,
});
}
createSuccessfulReadLatencyWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Successful Read Latency",
left: [
this.metricTM99SuccessfulReadRequestLatency,
this.metricAverageSuccessfulReadRequestLatency,
],
leftYAxis: common_1.TimeAxisMicrosFromZero,
leftAnnotations: [
...this.tm99SuccessfulReadRequestLatencyAlarmAnnotations,
...this.averageSuccessfulReadRequestLatencyAlarmAnnotations,
],
});
}
createSuccessfulWriteLatencyWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Successful Write Latency",
left: [
this.metricTM99SuccessfulWriteRequestLatency,
this.metricAverageSuccessfulWriteRequestLatency,
],
leftYAxis: common_1.TimeAxisMicrosFromZero,
leftAnnotations: [
...this.tm99SuccessfulWriteRequestLatencyAlarmAnnotations,
...this.averageSuccessfulWriteRequestLatencyAlarmAnnotations,
],
});
}
createCacheSizeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Cache Size",
left: [this.metricAverageCacheSize],
leftYAxis: common_1.SizeAxisBytesFromZero,
});
}
createCacheHitAndMissWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Hits/Misses",
left: [this.metricAverageCacheHitRate],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.hitRateAlarmAnnotations,
right: [this.metricCacheHits, this.metricCacheMisses],
rightYAxis: common_1.CountAxisFromZero,
});
}
createCacheCmdsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Commands",
left: [this.metricThrottleRate],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.throttleRateAlarmAnnotations,
right: [this.metricTotalCmds, this.metricTotalCmds],
rightYAxis: common_1.CountAxisFromZero,
});
}
createNetworkWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "IO",
left: [this.metricNetworkBytesIn, this.metricNetworkBytesOut],
leftYAxis: common_1.SizeAxisBytesFromZero,
});
}
createProcessingUnitsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Processing Units",
left: [this.metricMaxElastiCacheProcessingUnits],
leftYAxis: common_1.CountAxisFromZero,
});
}
createItemCountWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Items",
left: [this.metricMaxItemCount],
leftYAxis: common_1.CountAxisFromZero,
right: [this.metricEvictions],
rightYAxis: common_1.CountAxisFromZero,
});
}
createConnectionsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Connections",
left: [this.metricAverageConnections],
leftYAxis: common_1.CountAxisFromZero,
});
}
}
exports.ElastiCacheServerlessMonitoring = ElastiCacheServerlessMonitoring;
_a = JSII_RTTI_SYMBOL_1;
ElastiCacheServerlessMonitoring[_a] = { fqn: "cdk-monitoring-constructs.ElastiCacheServerlessMonitoring", version: "10.0.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWxhc3RpQ2FjaGVTZXJ2ZXJsZXNzTW9uaXRvcmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkVsYXN0aUNhY2hlU2VydmVybGVzc01vbml0b3JpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwrREFLb0M7QUFDcEMsNkZBRzhDO0FBQzlDLHlDQW9Cc0I7QUFDdEIsK0NBR3lCO0FBa0Z6QixNQUFhLCtCQUFnQyxTQUFRLG1CQUFVO0lBK0I3RCxZQUNFLEtBQXNCLEVBQ3RCLEtBQTJDO1FBRTNDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEIsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25FLE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IscUJBQXFCO1NBQ3RCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFFdkQsTUFBTSxhQUFhLEdBQUcsSUFBSSx1RUFBa0MsQ0FDMUQsS0FBSyxDQUFDLG1CQUFtQixFQUFFLEVBQzNCLEtBQUssQ0FDTixDQUFDO1FBQ0YsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzdELElBQUksQ0FBQyxlQUFlLEdBQUcsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxzQkFBc0IsR0FBRyxhQUFhLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNyRSxJQUFJLENBQUMsbUNBQW1DO1lBQ3RDLGFBQWEsQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyx3QkFBd0IsR0FBRyxhQUFhLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUN6RSxJQUFJLENBQUMsb0JBQW9C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SSxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1lBQy9CLFNBQVMsRUFBRSwwQkFBaUI7WUFDNUIsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUM3QixVQUFVLEVBQUUsMEJBQWlCO1NBQzlCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCx1QkFBdUIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUNuRCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxhQUFhO1lBQ3BCLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQztZQUNyQyxTQUFTLEVBQUUsMEJBQWlCO1NBQzdCLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBblZILDBFQW9WQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEdyYXBoV2lkZ2V0LFxuICBIb3Jpem9udGFsQW5ub3RhdGlvbixcbiAgSVdpZGdldCxcbiAgUm93LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcbmltcG9ydCB7XG4gIEVsYXN0aUNhY2hlU2VydmVybGVzc01ldHJpY0ZhY3RvcnksXG4gIEVsYXN0aUNhY2hlU2VydmVybGVzc01ldHJpY0ZhY3RvcnlQcm9wcyxcbn0gZnJvbSBcIi4vRWxhc3RpQ2FjaGVTZXJ2ZXJsZXNzTWV0cmljRmFjdG9yeVwiO1xuaW1wb3J0IHtcbiAgQmFzZU1vbml0b3JpbmdQcm9wcyxcbiAgQ291bnRBeGlzRnJvbVplcm8sXG4gIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQsXG4gIEVsYXN0aUNhY2hlQWxhcm1GYWN0b3J5LFxuICBIYWxmV2lkdGgsXG4gIExhdGVuY3lBbGFybUZhY3RvcnksXG4gIExhdGVuY3lUaHJlc2hvbGQsXG4gIExhdGVuY3lUeXBlLFxuICBNYXhUaHJvdHRsZVJhdGVUaHJlc2hvbGQsXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1pbkhpdFJhdGVUaHJlc2hvbGQsXG4gIE1vbml0b3JpbmcsXG4gIE1vbml0b3JpbmdTY29wZSxcbiAgUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICBUaGlyZFdpZHRoLFxuICBUaW1lQXhpc01pY3Jvc0Zyb21aZXJvLFxuICBUd29UaGlyZHNXaWR0aCxcbn0gZnJvbSBcIi4uLy4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTW9uaXRvcmluZ0hlYWRlcldpZGdldCxcbiAgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5LFxufSBmcm9tIFwiLi4vLi4vZGFzaGJvYXJkXCI7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBtb25pdG9yaW5nIEVsYXN0aUNhY2hlIFNlcnZlcmxlc3MgY2x1c3RlcnMuXG4gKlxuICogRXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzIHRvIGluY2x1ZGUgYWxhcm0gY29uZmlndXJhdGlvbnMgc3BlY2lmaWMgdG9cbiAqIEVsYXN0aUNhY2hlIFNlcnZlcmxlc3MgbWV0cmljcyBzdWNoIGFzIGxhdGVuY3ksIHRocm90dGxpbmcsIGNhY2hlIGhpdCByYXRlcyxcbiAqIGFuZCBpdGVtIGNvdW50cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbGFzdGlDYWNoZVNlcnZlcmxlc3NNb25pdG9yaW5nT3B0aW9uc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICAvKipcbiAgICogQWRkIGFsYXJtIHdoZW4gdGhlIDk5dGggcGVyY2VudGlsZSAoVE05OSkgbGF0ZW5jeSBmb3Igc3VjY2Vzc2Z1bCByZWFkIHJlcXVlc3RzIGV4Y2VlZHMgYSB0aHJlc2hvbGQuXG4gICAqXG4gICAqIFRoZSBrZXkgaXMgYSBkaXNhbWJpZ3VhdG9yIChlLmcuLCBcIldhcm5pbmdcIiwgXCJDcml0aWNhbFwiKSBhbmQgdGhlIHZhbHVlIGRlZmluZXMgdGhlIGxhdGVuY3kgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFsYXJtXG4gICAqL1xuICByZWFkb25seSBhZGRUTTk5U3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeUFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBMYXRlbmN5VGhyZXNob2xkXG4gID47XG5cbiAgLyoqXG4gICAqIEFkZCBhbGFybSB3aGVuIHRoZSBhdmVyYWdlIGxhdGVuY3kgZm9yIHN1Y2Nlc3NmdWwgcmVhZCByZXF1ZXN0cyBleGNlZWRzIGEgdGhyZXNob2xkLlxuICAgKlxuICAgKiBUaGUga2V5IGlzIGEgZGlzYW1iaWd1YXRvciAoZS5nLiwgXCJXYXJuaW5nXCIsIFwiQ3JpdGljYWxcIikgYW5kIHRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBsYXRlbmN5IHRocmVzaG9sZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBhbGFybVxuICAgKi9cbiAgcmVhZG9ubHkgYWRkQXZlcmFnZVN1Y2Nlc3NmdWxSZWFkUmVxdWVzdExhdGVuY3lBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTGF0ZW5jeVRocmVzaG9sZFxuICA+O1xuXG4gIC8qKlxuICAgKiBBZGQgYWxhcm0gd2hlbiB0aGUgOTl0aCBwZXJjZW50aWxlIChUTTk5KSBsYXRlbmN5IGZvciBzdWNjZXNzZnVsIHdyaXRlIHJlcXVlc3RzIGV4Y2VlZHMgYSB0aHJlc2hvbGQuXG4gICAqXG4gICAqIFRoZSBrZXkgaXMgYSBkaXNhbWJpZ3VhdG9yIChlLmcuLCBcIldhcm5pbmdcIiwgXCJDcml0aWNhbFwiKSBhbmQgdGhlIHZhbHVlIGRlZmluZXMgdGhlIGxhdGVuY3kgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFsYXJtXG4gICAqL1xuICByZWFkb25seSBhZGRUTTk5U3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTGF0ZW5jeVRocmVzaG9sZFxuICA+O1xuXG4gIC8qKlxuICAgKiBBZGQgYWxhcm0gd2hlbiB0aGUgYXZlcmFnZSBsYXRlbmN5IGZvciBzdWNjZXNzZnVsIHdyaXRlIHJlcXVlc3RzIGV4Y2VlZHMgYSB0aHJlc2hvbGQuXG4gICAqXG4gICAqIFRoZSBrZXkgaXMgYSBkaXNhbWJpZ3VhdG9yIChlLmcuLCBcIldhcm5pbmdcIiwgXCJDcml0aWNhbFwiKSBhbmQgdGhlIHZhbHVlIGRlZmluZXMgdGhlIGxhdGVuY3kgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFsYXJtXG4gICAqL1xuICByZWFkb25seSBhZGRBdmVyYWdlU3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTGF0ZW5jeVRocmVzaG9sZFxuICA+O1xuXG4gIC8qKlxuICAgKiBBZGQgYWxhcm0gd2hlbiB0aGUgdGhyb3R0bGUgcmF0ZSAocGVyY2VudGFnZSBvZiB0aHJvdHRsZWQgY29tbWFuZHMpIGV4Y2VlZHMgYSB0aHJlc2hvbGQuXG4gICAqXG4gICAqIFRoZSBrZXkgaXMgYSBkaXNhbWJpZ3VhdG9yIChlLmcuLCBcIldhcm5pbmdcIiwgXCJDcml0aWNhbFwiKSBhbmQgdGhlIHZhbHVlIGRlZmluZXMgdGhlIHVzYWdlIHRocmVzaG9sZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBhbGFybVxuICAgKi9cbiAgcmVhZG9ubHkgYWRkVGhyb3R0bGVSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBNYXhUaHJvdHRsZVJhdGVUaHJlc2hvbGQ+O1xuXG4gIC8qKlxuICAgKiBBZGQgYWxhcm0gd2hlbiB0aGUgY2FjaGUgaGl0IHJhdGUgZmFsbHMgYmVsb3cgYSBtaW5pbXVtIHRocmVzaG9sZC5cbiAgICpcbiAgICogVGhlIGtleSBpcyBhIGRpc2FtYmlndWF0b3IgKGUuZy4sIFwiV2FybmluZ1wiLCBcIkNyaXRpY2FsXCIpIGFuZCB0aGUgdmFsdWUgZGVmaW5lcyB0aGUgbWluaW11bSBoaXQgcmF0ZSB0aHJlc2hvbGQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYWxhcm1cbiAgICovXG4gIHJlYWRvbmx5IGFkZEhpdFJhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIE1pbkhpdFJhdGVUaHJlc2hvbGQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVsYXN0aUNhY2hlU2VydmVybGVzc01vbml0b3JpbmdQcm9wc1xuICBleHRlbmRzIEVsYXN0aUNhY2hlU2VydmVybGVzc01ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBFbGFzdGlDYWNoZVNlcnZlcmxlc3NNb25pdG9yaW5nT3B0aW9ucyB7fVxuXG5leHBvcnQgY2xhc3MgRWxhc3RpQ2FjaGVTZXJ2ZXJsZXNzTW9uaXRvcmluZyBleHRlbmRzIE1vbml0b3Jpbmcge1xuICByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IG1ldHJpY01heEl0ZW1Db3VudDogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljRXZpY3Rpb25zOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNBdmVyYWdlQ2FjaGVTaXplOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNNYXhFbGFzdGlDYWNoZVByb2Nlc3NpbmdVbml0czogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljQXZlcmFnZUNvbm5lY3Rpb25zOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNOZXR3b3JrQnl0ZXNJbjogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljTmV0d29ya0J5dGVzT3V0OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNUTTk5U3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeTogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljQXZlcmFnZVN1Y2Nlc3NmdWxSZWFkUmVxdWVzdExhdGVuY3k6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpY1RNOTlTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0TGF0ZW5jeTogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljQXZlcmFnZVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNUb3RhbFRocm90dGxlZENtZHM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpY1RvdGFsQ21kczogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbWV0cmljVGhyb3R0bGVSYXRlOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNBdmVyYWdlQ2FjaGVIaXRSYXRlOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBtZXRyaWNDYWNoZUhpdHM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG1ldHJpY0NhY2hlTWlzc2VzOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIHJlYWRvbmx5IGVsYXN0aUNhY2hlQWxhcm1GYWN0b3J5OiBFbGFzdGlDYWNoZUFsYXJtRmFjdG9yeTtcbiAgcmVhZG9ubHkgbGF0ZW5jeUFsYXJtRmFjdG9yeTogTGF0ZW5jeUFsYXJtRmFjdG9yeTtcblxuICByZWFkb25seSB0bTk5U3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeUFsYXJtQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGF2ZXJhZ2VTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgdG05OVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgYXZlcmFnZVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgdGhyb3R0bGVSYXRlQWxhcm1Bbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgaGl0UmF0ZUFsYXJtQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IE1vbml0b3JpbmdTY29wZSxcbiAgICBwcm9wczogRWxhc3RpQ2FjaGVTZXJ2ZXJsZXNzTW9uaXRvcmluZ1Byb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgcHJvcHMpO1xuXG4gICAgY29uc3QgZmFsbGJhY2tDb25zdHJ1Y3ROYW1lID0gW3Byb3BzLmNsdXN0ZXJJZCA/PyBcIkFMTFwiXS5qb2luKFwiLVwiKTtcbiAgICBjb25zdCBuYW1pbmdTdHJhdGVneSA9IG5ldyBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3koe1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWUsXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuXG4gICAgY29uc3QgbWV0cmljRmFjdG9yeSA9IG5ldyBFbGFzdGlDYWNoZVNlcnZlcmxlc3NNZXRyaWNGYWN0b3J5KFxuICAgICAgc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcbiAgICB0aGlzLm1ldHJpY01heEl0ZW1Db3VudCA9IG1ldHJpY0ZhY3RvcnkubWV0cmljTWF4SXRlbUNvdW50KCk7XG4gICAgdGhpcy5tZXRyaWNFdmljdGlvbnMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0V2aWN0aW9ucygpO1xuICAgIHRoaXMubWV0cmljQXZlcmFnZUNhY2hlU2l6ZSA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQXZlcmFnZUNhY2hlU2l6ZSgpO1xuICAgIHRoaXMubWV0cmljTWF4RWxhc3RpQ2FjaGVQcm9jZXNzaW5nVW5pdHMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNNYXhFbGFzdGlDYWNoZVByb2Nlc3NpbmdVbml0cygpO1xuICAgIHRoaXMubWV0cmljQXZlcmFnZUNvbm5lY3Rpb25zID0gbWV0cmljRmFjdG9yeS5tZXRyaWNBdmVyYWdlQ29ubmVjdGlvbnMoKTtcbiAgICB0aGlzLm1ldHJpY05ldHdvcmtCeXRlc0luID0gbWV0cmljRmFjdG9yeS5tZXRyaWNOZXR3b3JrQnl0ZXNJbigpO1xuICAgIHRoaXMubWV0cmljTmV0d29ya0J5dGVzT3V0ID0gbWV0cmljRmFjdG9yeS5tZXRyaWNOZXR3b3JrQnl0ZXNPdXQoKTtcbiAgICB0aGlzLm1ldHJpY1RNOTlTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5ID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljU3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeShMYXRlbmN5VHlwZS5UTTk5KTtcbiAgICB0aGlzLm1ldHJpY0F2ZXJhZ2VTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5ID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljU3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeShMYXRlbmN5VHlwZS5BVkVSQUdFKTtcbiAgICB0aGlzLm1ldHJpY1RNOTlTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0TGF0ZW5jeSA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1N1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5KExhdGVuY3lUeXBlLlRNOTkpO1xuICAgIHRoaXMubWV0cmljQXZlcmFnZVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5ID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljU3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3koTGF0ZW5jeVR5cGUuQVZFUkFHRSk7XG4gICAgdGhpcy5tZXRyaWNUb3RhbFRocm90dGxlZENtZHMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1RvdGFsVGhyb3R0bGVkQ21kcygpO1xuICAgIHRoaXMubWV0cmljVG90YWxDbWRzID0gbWV0cmljRmFjdG9yeS5tZXRyaWNUb3RhbENtZHMoKTtcbiAgICB0aGlzLm1ldHJpY1Rocm90dGxlUmF0ZSA9IG1ldHJpY0ZhY3RvcnkubWV0cmljVGhyb3R0bGVSYXRlKCk7XG4gICAgdGhpcy5tZXRyaWNBdmVyYWdlQ2FjaGVIaXRSYXRlID0gbWV0cmljRmFjdG9yeS5tZXRyaWNBdmVyYWdlQ2FjaGVIaXRSYXRlKCk7XG4gICAgdGhpcy5tZXRyaWNDYWNoZUhpdHMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0NhY2hlSGl0cygpO1xuICAgIHRoaXMubWV0cmljQ2FjaGVNaXNzZXMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0NhY2hlTWlzc2VzKCk7XG5cbiAgICB0aGlzLnRtOTlTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuYXZlcmFnZVN1Y2Nlc3NmdWxSZWFkUmVxdWVzdExhdGVuY3lBbGFybUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy50bTk5U3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5hdmVyYWdlU3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy50aHJvdHRsZVJhdGVBbGFybUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5oaXRSYXRlQWxhcm1Bbm5vdGF0aW9ucyA9IFtdO1xuXG4gICAgY29uc3QgYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKSxcbiAgICApO1xuICAgIHRoaXMuZWxhc3RpQ2FjaGVBbGFybUZhY3RvcnkgPSBuZXcgRWxhc3RpQ2FjaGVBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmxhdGVuY3lBbGFybUZhY3RvcnkgPSBuZXcgTGF0ZW5jeUFsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZFRNOTlTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPVxuICAgICAgICBwcm9wcy5hZGRUTTk5U3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5sYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWNUTTk5U3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeSxcbiAgICAgICAgTGF0ZW5jeVR5cGUuVE05OSxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgXCJTdWNjZXNzZnVsUmVhZFJlcXVlc3RcIixcbiAgICAgICk7XG4gICAgICB0aGlzLnRtOTlTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9ucy5wdXNoKFxuICAgICAgICBjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbixcbiAgICAgICk7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEF2ZXJhZ2VTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPVxuICAgICAgICBwcm9wcy5hZGRBdmVyYWdlU3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5sYXRlbmN5QWxhcm1GYWN0b3J5LmFkZExhdGVuY3lBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWNBdmVyYWdlU3VjY2Vzc2Z1bFJlYWRSZXF1ZXN0TGF0ZW5jeSxcbiAgICAgICAgTGF0ZW5jeVR5cGUuQVZFUkFHRSxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgXCJTdWNjZXNzZnVsUmVhZFJlcXVlc3RcIixcbiAgICAgICk7XG4gICAgICB0aGlzLmF2ZXJhZ2VTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9ucy5wdXNoKFxuICAgICAgICBjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbixcbiAgICAgICk7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZFRNOTlTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0TGF0ZW5jeUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID1cbiAgICAgICAgcHJvcHMuYWRkVE05OVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmxhdGVuY3lBbGFybUZhY3RvcnkuYWRkTGF0ZW5jeUFsYXJtKFxuICAgICAgICB0aGlzLm1ldHJpY1RNOTlTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0TGF0ZW5jeSxcbiAgICAgICAgTGF0ZW5jeVR5cGUuVE05OSxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgXCJTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0XCIsXG4gICAgICApO1xuICAgICAgdGhpcy50bTk5U3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybUFubm90YXRpb25zLnB1c2goXG4gICAgICAgIGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uLFxuICAgICAgKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkQXZlcmFnZVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPVxuICAgICAgICBwcm9wcy5hZGRBdmVyYWdlU3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMubGF0ZW5jeUFsYXJtRmFjdG9yeS5hZGRMYXRlbmN5QWxhcm0oXG4gICAgICAgIHRoaXMubWV0cmljQXZlcmFnZVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5LFxuICAgICAgICBMYXRlbmN5VHlwZS5BVkVSQUdFLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICBcIlN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RcIixcbiAgICAgICk7XG4gICAgICB0aGlzLmF2ZXJhZ2VTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0TGF0ZW5jeUFsYXJtQW5ub3RhdGlvbnMucHVzaChcbiAgICAgICAgY3JlYXRlZEFsYXJtLmFubm90YXRpb24sXG4gICAgICApO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRUaHJvdHRsZVJhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZFRocm90dGxlUmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lbGFzdGlDYWNoZUFsYXJtRmFjdG9yeS5hZGRNYXhUaHJvdHRsZVJhdGVBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWNUaHJvdHRsZVJhdGUsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy50aHJvdHRsZVJhdGVBbGFybUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRIaXRSYXRlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRIaXRSYXRlQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVsYXN0aUNhY2hlQWxhcm1GYWN0b3J5LmFkZE1pbkhpdFJhdGVBbGFybShcbiAgICAgICAgdGhpcy5tZXRyaWNBdmVyYWdlQ2FjaGVIaXRSYXRlLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuaGl0UmF0ZUFsYXJtQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgcHJvcHMudXNlQ3JlYXRlZEFsYXJtcz8uY29uc3VtZSh0aGlzLmNyZWF0ZWRBbGFybXMoKSk7XG4gIH1cblxuICBzdW1tYXJ5V2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICB0aGlzLmNyZWF0ZVByb2Nlc3NpbmdVbml0c1dpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZUNhY2hlSGl0QW5kTWlzc1dpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZVN1Y2Nlc3NmdWxSZWFkTGF0ZW5jeVdpZGdldChcbiAgICAgICAgVGhpcmRXaWR0aCxcbiAgICAgICAgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgICAgdGhpcy5jcmVhdGVTdWNjZXNzZnVsV3JpdGVMYXRlbmN5V2lkZ2V0KFxuICAgICAgICBUaGlyZFdpZHRoLFxuICAgICAgICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgICB0aGlzLmNyZWF0ZUl0ZW1Db3VudFdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgbmV3IFJvdyhcbiAgICAgICAgdGhpcy5jcmVhdGVDYWNoZVNpemVXaWRnZXQoVGhpcmRXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICAgdGhpcy5jcmVhdGVDYWNoZUhpdEFuZE1pc3NXaWRnZXQoXG4gICAgICAgICAgVHdvVGhpcmRzV2lkdGgsXG4gICAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICAgIG5ldyBSb3coXG4gICAgICAgIHRoaXMuY3JlYXRlU3VjY2Vzc2Z1bFJlYWRMYXRlbmN5V2lkZ2V0KFxuICAgICAgICAgIEhhbGZXaWR0aCxcbiAgICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICAgICksXG4gICAgICAgIHRoaXMuY3JlYXRlU3VjY2Vzc2Z1bFdyaXRlTGF0ZW5jeVdpZGdldChcbiAgICAgICAgICBIYWxmV2lkdGgsXG4gICAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICAgIG5ldyBSb3coXG4gICAgICAgIHRoaXMuY3JlYXRlTmV0d29ya1dpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgICB0aGlzLmNyZWF0ZUNhY2hlQ21kc1dpZGdldChUd29UaGlyZHNXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICksXG4gICAgICBuZXcgUm93KFxuICAgICAgICB0aGlzLmNyZWF0ZVByb2Nlc3NpbmdVbml0c1dpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgICB0aGlzLmNyZWF0ZUl0ZW1Db3VudFdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb25zV2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICApLFxuICAgIF07XG4gIH1cblxuICBjcmVhdGVUaXRsZVdpZGdldCgpIHtcbiAgICByZXR1cm4gbmV3IE1vbml0b3JpbmdIZWFkZXJXaWRnZXQoe1xuICAgICAgZmFtaWx5OiBcIlNlcnZlcmxlc3MgRWxhc3RpQ2FjaGVcIixcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlU3VjY2Vzc2Z1bFJlYWRMYXRlbmN5V2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIlN1Y2Nlc3NmdWwgUmVhZCBMYXRlbmN5XCIsXG4gICAgICBsZWZ0OiBbXG4gICAgICAgIHRoaXMubWV0cmljVE05OVN1Y2Nlc3NmdWxSZWFkUmVxdWVzdExhdGVuY3ksXG4gICAgICAgIHRoaXMubWV0cmljQXZlcmFnZVN1Y2Nlc3NmdWxSZWFkUmVxdWVzdExhdGVuY3ksXG4gICAgICBdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pY3Jvc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgIC4uLnRoaXMudG05OVN1Y2Nlc3NmdWxSZWFkUmVxdWVzdExhdGVuY3lBbGFybUFubm90YXRpb25zLFxuICAgICAgICAuLi50aGlzLmF2ZXJhZ2VTdWNjZXNzZnVsUmVhZFJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9ucyxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVTdWNjZXNzZnVsV3JpdGVMYXRlbmN5V2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIlN1Y2Nlc3NmdWwgV3JpdGUgTGF0ZW5jeVwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLm1ldHJpY1RNOTlTdWNjZXNzZnVsV3JpdGVSZXF1ZXN0TGF0ZW5jeSxcbiAgICAgICAgdGhpcy5tZXRyaWNBdmVyYWdlU3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3ksXG4gICAgICBdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pY3Jvc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiBbXG4gICAgICAgIC4uLnRoaXMudG05OVN1Y2Nlc3NmdWxXcml0ZVJlcXVlc3RMYXRlbmN5QWxhcm1Bbm5vdGF0aW9ucyxcbiAgICAgICAgLi4udGhpcy5hdmVyYWdlU3VjY2Vzc2Z1bFdyaXRlUmVxdWVzdExhdGVuY3lBbGFybUFubm90YXRpb25zLFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNhY2hlU2l6ZVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDYWNoZSBTaXplXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5tZXRyaWNBdmVyYWdlQ2FjaGVTaXplXSxcbiAgICAgIGxlZnRZQXhpczogU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQ2FjaGVIaXRBbmRNaXNzV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkhpdHMvTWlzc2VzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5tZXRyaWNBdmVyYWdlQ2FjaGVIaXRSYXRlXSxcbiAgICAgIGxlZnRZQXhpczogUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5oaXRSYXRlQWxhcm1Bbm5vdGF0aW9ucyxcbiAgICAgIHJpZ2h0OiBbdGhpcy5tZXRyaWNDYWNoZUhpdHMsIHRoaXMubWV0cmljQ2FjaGVNaXNzZXNdLFxuICAgICAgcmlnaHRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVDYWNoZUNtZHNXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiQ29tbWFuZHNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1ldHJpY1Rocm90dGxlUmF0ZV0sXG4gICAgICBsZWZ0WUF4aXM6IFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMudGhyb3R0bGVSYXRlQWxhcm1Bbm5vdGF0aW9ucyxcbiAgICAgIHJpZ2h0OiBbdGhpcy5tZXRyaWNUb3RhbENtZHMsIHRoaXMubWV0cmljVG90YWxDbWRzXSxcbiAgICAgIHJpZ2h0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTmV0d29ya1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJJT1wiLFxuICAgICAgbGVmdDogW3RoaXMubWV0cmljTmV0d29ya0J5dGVzSW4sIHRoaXMubWV0cmljTmV0d29ya0J5dGVzT3V0XSxcbiAgICAgIGxlZnRZQXhpczogU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlUHJvY2Vzc2luZ1VuaXRzV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIlByb2Nlc3NpbmcgVW5pdHNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1ldHJpY01heEVsYXN0aUNhY2hlUHJvY2Vzc2luZ1VuaXRzXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVJdGVtQ291bnRXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiSXRlbXNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLm1ldHJpY01heEl0ZW1Db3VudF0sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgcmlnaHQ6IFt0aGlzLm1ldHJpY0V2aWN0aW9uc10sXG4gICAgICByaWdodFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNvbm5lY3Rpb25zV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNvbm5lY3Rpb25zXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5tZXRyaWNBdmVyYWdlQ29ubmVjdGlvbnNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxufVxuIl19