cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
236 lines • 37.6 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.KinesisDataAnalyticsMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const KinesisDataAnalyticsMetricFactory_1 = require("./KinesisDataAnalyticsMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class KinesisDataAnalyticsMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope, props);
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
fallbackConstructName: props.application,
});
this.title = namingStrategy.resolveHumanReadableName();
this.kinesisDataAnalyticsUrl = scope
.createAwsConsoleUrlFactory()
.getKinesisAnalyticsUrl(props.application);
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.kdaAlarmFactory = new common_1.KinesisDataAnalyticsAlarmFactory(alarmFactory);
this.downtimeAnnotations = [];
this.fullRestartAnnotations = [];
this.fullRestartRateAnnotations = [];
this.backPressuredTimeMsPerSecondAnnotations = [];
this.checkpointFailureCountAnnotations = [];
this.checkpointFailureRateAnnotations = [];
const metricFactory = new KinesisDataAnalyticsMetricFactory_1.KinesisDataAnalyticsMetricFactory(scope.createMetricFactory(), props);
this.cpuUtilizationPercentMetric =
metricFactory.metricCpuUtilizationPercent();
this.downtimeMsMetric = metricFactory.metricDowntimeMs();
this.fullRestartsCountMetric = metricFactory.metricFullRestartsCount();
this.heapMemoryUtilizationPercentMetric =
metricFactory.metricHeapMemoryUtilizationPercent();
this.kpusCountMetric = metricFactory.metricKPUsCount();
this.lastCheckpointDurationMsMetric =
metricFactory.metricLastCheckpointDurationMs();
this.lastCheckpointSizeBytesMetric =
metricFactory.metricLastCheckpointSizeBytes();
this.numberOfFailedCheckpointsCountMetric =
metricFactory.metricNumberOfFailedCheckpointsCount();
this.oldGenerationGCCountMetric =
metricFactory.metricOldGenerationGCCount();
this.oldGenerationGCTimeMsMetric =
metricFactory.metricOldGenerationGCTimeMs();
this.checkpointFailureRateMetric =
metricFactory.metricCheckpointFailureRate();
this.fullRestartRateMetric = metricFactory.metricFullRestartRate();
this.backPressuredTimeMsPerSecondMetric =
metricFactory.metricBackPressuredTimeMsPerSecond();
for (const disambiguator in props.addDowntimeAlarm) {
const alarmProps = props.addDowntimeAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addDowntimeAlarm(this.downtimeMsMetric, alarmProps, disambiguator);
this.downtimeAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addFullRestartCountAlarm) {
const alarmProps = props.addFullRestartCountAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addFullRestartAlarm(this.fullRestartsCountMetric, alarmProps, disambiguator);
this.fullRestartAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addFullRestartRateAlarm) {
const alarmProps = props.addFullRestartRateAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addFullRestartRateAlarm(this.fullRestartRateMetric, alarmProps, disambiguator);
this.fullRestartRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addBackPressuredTimeMsPerSecondAlarm) {
const alarmProps = props.addBackPressuredTimeMsPerSecondAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addBackPressuredTimeMsPerSecondAlarm(this.backPressuredTimeMsPerSecondMetric, alarmProps, disambiguator);
this.backPressuredTimeMsPerSecondAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addCheckpointFailureCountAlarm) {
const alarmProps = props.addCheckpointFailureCountAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addCheckpointFailureCountAlarm(this.numberOfFailedCheckpointsCountMetric, alarmProps, disambiguator);
this.checkpointFailureCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addCheckpointFailureRateAlarm) {
const alarmProps = props.addCheckpointFailureRateAlarm[disambiguator];
const createdAlarm = this.kdaAlarmFactory.addCheckpointFailureRateAlarm(this.checkpointFailureRateMetric, alarmProps, disambiguator);
this.checkpointFailureRateAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
return [
this.createTitleWidget(),
...this.createSummaryWidgetRow(common_1.DefaultSummaryWidgetHeight),
];
}
widgets() {
return [
this.createTitleWidget(),
...this.createSummaryWidgetRow(common_1.DefaultGraphWidgetHeight),
...this.createCheckpointAndGcWidgets(),
];
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "Kinesis Data Analytics",
title: this.title,
goToLinkUrl: this.kinesisDataAnalyticsUrl,
});
}
createKPUWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "KPU Usage",
left: [this.kpusCountMetric],
leftYAxis: common_1.CountAxisFromZero,
});
}
createResourceUtilizationWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Resource Utilization",
left: [
this.cpuUtilizationPercentMetric,
this.heapMemoryUtilizationPercentMetric,
],
leftYAxis: common_1.PercentageAxisFromZeroToHundred,
});
}
createDownTimeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Down Time",
left: [this.downtimeMsMetric],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.downtimeAnnotations,
});
}
createFullRestartsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Full Restarts",
left: [this.fullRestartsCountMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.fullRestartAnnotations,
right: [this.fullRestartRateMetric],
rightYAxis: common_1.RateAxisFromZero,
rightAnnotations: this.fullRestartRateAnnotations,
});
}
createBackPressuredTimeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Back Pressured Time",
left: [this.backPressuredTimeMsPerSecondMetric],
leftYAxis: common_1.TimeAxisMillisFromZero,
leftAnnotations: this.backPressuredTimeMsPerSecondAnnotations,
});
}
createNumberOfFailedCheckpointsWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Failures",
left: [this.numberOfFailedCheckpointsCountMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.checkpointFailureCountAnnotations,
right: [this.checkpointFailureRateMetric],
rightYAxis: common_1.RateAxisFromZero,
rightAnnotations: this.checkpointFailureRateAnnotations,
});
}
createLastCheckpointDurationWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Duration",
left: [this.lastCheckpointDurationMsMetric],
leftYAxis: common_1.TimeAxisMillisFromZero,
});
}
createLastCheckpointSizeWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Checkpoint Size",
left: [this.lastCheckpointSizeBytesMetric],
leftYAxis: common_1.SizeAxisBytesFromZero,
});
}
createGarbageCollectionWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Garbage Collection",
left: [this.oldGenerationGCCountMetric],
leftYAxis: common_1.CountAxisFromZero,
right: [this.oldGenerationGCTimeMsMetric],
rightYAxis: common_1.TimeAxisMillisFromZero,
});
}
createSummaryWidgetRow(height) {
return [
// KPUs
this.createKPUWidget(common_1.QuarterWidth, height),
// CPU And Heap Usage
this.createResourceUtilizationWidget(common_1.QuarterWidth, height),
// Down Time and Up Time
this.createDownTimeWidget(common_1.QuarterWidth, height),
// Full Restarts
this.createFullRestartsWidget(common_1.QuarterWidth, height),
];
}
createCheckpointAndGcWidgets() {
return [
// Back Pressure
this.createBackPressuredTimeWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Checkpointing
this.createNumberOfFailedCheckpointsWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Checkpoint Duration
this.createLastCheckpointDurationWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Checkpoint Size
this.createLastCheckpointSizeWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
// Garbage Collection
this.createGarbageCollectionWidget(common_1.QuarterWidth, common_1.DefaultGraphWidgetHeight),
];
}
}
exports.KinesisDataAnalyticsMonitoring = KinesisDataAnalyticsMonitoring;
_a = JSII_RTTI_SYMBOL_1;
KinesisDataAnalyticsMonitoring[_a] = { fqn: "cdk-monitoring-constructs.KinesisDataAnalyticsMonitoring", version: "10.0.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0RBSW9DO0FBRXBDLDJGQUc2QztBQUM3Qyx5Q0FtQnNCO0FBQ3RCLCtDQUd5QjtBQXdCekIsTUFBYSw4QkFBK0IsU0FBUSxtQkFBVTtJQTBCNUQsWUFDRSxLQUFzQixFQUN0QixLQUEwQztRQUUxQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXBCLE1BQU0sY0FBYyxHQUFHLElBQUksb0NBQXdCLENBQUM7WUFDbEQsR0FBRyxLQUFLO1lBQ1IscUJBQXFCLEVBQUUsS0FBSyxDQUFDLFdBQVc7U0FDekMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUN2RCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsS0FBSzthQUNqQywwQkFBMEIsRUFBRTthQUM1QixzQkFBc0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFN0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUMxQyxjQUFjLENBQUMsd0JBQXdCLEVBQUUsQ0FDMUMsQ0FBQztRQUNGLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSx5Q0FBZ0MsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsdUNBQXVDLEdBQUcsRUFBRSxDQUFDO1FBQ2xELElBQUksQ0FBQyxpQ0FBaUMsR0FBRyxFQUFFLENBQUM7UUFDNUMsSUFBSSxDQUFDLGdDQUFnQyxHQUFH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LENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxNQUFjO1FBQzNDLE9BQU87WUFDTCxPQUFPO1lBQ1AsSUFBSSxDQUFDLGVBQWUsQ0FBQyxxQkFBWSxFQUFFLE1BQU0sQ0FBQztZQUMxQyxxQkFBcUI7WUFDckIsSUFBSSxDQUFDLCtCQUErQixDQUFDLHFCQUFZLEVBQUUsTUFBTSxDQUFDO1lBQzFELHdCQUF3QjtZQUN4QixJQUFJLENBQUMsb0JBQW9CLENBQUMscUJBQVksRUFBRSxNQUFNLENBQUM7WUFDL0MsZ0JBQWdCO1lBQ2hCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxxQkFBWSxFQUFFLE1BQU0sQ0FBQztTQUNwRCxDQUFDO0lBQ0osQ0FBQztJQUVPLDRCQUE0QjtRQUNsQyxPQUFPO1lBQ0wsZ0JBQWdCO1lBQ2hCLElBQUksQ0FBQyw2QkFBNkIsQ0FDaEMscUJBQVksRUFDWixpQ0FBd0IsQ0FDekI7WUFDRCxnQkFBZ0I7WUFDaEIsSUFBSSxDQUFDLHFDQUFxQyxDQUN4QyxxQkFBWSxFQUNaLGlDQUF3QixDQUN6QjtZQUNELHNCQUFzQjtZQUN0QixJQUFJLENBQUMsa0NBQWtDLENBQ3JDLHFCQUFZLEVBQ1osaUNBQXdCLENBQ3pCO1lBQ0Qsa0JBQWtCO1lBQ2xCLElBQUksQ0FBQyw4QkFBOEIsQ0FDakMscUJBQVksRUFDWixpQ0FBd0IsQ0FDekI7WUFDRCxxQkFBcUI7WUFDckIsSUFBSSxDQUFDLDZCQUE2QixDQUNoQyxxQkFBWSxFQUNaLGlDQUF3QixDQUN6QjtTQUNGLENBQUM7SUFDSixDQUFDOztBQWxVSCx3RUFtVUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFdpZGdldCxcbiAgSG9yaXpvbnRhbEFubm90YXRpb24sXG4gIElXaWRnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuXG5pbXBvcnQge1xuICBLaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnksXG4gIEtpbmVzaXNEYXRhQW5hbHl0aWNzTWV0cmljRmFjdG9yeVByb3BzLFxufSBmcm9tIFwiLi9LaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnlcIjtcbmltcG9ydCB7XG4gIEJhc2VNb25pdG9yaW5nUHJvcHMsXG4gIENvdW50QXhpc0Zyb21aZXJvLFxuICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0LFxuICBFcnJvckNvdW50VGhyZXNob2xkLFxuICBFcnJvclJhdGVUaHJlc2hvbGQsXG4gIEZ1bGxSZXN0YXJ0Q291bnRUaHJlc2hvbGQsXG4gIEtpbmVzaXNEYXRhQW5hbHl0aWNzQWxhcm1GYWN0b3J5LFxuICBNYXhCYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kVGhyZXNob2xkLFxuICBNYXhEb3dudGltZVRocmVzaG9sZCxcbiAgTWV0cmljV2l0aEFsYXJtU3VwcG9ydCxcbiAgTW9uaXRvcmluZyxcbiAgTW9uaXRvcmluZ1Njb3BlLFxuICBQZXJjZW50YWdlQXhpc0Zyb21aZXJvVG9IdW5kcmVkLFxuICBRdWFydGVyV2lkdGgsXG4gIFJhdGVBeGlzRnJvbVplcm8sXG4gIFNpemVBeGlzQnl0ZXNGcm9tWmVybyxcbiAgVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbn0gZnJvbSBcIi4uLy4uL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTW9uaXRvcmluZ0hlYWRlcldpZGdldCxcbiAgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5LFxufSBmcm9tIFwiLi4vLi4vZGFzaGJvYXJkXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nT3B0aW9uc1xuICBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICByZWFkb25seSBhZGREb3dudGltZUFsYXJtPzogUmVjb3JkPHN0cmluZywgTWF4RG93bnRpbWVUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybT86IFJlY29yZDxzdHJpbmcsIEZ1bGxSZXN0YXJ0Q291bnRUaHJlc2hvbGQ+O1xuXG4gIHJlYWRvbmx5IGFkZEZ1bGxSZXN0YXJ0UmF0ZUFsYXJtPzogUmVjb3JkPHN0cmluZywgRXJyb3JSYXRlVGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRCYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kQWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIE1heEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRUaHJlc2hvbGRcbiAgPjtcblxuICByZWFkb25seSBhZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm0/OiBSZWNvcmQ8c3RyaW5nLCBFcnJvckNvdW50VGhyZXNob2xkPjtcblxuICByZWFkb25seSBhZGRDaGVja3BvaW50RmFpbHVyZVJhdGVBbGFybT86IFJlY29yZDxzdHJpbmcsIEVycm9yUmF0ZVRocmVzaG9sZD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nUHJvcHNcbiAgZXh0ZW5kcyBLaW5lc2lzRGF0YUFuYWx5dGljc01ldHJpY0ZhY3RvcnlQcm9wcyxcbiAgICBLaW5lc2lzRGF0YUFuYWx5dGljc01vbml0b3JpbmdPcHRpb25zIHt9XG5cbmV4cG9ydCBjbGFzcyBLaW5lc2lzRGF0YUFuYWx5dGljc01vbml0b3JpbmcgZXh0ZW5kcyBNb25pdG9yaW5nIHtcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcmVhZG9ubHkga2luZXNpc0RhdGFBbmFseXRpY3NVcmw/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkga2RhQWxhcm1GYWN0b3J5OiBLaW5lc2lzRGF0YUFuYWx5dGljc0FsYXJtRmFjdG9yeTtcbiAgcmVhZG9ubHkgZG93bnRpbWVBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgZnVsbFJlc3RhcnRBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgZnVsbFJlc3RhcnRSYXRlQW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG4gIHJlYWRvbmx5IGJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcbiAgcmVhZG9ubHkgY2hlY2twb2ludEZhaWx1cmVDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBjaGVja3BvaW50RmFpbHVyZVJhdGVBbm5vdGF0aW9uczogSG9yaXpvbnRhbEFubm90YXRpb25bXTtcblxuICByZWFkb25seSBjcHVVdGlsaXphdGlvblBlcmNlbnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGRvd250aW1lTXNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGZ1bGxSZXN0YXJ0c0NvdW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBoZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50TWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBrcHVzQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGxhc3RDaGVja3BvaW50RHVyYXRpb25Nc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgbGFzdENoZWNrcG9pbnRTaXplQnl0ZXNNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG51bWJlck9mRmFpbGVkQ2hlY2twb2ludHNDb3VudE1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgb2xkR2VuZXJhdGlvbkdDQ291bnRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IG9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBmdWxsUmVzdGFydFJhdGVNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRNZXRyaWM6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IE1vbml0b3JpbmdTY29wZSxcbiAgICBwcm9wczogS2luZXNpc0RhdGFBbmFseXRpY3NNb25pdG9yaW5nUHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBwcm9wcyk7XG5cbiAgICBjb25zdCBuYW1pbmdTdHJhdGVneSA9IG5ldyBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3koe1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBmYWxsYmFja0NvbnN0cnVjdE5hbWU6IHByb3BzLmFwcGxpY2F0aW9uLFxuICAgIH0pO1xuICAgIHRoaXMudGl0bGUgPSBuYW1pbmdTdHJhdGVneS5yZXNvbHZlSHVtYW5SZWFkYWJsZU5hbWUoKTtcbiAgICB0aGlzLmtpbmVzaXNEYXRhQW5hbHl0aWNzVXJsID0gc2NvcGVcbiAgICAgIC5jcmVhdGVBd3NDb25zb2xlVXJsRmFjdG9yeSgpXG4gICAgICAuZ2V0S2luZXNpc0FuYWx5dGljc1VybChwcm9wcy5hcHBsaWNhdGlvbik7XG5cbiAgICBjb25zdCBhbGFybUZhY3RvcnkgPSB0aGlzLmNyZWF0ZUFsYXJtRmFjdG9yeShcbiAgICAgIG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVBbGFybUZyaWVuZGx5TmFtZSgpLFxuICAgICk7XG4gICAgdGhpcy5rZGFBbGFybUZhY3RvcnkgPSBuZXcgS2luZXNpc0RhdGFBbmFseXRpY3NBbGFybUZhY3RvcnkoYWxhcm1GYWN0b3J5KTtcbiAgICB0aGlzLmRvd250aW1lQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmZ1bGxSZXN0YXJ0UmF0ZUFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5iYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kQW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlQ291bnRBbm5vdGF0aW9ucyA9IFtdO1xuICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlQW5ub3RhdGlvbnMgPSBbXTtcblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgS2luZXNpc0RhdGFBbmFseXRpY3NNZXRyaWNGYWN0b3J5KFxuICAgICAgc2NvcGUuY3JlYXRlTWV0cmljRmFjdG9yeSgpLFxuICAgICAgcHJvcHMsXG4gICAgKTtcblxuICAgIHRoaXMuY3B1VXRpbGl6YXRpb25QZXJjZW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ3B1VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5kb3dudGltZU1zTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNEb3dudGltZU1zKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpYyA9IG1ldHJpY0ZhY3RvcnkubWV0cmljRnVsbFJlc3RhcnRzQ291bnQoKTtcbiAgICB0aGlzLmhlYXBNZW1vcnlVdGlsaXphdGlvblBlcmNlbnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNIZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50KCk7XG4gICAgdGhpcy5rcHVzQ291bnRNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0tQVXNDb3VudCgpO1xuICAgIHRoaXMubGFzdENoZWNrcG9pbnREdXJhdGlvbk1zTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljTGFzdENoZWNrcG9pbnREdXJhdGlvbk1zKCk7XG4gICAgdGhpcy5sYXN0Q2hlY2twb2ludFNpemVCeXRlc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0xhc3RDaGVja3BvaW50U2l6ZUJ5dGVzKCk7XG4gICAgdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWMgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ0NvdW50TWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljT2xkR2VuZXJhdGlvbkdDQ291bnQoKTtcbiAgICB0aGlzLm9sZEdlbmVyYXRpb25HQ1RpbWVNc01ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY09sZEdlbmVyYXRpb25HQ1RpbWVNcygpO1xuICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljQ2hlY2twb2ludEZhaWx1cmVSYXRlKCk7XG4gICAgdGhpcy5mdWxsUmVzdGFydFJhdGVNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0Z1bGxSZXN0YXJ0UmF0ZSgpO1xuICAgIHRoaXMuYmFja1ByZXNzdXJlZFRpbWVNc1BlclNlY29uZE1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0JhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmQoKTtcblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGREb3dudGltZUFsYXJtKSB7XG4gICAgICBjb25zdCBhbGFybVByb3BzID0gcHJvcHMuYWRkRG93bnRpbWVBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZERvd250aW1lQWxhcm0oXG4gICAgICAgIHRoaXMuZG93bnRpbWVNc01ldHJpYyxcbiAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICk7XG4gICAgICB0aGlzLmRvd250aW1lQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEZ1bGxSZXN0YXJ0Q291bnRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9IHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZEZ1bGxSZXN0YXJ0QWxhcm0oXG4gICAgICAgIHRoaXMuZnVsbFJlc3RhcnRzQ291bnRNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5mdWxsUmVzdGFydEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRGdWxsUmVzdGFydFJhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZEZ1bGxSZXN0YXJ0UmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkRnVsbFJlc3RhcnRSYXRlQWxhcm0oXG4gICAgICAgIHRoaXMuZnVsbFJlc3RhcnRSYXRlTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuZnVsbFJlc3RhcnRSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkaXNhbWJpZ3VhdG9yIGluIHByb3BzLmFkZEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9XG4gICAgICAgIHByb3BzLmFkZEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgIHRoaXMua2RhQWxhcm1GYWN0b3J5LmFkZEJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRBbGFybShcbiAgICAgICAgICB0aGlzLmJhY2tQcmVzc3VyZWRUaW1lTXNQZXJTZWNvbmRNZXRyaWMsXG4gICAgICAgICAgYWxhcm1Qcm9wcyxcbiAgICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgICApO1xuICAgICAgdGhpcy5iYWNrUHJlc3N1cmVkVGltZU1zUGVyU2Vjb25kQW5ub3RhdGlvbnMucHVzaChcbiAgICAgICAgY3JlYXRlZEFsYXJtLmFubm90YXRpb24sXG4gICAgICApO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmtkYUFsYXJtRmFjdG9yeS5hZGRDaGVja3BvaW50RmFpbHVyZUNvdW50QWxhcm0oXG4gICAgICAgIHRoaXMubnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c0NvdW50TWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVDb3VudEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRDaGVja3BvaW50RmFpbHVyZVJhdGVBbGFybSkge1xuICAgICAgY29uc3QgYWxhcm1Qcm9wcyA9IHByb3BzLmFkZENoZWNrcG9pbnRGYWlsdXJlUmF0ZUFsYXJtW2Rpc2FtYmlndWF0b3JdO1xuICAgICAgY29uc3QgY3JlYXRlZEFsYXJtID0gdGhpcy5rZGFBbGFybUZhY3RvcnkuYWRkQ2hlY2twb2ludEZhaWx1cmVSYXRlQWxhcm0oXG4gICAgICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljLFxuICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICBkaXNhbWJpZ3VhdG9yLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlQW5ub3RhdGlvbnMucHVzaChjcmVhdGVkQWxhcm0uYW5ub3RhdGlvbik7XG4gICAgICB0aGlzLmFkZEFsYXJtKGNyZWF0ZWRBbGFybSk7XG4gICAgfVxuXG4gICAgcHJvcHMudXNlQ3JlYXRlZEFsYXJtcz8uY29uc3VtZSh0aGlzLmNyZWF0ZWRBbGFybXMoKSk7XG4gIH1cblxuICBzdW1tYXJ5V2lkZ2V0cygpOiBJV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLmNyZWF0ZVRpdGxlV2lkZ2V0KCksXG4gICAgICAuLi50aGlzLmNyZWF0ZVN1bW1hcnlXaWRnZXRSb3coRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgIF07XG4gIH1cblxuICB3aWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIC4uLnRoaXMuY3JlYXRlU3VtbWFyeVdpZGdldFJvdyhEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpLFxuICAgICAgLi4udGhpcy5jcmVhdGVDaGVja3BvaW50QW5kR2NXaWRnZXRzKCksXG4gICAgXTtcbiAgfVxuXG4gIGNyZWF0ZVRpdGxlV2lkZ2V0KCkge1xuICAgIHJldHVybiBuZXcgTW9uaXRvcmluZ0hlYWRlcldpZGdldCh7XG4gICAgICBmYW1pbHk6IFwiS2luZXNpcyBEYXRhIEFuYWx5dGljc1wiLFxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXG4gICAgICBnb1RvTGlua1VybDogdGhpcy5raW5lc2lzRGF0YUFuYWx5dGljc1VybCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUtQVVdpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJLUFUgVXNhZ2VcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmtwdXNDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlUmVzb3VyY2VVdGlsaXphdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJSZXNvdXJjZSBVdGlsaXphdGlvblwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLmNwdVV0aWxpemF0aW9uUGVyY2VudE1ldHJpYyxcbiAgICAgICAgdGhpcy5oZWFwTWVtb3J5VXRpbGl6YXRpb25QZXJjZW50TWV0cmljLFxuICAgICAgXSxcbiAgICAgIGxlZnRZQXhpczogUGVyY2VudGFnZUF4aXNGcm9tWmVyb1RvSHVuZHJlZCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZURvd25UaW1lV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkRvd24gVGltZVwiLFxuICAgICAgbGVmdDogW3RoaXMuZG93bnRpbWVNc01ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuZG93bnRpbWVBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUZ1bGxSZXN0YXJ0c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJGdWxsIFJlc3RhcnRzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5mdWxsUmVzdGFydHNDb3VudE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgICAgbGVmdEFubm90YXRpb25zOiB0aGlzLmZ1bGxSZXN0YXJ0QW5ub3RhdGlvbnMsXG4gICAgICByaWdodDogW3RoaXMuZnVsbFJlc3RhcnRSYXRlTWV0cmljXSxcbiAgICAgIHJpZ2h0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICByaWdodEFubm90YXRpb25zOiB0aGlzLmZ1bGxSZXN0YXJ0UmF0ZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQmFja1ByZXNzdXJlZFRpbWVXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiQmFjayBQcmVzc3VyZWQgVGltZVwiLFxuICAgICAgbGVmdDogW3RoaXMuYmFja1ByZXNzdXJlZFRpbWVNc1BlclNlY29uZE1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuYmFja1ByZXNzdXJlZFRpbWVNc1BlclNlY29uZEFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTnVtYmVyT2ZGYWlsZWRDaGVja3BvaW50c1dpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDaGVja3BvaW50IEZhaWx1cmVzXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5udW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzQ291bnRNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBDb3VudEF4aXNGcm9tWmVybyxcbiAgICAgIGxlZnRBbm5vdGF0aW9uczogdGhpcy5jaGVja3BvaW50RmFpbHVyZUNvdW50QW5ub3RhdGlvbnMsXG4gICAgICByaWdodDogW3RoaXMuY2hlY2twb2ludEZhaWx1cmVSYXRlTWV0cmljXSxcbiAgICAgIHJpZ2h0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICByaWdodEFubm90YXRpb25zOiB0aGlzLmNoZWNrcG9pbnRGYWlsdXJlUmF0ZUFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTGFzdENoZWNrcG9pbnREdXJhdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDaGVja3BvaW50IER1cmF0aW9uXCIsXG4gICAgICBsZWZ0OiBbdGhpcy5sYXN0Q2hlY2twb2ludER1cmF0aW9uTXNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTGFzdENoZWNrcG9pbnRTaXplV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIkNoZWNrcG9pbnQgU2l6ZVwiLFxuICAgICAgbGVmdDogW3RoaXMubGFzdENoZWNrcG9pbnRTaXplQnl0ZXNNZXRyaWNdLFxuICAgICAgbGVmdFlBeGlzOiBTaXplQXhpc0J5dGVzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVHYXJiYWdlQ29sbGVjdGlvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJHYXJiYWdlIENvbGxlY3Rpb25cIixcbiAgICAgIGxlZnQ6IFt0aGlzLm9sZEdlbmVyYXRpb25HQ0NvdW50TWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICByaWdodDogW3RoaXMub2xkR2VuZXJhdGlvbkdDVGltZU1zTWV0cmljXSxcbiAgICAgIHJpZ2h0WUF4aXM6IFRpbWVBeGlzTWlsbGlzRnJvbVplcm8sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVN1bW1hcnlXaWRnZXRSb3coaGVpZ2h0OiBudW1iZXIpOiBHcmFwaFdpZGdldFtdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gS1BVc1xuICAgICAgdGhpcy5jcmVhdGVLUFVXaWRnZXQoUXVhcnRlcldpZHRoLCBoZWlnaHQpLFxuICAgICAgLy8gQ1BVIEFuZCBIZWFwIFVzYWdlXG4gICAgICB0aGlzLmNyZWF0ZVJlc291cmNlVXRpbGl6YXRpb25XaWRnZXQoUXVhcnRlcldpZHRoLCBoZWlnaHQpLFxuICAgICAgLy8gRG93biBUaW1lIGFuZCBVcCBUaW1lXG4gICAgICB0aGlzLmNyZWF0ZURvd25UaW1lV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICAgIC8vIEZ1bGwgUmVzdGFydHNcbiAgICAgIHRoaXMuY3JlYXRlRnVsbFJlc3RhcnRzV2lkZ2V0KFF1YXJ0ZXJXaWR0aCwgaGVpZ2h0KSxcbiAgICBdO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDaGVja3BvaW50QW5kR2NXaWRnZXRzKCk6IEdyYXBoV2lkZ2V0W10ge1xuICAgIHJldHVybiBbXG4gICAgICAvLyBCYWNrIFByZXNzdXJlXG4gICAgICB0aGlzLmNyZWF0ZUJhY2tQcmVzc3VyZWRUaW1lV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgICAvLyBDaGVja3BvaW50aW5nXG4gICAgICB0aGlzLmNyZWF0ZU51bWJlck9mRmFpbGVkQ2hlY2twb2ludHNXaWRnZXQoXG4gICAgICAgIFF1YXJ0ZXJXaWR0aCxcbiAgICAgICAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICAgICAgKSxcbiAgICAgIC8vIENoZWNrcG9pbnQgRHVyYXRpb25cbiAgICAgIHRoaXMuY3JlYXRlTGFzdENoZWNrcG9pbnREdXJhdGlvbldpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgICAgLy8gQ2hlY2twb2ludCBTaXplXG4gICAgICB0aGlzLmNyZWF0ZUxhc3RDaGVja3BvaW50U2l6ZVdpZGdldChcbiAgICAgICAgUXVhcnRlcldpZHRoLFxuICAgICAgICBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQsXG4gICAgICApLFxuICAgICAgLy8gR2FyYmFnZSBDb2xsZWN0aW9uXG4gICAgICB0aGlzLmNyZWF0ZUdhcmJhZ2VDb2xsZWN0aW9uV2lkZ2V0KFxuICAgICAgICBRdWFydGVyV2lkdGgsXG4gICAgICAgIERlZmF1bHRHcmFwaFdpZGdldEhlaWdodCxcbiAgICAgICksXG4gICAgXTtcbiAgfVxufVxuIl19