cdk-monitoring-constructs
Version:
[](https://gitpod.io/#https://github.com/cdklabs/cdk-monitoring-constructs) [](https://badge
220 lines • 44.4 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiGatewayV2HttpApiMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
const ApiGatewayV2HttpApiMetricFactory_1 = require("./ApiGatewayV2HttpApiMetricFactory");
const DefaultLatencyTypesToRender = [
common_1.LatencyType.P50,
common_1.LatencyType.P90,
common_1.LatencyType.P99,
];
class ApiGatewayV2HttpApiMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
namedConstruct: props.api,
fallbackConstructName: props.api.apiId,
humanReadableName: `${props.api.apiId} ${props.apiStage ?? "$default"} ${props.apiMethod ?? ""} ${props.apiResource ?? ""}`,
});
this.title = namingStrategy.resolveHumanReadableName();
this.alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.errorAlarmFactory = new common_1.ErrorAlarmFactory(this.alarmFactory);
this.tpsAlarmFactory = new common_1.TpsAlarmFactory(this.alarmFactory);
this.latencyAlarmFactory = new common_1.LatencyAlarmFactory(this.alarmFactory);
this.tpsAnnotations = [];
this.latencyAnnotations = [];
this.errorCountAnnotations = [];
this.errorRateAnnotations = [];
const metricFactory = new ApiGatewayV2HttpApiMetricFactory_1.ApiGatewayV2HttpApiMetricFactory(scope.createMetricFactory(), props);
this.tpsMetric = metricFactory.metricTps();
this.latencyMetrics = {};
this.integrationLatencyMetrics = {};
this.latencyTypesToRender = [
...(props.latencyTypesToRender ?? DefaultLatencyTypesToRender),
];
this.error4xxCountMetric = metricFactory.metric4xxCount();
this.error4xxRateMetric = metricFactory.metric4xxRate();
this.error5xxCountMetric = metricFactory.metric5xxCount();
this.error5xxRateMetric = metricFactory.metric5xxRate();
const latencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addLatencyP100Alarm,
[common_1.LatencyType.TM50]: props.addLatencyTM50Alarm,
[common_1.LatencyType.TM70]: props.addLatencyTM70Alarm,
[common_1.LatencyType.TM90]: props.addLatencyTM90Alarm,
[common_1.LatencyType.TM95]: props.addLatencyTM95Alarm,
[common_1.LatencyType.TM99]: props.addLatencyTM99Alarm,
[common_1.LatencyType.TM999]: props.addLatencyTM999Alarm,
[common_1.LatencyType.TM9999]: props.addLatencyTM9999Alarm,
[common_1.LatencyType.AVERAGE]: props.addLatencyAverageAlarm,
};
const integrationLatencyAlarmDefinitions = {
[common_1.LatencyType.P50]: props.addIntegrationLatencyP50Alarm,
[common_1.LatencyType.P70]: props.addIntegrationLatencyP70Alarm,
[common_1.LatencyType.P90]: props.addIntegrationLatencyP90Alarm,
[common_1.LatencyType.P95]: props.addIntegrationLatencyP95Alarm,
[common_1.LatencyType.P99]: props.addIntegrationLatencyP99Alarm,
[common_1.LatencyType.P999]: props.addIntegrationLatencyP999Alarm,
[common_1.LatencyType.P9999]: props.addIntegrationLatencyP9999Alarm,
[common_1.LatencyType.P100]: props.addIntegrationLatencyP100Alarm,
[common_1.LatencyType.TM50]: props.addIntegrationLatencyTM50Alarm,
[common_1.LatencyType.TM70]: props.addIntegrationLatencyTM70Alarm,
[common_1.LatencyType.TM90]: props.addIntegrationLatencyTM90Alarm,
[common_1.LatencyType.TM95]: props.addIntegrationLatencyTM95Alarm,
[common_1.LatencyType.TM99]: props.addIntegrationLatencyTM99Alarm,
[common_1.LatencyType.TM999]: props.addIntegrationLatencyTM999Alarm,
[common_1.LatencyType.TM9999]: props.addIntegrationLatencyTM9999Alarm,
[common_1.LatencyType.AVERAGE]: props.addIntegrationLatencyAverageAlarm,
};
Object.values(common_1.LatencyType).forEach((latencyType) => {
this.latencyMetrics[latencyType] =
metricFactory.metricLatencyInMillis(latencyType);
this.integrationLatencyMetrics[latencyType] =
metricFactory.metricIntegrationLatencyInMillis(latencyType);
});
for (const [latencyType, alarmDefinition] of Object.entries(latencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.latencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const [latencyType, alarmDefinition] of Object.entries(integrationLatencyAlarmDefinitions)) {
for (const disambiguator in alarmDefinition) {
const alarmProps = alarmDefinition[disambiguator];
const latencyTypeEnum = latencyType;
const metric = this.integrationLatencyMetrics[latencyTypeEnum];
const createdAlarm = this.latencyAlarmFactory.addIntegrationLatencyAlarm(metric, latencyTypeEnum, alarmProps, disambiguator);
this.latencyAnnotations.push(createdAlarm.annotation);
this.latencyTypesToRender.push(latencyTypeEnum);
this.addAlarm(createdAlarm);
}
}
for (const disambiguator in props.add4xxCountAlarm) {
const alarmProps = props.add4xxCountAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.error4xxCountMetric, common_1.ErrorType.ERROR, alarmProps, disambiguator);
this.errorCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.add4xxRateAlarm) {
const alarmProps = props.add4xxRateAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.error4xxRateMetric, common_1.ErrorType.ERROR, alarmProps, disambiguator);
this.errorRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.add5xxCountAlarm) {
const alarmProps = props.add5xxCountAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorCountAlarm(this.error5xxCountMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator);
this.errorCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.add5xxRateAlarm) {
const alarmProps = props.add5xxRateAlarm[disambiguator];
const createdAlarm = this.errorAlarmFactory.addErrorRateAlarm(this.error5xxRateMetric, common_1.ErrorType.FAULT, alarmProps, disambiguator);
this.errorRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addLowTpsAlarm) {
const alarmProps = props.addLowTpsAlarm[disambiguator];
const createdAlarm = this.tpsAlarmFactory.addMinTpsAlarm(this.tpsMetric, alarmProps, disambiguator);
this.tpsAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addHighTpsAlarm) {
const alarmProps = props.addHighTpsAlarm[disambiguator];
const createdAlarm = this.tpsAlarmFactory.addMaxTpsAlarm(this.tpsMetric, alarmProps, disambiguator);
this.tpsAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
this.createTpsWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createLatencyWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createErrorRateWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
return [
this.createTitleWidget(),
this.createTpsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createLatencyWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createErrorCountWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createErrorRateWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "API Gateway V2 HTTP Endpoint",
title: this.title,
});
}
createTpsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "TPS",
left: [this.tpsMetric],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.tpsAnnotations,
});
}
createLatencyWidget(width, height) {
const left = [];
Array.from(new Set(this.latencyTypesToRender))
.sort()
.forEach((type) => {
left.push(this.latencyMetrics[type]);
left.push(this.integrationLatencyMetrics[type]);
});
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Latency",
left,
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.latencyAnnotations,
});
}
createErrorCountWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Errors",
left: [this.error4xxCountMetric, this.error5xxCountMetric],
leftAnnotations: this.errorCountAnnotations,
leftYAxis: common_1.CountAxisFromZero,
});
}
createErrorRateWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Errors (rate)",
left: [this.error4xxRateMetric, this.error5xxRateMetric],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.errorRateAnnotations,
});
}
}
exports.ApiGatewayV2HttpApiMonitoring = ApiGatewayV2HttpApiMonitoring;
_a = JSII_RTTI_SYMBOL_1;
ApiGatewayV2HttpApiMonitoring[_a] = { fqn: "cdk-monitoring-constructs.ApiGatewayV2HttpApiMonitoring", version: "1.21.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBpR2F0ZXdheVYySHR0cEFwaU1vbml0b3JpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcGlHYXRld2F5VjJIdHRwQXBpTW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtEQUtvQztBQUVwQyx5Q0F1QnNCO0FBQ3RCLCtDQUd5QjtBQUN6Qix5RkFHNEM7QUFFNUMsTUFBTSwyQkFBMkIsR0FBRztJQUNsQyxvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7SUFDZixvQkFBVyxDQUFDLEdBQUc7Q0FDaEIsQ0FBQztBQTJERixNQUFhLDZCQUE4QixTQUFRLG1CQUFVO0lBNkIzRCxZQUNFLEtBQXNCLEVBQ3RCLEtBQXlDO1FBRXpDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxvQ0FBd0IsQ0FBQztZQUNsRCxHQUFHLEtBQUs7WUFDUixjQUFjLEVBQUUsS0FBSyxDQUFDLEdBQUc7WUFDekIscUJBQXFCLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLO1lBQ3RDLGlCQUFpQixFQUFFLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxVQUFVLElBQ25FLEtBQUssQ0FBQyxTQUFTLElBQUksRUFDckIsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLEVBQUUsRUFBRTtTQUM5QixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBRXZELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUN6QyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FDMUMsQ0FBQztRQUVGLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLDBCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksd0JBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksNEJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXRFLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsRUFBRSxDQUFDO1FBRS9CLE1BQU0sYUFBYSxHQUFHLElBQUksbUVBQWdDLENBQ3hELEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxFQUMzQixLQUFLLENBQ04sQ0FBQztRQUVGLElBQUksQ0FBQyxTQUFTLEdBQUcsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRTNDLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxFQUFFLENBQUM7UUFDcEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHO1lBQzFCLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLElBQUksMkJBQTJCLENBQUM7U0FDL0QsQ0FBQztRQUVGLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDMUQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUV4RCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsYUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzFELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxhQUFhLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFeEQsTUFBTSx1QkFBdUIsR0FBRztZQUM5QixDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUMzQyxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUMzQyxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUMzQyxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUMzQyxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUMzQyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLG9CQUFvQjtZQUMvQyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM3QyxDQUFDLG9CQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLG9CQUFvQjtZQUMvQyxDQUFDLG9CQUFXLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxDQUFDLHFCQUFxQjtZQUNqRCxDQUFDLG9CQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxDQUFDLHNCQUFzQjtTQUNwRCxDQUFDO1FBRUYsTUFBTSxrQ0FBa0MsR0FBRztZQUN6QyxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLDZCQUE2QjtZQUN0RCxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLDZCQUE2QjtZQUN0RCxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLDZCQUE2QjtZQUN0RCxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLDZCQUE2QjtZQUN0RCxDQUFDLG9CQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLDZCQUE2QjtZQUN0RCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLCtCQUErQjtZQUMxRCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLDhCQUE4QjtZQUN4RCxDQUFDLG9CQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLCtCQUErQjtZQUMxRCxDQUFDLG9CQUFXLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxDQUFDLGdDQUFnQztZQUM1RCxDQUFDLG9CQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxDQUFDLGlDQUFpQztTQUMvRCxDQUFDO1FBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxvQkFBVyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDakQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUM7Z0JBQzlCLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUMseUJBQXlCLENBQUMsV0FBVyxDQUFDO2dCQUN6QyxhQUFhLENBQUMsZ0NBQWdDLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxLQUFLLE1BQU0sQ0FBQyxXQUFXLEVBQUUsZUFBZSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FDekQsdUJBQXVCLENBQ3hCLEVBQUU7WUFDRCxLQUFLLE1BQU0sYUFBYSxJQUFJLGVBQWUsRUFBRTtnQkFDM0MsTUFBTSxVQUFVLEdBQUcsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUNsRCxNQUFNLGVBQWUsR0FBRyxXQUEwQixDQUFDO2dCQUNuRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUNwRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxDQUMzRCxNQUFNLEVBQ04sZUFBZSxFQUNmLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztnQkFDRixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUM3QjtTQUNGO1FBRUQsS0FBSyxNQUFNLENBQUMsV0FBVyxFQUFFLGVBQWUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQ3pELGtDQUFrQyxDQUNuQyxFQUFFO1lBQ0QsS0FBSyxNQUFNLGFBQWEsSUFBSSxlQUFlLEVBQUU7Z0JBQzNDLE1BQU0sVUFBVSxHQUFHLGVBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDbEQsTUFBTSxlQUFlLEdBQUcsV0FBMEIsQ0FBQztnQkFDbkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLFlBQVksR0FDaEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLDBCQUEwQixDQUNqRCxNQUFNLEVBQ04sZUFBZSxFQUNmLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztnQkFDSixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUM3QjtTQUNGO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsZ0JBQWdCLEVBQUU7WUFDbEQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FDNUQsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixrQkFBUyxDQUFDLEtBQUssRUFDZixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQzdCO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQ2pELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDeEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixDQUMzRCxJQUFJLENBQUMsa0JBQWtCLEVBQ3ZCLGtCQUFTLENBQUMsS0FBSyxFQUNmLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDN0I7UUFFRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRTtZQUNsRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDekQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixDQUM1RCxJQUFJLENBQUMsbUJBQW1CLEVBQ3hCLGtCQUFTLENBQUMsS0FBSyxFQUNmLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDN0I7UUFFRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxlQUFlLEVBQUU7WUFDakQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQzNELElBQUksQ0FBQyxrQkFBa0IsRUFDdkIsa0JBQVMsQ0FBQyxLQUFLLEVBQ2YsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUM3QjtRQUVELEtBQUssTUFBTSxhQUFhLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRTtZQUNoRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUN0RCxJQUFJLENBQUMsU0FBUyxFQUNkLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQzdCO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQ2pELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDeEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQ3RELElBQUksQ0FBQyxTQUFTLEVBQ2QsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDN0I7UUFFRCxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTztZQUNMLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLG1CQUFVLEVBQUUsbUNBQTBCLENBQUM7WUFDNUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLG1CQUFVLEVBQUUsbUNBQTBCLENBQUM7WUFDaEUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLG1CQUFVLEVBQUUsbUNBQTBCLENBQUM7U0FDbkUsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTztZQUNMLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLHFCQUFZLEVBQUUsaUNBQXdCLENBQUM7WUFDNUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLHFCQUFZLEVBQUUsaUNBQXdCLENBQUM7WUFDaEUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLHFCQUFZLEVBQUUsaUNBQXdCLENBQUM7WUFDbkUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLHFCQUFZLEVBQUUsaUNBQXdCLENBQUM7U0FDbkUsQ0FBQztJQUNKLENBQUM7SUFFUyxpQkFBaUI7UUFDekIsT0FBTyxJQUFJLGtDQUFzQixDQUFDO1lBQ2hDLE1BQU0sRUFBRSw4QkFBOEI7WUFDdEMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1NBQ2xCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxlQUFlLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDckQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsS0FBSztZQUNaLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDdEIsU0FBUyxFQUFFLHlCQUFnQjtZQUMzQixlQUFlLEVBQUUsSUFBSSxDQUFDLGNBQWM7U0FDckMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLG1CQUFtQixDQUFDLEtBQWEsRUFBRSxNQUFjO1FBQ3pELE1BQU0sSUFBSSxHQUFjLEVBQUUsQ0FBQztRQUUzQixLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO2FBQzNDLElBQUksRUFBRTthQUNOLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7UUFFTCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxTQUFTO1lBQ2hCLElBQUk7WUFDSixTQUFTLEVBQUUsK0JBQXNCO1lBQ2pDLGVBQWUsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1NBQ3pDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxzQkFBc0IsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUM1RCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxRQUFRO1lBQ2YsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztZQUMxRCxlQUFlLEVBQUUsSUFBSSxDQUFDLHFCQUFxQjtZQUMzQyxTQUFTLEVBQUUsMEJBQWlCO1NBQzdCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxxQkFBcUIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUMzRCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxlQUFlO1lBQ3RCLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFDeEQsU0FBUyxFQUFFLHlCQUFnQjtZQUMzQixlQUFlLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtTQUMzQyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXhUSCxzRUF5VEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElNZXRyaWMsXG4gIElXaWRnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuXG5pbXBvcnQge1xuICBBbGFybUZhY3RvcnksXG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBFcnJvckFsYXJtRmFjdG9yeSxcbiAgRXJyb3JDb3VudFRocmVzaG9sZCxcbiAgRXJyb3JSYXRlVGhyZXNob2xkLFxuICBFcnJvclR5cGUsXG4gIEhpZ2hUcHNUaHJlc2hvbGQsXG4gIExhdGVuY3lBbGFybUZhY3RvcnksXG4gIExhdGVuY3lUaHJlc2hvbGQsXG4gIExhdGVuY3lUeXBlLFxuICBMb3dUcHNUaHJlc2hvbGQsXG4gIE1ldHJpY1dpdGhBbGFybVN1cHBvcnQsXG4gIE1vbml0b3JpbmcsXG4gIE1vbml0b3JpbmdTY29wZSxcbiAgUXVhcnRlcldpZHRoLFxuICBSYXRlQXhpc0Zyb21aZXJvLFxuICBUaGlyZFdpZHRoLFxuICBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICBUcHNBbGFybUZhY3RvcnksXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcbmltcG9ydCB7XG4gIE1vbml0b3JpbmdIZWFkZXJXaWRnZXQsXG4gIE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSxcbn0gZnJvbSBcIi4uLy4uL2Rhc2hib2FyZFwiO1xuaW1wb3J0IHtcbiAgQXBpR2F0ZXdheVYySHR0cEFwaU1ldHJpY0ZhY3RvcnksXG4gIEFwaUdhdGV3YXlWMkh0dHBBcGlNZXRyaWNGYWN0b3J5UHJvcHMsXG59IGZyb20gXCIuL0FwaUdhdGV3YXlWMkh0dHBBcGlNZXRyaWNGYWN0b3J5XCI7XG5cbmNvbnN0IERlZmF1bHRMYXRlbmN5VHlwZXNUb1JlbmRlciA9IFtcbiAgTGF0ZW5jeVR5cGUuUDUwLFxuICBMYXRlbmN5VHlwZS5QOTAsXG4gIExhdGVuY3lUeXBlLlA5OSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBpR2F0ZXdheVYyTW9uaXRvcmluZ09wdGlvbnMgZXh0ZW5kcyBCYXNlTW9uaXRvcmluZ1Byb3BzIHtcbiAgcmVhZG9ubHkgYWRkNHh4Q291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yQ291bnRUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGQ0eHhSYXRlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvclJhdGVUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGQ1eHhDb3VudEFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JDb3VudFRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZDV4eFJhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVA1MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQNzBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5UDkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVA5NUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQOTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5UDk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQOTk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lQMTAwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVRNNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5VE03MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lUTTkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkTGF0ZW5jeVRNOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5VE05OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lUTTk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZExhdGVuY3lUTTk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRMYXRlbmN5QXZlcmFnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG5cbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDUwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDkwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDk1QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDk5OUFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEludGVncmF0aW9uTGF0ZW5jeVA5OTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5UDEwMEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEludGVncmF0aW9uTGF0ZW5jeVRNNTBBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnRlZ3JhdGlvbkxhdGVuY3lUTTcwQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5VE05MEFsYXJtPzogUmVjb3JkPHN0cmluZywgTGF0ZW5jeVRocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEludGVncmF0aW9uTGF0ZW5jeVRNOTVBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnRlZ3JhdGlvbkxhdGVuY3lUTTk5QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcbiAgcmVhZG9ubHkgYWRkSW50ZWdyYXRpb25MYXRlbmN5VE05OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnRlZ3JhdGlvbkxhdGVuY3lUTTk5OTlBbGFybT86IFJlY29yZDxzdHJpbmcsIExhdGVuY3lUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbnRlZ3JhdGlvbkxhdGVuY3lBdmVyYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBMYXRlbmN5VGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRMb3dUcHNBbGFybT86IFJlY29yZDxzdHJpbmcsIExvd1Rwc1RocmVzaG9sZD47XG4gIHJlYWRvbmx5IGFkZEhpZ2hUcHNBbGFybT86IFJlY29yZDxzdHJpbmcsIEhpZ2hUcHNUaHJlc2hvbGQ+O1xuXG4gIC8qKlxuICAgKiBZb3UgY2FuIHNwZWNpZnkgd2hhdCBsYXRlbmN5IHR5cGVzIHlvdSB3YW50IHRvIGJlIHJlbmRlcmVkIGluIHRoZSBkYXNoYm9hcmRzLlxuICAgKiBOb3RlOiBhbnkgbGF0ZW5jeSB0eXBlIHdpdGggYW4gYWxhcm0gd2lsbCBiZSBhbHNvIGFkZGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqIElmIHRoZSBsaXN0IGlzIHVuZGVmaW5lZCwgZGVmYXVsdCB2YWx1ZXMgd2lsbCBiZSBzaG93bi5cbiAgICogSWYgdGhlIGxpc3QgaXMgZW1wdHksIG9ubHkgdGhlIGxhdGVuY3kgdHlwZXMgd2l0aCBhbiBhbGFybSB3aWxsIGJlIHNob3duIChpZiBhbnkpLlxuICAgKiBAZGVmYXVsdCAtIHA1MCwgcDkwLCBwOTkgKEBzZWUgRGVmYXVsdExhdGVuY3lUeXBlc1Nob3duKVxuICAgKi9cbiAgcmVhZG9ubHkgbGF0ZW5jeVR5cGVzVG9SZW5kZXI/OiBMYXRlbmN5VHlwZVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFwaUdhdGV3YXlWMkh0dHBBcGlNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBBcGlHYXRld2F5VjJIdHRwQXBpTWV0cmljRmFjdG9yeVByb3BzLFxuICAgIEFwaUdhdGV3YXlWMk1vbml0b3JpbmdPcHRpb25zIHt9XG5cbmV4cG9ydCBjbGFzcyBBcGlHYXRld2F5VjJIdHRwQXBpTW9uaXRvcmluZyBleHRlbmRzIE1vbml0b3Jpbmcge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYWxhcm1GYWN0b3J5OiBBbGFybUZhY3Rvcnk7XG4gIHByb3RlY3RlZCByZWFkb25seSBlcnJvckFsYXJtRmFjdG9yeTogRXJyb3JBbGFybUZhY3Rvcnk7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cHNBbGFybUZhY3Rvcnk6IFRwc0FsYXJtRmFjdG9yeTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxhdGVuY3lBbGFybUZhY3Rvcnk6IExhdGVuY3lBbGFybUZhY3Rvcnk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRwc0Fubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGF0ZW5jeUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3JDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3JSYXRlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRwc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3I0eHhDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGVycm9yNHh4UmF0ZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3I1eHhDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGVycm9yNXh4UmF0ZU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICAvLyBrZXlzIGFyZSBMYXRlbmN5VHlwZSwgYnV0IEpTSUkgZG9lc24ndCBsaWtlIG5vbi1zdHJpbmcgdHlwZXNcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxhdGVuY3lNZXRyaWNzOiBSZWNvcmQ8c3RyaW5nLCBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0PjtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGludGVncmF0aW9uTGF0ZW5jeU1ldHJpY3M6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTWV0cmljV2l0aEFsYXJtU3VwcG9ydFxuICA+O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGF0ZW5jeVR5cGVzVG9SZW5kZXI6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBNb25pdG9yaW5nU2NvcGUsXG4gICAgcHJvcHM6IEFwaUdhdGV3YXlWMkh0dHBBcGlNb25pdG9yaW5nUHJvcHNcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIGNvbnN0IG5hbWluZ1N0cmF0ZWd5ID0gbmV3IE1vbml0b3JpbmdOYW1pbmdTdHJhdGVneSh7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG5hbWVkQ29uc3RydWN0OiBwcm9wcy5hcGksXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWU6IHByb3BzLmFwaS5hcGlJZCxcbiAgICAgIGh1bWFuUmVhZGFibGVOYW1lOiBgJHtwcm9wcy5hcGkuYXBpSWR9ICR7cHJvcHMuYXBpU3RhZ2UgPz8gXCIkZGVmYXVsdFwifSAke1xuICAgICAgICBwcm9wcy5hcGlNZXRob2QgPz8gXCJcIlxuICAgICAgfSAke3Byb3BzLmFwaVJlc291cmNlID8/IFwiXCJ9YCxcbiAgICB9KTtcblxuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcblxuICAgIHRoaXMuYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKVxuICAgICk7XG5cbiAgICB0aGlzLmVycm9yQWxhcm1GYWN0b3J5ID0gbmV3IEVycm9yQWxhcm1GYWN0b3J5KHRoaXMuYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLnRwc0FsYXJtRmFjdG9yeSA9IG5ldyBUcHNBbGFybUZhY3RvcnkodGhpcy5hbGFybUZhY3RvcnkpO1xuICAgIHRoaXMubGF0ZW5jeUFsYXJtRmFjdG9yeSA9IG5ldyBMYXRlbmN5QWxhcm1GYWN0b3J5KHRoaXMuYWxhcm1GYWN0b3J5KTtcblxuICAgIHRoaXMudHBzQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmxhdGVuY3lBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuZXJyb3JDb3VudEFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5lcnJvclJhdGVBbm5vdGF0aW9ucyA9IFtdO1xuXG4gICAgY29uc3QgbWV0cmljRmFjdG9yeSA9IG5ldyBBcGlHYXRld2F5VjJIdHRwQXBpTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzXG4gICAgKTtcblxuICAgIHRoaXMudHBzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNUcHMoKTtcblxuICAgIHRoaXMubGF0ZW5jeU1ldHJpY3MgPSB7fTtcbiAgICB0aGlzLmludGVncmF0aW9uTGF0ZW5jeU1ldHJpY3MgPSB7fTtcbiAgICB0aGlzLmxhdGVuY3lUeXBlc1RvUmVuZGVyID0gW1xuICAgICAgLi4uKHByb3BzLmxhdGVuY3lUeXBlc1RvUmVuZGVyID8/IERlZmF1bHRMYXRlbmN5VHlwZXNUb1JlbmRlciksXG4gICAgXTtcblxuICAgIHRoaXMuZXJyb3I0eHhDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljNHh4Q291bnQoKTtcbiAgICB0aGlzLmVycm9yNHh4UmF0ZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljNHh4UmF0ZSgpO1xuXG4gICAgdGhpcy5lcnJvcjV4eENvdW50TWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWM1eHhDb3VudCgpO1xuICAgIHRoaXMuZXJyb3I1eHhSYXRlTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWM1eHhSYXRlKCk7XG5cbiAgICBjb25zdCBsYXRlbmN5QWxhcm1EZWZpbml0aW9ucyA9IHtcbiAgICAgIFtMYXRlbmN5VHlwZS5QNTBdOiBwcm9wcy5hZGRMYXRlbmN5UDUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDcwXTogcHJvcHMuYWRkTGF0ZW5jeVA3MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5MF06IHByb3BzLmFkZExhdGVuY3lQOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTVdOiBwcm9wcy5hZGRMYXRlbmN5UDk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5XTogcHJvcHMuYWRkTGF0ZW5jeVA5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTldOiBwcm9wcy5hZGRMYXRlbmN5UDk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlA5OTk5XTogcHJvcHMuYWRkTGF0ZW5jeVA5OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDEwMF06IHByb3BzLmFkZExhdGVuY3lQMTAwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE01MF06IHByb3BzLmFkZExhdGVuY3lUTTUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE03MF06IHByb3BzLmFkZExhdGVuY3lUTTcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE05MF06IHByb3BzLmFkZExhdGVuY3lUTTkwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE05NV06IHByb3BzLmFkZExhdGVuY3lUTTk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE05OV06IHByb3BzLmFkZExhdGVuY3lUTTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE05OTldOiBwcm9wcy5hZGRMYXRlbmN5VE05OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTk5OTldOiBwcm9wcy5hZGRMYXRlbmN5VE05OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuQVZFUkFHRV06IHByb3BzLmFkZExhdGVuY3lBdmVyYWdlQWxhcm0sXG4gICAgfTtcblxuICAgIGNvbnN0IGludGVncmF0aW9uTGF0ZW5jeUFsYXJtRGVmaW5pdGlvbnMgPSB7XG4gICAgICBbTGF0ZW5jeVR5cGUuUDUwXTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5UDUwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDcwXTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5UDcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDkwXTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5UDkwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk1XTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5UDk1QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5XTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5UDk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDk5OV06IHByb3BzLmFkZEludGVncmF0aW9uTGF0ZW5jeVA5OTlBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5QOTk5OV06IHByb3BzLmFkZEludGVncmF0aW9uTGF0ZW5jeVA5OTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuUDEwMF06IHByb3BzLmFkZEludGVncmF0aW9uTGF0ZW5jeVAxMDBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTUwXTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5VE01MEFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlRNNzBdOiBwcm9wcy5hZGRJbnRlZ3JhdGlvbkxhdGVuY3lUTTcwQWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE05MF06IHByb3BzLmFkZEludGVncmF0aW9uTGF0ZW5jeVRNOTBBbGFybSxcbiAgICAgIFtMYXRlbmN5VHlwZS5UTTk1XTogcHJvcHMuYWRkSW50ZWdyYXRpb25MYXRlbmN5VE05NUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlRNOTldOiBwcm9wcy5hZGRJbnRlZ3JhdGlvbkxhdGVuY3lUTTk5QWxhcm0sXG4gICAgICBbTGF0ZW5jeVR5cGUuVE05OTldOiBwcm9wcy5hZGRJbnRlZ3JhdGlvbkxhdGVuY3lUTTk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLlRNOTk5OV06IHByb3BzLmFkZEludGVncmF0aW9uTGF0ZW5jeVRNOTk5OUFsYXJtLFxuICAgICAgW0xhdGVuY3lUeXBlLkFWRVJBR0VdOiBwcm9wcy5hZGRJbnRlZ3JhdGlvbkxhdGVuY3lBdmVyYWdlQWxhcm0sXG4gICAgfTtcblxuICAgIE9iamVjdC52YWx1ZXMoTGF0ZW5jeVR5cGUpLmZvckVhY2goKGxhdGVuY3lUeXBlKSA9PiB7XG4gICAgICB0aGlzLmxhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlXSA9XG4gICAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljTGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlKTtcbiAgICAgIHRoaXMuaW50ZWdyYXRpb25MYXRlbmN5TWV0cmljc1tsYXRlbmN5VHlwZV0gPVxuICAgICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0ludGVncmF0aW9uTGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlKTtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3QgW2xhdGVuY3lUeXBlLCBhbGFybURlZmluaXRpb25dIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgICAgbGF0ZW5jeUFsYXJtRGVmaW5pdGlvbnNcbiAgICApKSB7XG4gICAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gYWxhcm1EZWZpbml0aW9uKSB7XG4gICAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBhbGFybURlZmluaXRpb25bZGlzYW1iaWd1YXRvcl07XG4gICAgICAgIGNvbnN0IGxhdGVuY3lUeXBlRW51bSA9IGxhdGVuY3lUeXBlIGFzIExhdGVuY3lUeXBlO1xuICAgICAgICBjb25zdCBtZXRyaWMgPSB0aGlzLmxhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlRW51bV07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMubGF0ZW5jeUFsYXJtRmFjdG9yeS5hZGRMYXRlbmN5QWxhcm0oXG4gICAgICAgICAgbWV0cmljLFxuICAgICAgICAgIGxhdGVuY3lUeXBlRW51bSxcbiAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5sYXRlbmN5QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICAgIHRoaXMubGF0ZW5jeVR5cGVzVG9SZW5kZXIucHVzaChsYXRlbmN5VHlwZUVudW0pO1xuICAgICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbbGF0ZW5jeVR5cGUsIGFsYXJtRGVmaW5pdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMoXG4gICAgICBpbnRlZ3JhdGlvbkxhdGVuY3lBbGFybURlZmluaXRpb25zXG4gICAgKSkge1xuICAgICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIGFsYXJtRGVmaW5pdGlvbikge1xuICAgICAgICBjb25zdCBhbGFybVByb3BzID0gYWxhcm1EZWZpbml0aW9uW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgICBjb25zdCBsYXRlbmN5VHlwZUVudW0gPSBsYXRlbmN5VHlwZSBhcyBMYXRlbmN5VHlwZTtcbiAgICAgICAgY29uc3QgbWV0cmljID0gdGhpcy5pbnRlZ3JhdGlvbkxhdGVuY3lNZXRyaWNzW2xhdGVuY3lUeXBlRW51bV07XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgICAgdGhpcy5sYXRlbmN5QWxhcm1GYWN0b3J5LmFkZEludGVncmF0aW9uTGF0ZW5jeUFsYXJtKFxuICAgICAgICAgICAgbWV0cmljLFxuICAgICAgICAgICAgbGF0ZW5jeVR5cGVFbnVtLFxuICAgICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICAgICApO1xuICAgICAgICB0aGlzLmxhdGVuY3lBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgICAgdGhpcy5sYXRlbmN5VHlwZXNUb1JlbmRlci5wdXNoKGxhdGVuY3lUeXBlRW51bSk7XG4gICAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkNHh4Q291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZDR4eENvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmVycm9yQWxhcm1GYWN0b3J5LmFkZEVycm9yQ291bnRBbGFybShcbiAgICAgICAgdGhpcy5lcnJvcjR4eENvdW50TWV0cmljLFxuICAgICAgICBFcnJvclR5cGUuRVJST1IsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkNHh4UmF0ZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkNHh4UmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lcnJvckFsYXJtRmFjdG9yeS5hZGRFcnJvclJhdGVBbGFybShcbiAgICAgICAgdGhpcy5lcnJvcjR4eFJhdGVNZXRyaWMsXG4gICAgICAgIEVycm9yVHlwZS5FUlJPUixcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvclxuICAgICAgKTtcbiAgICAgIHRoaXMuZXJyb3JSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZDV4eENvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGQ1eHhDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lcnJvckFsYXJtRmFjdG9yeS5hZGRFcnJvckNvdW50QWxhcm0oXG4gICAgICAgIHRoaXMuZXJyb3I1eHhDb3VudE1ldHJpYyxcbiAgICAgICAgRXJyb3JUeXBlLkZBVUxULFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy5lcnJvckNvdW50QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZDV4eFJhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZDV4eFJhdGVBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMuZXJyb3JBbGFybUZhY3RvcnkuYWRkRXJyb3JSYXRlQWxhcm0oXG4gICAgICAgIHRoaXMuZXJyb3I1eHhSYXRlTWV0cmljLFxuICAgICAgICBFcnJvclR5cGUuRkFVTFQsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3JcbiAgICAgICk7XG4gICAgICB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRMb3dUcHNBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZExvd1Rwc0FsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy50cHNBbGFybUZhY3RvcnkuYWRkTWluVHBzQWxhcm0oXG4gICAgICAgIHRoaXMudHBzTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy50cHNBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSGlnaFRwc0FsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkSGlnaFRwc0FsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy50cHNBbGFybUZhY3RvcnkuYWRkTWF4VHBzQWxhcm0oXG4gICAgICAgIHRoaXMudHBzTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yXG4gICAgICApO1xuICAgICAgdGhpcy50cHNBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBwcm9wcy51c2VDcmVhdGVkQWxhcm1zPy5jb25zdW1lKHRoaXMuY3JlYXRlZEFsYXJtcygpKTtcbiAgfVxuXG4gIHN1bW1hcnlXaWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIHRoaXMuY3JlYXRlVHBzV2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlTGF0ZW5jeVdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZUVycm9yUmF0ZVdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgdGhpcy5jcmVhdGVUcHNXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgdGhpcy5jcmVhdGVMYXRlbmN5V2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlRXJyb3JDb3VudFdpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZUVycm9yUmF0ZVdpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVUaXRsZVdpZGdldCgpIHtcbiAgICByZXR1cm4gbmV3IE1vbml0b3JpbmdIZWFkZXJXaWRnZXQoe1xuICAgICAgZmFtaWx5OiBcIkFQSSBHYXRld2F5IFYyIEhUVFAgRW5kcG9pbnRcIixcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVRwc1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJUUFNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLnRwc01ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMudHBzQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlTGF0ZW5jeVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGxlZnQ6IElNZXRyaWNbXSA9IFtdO1xuXG4gICAgQXJyYXkuZnJvbShuZXcgU2V0KHRoaXMubGF0ZW5jeVR5cGVzVG9SZW5kZXIpKVxuICAgICAgLnNvcnQoKVxuICAgICAgLmZvckVhY2goKHR5cGUpID0+IHtcbiAgICAgICAgbGVmdC5wdXNoKHRoaXMubGF0ZW5jeU1ldHJpY3NbdHlwZV0pO1xuICAgICAgICBsZWZ0LnB1c2godGhpcy5pbnRlZ3JhdGlvbkxhdGVuY3lNZXRyaWNzW3R5cGVdKTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkxhdGVuY3lcIixcbiAgICAgIGxlZnQsXG4gICAgICBsZWZ0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMubGF0ZW5jeUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUVycm9yQ291bnRXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiRXJyb3JzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5lcnJvcjR4eENvdW50TWV0cmljLCB0aGlzLmVycm9yNXh4Q291bnRNZXRyaWNdLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmVycm9yQ291bnRBbm5vdGF0aW9ucyxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRXJyb3JSYXRlV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkVycm9ycyAocmF0ZSlcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmVycm9yNHh4UmF0ZU1ldHJpYywgdGhpcy5lcnJvcjV4eFJhdGVNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBSYXRlQXhpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmVycm9yUmF0ZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG59XG4iXX0=