cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
150 lines • 26.8 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.KinesisFirehoseMonitoring = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
const KinesisFirehoseMetricFactory_1 = require("./KinesisFirehoseMetricFactory");
const common_1 = require("../../common");
const dashboard_1 = require("../../dashboard");
class KinesisFirehoseMonitoring extends common_1.Monitoring {
constructor(scope, props) {
super(scope);
const namingStrategy = new dashboard_1.MonitoringNamingStrategy({
...props,
fallbackConstructName: props.deliveryStreamName,
});
this.title = namingStrategy.resolveHumanReadableName();
this.streamUrl = scope
.createAwsConsoleUrlFactory()
.getKinesisFirehoseDeliveryStreamUrl(props.deliveryStreamName);
const metricFactory = new KinesisFirehoseMetricFactory_1.KinesisFirehoseMetricFactory(scope.createMetricFactory(), props);
const alarmFactory = this.createAlarmFactory(namingStrategy.resolveAlarmFriendlyName());
this.kinesisAlarmFactory = new common_1.KinesisAlarmFactory(alarmFactory);
this.recordCountAnnotations = [];
this.incomingLimitAnnotations = [{ value: 1, label: "100% usage" }];
this.incomingBytesMetric = metricFactory.metricIncomingBytes();
this.incomingRecordsMetric = metricFactory.metricIncomingRecordCount();
this.throttledRecordsMetric = metricFactory.metricThrottledRecordCount();
this.isDataFormatConversionEnabled =
props.isDataFormatConversionEnabled ?? true;
this.successfulConversionMetric =
metricFactory.metricSuccessfulConversionCount();
this.failedConversionMetric = metricFactory.metricFailedConversionCount();
this.putRecordLatency = metricFactory.metricPutRecordLatencyP90InMillis();
this.putRecordBatchLatency =
metricFactory.metricPutRecordBatchLatencyP90InMillis();
this.incomingBytesToLimitRate =
metricFactory.metricIncomingBytesToLimitRate();
this.incomingRecordsToLimitRate =
metricFactory.metricIncomingRecordsToLimitRate();
this.incomingPutRequestsToLimitRate =
metricFactory.metricIncomingPutRequestsToLimitRate();
for (const disambiguator in props.addRecordsThrottledAlarm) {
const alarmProps = props.addRecordsThrottledAlarm[disambiguator];
const createdAlarm = this.kinesisAlarmFactory.addPutRecordsThrottledAlarm(this.throttledRecordsMetric, alarmProps, disambiguator);
this.recordCountAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addIncomingBytesExceedThresholdAlarm) {
const alarmProps = props.addIncomingBytesExceedThresholdAlarm[disambiguator];
const createdAlarm = this.kinesisAlarmFactory.addFirehoseStreamExceedSafetyThresholdAlarm(this.incomingBytesToLimitRate, "IncomingBytes", "BytesPerSecondLimit", alarmProps, disambiguator);
this.incomingLimitAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addIncomingRecordsExceedThresholdAlarm) {
const alarmProps = props.addIncomingRecordsExceedThresholdAlarm[disambiguator];
const createdAlarm = this.kinesisAlarmFactory.addFirehoseStreamExceedSafetyThresholdAlarm(this.incomingRecordsToLimitRate, "IncomingRecords", "RecordsPerSecondLimit", alarmProps, disambiguator);
this.incomingLimitAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
for (const disambiguator in props.addIncomingPutRequestsExceedThresholdAlarm) {
const alarmProps = props.addIncomingPutRequestsExceedThresholdAlarm[disambiguator];
const createdAlarm = this.kinesisAlarmFactory.addFirehoseStreamExceedSafetyThresholdAlarm(this.incomingPutRequestsToLimitRate, "IncomingPutRequests", "PutRequestsPerSecondLimit", alarmProps, disambiguator);
this.incomingLimitAnnotations.push(createdAlarm.annotation);
this.addAlarm(createdAlarm);
}
props.useCreatedAlarms?.consume(this.createdAlarms());
}
summaryWidgets() {
const widgetWidth = this.isDataFormatConversionEnabled
? common_1.HalfWidth
: common_1.FullWidth;
const widgets = [
this.createTitleWidget(),
this.createIncomingRecordWidget(widgetWidth, common_1.DefaultSummaryWidgetHeight),
];
if (this.isDataFormatConversionEnabled) {
widgets.push(this.createConversionWidget(widgetWidth, common_1.DefaultSummaryWidgetHeight));
}
return widgets;
}
widgets() {
const widgetWidth = this.isDataFormatConversionEnabled
? common_1.QuarterWidth
: common_1.ThirdWidth;
let widgets = [
this.createTitleWidget(),
this.createIncomingRecordWidget(widgetWidth, common_1.DefaultGraphWidgetHeight),
this.createLatencyWidget(widgetWidth, common_1.DefaultGraphWidgetHeight),
];
if (this.isDataFormatConversionEnabled) {
widgets.push(this.createConversionWidget(widgetWidth, common_1.DefaultGraphWidgetHeight));
}
widgets.push(this.createLimitWidget(widgetWidth, common_1.DefaultGraphWidgetHeight));
return widgets;
}
createTitleWidget() {
return new dashboard_1.MonitoringHeaderWidget({
family: "Firehose Delivery Stream",
title: this.title,
goToLinkUrl: this.streamUrl,
});
}
createIncomingRecordWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Records",
left: [this.incomingRecordsMetric, this.throttledRecordsMetric],
leftYAxis: common_1.CountAxisFromZero,
leftAnnotations: this.recordCountAnnotations,
});
}
createLatencyWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Latency (P90)",
left: [this.putRecordLatency, this.putRecordBatchLatency],
leftYAxis: common_1.TimeAxisMillisFromZero,
});
}
createConversionWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Conversions",
left: [this.successfulConversionMetric, this.failedConversionMetric],
leftYAxis: common_1.CountAxisFromZero,
});
}
createLimitWidget(width, height) {
return new aws_cloudwatch_1.GraphWidget({
width,
height,
title: "Limits (rate)",
left: [
this.incomingBytesToLimitRate.with({ label: "Bytes" }),
this.incomingRecordsToLimitRate.with({ label: "Records" }),
this.incomingPutRequestsToLimitRate.with({ label: "PutRequests" }),
],
leftYAxis: common_1.RateAxisFromZero,
leftAnnotations: this.incomingLimitAnnotations,
});
}
}
exports.KinesisFirehoseMonitoring = KinesisFirehoseMonitoring;
_a = JSII_RTTI_SYMBOL_1;
KinesisFirehoseMonitoring[_a] = { fqn: "cdk-monitoring-constructs.KinesisFirehoseMonitoring", version: "9.15.2" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2luZXNpc0ZpcmVob3NlTW9uaXRvcmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIktpbmVzaXNGaXJlaG9zZU1vbml0b3JpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwrREFJb0M7QUFFcEMsaUZBR3dDO0FBQ3hDLHlDQWlCc0I7QUFDdEIsK0NBR3lCO0FBOEJ6QixNQUFhLHlCQUEwQixTQUFRLG1CQUFVO0lBc0J2RCxZQUFZLEtBQXNCLEVBQUUsS0FBcUM7UUFDdkUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsTUFBTSxjQUFjLEdBQUcsSUFBSSxvQ0FBd0IsQ0FBQztZQUNsRCxHQUFHLEtBQUs7WUFDUixxQkFBcUIsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1NBQ2hELENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLO2FBQ25CLDBCQUEwQixFQUFFO2FBQzVCLG1DQUFtQyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRWpFLE1BQU0sYUFBYSxHQUFHLElBQUksMkRBQTRCLENBQ3BELEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxFQUMzQixLQUFLLENBQ04sQ0FBQztRQUNGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FDMUMsY0FBYyxDQUFDLHdCQUF3QixFQUFFLENBQzFDLENBQUM7UUFDRixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSw0QkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUVwRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcs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RUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUM7WUFDcEUsU0FBUyxFQUFFLDBCQUFpQjtTQUM3QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsaUJBQWlCLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDN0MsT0FBTyxJQUFJLDRCQUFXLENBQUM7WUFDckIsS0FBSztZQUNMLE1BQU07WUFDTixLQUFLLEVBQUUsZUFBZTtZQUN0QixJQUFJLEVBQUU7Z0JBQ0osSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQztnQkFDMUQsSUFBSSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsQ0FBQzthQUNuRTtZQUNELFNBQVMsRUFBRSx5QkFBZ0I7WUFDM0IsZUFBZSxFQUFFLElBQUksQ0FBQyx3QkFBd0I7U0FDL0MsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUFqTkgsOERBa05DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhXaWRnZXQsXG4gIEhvcml6b250YWxBbm5vdGF0aW9uLFxuICBJV2lkZ2V0LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcblxuaW1wb3J0IHtcbiAgS2luZXNpc0ZpcmVob3NlTWV0cmljRmFjdG9yeSxcbiAgS2luZXNpc0ZpcmVob3NlTWV0cmljRmFjdG9yeVByb3BzLFxufSBmcm9tIFwiLi9LaW5lc2lzRmlyZWhvc2VNZXRyaWNGYWN0b3J5XCI7XG5pbXBvcnQge1xuICBCYXNlTW9uaXRvcmluZ1Byb3BzLFxuICBDb3VudEF4aXNGcm9tWmVybyxcbiAgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0LFxuICBEZWZhdWx0U3VtbWFyeVdpZGdldEhlaWdodCxcbiAgSGFsZldpZHRoLFxuICBLaW5lc2lzQWxhcm1GYWN0b3J5LFxuICBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0LFxuICBNb25pdG9yaW5nLFxuICBNb25pdG9yaW5nU2NvcGUsXG4gIFF1YXJ0ZXJXaWR0aCxcbiAgUmF0ZUF4aXNGcm9tWmVybyxcbiAgUmVjb3Jkc1Rocm90dGxlZFRocmVzaG9sZCxcbiAgRmlyZWhvc2VTdHJlYW1MaW1pdFRocmVzaG9sZCxcbiAgVGltZUF4aXNNaWxsaXNGcm9tWmVybyxcbiAgRnVsbFdpZHRoLFxuICBUaGlyZFdpZHRoLFxufSBmcm9tIFwiLi4vLi4vY29tbW9uXCI7XG5pbXBvcnQge1xuICBNb25pdG9yaW5nSGVhZGVyV2lkZ2V0LFxuICBNb25pdG9yaW5nTmFtaW5nU3RyYXRlZ3ksXG59IGZyb20gXCIuLi8uLi9kYXNoYm9hcmRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBLaW5lc2lzRmlyZWhvc2VNb25pdG9yaW5nT3B0aW9ucyBleHRlbmRzIEJhc2VNb25pdG9yaW5nUHJvcHMge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIEtpbmVzaXMgRmlyZWhvc2UgaGFzIHJlY29yZCBmb3JtYXQgY29udmVyc2lvbiBlbmFibGVkLlxuICAgKiBUaGlzIGltcGFjdHMgd2hhdCB3aWRnZXRzIGFyZSBzaG93bi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0cnVlXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2ZpcmVob3NlL2xhdGVzdC9kZXYvZW5hYmxlLXJlY29yZC1mb3JtYXQtY29udmVyc2lvbi5odG1sXG4gICAqL1xuICByZWFkb25seSBpc0RhdGFGb3JtYXRDb252ZXJzaW9uRW5hYmxlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFkZFJlY29yZHNUaHJvdHRsZWRBbGFybT86IFJlY29yZDxzdHJpbmcsIFJlY29yZHNUaHJvdHRsZWRUaHJlc2hvbGQ+O1xuICByZWFkb25seSBhZGRJbmNvbWluZ0J5dGVzRXhjZWVkVGhyZXNob2xkQWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIEZpcmVob3NlU3RyZWFtTGltaXRUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkSW5jb21pbmdSZWNvcmRzRXhjZWVkVGhyZXNob2xkQWxhcm0/OiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIEZpcmVob3NlU3RyZWFtTGltaXRUaHJlc2hvbGRcbiAgPjtcbiAgcmVhZG9ubHkgYWRkSW5jb21pbmdQdXRSZXF1ZXN0c0V4Y2VlZFRocmVzaG9sZEFsYXJtPzogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBGaXJlaG9zZVN0cmVhbUxpbWl0VGhyZXNob2xkXG4gID47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2luZXNpc0ZpcmVob3NlTW9uaXRvcmluZ1Byb3BzXG4gIGV4dGVuZHMgS2luZXNpc0ZpcmVob3NlTWV0cmljRmFjdG9yeVByb3BzLFxuICAgIEtpbmVzaXNGaXJlaG9zZU1vbml0b3JpbmdPcHRpb25zIHt9XG5cbmV4cG9ydCBjbGFzcyBLaW5lc2lzRmlyZWhvc2VNb25pdG9yaW5nIGV4dGVuZHMgTW9uaXRvcmluZyB7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHN0cmVhbVVybD86IHN0cmluZztcblxuICByZWFkb25seSBraW5lc2lzQWxhcm1GYWN0b3J5OiBLaW5lc2lzQWxhcm1GYWN0b3J5O1xuICByZWFkb25seSByZWNvcmRDb3VudEFubm90YXRpb25zOiBIb3Jpem9udGFsQW5ub3RhdGlvbltdO1xuICByZWFkb25seSBpbmNvbWluZ0xpbWl0QW5ub3RhdGlvbnM6IEhvcml6b250YWxBbm5vdGF0aW9uW107XG5cbiAgcmVhZG9ubHkgaW5jb21pbmdCeXRlc01ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgaW5jb21pbmdSZWNvcmRzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSB0aHJvdHRsZWRSZWNvcmRzTWV0cmljOiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuXG4gIHJlYWRvbmx5IGlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkOiBib29sZWFuO1xuICByZWFkb25seSBzdWNjZXNzZnVsQ29udmVyc2lvbk1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgZmFpbGVkQ29udmVyc2lvbk1ldHJpYzogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICByZWFkb25seSBwdXRSZWNvcmRMYXRlbmN5OiBNZXRyaWNXaXRoQWxhcm1TdXBwb3J0O1xuICByZWFkb25seSBwdXRSZWNvcmRCYXRjaExhdGVuY3k6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGluY29taW5nQnl0ZXNUb0xpbWl0UmF0ZTogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcbiAgcmVhZG9ubHkgaW5jb21pbmdSZWNvcmRzVG9MaW1pdFJhdGU6IE1ldHJpY1dpdGhBbGFybVN1cHBvcnQ7XG4gIHJlYWRvbmx5IGluY29taW5nUHV0UmVxdWVzdHNUb0xpbWl0UmF0ZTogTWV0cmljV2l0aEFsYXJtU3VwcG9ydDtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogTW9uaXRvcmluZ1Njb3BlLCBwcm9wczogS2luZXNpc0ZpcmVob3NlTW9uaXRvcmluZ1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUpO1xuXG4gICAgY29uc3QgbmFtaW5nU3RyYXRlZ3kgPSBuZXcgTW9uaXRvcmluZ05hbWluZ1N0cmF0ZWd5KHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgZmFsbGJhY2tDb25zdHJ1Y3ROYW1lOiBwcm9wcy5kZWxpdmVyeVN0cmVhbU5hbWUsXG4gICAgfSk7XG4gICAgdGhpcy50aXRsZSA9IG5hbWluZ1N0cmF0ZWd5LnJlc29sdmVIdW1hblJlYWRhYmxlTmFtZSgpO1xuICAgIHRoaXMuc3RyZWFtVXJsID0gc2NvcGVcbiAgICAgIC5jcmVhdGVBd3NDb25zb2xlVXJsRmFjdG9yeSgpXG4gICAgICAuZ2V0S2luZXNpc0ZpcmVob3NlRGVsaXZlcnlTdHJlYW1VcmwocHJvcHMuZGVsaXZlcnlTdHJlYW1OYW1lKTtcblxuICAgIGNvbnN0IG1ldHJpY0ZhY3RvcnkgPSBuZXcgS2luZXNpc0ZpcmVob3NlTWV0cmljRmFjdG9yeShcbiAgICAgIHNjb3BlLmNyZWF0ZU1ldHJpY0ZhY3RvcnkoKSxcbiAgICAgIHByb3BzLFxuICAgICk7XG4gICAgY29uc3QgYWxhcm1GYWN0b3J5ID0gdGhpcy5jcmVhdGVBbGFybUZhY3RvcnkoXG4gICAgICBuYW1pbmdTdHJhdGVneS5yZXNvbHZlQWxhcm1GcmllbmRseU5hbWUoKSxcbiAgICApO1xuICAgIHRoaXMua2luZXNpc0FsYXJtRmFjdG9yeSA9IG5ldyBLaW5lc2lzQWxhcm1GYWN0b3J5KGFsYXJtRmFjdG9yeSk7XG4gICAgdGhpcy5yZWNvcmRDb3VudEFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5pbmNvbWluZ0xpbWl0QW5ub3RhdGlvbnMgPSBbeyB2YWx1ZTogMSwgbGFiZWw6IFwiMTAwJSB1c2FnZVwiIH1dO1xuXG4gICAgdGhpcy5pbmNvbWluZ0J5dGVzTWV0cmljID0gbWV0cmljRmFjdG9yeS5tZXRyaWNJbmNvbWluZ0J5dGVzKCk7XG4gICAgdGhpcy5pbmNvbWluZ1JlY29yZHNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0luY29taW5nUmVjb3JkQ291bnQoKTtcbiAgICB0aGlzLnRocm90dGxlZFJlY29yZHNNZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY1Rocm90dGxlZFJlY29yZENvdW50KCk7XG5cbiAgICB0aGlzLmlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkID1cbiAgICAgIHByb3BzLmlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkID8/IHRydWU7XG4gICAgdGhpcy5zdWNjZXNzZnVsQ29udmVyc2lvbk1ldHJpYyA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY1N1Y2Nlc3NmdWxDb252ZXJzaW9uQ291bnQoKTtcbiAgICB0aGlzLmZhaWxlZENvbnZlcnNpb25NZXRyaWMgPSBtZXRyaWNGYWN0b3J5Lm1ldHJpY0ZhaWxlZENvbnZlcnNpb25Db3VudCgpO1xuICAgIHRoaXMucHV0UmVjb3JkTGF0ZW5jeSA9IG1ldHJpY0ZhY3RvcnkubWV0cmljUHV0UmVjb3JkTGF0ZW5jeVA5MEluTWlsbGlzKCk7XG4gICAgdGhpcy5wdXRSZWNvcmRCYXRjaExhdGVuY3kgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNQdXRSZWNvcmRCYXRjaExhdGVuY3lQOTBJbk1pbGxpcygpO1xuICAgIHRoaXMuaW5jb21pbmdCeXRlc1RvTGltaXRSYXRlID1cbiAgICAgIG1ldHJpY0ZhY3RvcnkubWV0cmljSW5jb21pbmdCeXRlc1RvTGltaXRSYXRlKCk7XG4gICAgdGhpcy5pbmNvbWluZ1JlY29yZHNUb0xpbWl0UmF0ZSA9XG4gICAgICBtZXRyaWNGYWN0b3J5Lm1ldHJpY0luY29taW5nUmVjb3Jkc1RvTGltaXRSYXRlKCk7XG4gICAgdGhpcy5pbmNvbWluZ1B1dFJlcXVlc3RzVG9MaW1pdFJhdGUgPVxuICAgICAgbWV0cmljRmFjdG9yeS5tZXRyaWNJbmNvbWluZ1B1dFJlcXVlc3RzVG9MaW1pdFJhdGUoKTtcblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRSZWNvcmRzVGhyb3R0bGVkQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPSBwcm9wcy5hZGRSZWNvcmRzVGhyb3R0bGVkQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPSB0aGlzLmtpbmVzaXNBbGFybUZhY3RvcnkuYWRkUHV0UmVjb3Jkc1Rocm90dGxlZEFsYXJtKFxuICAgICAgICB0aGlzLnRocm90dGxlZFJlY29yZHNNZXRyaWMsXG4gICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICApO1xuICAgICAgdGhpcy5yZWNvcmRDb3VudEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRJbmNvbWluZ0J5dGVzRXhjZWVkVGhyZXNob2xkQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPVxuICAgICAgICBwcm9wcy5hZGRJbmNvbWluZ0J5dGVzRXhjZWVkVGhyZXNob2xkQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICB0aGlzLmtpbmVzaXNBbGFybUZhY3RvcnkuYWRkRmlyZWhvc2VTdHJlYW1FeGNlZWRTYWZldHlUaHJlc2hvbGRBbGFybShcbiAgICAgICAgICB0aGlzLmluY29taW5nQnl0ZXNUb0xpbWl0UmF0ZSxcbiAgICAgICAgICBcIkluY29taW5nQnl0ZXNcIixcbiAgICAgICAgICBcIkJ5dGVzUGVyU2Vjb25kTGltaXRcIixcbiAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICk7XG4gICAgICB0aGlzLmluY29taW5nTGltaXRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGRpc2FtYmlndWF0b3IgaW4gcHJvcHMuYWRkSW5jb21pbmdSZWNvcmRzRXhjZWVkVGhyZXNob2xkQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPVxuICAgICAgICBwcm9wcy5hZGRJbmNvbWluZ1JlY29yZHNFeGNlZWRUaHJlc2hvbGRBbGFybVtkaXNhbWJpZ3VhdG9yXTtcbiAgICAgIGNvbnN0IGNyZWF0ZWRBbGFybSA9XG4gICAgICAgIHRoaXMua2luZXNpc0FsYXJtRmFjdG9yeS5hZGRGaXJlaG9zZVN0cmVhbUV4Y2VlZFNhZmV0eVRocmVzaG9sZEFsYXJtKFxuICAgICAgICAgIHRoaXMuaW5jb21pbmdSZWNvcmRzVG9MaW1pdFJhdGUsXG4gICAgICAgICAgXCJJbmNvbWluZ1JlY29yZHNcIixcbiAgICAgICAgICBcIlJlY29yZHNQZXJTZWNvbmRMaW1pdFwiLFxuICAgICAgICAgIGFsYXJtUHJvcHMsXG4gICAgICAgICAgZGlzYW1iaWd1YXRvcixcbiAgICAgICAgKTtcbiAgICAgIHRoaXMuaW5jb21pbmdMaW1pdEFubm90YXRpb25zLnB1c2goY3JlYXRlZEFsYXJtLmFubm90YXRpb24pO1xuICAgICAgdGhpcy5hZGRBbGFybShjcmVhdGVkQWxhcm0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGlzYW1iaWd1YXRvciBpbiBwcm9wcy5hZGRJbmNvbWluZ1B1dFJlcXVlc3RzRXhjZWVkVGhyZXNob2xkQWxhcm0pIHtcbiAgICAgIGNvbnN0IGFsYXJtUHJvcHMgPVxuICAgICAgICBwcm9wcy5hZGRJbmNvbWluZ1B1dFJlcXVlc3RzRXhjZWVkVGhyZXNob2xkQWxhcm1bZGlzYW1iaWd1YXRvcl07XG4gICAgICBjb25zdCBjcmVhdGVkQWxhcm0gPVxuICAgICAgICB0aGlzLmtpbmVzaXNBbGFybUZhY3RvcnkuYWRkRmlyZWhvc2VTdHJlYW1FeGNlZWRTYWZldHlUaHJlc2hvbGRBbGFybShcbiAgICAgICAgICB0aGlzLmluY29taW5nUHV0UmVxdWVzdHNUb0xpbWl0UmF0ZSxcbiAgICAgICAgICBcIkluY29taW5nUHV0UmVxdWVzdHNcIixcbiAgICAgICAgICBcIlB1dFJlcXVlc3RzUGVyU2Vjb25kTGltaXRcIixcbiAgICAgICAgICBhbGFybVByb3BzLFxuICAgICAgICAgIGRpc2FtYmlndWF0b3IsXG4gICAgICAgICk7XG4gICAgICB0aGlzLmluY29taW5nTGltaXRBbm5vdGF0aW9ucy5wdXNoKGNyZWF0ZWRBbGFybS5hbm5vdGF0aW9uKTtcbiAgICAgIHRoaXMuYWRkQWxhcm0oY3JlYXRlZEFsYXJtKTtcbiAgICB9XG5cbiAgICBwcm9wcy51c2VDcmVhdGVkQWxhcm1zPy5jb25zdW1lKHRoaXMuY3JlYXRlZEFsYXJtcygpKTtcbiAgfVxuXG4gIHN1bW1hcnlXaWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgY29uc3Qgd2lkZ2V0V2lkdGggPSB0aGlzLmlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkXG4gICAgICA/IEhhbGZXaWR0aFxuICAgICAgOiBGdWxsV2lkdGg7XG4gICAgY29uc3Qgd2lkZ2V0cyA9IFtcbiAgICAgIHRoaXMuY3JlYXRlVGl0bGVXaWRnZXQoKSxcbiAgICAgIHRoaXMuY3JlYXRlSW5jb21pbmdSZWNvcmRXaWRnZXQod2lkZ2V0V2lkdGgsIERlZmF1bHRTdW1tYXJ5V2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICAgIGlmICh0aGlzLmlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkKSB7XG4gICAgICB3aWRnZXRzLnB1c2goXG4gICAgICAgIHRoaXMuY3JlYXRlQ29udmVyc2lvbldpZGdldCh3aWRnZXRXaWR0aCwgRGVmYXVsdFN1bW1hcnlXaWRnZXRIZWlnaHQpLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHdpZGdldHM7XG4gIH1cblxuICB3aWRnZXRzKCk6IElXaWRnZXRbXSB7XG4gICAgY29uc3Qgd2lkZ2V0V2lkdGggPSB0aGlzLmlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkXG4gICAgICA/IFF1YXJ0ZXJXaWR0aFxuICAgICAgOiBUaGlyZFdpZHRoO1xuICAgIGxldCB3aWRnZXRzID0gW1xuICAgICAgdGhpcy5jcmVhdGVUaXRsZVdpZGdldCgpLFxuICAgICAgdGhpcy5jcmVhdGVJbmNvbWluZ1JlY29yZFdpZGdldCh3aWRnZXRXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgIHRoaXMuY3JlYXRlTGF0ZW5jeVdpZGdldCh3aWRnZXRXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICBdO1xuICAgIGlmICh0aGlzLmlzRGF0YUZvcm1hdENvbnZlcnNpb25FbmFibGVkKSB7XG4gICAgICB3aWRnZXRzLnB1c2goXG4gICAgICAgIHRoaXMuY3JlYXRlQ29udmVyc2lvbldpZGdldCh3aWRnZXRXaWR0aCwgRGVmYXVsdEdyYXBoV2lkZ2V0SGVpZ2h0KSxcbiAgICAgICk7XG4gICAgfVxuICAgIHdpZGdldHMucHVzaCh0aGlzLmNyZWF0ZUxpbWl0V2lkZ2V0KHdpZGdldFdpZHRoLCBEZWZhdWx0R3JhcGhXaWRnZXRIZWlnaHQpKTtcbiAgICByZXR1cm4gd2lkZ2V0cztcbiAgfVxuXG4gIGNyZWF0ZVRpdGxlV2lkZ2V0KCkge1xuICAgIHJldHVybiBuZXcgTW9uaXRvcmluZ0hlYWRlcldpZGdldCh7XG4gICAgICBmYW1pbHk6IFwiRmlyZWhvc2UgRGVsaXZlcnkgU3RyZWFtXCIsXG4gICAgICB0aXRsZTogdGhpcy50aXRsZSxcbiAgICAgIGdvVG9MaW5rVXJsOiB0aGlzLnN0cmVhbVVybCxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUluY29taW5nUmVjb3JkV2lkZ2V0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBHcmFwaFdpZGdldCh7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHRpdGxlOiBcIlJlY29yZHNcIixcbiAgICAgIGxlZnQ6IFt0aGlzLmluY29taW5nUmVjb3Jkc01ldHJpYywgdGhpcy50aHJvdHRsZWRSZWNvcmRzTWV0cmljXSxcbiAgICAgIGxlZnRZQXhpczogQ291bnRBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMucmVjb3JkQ291bnRBbm5vdGF0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUxhdGVuY3lXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiTGF0ZW5jeSAoUDkwKVwiLFxuICAgICAgbGVmdDogW3RoaXMucHV0UmVjb3JkTGF0ZW5jeSwgdGhpcy5wdXRSZWNvcmRCYXRjaExhdGVuY3ldLFxuICAgICAgbGVmdFlBeGlzOiBUaW1lQXhpc01pbGxpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQ29udmVyc2lvbldpZGdldCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgR3JhcGhXaWRnZXQoe1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB0aXRsZTogXCJDb252ZXJzaW9uc1wiLFxuICAgICAgbGVmdDogW3RoaXMuc3VjY2Vzc2Z1bENvbnZlcnNpb25NZXRyaWMsIHRoaXMuZmFpbGVkQ29udmVyc2lvbk1ldHJpY10sXG4gICAgICBsZWZ0WUF4aXM6IENvdW50QXhpc0Zyb21aZXJvLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlTGltaXRXaWRnZXQod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IEdyYXBoV2lkZ2V0KHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgdGl0bGU6IFwiTGltaXRzIChyYXRlKVwiLFxuICAgICAgbGVmdDogW1xuICAgICAgICB0aGlzLmluY29taW5nQnl0ZXNUb0xpbWl0UmF0ZS53aXRoKHsgbGFiZWw6IFwiQnl0ZXNcIiB9KSxcbiAgICAgICAgdGhpcy5pbmNvbWluZ1JlY29yZHNUb0xpbWl0UmF0ZS53aXRoKHsgbGFiZWw6IFwiUmVjb3Jkc1wiIH0pLFxuICAgICAgICB0aGlzLmluY29taW5nUHV0UmVxdWVzdHNUb0xpbWl0UmF0ZS53aXRoKHsgbGFiZWw6IFwiUHV0UmVxdWVzdHNcIiB9KSxcbiAgICAgIF0sXG4gICAgICBsZWZ0WUF4aXM6IFJhdGVBeGlzRnJvbVplcm8sXG4gICAgICBsZWZ0QW5ub3RhdGlvbnM6IHRoaXMuaW5jb21pbmdMaW1pdEFubm90YXRpb25zLFxuICAgIH0pO1xuICB9XG59XG4iXX0=