cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
288 lines • 59.6 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RdsClusterMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const RdsClusterMetricFactory_1 = require("./RdsClusterMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
const DefaultLatencyTypesToRender = [
common_1.LatencyType.P50,
common_1.LatencyType.P90,
common_1.LatencyType.P99,
];
class RdsClusterMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
const metricFactory = new RdsClusterMetricFactory_1.RdsClusterMetricFactory(scope.createMetricFactory(), props);
this.connectionsMetric = metricFactory.metricTotalConnectionCount();
this.diskSpaceUsageMetric = metricFactory.metricDiskSpaceUsageInPercent();
this.cpuUsageMetric = metricFactory.metricAverageCpuUsageInPercent();
this.readIopsMetric = metricFactory.metricReadIOPS();
this.writeIopsMetric = metricFactory.metricWriteIOPS();
this.selectLatencyMetrics = {};
this.insertLatencyMetrics = {};
this.updateLatencyMetrics = {};
this.deleteLatencyMetrics = {};
this.commitLatencyMetrics = {};
this.latencyTypesToRender = [
...(props.latencyTypesToRender ?? DefaultLatencyTypesToRender),
];
Object.values(common_1.LatencyType).forEach((latencyType) => {
this.selectLatencyMetrics[latencyType] =
metricFactory.metricSelectLatencyInMillis(latencyType);
this.insertLatencyMetrics[latencyType] =
metricFactory.metricInsertLatencyInMillis(latencyType);
this.updateLatencyMetrics[latencyType] =
metricFactory.metricUpdateLatencyInMillis(latencyType);
this.deleteLatencyMetrics[latencyType] =
metricFactory.metricDeleteLatencyInMillis(latencyType);
this.commitLatencyMetrics[latencyType] =
metricFactory.metricCommitLatencyInMillis(latencyType);
});
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
fallbackConstructName: metricFactory.clusterIdentifier,
namedConstruct: props.cluster,
});
this.title = namingStrategy.resolveHumanReadableName();
this.url = scope
.createAwsConsoleUrlFactory()
.getRdsClusterUrl(metricFactory.clusterIdentifier);
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.usageAlarmFactory = new common_1.UsageAlarmFactory(alarmFactory);
this.connectionAlarmFactory = new common_1.ConnectionAlarmFactory(alarmFactory);
this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(alarmFactory);
this.usageAnnotations = [];
this.connectionAnnotations = [];
this.readLatencyAnnotations = [];
this.writeLatencyAnnotations = [];
this.iopsAnnotations = [];
for (const disambiguator in props.addDiskSpaceUsageAlarm) {
const alarmProps = props.addDiskSpaceUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxDiskUsagePercentAlarm(this.diskSpaceUsageMetric, alarmProps, disambiguator);
this.usageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addCpuUsageAlarm) {
const alarmProps = props.addCpuUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.cpuUsageMetric, alarmProps, disambiguator);
this.usageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMinConnectionCountAlarm) {
const alarmProps = props.addMinConnectionCountAlarm[disambiguator];
const createdAlarm = this.connectionAlarmFactory.addMinConnectionCountAlarm(this.connectionsMetric, alarmProps, disambiguator);
this.connectionAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxConnectionCountAlarm) {
const alarmProps = props.addMaxConnectionCountAlarm[disambiguator];
const createdAlarm = this.connectionAlarmFactory.addMaxConnectionCountAlarm(this.connectionsMetric, alarmProps, disambiguator);
this.connectionAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
const selectLatencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addSelectLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addSelectLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addSelectLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addSelectLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addSelectLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addSelectLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addSelectLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addSelectLatencyP100Alarm,
[common_1.LatencyType.AVERAGE]: props.addSelectLatencyAverageAlarm,
};
const insertLatencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addInsertLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addInsertLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addInsertLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addInsertLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addInsertLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addInsertLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addInsertLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addInsertLatencyP100Alarm,
[common_1.LatencyType.AVERAGE]: props.addInsertLatencyAverageAlarm,
};
const updateLatencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addUpdateLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addUpdateLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addUpdateLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addUpdateLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addUpdateLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addUpdateLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addUpdateLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addUpdateLatencyP100Alarm,
[common_1.LatencyType.AVERAGE]: props.addUpdateLatencyAverageAlarm,
};
const deleteLatencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addDeleteLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addDeleteLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addDeleteLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addDeleteLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addDeleteLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addDeleteLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addDeleteLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addDeleteLatencyP100Alarm,
[common_1.LatencyType.AVERAGE]: props.addDeleteLatencyAverageAlarm,
};
const commitLatencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addCommitLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addCommitLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addCommitLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addCommitLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addCommitLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addCommitLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addCommitLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addCommitLatencyP100Alarm,
[common_1.LatencyType.AVERAGE]: props.addCommitLatencyAverageAlarm,
};
for (const [latencyType, alarmDefinition] of Object.entries(selectLatencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.selectLatencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Select");
this.readLatencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const [latencyType, alarmDefinition] of Object.entries(insertLatencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.insertLatencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Insert");
this.writeLatencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const [latencyType, alarmDefinition] of Object.entries(updateLatencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.updateLatencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Update");
this.writeLatencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const [latencyType, alarmDefinition] of Object.entries(deleteLatencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.deleteLatencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Delete");
this.writeLatencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const [latencyType, alarmDefinition] of Object.entries(commitLatencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.commitLatencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator, "Commit");
this.writeLatencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const disambiguator in props.addReadIOPSAlarm) {
const alarmProps = props.addReadIOPSAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxReadIOPSAlarm(this.readIopsMetric, alarmProps, disambiguator);
this.usageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addWriteIOPSAlarm) {
const alarmProps = props.addWriteIOPSAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxWriteIOPSAlarm(this.writeIopsMetric, alarmProps, disambiguator);
this.usageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
this.createCpuAndDiskUsageWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight),
this.createConnectionsWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight),
this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight),
this.createIOPSWidget(common_1.QuarterWidth, common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
return [
this.createTitleWidget(),
this.createCpuAndDiskUsageWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createConnectionsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createIOPSWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "RDS Cluster",
title: this.title,
goToLinkUrl: this.url,
});
}
createCpuAndDiskUsageWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "CPU/Disk Usage",
left: [this.cpuUsageMetric, this.diskSpaceUsageMetric],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.usageAnnotations,
});
}
createConnectionsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Connections",
left: [this.connectionsMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.connectionAnnotations,
});
}
createLatencyWidget(width, height) {
const left = Array.from(new Set(this.latencyTypesToRender))
.sort()
.reduce((metrics, type) => {
metrics.push(this.selectLatencyMetrics[type], this.insertLatencyMetrics[type], this.updateLatencyMetrics[type], this.deleteLatencyMetrics[type], this.commitLatencyMetrics[type]);
return metrics;
}, []);
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Query Duration",
left,
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: [
...this.readLatencyAnnotations,
...this.writeLatencyAnnotations,
],
});
}
createIOPSWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "IOPS",
left: [this.readIopsMetric, this.writeIopsMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.iopsAnnotations,
});
}
}
exports.RdsClusterMonitoring = RdsClusterMonitoring;
_a = JSII_RTTI_SYMBOL_1;
RdsClusterMonitoring[_a] = { fqn: "cdk-monitoring-constructs.RdsClusterMonitoring", version: "10.0.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmRzQ2x1c3Rlck1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJSZHNDbHVzdGVyTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUlvQztBQUVwQyx1RUFHbUM7QUFDbkMseUNBb0JzQjtBQUN0QiwrQ0FHeUI7QUFFekIsTUFBTSwyQkFBMkIsR0FBRztJQUNsQyxvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7Q0FDaEIsQ0FBQztBQWdGRixNQUFhLG9CQUFxQixTQUFRLG1CQUFVO0lBMkJsRCxZQUFZLEtBQXNCLEVBQUUsS0FBZ0M7UUFDbEUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQixNQUFNLGFBQWEsR0FBRyxJQUFJLGlEQUF1QixDQUMvQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsRUFDM0IsS0FBSyxDQUNOLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsYUFBYSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDcEUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGFBQWEsQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO1FBQzFFLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDLDhCQUE4QixFQUFFLENBQUM7UUFDckUsSUFBSSxDQUFDLGNBQWMsR0FBRyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDckQsSUFBSSxDQUFDLGVBQWUsR0FBRyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFdkQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxvQkFBb0IsR0FBRztZQUMxQixHQUFHLENBQUMsS0FBSyxDQUFDLG9CQUFvQixJQUFJLDJCQUEyQixDQUFDO1NBQy9ELENBQUM7UUFFRixNQUFNLENBQUMsTUFBTSxDQUFDLG9CQUFXLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNqRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxDQUFDO2dCQUNwQyxhQUFhLENBQUMsMkJBQTJCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQztnQkFDcEMsYUFBYSxDQUFDLDJCQUEyQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUM7Z0JBQ3BDLGFBQWEsQ0FBQywyQkFBMkIsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxDQUFDO2dCQUNwQyxhQUFhLENBQUMsMkJBQTJCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQztnQkFDcEMsYUFBYSxDQUFDLDJCQUEyQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxjQUFjLEdBQUcsSUFBSSxvQ0FBd0IsQ0FBQztZQUNsRCxHQUFHLEtBQUs7WUFDUixxQkFBcUIsRUFBRSxhQUFhLENBQUMsaUJBQWlCO1lBQ3RELGNBQWMsRUFBRSxLQUFLLENBQUMsT0FBTztTQUM5QixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxHQUFHLEdBQUcsS0FBSzthQUNiLDBCQUEwQixFQUFFO2FBQzVCLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FDMUMsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQzFDLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSwwQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSwrQkFBc0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSw0QkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVqRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLHNCQUFzQixHQUFHLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBRTFCLEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDekQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQywyQkFBMkIsQ0FDckUsSUFBSSxDQUFDLG9CQUFvQixFQUN6QixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ25ELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN6RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsMEJBQTBCLENBQ3BFLElBQUksQ0FBQyxjQUFjLEVBQ25CLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUVELEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLDBCQUEwQixFQUFFLENBQUM7WUFDN0QsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLDBCQUEwQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sWUFBWSxHQUNoQixJQUFJLENBQUMsc0JBQXNCLENBQUMsMEJBQTBCLENBQ3BELElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0osSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztZQUM3RCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsMEJBQTBCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDbkUsTUFBTSxZQUFZLEdBQ2hCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQywwQkFBMEIsQ0FDcEQsSUFBSSxDQUFDLGlCQUFpQixFQUN0QixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDSixJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCxNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsMEJBQTBCO1lBQ3JELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLENBQUMsNEJBQTRCO1NBQzFELENBQUM7UUFFRixNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsMEJBQTBCO1lBQ3JELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLENBQUMsNEJBQTRCO1NBQzFELENBQUM7UUFFRixNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsMEJBQTBCO1lBQ3JELENBQUMsb0JBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMseUJBQXlCO1lBQ25ELENBQUMsb0JBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLENBQUMsNEJBQTRCO1NBQzFELENBQUM7UUFFRixNQUFNLDZCQUE2QixHQUFHO1lBQ3BDLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ2pELENBQUMs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LENBQUM7SUFDTCxDQUFDOztBQXBaSCxvREFxWkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElXaWRnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuXG5pbXBvcnQge1xuICBSZHNDbHVzdGVyTWV0cmljRmFjdG9yeSxcbiAgUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbn0gZnJvbSBcIi4vUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnlcIjtcbmltcG9ydCB7XG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvbm5lY3Rpb25BbGFybUZhY3RvcnksXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBIaWdoQ29ubmVjdGlvbkNvdW50VGhyZXNob2xkLFxuICBMYXRlbmN5QWxhcm1GYWN0b3J5LFxuICBMYXRlbmN5VGhyZXNob2xkLFxuICBMYXRlbmN5VHlwZSxcbiAgTG93Q29ubmVjdGlvbkNvdW50VGhyZXNob2xkLFxuICBNYXhVc2FnZUNvdW50VGhyZXNob2xkLFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIFBlcmNlbnRhZ2VBeGlzRnJvbVplcm9Ub0h1bmRyZWQsXG4gIFF1YXJ0ZXJXaWR0aCxcbiAgVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbiAgVXNhZ2VBbGFybUZhY3RvcnksXG4gIFVzYWdlVGhyZXNob2xkLFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0LFxuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcblxuY29uc3QgRGVmYXVsdExhdGVuY3lUeXBlc1RvUmVuZGVyID0gW1xuICBMYXRlbmN5VHlwZS5QNTAsXG4gIExhdGVuY3lUeXBlLlA5MCxcbiAgTGF0ZW5jeVR5cGUuUDk5LFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBSZHNDbHVzdGVyTW9uaXRvcmluZ09wdGlvbnMgZXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkRGlza1NwYWNlVXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ3B1VXNhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIFVzYWdlVGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTWluQ29ubmVjdGlvbkNvdW50QWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIExvd0Nvbm5lY3Rpb25Db3VudFRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRNYXhDb25uZWN0aW9uQ291bnRBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgSGlnaENvbm5lY3Rpb25Db3VudFRocmVzaG9sZFxuICA+O1xuICByZWFkb25seSBhZGRSZWFkSU9QU0FsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4VXNhZ2VDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFdyaXRlSU9QU0FsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4VXNhZ2VDb3VudFRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkU2VsZWN0TGF0ZW5jeVA1MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQNzBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRTZWxlY3RMYXRlbmN5UDkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkU2VsZWN0TGF0ZW5jeVA5NUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRTZWxlY3RMYXRlbmN5UDk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQOTk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFNlbGVjdExhdGVuY3lQMTAwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkU2VsZWN0TGF0ZW5jeUF2ZXJhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEluc2VydExhdGVuY3lQNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW5zZXJ0TGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEluc2VydExhdGVuY3lQOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW5zZXJ0TGF0ZW5jeVA5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnNlcnRMYXRlbmN5UDEwMEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEluc2VydExhdGVuY3lBdmVyYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRVcGRhdGVMYXRlbmN5UDUwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVA3MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFVwZGF0ZUxhdGVuY3lQOTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRVcGRhdGVMYXRlbmN5UDk1QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVA5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZFVwZGF0ZUxhdGVuY3lQOTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVA5OTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkVXBkYXRlTGF0ZW5jeVAxMDBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRVcGRhdGVMYXRlbmN5QXZlcmFnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkRGVsZXRlTGF0ZW5jeVA1MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQNzBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGREZWxldGVMYXRlbmN5UDkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRGVsZXRlTGF0ZW5jeVA5NUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGREZWxldGVMYXRlbmN5UDk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQOTk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZERlbGV0ZUxhdGVuY3lQMTAwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkRGVsZXRlTGF0ZW5jeUF2ZXJhZ2VBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZENvbW1pdExhdGVuY3lQNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ29tbWl0TGF0ZW5jeVA5MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZENvbW1pdExhdGVuY3lQOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkQ29tbWl0TGF0ZW5jeVA5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRDb21taXRMYXRlbmN5UDEwMEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZENvbW1pdExhdGVuY3lBdmVyYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcblxuICAvKipcbiAgICogWW91IGNhbiBzcGVjaWZ5IHdoYXQgbGF0ZW5jeSB0eXBlcyB5b3Ugd2FudCB0byBiZSByZW5kZXJlZCBpbiB0aGUgZGFzaGJvYXJkcy5cbiAgICogTm90ZTogYW55IGxhdGVuY3kgdHlwZSB3aXRoIGFuIGFsYXJtIHdpbGwgYmUgYWxzbyBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICAgKiBJZiB0aGUgbGlzdCBpcyB1bmRlZmluZWQsIGRlZmF1bHQgdmFsdWVzIHdpbGwgYmUgc2hvd24uXG4gICAqIElmIHRoZSBsaXN0IGlzIGVtcHR5LCBvbmx5IHRoZSBsYXRlbmN5IHR5cGVzIHdpdGggYW4gYWxhcm0gd2lsbCBiZSBzaG93biAoaWYgYW55KS5cbiAgICogQGRlZmF1bHQgLSBwOTAgZm9yIGFsbCBvcGVyYXRpb24gdHlwZXNcbiAgICovXG4gIHJlYWRvbmx5IGxhdGVuY3lUeXBlc1RvUmVuZGVyPzogTGF0ZW5jeVR5cGVbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZHNDbHVzdGVyTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBSZHNDbHVzdGVyTW9uaXRvcmluZ09wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIFJkc0NsdXN0ZXJNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVybD86IHN0cmluZztcblxuICByZWFkb25seSB1c2FnZUFsYXJtRmFjdG9yeTogVXNhZ2VBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25BbGFybUZhY3Rvcnk6IENvbm5lY3Rpb25BbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGxhdGVuY3lBbGFybUZhY3Rvcnk6IExhdGVuY3lBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IHVzYWdlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25Bbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgcmVhZExhdGVuY3lBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgd3JpdGVMYXRlbmN5QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGlvcHNBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICByZWFkb25seSBjb25uZWN0aW9uc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgZGlza1NwYWNlVXNhZ2VNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGNwdVVzYWdlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSByZWFkSW9wc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgd3JpdGVJb3BzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIC8vIGtleXMgYXJlIExhdGVuY3lUeXBlLCBidXQgSlNJSSBkb2Vzbid0IGxpa2Ugbm9uLXN0cmluZyB0eXBlc1xuICByZWFkb25seSBzZWxlY3RMYXRlbmN5TWV0cmljczogUmVjb3JkPHN0cmluZywgTWV0cmljV2l0aEFsYXJtU3VwcG9ydD47XG4gIHJlYWRvbmx5IGluc2VydExhdGVuY3lNZXRyaWNzOiBSZWNvcmQ8c3RyaW5nLCBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0PjtcbiAgcmVhZG9ubHkgdXBkYXRlTGF0ZW5jeU1ldHJpY3M6IFJlY29yZDxzdHJpbmcsIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ+O1xuICByZWFkb25seSBkZWxldGVMYXRlbmN5TWV0cmljczogUmVjb3JkPHN0cmluZywgTWV0cmljV2l0aEFsYXJtU3VwcG9ydD47XG4gIHJlYWRvbmx5IGNvbW1pdExhdGVuY3lNZXRyaWNzOiBSZWNvcmQ8c3RyaW5nLCBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0PjtcbiAgcmVhZG9ubHkgbGF0ZW5jeVR5cGVzVG9SZW5kZXI6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBNb25pdG9yaW5nU2NvcGUsIHByb3BzOiBSZHNDbHVzdGVyTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgUmRzQ2x1c3Rlck1ldHJpY0ZhY3RvcnkoXG4gICAgICBzY29wZS5jcmVhdGVNZXRyaWNGYWN0b3J5KCksXG4gICAgICBwcm9wcyxcbiAgICApO1xuICAgIHRoaXMuY29ubmVjdGlvbnNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1RvdGFsQ29ubmVjdGlvbkNvdW50KCk7XG4gICAgdGhpcy5kaXNrU3BhY2VVc2FnZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljRGlza1NwYWNlVXNhZ2VJblBlcmNlbnQoKTtcbiAgICB0aGlzLmNwdVVzYWdlTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNBdmVyYWdlQ3B1VXNhZ2VJblBlcmNlbnQoKTtcbiAgICB0aGlzLnJlYWRJb3BzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNSZWFkSU9QUygpO1xuICAgIHRoaXMud3JpdGVJb3BzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNXcml0ZUlPUFMoKTtcblxuICAgIHRoaXMuc2VsZWN0TGF0ZW5jeU1ldHJpY3MgPSB7fTtcbiAgICB0aGlzLmluc2VydExhdGVuY3lNZXRyaWNzID0ge307XG4gICAgdGhpcy51cGRhdGVMYXRlbmN5TWV0cmljcyA9IHt9O1xuICAgIHRoaXMuZGVsZXRlTGF0ZW5jeU1ldHJpY3MgPSB7fTtcbiAgICB0aGlzLmNvbW1pdExhdGVuY3lNZXRyaWNzID0ge307XG4gICAgdGhpcy5sYXRlbmN5VHlwZXNUb1JlbmRlciA9IFtcbiAgICAgIC4uLihwcm9wcy5sYXRlbmN5VHlwZXNUb1JlbmRlciA/PyBEZWZhdWx0TGF0ZW5jeVR5cGVzVG9SZW5kZXIpLFxuICAgIF07XG5cbiAgICBPYmplY3QudmFsdWVzKExhdGVuY3lUeXBlKS5mb3JFYWNoKChsYXRlbmN5VHlwZSkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RMYXRlbmN5TWV0cmljc1tsYXRlbmN5VHlwZV0gPVxuICAgICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1NlbGVjdExhdGVuY3lJbk1pbGxpcyhsYXRlbmN5VHlwZSk7XG4gICAgICB0aGlzLmluc2VydExhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlXSA9XG4gICAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljSW5zZXJ0TGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlKTtcbiAgICAgIHRoaXMudXBkYXRlTGF0ZW5jeU1ldHJpY3NbbGF0ZW5jeVR5cGVdID1cbiAgICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNVcGRhdGVMYXRlbmN5SW5NaWxsaXMobGF0ZW5jeVR5cGUpO1xuICAgICAgdGhpcy5kZWxldGVMYXRlbmN5TWV0cmljc1tsYXRlbmN5VHlwZV0gPVxuICAgICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0RlbGV0ZUxhdGVuY3lJbk1pbGxpcyhsYXRlbmN5VHlwZSk7XG4gICAgICB0aGlzLmNvbW1pdExhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlXSA9XG4gICAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ29tbWl0TGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGZhbGxiYWNrQ29uc3RydWN0TmFtZTogbWV0cmljRmFjdG9yeS5jbHVzdGVySWRlbnRpZmllcixcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5jbHVzdGVyLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcbiAgICB0aGlzLnVybCA9IHNjb3BlXG4gICAgICAuY3JlYXRlQXdzQ29uc29sZVVybEZhY3RvcnkoKVxuICAgICAgLmdldFJkc0NsdXN0ZXJVcmwobWV0cmljRmFjdG9yeS5jbHVzdGVySWRlbnRpZmllcik7XG4gICAgY29uc3QgYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKSxcbiAgICApO1xuICAgIHRoaXMudXNhZ2VBbGFybUZhY3RvcnkgPSBuZXcgVXNhZ2VBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmNvbm5lY3Rpb25BbGFybUZhY3RvcnkgPSBuZXcgQ29ubmVjdGlvbkFsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuICAgIHRoaXMubGF0ZW5jeUFsYXJtRmFjdG9yeSA9IG5ldyBMYXRlbmN5QWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG5cbiAgICB0aGlzLnVzYWdlQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmNvbm5lY3Rpb25Bbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMucmVhZExhdGVuY3lBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMud3JpdGVMYXRlbmN5QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmlvcHNBbm5vdGF0aW9ucyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZERpc2tTcGFjZVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGREaXNrU3BhY2VVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhEaXNrVXNhZ2VQZXJjZW50QWxhcm0oXG4gICAgICAgIHRoaXMuZGlza1NwYWNlVXNhZ2VNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy51c2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDcHVVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkQ3B1VXNhZ2VBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMudXNhZ2VBbGFybUZhY3RvcnkuYWRkTWF4Q3B1VXNhZ2VQZXJjZW50QWxhcm0oXG4gICAgICAgIHRoaXMuY3B1VXNhZ2VNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy51c2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRNaW5Db25uZWN0aW9uQ291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZE1pbkNvbm5lY3Rpb25Db3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID1cbiAgICAgICAgdGhpcy5jb25uZWN0aW9uQWxhcm1GYWN0b3J5LmFkZE1pbkNvbm5lY3Rpb25Db3VudEFsYXJtKFxuICAgICAgICAgIHRoaXMuY29ubmVjdGlvbnNNZXRyaWMsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1xuICAgICAgdGhpcy5jb25uZWN0aW9uQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZE1heENvbm5lY3Rpb25Db3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWF4Q29ubmVjdGlvbkNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25BbGFybUZhY3RvcnkuYWRkTWF4Q29ubmVjdGlvbkNvdW50QWxhcm0oXG4gICAgICAgICAgdGhpcy5jb25uZWN0aW9uc01ldHJpYyxcbiAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICk7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25Bbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RMYXRlbmN5QWxhcm1EZWZpbml0aW9ucyA9IHtcbiAgICAgIFtMYXRlbmN5VHlwZS5QNTBdOiBwcm9wcy5hZGRTZWxlY3RMYXRlbmN5UDUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDcwXTogcHJvcHMuYWRkU2VsZWN0TGF0ZW5jeVA3MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5MF06IHByb3BzLmFkZFNlbGVjdExhdGVuY3lQOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTVdOiBwcm9wcy5hZGRTZWxlY3RMYXRlbmN5UDk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5XTogcHJvcHMuYWRkU2VsZWN0TGF0ZW5jeVA5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTldOiBwcm9wcy5hZGRTZWxlY3RMYXRlbmN5UDk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTk5XTogcHJvcHMuYWRkU2VsZWN0TGF0ZW5jeVA5OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDEwMF06IHByb3BzLmFkZFNlbGVjdExhdGVuY3lQMTAwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuQVZFUkFHRV06IHByb3BzLmFkZFNlbGVjdExhdGVuY3lBdmVyYWdlQWxhcm0sXG4gICAgfTtcblxuICAgIGNvbnN0IGluc2VydExhdGVuY3lBbGFybURlZmluaXRpb25zID0ge1xuICAgICAgW0xhdGVuY3lUeXBlLlA1MF06IHByb3BzLmFkZEluc2VydExhdGVuY3lQNTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QNzBdOiBwcm9wcy5hZGRJbnNlcnRMYXRlbmN5UDcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDkwXTogcHJvcHMuYWRkSW5zZXJ0TGF0ZW5jeVA5MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5NV06IHByb3BzLmFkZEluc2VydExhdGVuY3lQOTVBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTldOiBwcm9wcy5hZGRJbnNlcnRMYXRlbmN5UDk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OV06IHByb3BzLmFkZEluc2VydExhdGVuY3lQOTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OTldOiBwcm9wcy5hZGRJbnNlcnRMYXRlbmN5UDk5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QMTAwXTogcHJvcHMuYWRkSW5zZXJ0TGF0ZW5jeVAxMDBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5BVkVSQUdFXTogcHJvcHMuYWRkSW5zZXJ0TGF0ZW5jeUF2ZXJhZ2VBbGFybSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlTGF0ZW5jeUFsYXJtRGVmaW5pdGlvbnMgPSB7XG4gICAgICBbTGF0ZW5jeVR5cGUuUDUwXTogcHJvcHMuYWRkVXBkYXRlTGF0ZW5jeVA1MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA3MF06IHByb3BzLmFkZFVwZGF0ZUxhdGVuY3lQNzBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTBdOiBwcm9wcy5hZGRVcGRhdGVMYXRlbmN5UDkwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk1XTogcHJvcHMuYWRkVXBkYXRlTGF0ZW5jeVA5NUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OV06IHByb3BzLmFkZFVwZGF0ZUxhdGVuY3lQOTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTk5XTogcHJvcHMuYWRkVXBkYXRlTGF0ZW5jeVA5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTk5OV06IHByb3BzLmFkZFVwZGF0ZUxhdGVuY3lQOTk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlAxMDBdOiBwcm9wcy5hZGRVcGRhdGVMYXRlbmN5UDEwMEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLkFWRVJBR0VdOiBwcm9wcy5hZGRVcGRhdGVMYXRlbmN5QXZlcmFnZUFsYXJtLFxuICAgIH07XG5cbiAgICBjb25zdCBkZWxldGVMYXRlbmN5QWxhcm1EZWZpbml0aW9ucyA9IHtcbiAgICAgIFtMYXRlbmN5VHlwZS5QNTBdOiBwcm9wcy5hZGREZWxldGVMYXRlbmN5UDUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDcwXTogcHJvcHMuYWRkRGVsZXRlTGF0ZW5jeVA3MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5MF06IHByb3BzLmFkZERlbGV0ZUxhdGVuY3lQOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTVdOiBwcm9wcy5hZGREZWxldGVMYXRlbmN5UDk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5XTogcHJvcHMuYWRkRGVsZXRlTGF0ZW5jeVA5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTldOiBwcm9wcy5hZGREZWxldGVMYXRlbmN5UDk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTk5XTogcHJvcHMuYWRkRGVsZXRlTGF0ZW5jeVA5OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDEwMF06IHByb3BzLmFkZERlbGV0ZUxhdGVuY3lQMTAwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuQVZFUkFHRV06IHByb3BzLmFkZERlbGV0ZUxhdGVuY3lBdmVyYWdlQWxhcm0sXG4gICAgfTtcblxuICAgIGNvbnN0IGNvbW1pdExhdGVuY3lBbGFybURlZmluaXRpb25zID0ge1xuICAgICAgW0xhdGVuY3lUeXBlLlA1MF06IHByb3BzLmFkZENvbW1pdExhdGVuY3lQNTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QNzBdOiBwcm9wcy5hZGRDb21taXRMYXRlbmN5UDcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDkwXTogcHJvcHMuYWRkQ29tbWl0TGF0ZW5jeVA5MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5NV06IHByb3BzLmFkZENvbW1pdExhdGVuY3lQOTVBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTldOiBwcm9wcy5hZGRDb21taXRMYXRlbmN5UDk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OV06IHByb3BzLmFkZENvbW1pdExhdGVuY3lQOTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OTldOiBwcm9wcy5hZGRDb21taXRMYXRlbmN5UDk5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QMTAwXTogcHJvcHMuYWRkQ29tbWl0TGF0ZW5jeVAxMDBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5BVkVSQUdFXTogcHJvcHMuYWRkQ29tbWl0TGF0ZW5jeUF2ZXJhZ2VBbGFybSxcbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBbbGF0ZW5jeVR5cGUsIGFsYXJtRGVmaW5pdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMoXG4gICAgICBzZWxlY3RMYXRlbmN