cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
184 lines • 33.5 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElastiCacheClusterMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const ElastiCacheClusterMetricFactory_1 = require("./ElastiCacheClusterMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class ElastiCacheClusterMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
this.clusterType = props.clusterType;
const clusterType = common_1.capitalizeFirstLetterOnly(ElastiCacheClusterMetricFactory_1.ElastiCacheClusterType[props.clusterType]);
const fallbackConstructName = [clusterType, props.clusterId ?? "ALL"].join("-");
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
fallbackConstructName,
});
this.title = namingStrategy.resolveHumanReadableName();
if (props.clusterId) {
this.clusterUrl = scope
.createAwsConsoleUrlFactory()
.getElastiCacheClusterUrl(props.clusterId, props.clusterType);
}
const metricFactory = new ElastiCacheClusterMetricFactory_1.ElastiCacheClusterMetricFactory(scope.createMetricFactory(), props);
this.connectionsMetric = metricFactory.metricAverageConnections();
this.cpuUsageMetric = metricFactory.metricMaxCpuUtilizationInPercent();
this.redisEngineCpuUsageMetric =
metricFactory.metricMaxRedisEngineCpuUtilizationInPercent();
this.freeableMemoryMetric =
metricFactory.metricAverageFreeableMemoryInBytes();
this.unusedMemoryMetric = metricFactory.metricAverageUnusedMemoryInBytes();
this.swapMemoryMetric = metricFactory.metricAverageSwapUsageInBytes();
this.itemsMemoryMetric =
metricFactory.metricAverageCachedItemsSizeInBytes();
this.itemsCountMetrics = metricFactory.metricMaxItemCount();
this.itemsEvictedMetrics = metricFactory.metricEvictions();
this.cpuUsageAnnotations = [];
this.redisEngineCpuUsageAnnotations = [];
this.itemsCountAnnotations = [];
this.evictedItemsCountAnnotations = [];
this.memoryUsageAnnotations = [];
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.usageAlarmFactory = new common_1.UsageAlarmFactory(alarmFactory);
this.elastiCacheAlarmFactory = new common_1.ElastiCacheAlarmFactory(alarmFactory);
for (const disambiguator in props.addCpuUsageAlarm) {
const alarmProps = props.addCpuUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.cpuUsageMetric, alarmProps, disambiguator);
this.cpuUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
if (props.addRedisEngineCpuUsageAlarm !== undefined &&
props.clusterType !== ElastiCacheClusterMetricFactory_1.ElastiCacheClusterType.REDIS) {
throw new Error("It is only possible to alarm on Redis Engine CPU Usage for Redis clusters");
}
for (const disambiguator in props.addRedisEngineCpuUsageAlarm) {
const alarmProps = props.addRedisEngineCpuUsageAlarm[disambiguator];
const createdAlarm = this.usageAlarmFactory.addMaxCpuUsagePercentAlarm(this.redisEngineCpuUsageMetric, alarmProps, disambiguator, undefined, "RedisEngine");
this.redisEngineCpuUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxItemsCountAlarm) {
const alarmProps = props.addMaxItemsCountAlarm[disambiguator];
const createdAlarm = this.elastiCacheAlarmFactory.addMaxItemsCountAlarm(this.itemsCountMetrics, alarmProps, disambiguator);
this.itemsCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxEvictedItemsCountAlarm) {
const alarmProps = props.addMaxEvictedItemsCountAlarm[disambiguator];
const createdAlarm = this.elastiCacheAlarmFactory.addMaxEvictedItemsCountAlarm(this.itemsEvictedMetrics, alarmProps, disambiguator);
this.evictedItemsCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMinFreeableMemoryAlarm) {
const alarmProps = props.addMinFreeableMemoryAlarm[disambiguator];
const createdAlarm = this.elastiCacheAlarmFactory.addMinFreeableMemoryAlarm(this.freeableMemoryMetric, alarmProps, disambiguator);
this.memoryUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addMaxUsedSwapMemoryAlarm) {
const alarmProps = props.addMaxUsedSwapMemoryAlarm[disambiguator];
const createdAlarm = this.elastiCacheAlarmFactory.addMaxUsedSwapMemoryAlarm(this.swapMemoryMetric, alarmProps, disambiguator);
this.memoryUsageAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
this.createCpuUsageWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createMemoryUsageWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
this.createItemCountWidget(common_1.ThirdWidth, common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
if (this.clusterType === ElastiCacheClusterMetricFactory_1.ElastiCacheClusterType.REDIS) {
return [
this.createTitleWidget(),
new aws_cloudwatch_1.Column(this.createCpuUsageWidget(common_1.QuarterWidth, common_1.DefaultTwoLinerGraphWidgetHalfHeight), this.createRedisEngineCpuUsageWidget(common_1.QuarterWidth, common_1.DefaultTwoLinerGraphWidgetHalfHeight)),
this.createMemoryUsageWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createConnectionsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createItemCountWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
else {
return [
this.createTitleWidget(),
this.createCpuUsageWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createMemoryUsageWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createConnectionsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
this.createItemCountWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "ElastiCache Cluster",
title: this.title,
goToLinkUrl: this.clusterUrl,
});
}
createCpuUsageWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "CPU Utilization",
left: [this.cpuUsageMetric],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.cpuUsageAnnotations,
});
}
createRedisEngineCpuUsageWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Engine CPU Utilization",
left: [this.redisEngineCpuUsageMetric],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
leftAnnotations: this.redisEngineCpuUsageAnnotations,
});
}
createMemoryUsageWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Memory Utilization",
left: [
this.freeableMemoryMetric,
this.unusedMemoryMetric,
this.swapMemoryMetric,
],
leftYAxis: common_1.SizeAxisBytesFromZero,
leftAnnotations: this.memoryUsageAnnotations,
});
}
createItemCountWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Items",
left: [this.itemsCountMetrics],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.itemsCountAnnotations,
right: [this.itemsEvictedMetrics],
rightYAxis: common_1.CountAxisFromZero,
rightAnnotations: this.evictedItemsCountAnnotations,
});
}
createConnectionsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Connections",
left: [this.connectionsMetric],
leftYAxis: common_1.CountAxisFromZero,
});
}
}
exports.ElastiCacheClusterMonitoring = ElastiCacheClusterMonitoring;
_a = JSII_RTTI_SYMBOL_1;
ElastiCacheClusterMonitoring[_a] = { fqn: "cdk-monitoring-constructs.ElastiCacheClusterMonitoring", version: "9.15.2" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWxhc3RpQ2FjaGVDbHVzdGVyTW9uaXRvcmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkVsYXN0aUNhY2hlQ2x1c3Rlck1vbml0b3JpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwrREFLb0M7QUFFcEMsdUZBSTJDO0FBQzNDLHlDQW9Cc0I7QUFDdEIsK0NBR3lCO0FBc0R6QixNQUFhLDRCQUE2QixTQUFRLG1CQUFVO0lBdUIxRCxZQUNFLEtBQXNCLEVBQ3RCLEtBQXdDO1FBRXhDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFcEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBRXJDLE1BQU0sV0FBVyxHQUFHLGtDQUF5QixDQUMzQyx3REFBc0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQzFDLENBQUM7UUFDRixNQUFNLHFCQUFxQixHQUFHLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxDQUN4RSxHQUFHLENBQ0osQ0FBQztRQUNGLE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IscUJBQXFCO1NBQ3RCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDdkQsSUFBSSxLQUFLLENBQUMsU0FBUyxFQUFFO1lBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSztpQkFDcEIsMEJBQTBCLEVBQUU7aUJBQzVCLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQ2pFO1FBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxpRUFBK0IsQ0FDdkQsS0FBSyxDQUFDLG1CQUFtQixFQUFFLEVBQzNCLEtBQUssQ0FDTixDQUFDO1FBQ0YsSUFBSSxDQUFDLGlC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QUM7SUFFRCx1QkFBdUIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUNuRCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxvQkFBb0I7WUFDM0IsSUFBSSxFQUFFO2dCQUNKLElBQUksQ0FBQyxvQkFBb0I7Z0JBQ3pCLElBQUksQ0FBQyxrQkFBa0I7Z0JBQ3ZCLElBQUksQ0FBQyxnQkFBZ0I7YUFDdEI7WUFDRCxTQUFTLEVBQUUsOEJBQXFCO1lBQ2hDLGVBQWUsRUFBRSxJQUFJLENBQUMsc0JBQXNCO1NBQzdDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUNqRCxPQUFPLElBQUksNEJBQVcsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUssRUFBRSxPQUFPO1lBQ2QsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDO1lBQzlCLFNBQVMsRUFBRSwwQkFBaUI7WUFDNUIsZUFBZSxFQUFFLElBQUksQ0FBQyxxQkFBcUI7WUFDM0MsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1lBQ2pDLFVBQVUsRUFBRSwwQkFBaUI7WUFDN0IsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLDRCQUE0QjtTQUNwRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsdUJBQXVCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDbkQsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsYUFBYTtZQUNwQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUM7WUFDOUIsU0FBUyxFQUFFLDBCQUFpQjtTQUM3QixDQUFDLENBQUM7SUFDTCxDQUFDOztBQXRRSCxvRUF1UUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb2x1bW4sXG4gIEdyYXBoV2lkZ2V0LFxuICBIb3Jpem9udGFsQW5ub3RhdGlvbixcbiAgSVdpZGdldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCI7XG5cbmltcG9ydCB7XG4gIEVsYXN0aUNhY2hlQ2x1c3Rlck1ldHJpY0ZhY3RvcnksXG4gIEVsYXN0aUNhY2hlQ2x1c3Rlck1ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgRWxhc3RpQ2FjaGVDbHVzdGVyVHlwZSxcbn0gZnJvbSBcIi4vRWxhc3RpQ2FjaGVDbHVzdGVyTWV0cmljRmFjdG9yeVwiO1xuaW1wb3J0IHtcbiAgQmFzZU1vbml0b3JpbmdQcm9wcyxcbiAgQ291bnRBeGlzRnJvbVplcm8sXG4gIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgRGVmYXVsdFR3b0xpbmVyR3JhcGhXaWRnZXRIYWxmSGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgRWxhc3RpQ2FjaGVBbGFybUZhY3RvcnksXG4gIE1heEl0ZW1zQ291bnRUaHJlc2hvbGQsXG4gIE1heFVzZWRTd2FwTWVtb3J5VGhyZXNob2xkLFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNaW5GcmVlYWJsZU1lbW9yeVRocmVzaG9sZCxcbiAgTW9uaXRvcmluZyxcbiAgTW9uaXRvcmluZ1Njb3BlLFxuICBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICBRdWFydGVyV2lkdGgsXG4gIFNpemVBeGlzQnl0ZXNGcm9tWmVybyxcbiAgVGhpcmRXaWR0aCxcbiAgVXNhZ2VBbGFybUZhY3RvcnksXG4gIFVzYWdlVGhyZXNob2xkLFxuICBjYXBpdGFsaXplRmlyc3RMZXR0ZXJPbmx5LFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0LFxuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBFbGFzdGlDYWNoZUNsdXN0ZXJNb25pdG9yaW5nT3B0aW9uc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICAvKipcbiAgICogQ2x1c3RlciB0eXBlIChuZWVkZWQsIHNpbmNlIGVhY2ggdHlwZSBoYXMgdGhlaXIgb3duIHNwZWNpZmljIG1ldHJpY3MpXG4gICAqL1xuICByZWFkb25seSBjbHVzdGVyVHlwZTogRWxhc3RpQ2FjaGVDbHVzdGVyVHlwZTtcblxuICAvKipcbiAgICogQWRkIENQVSB1c2FnZSBhbGFybSAodXNlZnVsIGZvciBhbGwgY2x1c3RlclR5cGVzIGluY2x1ZGluZyBSZWRpcylcbiAgICovXG4gIHJlYWRvbmx5IGFkZENwdVVzYWdlQWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBVc2FnZVRocmVzaG9sZD47XG5cbiAgLyoqXG4gICAqIEFkZCBSZWRpcyBlbmdpbmUgQ1BVIHVzYWdlIGFsYXJtLlxuICAgKlxuICAgKiBJdCBpcyByZWNvbW1lbmRlZCB0byBtb25pdG9yIENQVSB1dGlsaXphdGlvbiB3aXRoIGBhZGRDcHVVc2FnZUFsYXJtYFxuICAgKiBhcyB3ZWxsIGZvciBob3N0cyB3aXRoIHR3byB2Q1BVcyBvciBsZXNzLlxuICAgKi9cbiAgcmVhZG9ubHkgYWRkUmVkaXNFbmdpbmVDcHVVc2FnZUFsYXJtPzogUmVjb3JkPHN0cmluZywgVXNhZ2VUaHJlc2hvbGQ+O1xuXG4gIC8qKlxuICAgKiBBZGQgYWxhcm0gb24gdG90YWwgbnVtYmVyIG9mIGl0ZW1zXG4gICAqL1xuICByZWFkb25seSBhZGRNYXhJdGVtc0NvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBNYXhJdGVtc0NvdW50VGhyZXNob2xkPjtcbiAgLyoqXG4gICAqIEFkZCBhbGFybSBvbiBudW1iZXIgb2YgZXZpY3RlZCBpdGVtc1xuICAgKi9cbiAgcmVhZG9ubHkgYWRkTWF4RXZpY3RlZEl0ZW1zQ291bnRBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTWF4SXRlbXNDb3VudFRocmVzaG9sZFxuICA+O1xuXG4gIC8qKlxuICAgKiBBZGQgYWxhcm0gb24gYW1vdW50IG9mIGZyZWVhYmxlIG1lbW9yeVxuICAgKi9cbiAgcmVhZG9ubHkgYWRkTWluRnJlZWFibGVNZW1vcnlBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTWluRnJlZWFibGVNZW1vcnlUaHJlc2hvbGRcbiAgPjtcbiAgLyoqXG4gICAqIEFkZCBhbGFybSBvbiBhbW91bnQgb2YgdXNlZCBzd2FwIG1lbW9yeVxuICAgKi9cbiAgcmVhZG9ubHkgYWRkTWF4VXNlZFN3YXBNZW1vcnlBbGFybT86IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgTWF4VXNlZFN3YXBNZW1vcnlUaHJlc2hvbGRcbiAgPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFbGFzdGlDYWNoZUNsdXN0ZXJNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBFbGFzdGlDYWNoZUNsdXN0ZXJNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICAgRWxhc3RpQ2FjaGVDbHVzdGVyTW9uaXRvcmluZ09wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIEVsYXN0aUNhY2hlQ2x1c3Rlck1vbml0b3JpbmcgZXh0ZW5kcyBNb25pdG9yaW5nIHtcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcmVhZG9ubHkgY2x1c3RlclVybD86IHN0cmluZztcbiAgcmVhZG9ubHkgY2x1c3RlclR5cGU6IEVsYXN0aUNhY2hlQ2x1c3RlclR5cGU7XG5cbiAgcmVhZG9ubHkgY29ubmVjdGlvbnNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGNwdVVzYWdlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSByZWRpc0VuZ2luZUNwdVVzYWdlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBmcmVlYWJsZU1lbW9yeU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgdW51c2VkTWVtb3J5TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBzd2FwTWVtb3J5TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBpdGVtc01lbW9yeU1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgaXRlbXNDb3VudE1ldHJpY3M6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGl0ZW1zRXZpY3RlZE1ldHJpY3M6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgcmVhZG9ubHkgdXNhZ2VBbGFybUZhY3Rvcnk6IFVzYWdlQWxhcm1GYWN0b3J5O1xuICByZWFkb25seSBlbGFzdGlDYWNoZUFsYXJtRmFjdG9yeTogRWxhc3RpQ2FjaGVBbGFybUZhY3Rvcnk7XG4gIHJlYWRvbmx5IGNwdVVzYWdlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IHJlZGlzRW5naW5lQ3B1VXNhZ2VBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgaXRlbXNDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBldmljdGVkSXRlbXNDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBtZW1vcnlVc2FnZUFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBNb25pdG9yaW5nU2NvcGUsXG4gICAgcHJvcHM6IEVsYXN0aUNhY2hlQ2x1c3Rlck1vbml0b3JpbmdQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIHByb3BzKTtcblxuICAgIHRoaXMuY2x1c3RlclR5cGUgPSBwcm9wcy5jbHVzdGVyVHlwZTtcblxuICAgIGNvbnN0IGNsdXN0ZXJUeXBlID0gY2FwaXRhbGl6ZUZpcnN0TGV0dGVyT25seShcbiAgICAgIEVsYXN0aUNhY2hlQ2x1c3RlclR5cGVbcHJvcHMuY2x1c3RlclR5cGVdLFxuICAgICk7XG4gICAgY29uc3QgZmFsbGJhY2tDb25zdHJ1Y3ROYW1lID0gW2NsdXN0ZXJUeXBlLCBwcm9wcy5jbHVzdGVySWQgPz8gXCJBTExcIl0uam9pbihcbiAgICAgIFwiLVwiLFxuICAgICk7XG4gICAgY29uc3QgbmFtaW5nU3RyYXRlZ3kgPSBuZXcgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5KHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZmFsbGJhY2tDb25zdHJ1Y3ROYW1lLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcbiAgICBpZiAocHJvcHMuY2x1c3RlcklkKSB7XG4gICAgICB0aGlzLmNsdXN0ZXJVcmwgPSBzY29wZVxuICAgICAgICAuY3JlYXRlQXdzQ29uc29sZVVybEZhY3RvcnkoKVxuICAgICAgICAuZ2V0RWxhc3RpQ2FjaGVDbHVzdGVyVXJsKHByb3BzLmNsdXN0ZXJJZCwgcHJvcHMuY2x1c3RlclR5cGUpO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgRWxhc3RpQ2FjaGVDbHVzdGVyTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzLFxuICAgICk7XG4gICAgdGhpcy5jb25uZWN0aW9uc01ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQXZlcmFnZUNvbm5lY3Rpb25zKCk7XG4gICAgdGhpcy5jcHVVc2FnZU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljTWF4Q3B1VXRpbGl6YXRpb25JblBlcmNlbnQoKTtcbiAgICB0aGlzLnJlZGlzRW5naW5lQ3B1VXNhZ2VNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNNYXhSZWRpc0VuZ2luZUNwdVV0aWxpemF0aW9uSW5QZXJjZW50KCk7XG4gICAgdGhpcy5mcmVlYWJsZU1lbW9yeU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0F2ZXJhZ2VGcmVlYWJsZU1lbW9yeUluQnl0ZXMoKTtcbiAgICB0aGlzLnVudXNlZE1lbW9yeU1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljQXZlcmFnZVVudXNlZE1lbW9yeUluQnl0ZXMoKTtcbiAgICB0aGlzLnN3YXBNZW1vcnlNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0F2ZXJhZ2VTd2FwVXNhZ2VJbkJ5dGVzKCk7XG4gICAgdGhpcy5pdGVtc01lbW9yeU1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0F2ZXJhZ2VDYWNoZWRJdGVtc1NpemVJbkJ5dGVzKCk7XG4gICAgdGhpcy5pdGVtc0NvdW50TWV0cmljcyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljTWF4SXRlbUNvdW50KCk7XG4gICAgdGhpcy5pdGVtc0V2aWN0ZWRNZXRyaWNzID0gbWV0cmljRmFjdG9yeS5tZXRyaWNFdmljdGlvbnMoKTtcblxuICAgIHRoaXMuY3B1VXNhZ2VBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMucmVkaXNFbmdpbmVDcHVVc2FnZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5pdGVtc0NvdW50QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmV2aWN0ZWRJdGVtc0NvdW50QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLm1lbW9yeVVzYWdlQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGNvbnN0IGFsYXJtRmFjdG9yeSA9IHRoaXMuY3JlYXRlQWxhcm1GYWN0b3J5KFxuICAgICAgbmFtaW5nU3RyYXRlZ3kucmVzb2x2ZUFsYXJtRnJpZW5kbHlOYW1lKCksXG4gICAgKTtcbiAgICB0aGlzLnVzYWdlQWxhcm1GYWN0b3J5ID0gbmV3IFVzYWdlQWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy5lbGFzdGlDYWNoZUFsYXJtRmFjdG9yeSA9IG5ldyBFbGFzdGlDYWNoZUFsYXJtRmFjdG9yeShhbGFybUZhY3RvcnkpO1xuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZENwdVVzYWdlQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRDcHVVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhDcHVVc2FnZVBlcmNlbnRBbGFybShcbiAgICAgICAgdGhpcy5jcHVVc2FnZU1ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmNwdVVzYWdlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcHJvcHMuYWRkUmVkaXNFbmdpbmVDcHVVc2FnZUFsYXJtICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHByb3BzLmNsdXN0ZXJUeXBlICE9PSBFbGFzdGlDYWNoZUNsdXN0ZXJUeXBlLlJFRElTXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiSXQgaXMgb25seSBwb3NzaWJsZSB0byBhbGFybSBvbiBSZWRpcyBFbmdpbmUgQ1BVIFVzYWdlIGZvciBSZWRpcyBjbHVzdGVyc1wiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkUmVkaXNFbmdpbmVDcHVVc2FnZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkUmVkaXNFbmdpbmVDcHVVc2FnZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy51c2FnZUFsYXJtRmFjdG9yeS5hZGRNYXhDcHVVc2FnZVBlcmNlbnRBbGFybShcbiAgICAgICAgdGhpcy5yZWRpc0VuZ2luZUNwdVVzYWdlTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIFwiUmVkaXNFbmdpbmVcIixcbiAgICAgICk7XG4gICAgICB0aGlzLnJlZGlzRW5naW5lQ3B1VXNhZ2VBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkTWF4SXRlbXNDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWF4SXRlbXNDb3VudEFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5lbGFzdGlDYWNoZUFsYXJtRmFjdG9yeS5hZGRNYXhJdGVtc0NvdW50QWxhcm0oXG4gICAgICAgIHRoaXMuaXRlbXNDb3VudE1ldHJpY3MsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5pdGVtc0NvdW50QW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRNYXhFdmljdGVkSXRlbXNDb3VudEFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWF4RXZpY3RlZEl0ZW1zQ291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgIHRoaXMuZWxhc3RpQ2FjaGVBbGFybUZhY3RvcnkuYWRkTWF4RXZpY3RlZEl0ZW1zQ291bnRBbGFybShcbiAgICAgICAgICB0aGlzLml0ZW1zRXZpY3RlZE1ldHJpY3MsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1xuICAgICAgdGhpcy5ldmljdGVkSXRlbXNDb3VudEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkTWluRnJlZWFibGVNZW1vcnlBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZE1pbkZyZWVhYmxlTWVtb3J5QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICB0aGlzLmVsYXN0aUNhY2hlQWxhcm1GYWN0b3J5LmFkZE1pbkZyZWVhYmxlTWVtb3J5QWxhcm0oXG4gICAgICAgICAgdGhpcy5mcmVlYWJsZU1lbW9yeU1ldHJpYyxcbiAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICk7XG4gICAgICB0aGlzLm1lbW9yeVVzYWdlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRNYXhVc2VkU3dhcE1lbW9yeUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkTWF4VXNlZFN3YXBNZW1vcnlBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgIHRoaXMuZWxhc3RpQ2FjaGVBbGFybUZhY3RvcnkuYWRkTWF4VXNlZFN3YXBNZW1vcnlBbGFybShcbiAgICAgICAgICB0aGlzLnN3YXBNZW1vcnlNZXRyaWMsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1xuICAgICAgdGhpcy5tZW1vcnlVc2FnZUFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIHByb3BzLnVzZUNyZWF0ZWRBbGFybXM/LmNvbnN1bWUodGhpcy5jcmVhdGVkQWxhcm1zKCkpO1xuICB9XG5cbiAgc3VtbWFyeVdpZGdldHMoKTogSVdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgdGhpcy5jcmVhdGVDcHVVc2FnZVdpZGdldChUaGlyZFdpZHRoLCBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCksXG4gICAgICB0aGlzLmNyZWF0ZU1lbW9yeVVzYWdlV2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlSXRlbUNvdW50V2lkZ2V0KFRoaXJkV2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgd2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIGlmICh0aGlzLmNsdXN0ZXJUeXBlID09PSBFbGFzdGlDYWNoZUNsdXN0ZXJUeXBlLlJFRElTKSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICAgIG5ldyBDb2x1bW4oXG4gICAgICAgICAgdGhpcy5jcmVhdGVDcHVVc2FnZVdpZGdldChcbiAgICAgICAgICAgIFF1YXJ0ZXJXaWR0aCxcbiAgICAgICAgICAgIERlZmF1bHRUd29MaW5lckdyYXBoV2lkZ2V0SGFsZkhlaWdodCxcbiAgICAgICAgICApLFxuICAgICAgICAgIHRoaXMuY3JlYXRlUmVkaXNFbmdpbmVDcHVVc2FnZVdpZGdldChcbiAgICAgICAgICAgIFF1YXJ0ZXJXaWR0aCxcbiAgICAgICAgICAgIERlZmF1bHRUd29MaW5lckdyYXBoV2lkZ2V0SGFsZkhlaWdodCxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgICB0aGlzLmNyZWF0ZU1lbW9yeVVzYWdlV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICAgdGhpcy5jcmVhdGVDb25uZWN0aW9uc1dpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAgIHRoaXMuY3JlYXRlSXRlbUNvdW50V2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgICAgdGhpcy5jcmVhdGVDcHVVc2FnZVdpZGdldChRdWFydGVyV2lkdGgsIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCksXG4gICAgICAgIHRoaXMuY3JlYXRlTWVtb3J5VXNhZ2VXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb25zV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICAgdGhpcy5jcmVhdGVJdGVtQ291bnRXaWRnZXQoUXVhcnRlcldpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgXTtcbiAgICB9XG4gIH1cblxuICBjcmVhdGVUaXRsZVdpZGdldCgpIHtcbiAgICByZXR1cm4gbmV3IE1vbml0b3JpbmdIZWFkZXJXaWRnZXQoe1xuICAgICAgZmFtaWx5OiBcIkVsYXN0aUNhY2hlIENsdXN0ZXJcIixcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgICAgZ29Ub0xpbmtVcmw6IHRoaXMuY2x1c3RlclVybCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNwdVVzYWdlV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNQVSBVdGlsaXphdGlvblwiLFxuICAgICAgbGVmdDogW3RoaXMuY3B1VXNhZ2VNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmNwdVVzYWdlQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVSZWRpc0VuZ2luZUNwdVVzYWdlV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkVuZ2luZSBDUFUgVXRpbGl6YXRpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLnJlZGlzRW5naW5lQ3B1VXNhZ2VNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLnJlZGlzRW5naW5lQ3B1VXNhZ2VBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZU1lbW9yeVVzYWdlV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIk1lbW9yeSBVdGlsaXphdGlvblwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLmZyZWVhYmxlTWVtb3J5TWV0cmljLFxuICAgICAgICB0aGlzLnVudXNlZE1lbW9yeU1ldHJpYyxcbiAgICAgICAgdGhpcy5zd2FwTWVtb3J5TWV0cmljLFxuICAgICAgXSxcbiAgICAgIGxlZnRZQXhpczogU2l6ZUF4aXNCeXRlc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLm1lbW9yeVVzYWdlQW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVJdGVtQ291bnRXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiSXRlbXNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLml0ZW1zQ291bnRNZXRyaWNzXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuaXRlbXNDb3VudEFubm90YXRpb25zLFxuICAgICAgcmlnaHQ6IFt0aGlzLml0ZW1zRXZpY3RlZE1ldHJpY3NdLFxuICAgICAgcmlnaHRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICByaWdodEFubm90YXRpb25zOiB0aGlzLmV2aWN0ZWRJdGVtc0NvdW50QW5ub3RhdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVDb25uZWN0aW9uc1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDb25uZWN0aW9uc1wiLFxuICAgICAgbGVmdDogW3RoaXMuY29ubmVjdGlvbnNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICB9KTtcbiAgfVxufVxuIl19