@renovosolutions/cdk-library-cloudwatch-alarms
Version:
AWS CDK Construct Library to automatically create CloudWatch Alarms for resources in a CDK app based on resource type.
393 lines • 68.3 kB
JavaScript
"use strict";
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SfRecommendedAlarmsAspect = exports.StateMachine = exports.SfStateMachineRecommendedAlarms = exports.SfStateMachineExecutionsTimedOutAlarm = exports.SfStateMachineExecutionsFailedAlarm = exports.SfStateMachineExecutionThrottledAlarm = exports.SfStateMachineExecutionTimeAlarm = exports.SfRecommendedAlarmsMetrics = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const constructs_1 = require("constructs");
const common_1 = require("./common");
/**
* The recommended metrics for StepFunctions alarms.
*/
var SfRecommendedAlarmsMetrics;
(function (SfRecommendedAlarmsMetrics) {
/**
* Interval, in milliseconds, between the time the execution starts and the time it closes.
*/
SfRecommendedAlarmsMetrics["EXECUTION_TIME"] = "ExecutionTime";
/**
* Number of StateEntered events and retries that have been throttled. This is related to
* StateTransition throttling. For more information, see Quotas related to state throttling.
*/
SfRecommendedAlarmsMetrics["EXECUTION_THROTTLED"] = "ExecutionThrottled";
/**
* Number of failed executions.
*/
SfRecommendedAlarmsMetrics["EXECUTIONS_FAILED"] = "ExecutionsFailed";
/**
* Number of executions that time out for any reason.
*/
SfRecommendedAlarmsMetrics["EXECUTIONS_TIMED_OUT"] = "ExecutionsTimedOut";
})(SfRecommendedAlarmsMetrics || (exports.SfRecommendedAlarmsMetrics = SfRecommendedAlarmsMetrics = {}));
/**
* This metric can be a valuable tool for early detection of issues that might not be immediately apparent from other metrics.
*
* A sudden increase in execution time might indicate issues with the steps of the resources they interact with.
*
* The alarm is triggered when the time in milliseconds exceed the threshold.
*/
class SfStateMachineExecutionTimeAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm {
constructor(scope, id, props) {
const alarmName = props.alarmName ?? `${props.stateMachine.stateMachineName} - ${SfRecommendedAlarmsMetrics.EXECUTION_TIME}`;
const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1);
const evaluationPeriods = props.evaluationPeriods ?? 5;
const datapointsToAlarm = props.datapointsToAlarm ?? 5;
const threshold = props.threshold;
const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING;
const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect sudden increases in execution time.';
(0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName);
super(scope, id, {
alarmName,
metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({
namespace: 'AWS/States',
metricName: SfRecommendedAlarmsMetrics.EXECUTION_TIME,
dimensionsMap: {
StateMachineArn: props.stateMachine.stateMachineArn,
},
period,
statistic: 'Average',
}),
threshold,
evaluationPeriods,
datapointsToAlarm,
treatMissingData,
comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
alarmDescription,
});
if (props.alarmAction)
this.addAlarmAction(props.alarmAction);
if (props.okAction)
this.addOkAction(props.okAction);
if (props.insufficientDataAction)
this.addInsufficientDataAction(props.insufficientDataAction);
}
}
exports.SfStateMachineExecutionTimeAlarm = SfStateMachineExecutionTimeAlarm;
_a = JSII_RTTI_SYMBOL_1;
SfStateMachineExecutionTimeAlarm[_a] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.SfStateMachineExecutionTimeAlarm", version: "0.0.13" };
;
/**
* The ExecutionThrottled metric tracks the number of times state machine executions are throttled due to exceeding AWS service limits.
*
* Monitoring this can help you identify when you are hitting this limits, which could signal that adjustments need to be made either in
* the process design or in the service limits themselves.
*
* The alarm is triggered when the number of executions throttled exceed the threshold.
*/
class SfStateMachineExecutionThrottledAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm {
constructor(scope, id, props) {
const alarmName = props.alarmName ?? `${props.stateMachine.stateMachineName} - ${SfRecommendedAlarmsMetrics.EXECUTION_THROTTLED}`;
const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1);
const evaluationPeriods = props.evaluationPeriods ?? 5;
const datapointsToAlarm = props.datapointsToAlarm ?? 5;
const threshold = props.threshold ?? 5;
const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING;
const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect throttled executions due to exceeding AWS service limits.';
(0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName);
super(scope, id, {
alarmName,
metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({
namespace: 'AWS/States',
metricName: SfRecommendedAlarmsMetrics.EXECUTION_THROTTLED,
dimensionsMap: {
StateMachineArn: props.stateMachine.stateMachineArn,
},
period,
statistic: 'Sum',
}),
threshold,
evaluationPeriods,
datapointsToAlarm,
treatMissingData,
comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
alarmDescription,
});
if (props.alarmAction)
this.addAlarmAction(props.alarmAction);
if (props.okAction)
this.addOkAction(props.okAction);
if (props.insufficientDataAction)
this.addInsufficientDataAction(props.insufficientDataAction);
}
}
exports.SfStateMachineExecutionThrottledAlarm = SfStateMachineExecutionThrottledAlarm;
_b = JSII_RTTI_SYMBOL_1;
SfStateMachineExecutionThrottledAlarm[_b] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.SfStateMachineExecutionThrottledAlarm", version: "0.0.13" };
;
/**
* It helps in tracking the number of executions that fail in AWS Step Functions. This is crucial for identifying workflows that are
* not performing as expected and require attention.
*
* By monitoring the failures, developers can proactively identify and resolve issues before they impact the business operations. This reduces
* downtime and improves the overall stability of applications.
*
* The alarm is triggered when the number of failed executions exceed the threshold.
*/
class SfStateMachineExecutionsFailedAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm {
constructor(scope, id, props) {
const alarmName = props.alarmName ?? `${props.stateMachine.stateMachineName} - ${SfRecommendedAlarmsMetrics.EXECUTIONS_FAILED}`;
const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1);
const evaluationPeriods = props.evaluationPeriods ?? 5;
const datapointsToAlarm = props.datapointsToAlarm ?? 5;
const threshold = props.threshold ?? 5;
const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING;
const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect workflows that are not working as expected.';
(0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName);
super(scope, id, {
alarmName,
metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({
namespace: 'AWS/States',
metricName: SfRecommendedAlarmsMetrics.EXECUTIONS_FAILED,
dimensionsMap: {
StateMachineArn: props.stateMachine.stateMachineArn,
},
period,
statistic: 'Sum',
}),
threshold,
evaluationPeriods,
datapointsToAlarm,
treatMissingData,
comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
alarmDescription,
});
if (props.alarmAction)
this.addAlarmAction(props.alarmAction);
if (props.okAction)
this.addOkAction(props.okAction);
if (props.insufficientDataAction)
this.addInsufficientDataAction(props.insufficientDataAction);
}
}
exports.SfStateMachineExecutionsFailedAlarm = SfStateMachineExecutionsFailedAlarm;
_c = JSII_RTTI_SYMBOL_1;
SfStateMachineExecutionsFailedAlarm[_c] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.SfStateMachineExecutionsFailedAlarm", version: "0.0.13" };
;
/**
* This alarm helps in identifying timeouts in state machine executions.
*
* This can indicate problems like poor configuration, inadequate resource allocation, or issues in the called services that need addressing.
*
* The alarm is triggered when the number of timed out executions exceed the threshold.
*/
class SfStateMachineExecutionsTimedOutAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm {
constructor(scope, id, props) {
const alarmName = props.alarmName ?? `${props.stateMachine.stateMachineName} - ${SfRecommendedAlarmsMetrics.EXECUTIONS_TIMED_OUT}`;
const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1);
const evaluationPeriods = props.evaluationPeriods ?? 5;
const datapointsToAlarm = props.datapointsToAlarm ?? 5;
const threshold = props.threshold ?? 5;
const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING;
const alarmDescription = props.alarmDescription ?? 'This alarm helps in identifying timeouts in state machine executions due to poor configuration,'
+ ' inadequate resource allocation, or issues in the called services that need addressing.';
(0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName);
super(scope, id, {
alarmName,
metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({
namespace: 'AWS/States',
metricName: SfRecommendedAlarmsMetrics.EXECUTIONS_TIMED_OUT,
dimensionsMap: {
StateMachineArn: props.stateMachine.stateMachineArn,
},
period,
statistic: 'Sum',
}),
threshold,
evaluationPeriods,
datapointsToAlarm,
treatMissingData,
comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
alarmDescription,
});
if (props.alarmAction)
this.addAlarmAction(props.alarmAction);
if (props.okAction)
this.addOkAction(props.okAction);
if (props.insufficientDataAction)
this.addInsufficientDataAction(props.insufficientDataAction);
}
}
exports.SfStateMachineExecutionsTimedOutAlarm = SfStateMachineExecutionsTimedOutAlarm;
_d = JSII_RTTI_SYMBOL_1;
SfStateMachineExecutionsTimedOutAlarm[_d] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.SfStateMachineExecutionsTimedOutAlarm", version: "0.0.13" };
;
/**
* A construct that creates the recommended alarms for an StepFunctions StateMachine.
*/
class SfStateMachineRecommendedAlarms extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
if (!props.excludeAlarms?.includes(SfRecommendedAlarmsMetrics.EXECUTION_TIME)) {
this.alarmExecutionTime = new SfStateMachineExecutionTimeAlarm(this, `${props.stateMachine.node.id}_ExecutionTime`, {
stateMachine: props.stateMachine,
treatMissingData: props.treatMissingData,
...props.configExecutionTimeAlarm,
});
if (props.defaultAlarmAction &&
(!props.configExecutionTimeAlarm || !props.configExecutionTimeAlarm.alarmAction)) {
this.alarmExecutionTime.addAlarmAction(props.defaultAlarmAction);
}
if (props.defaultOkAction &&
(!props.configExecutionTimeAlarm || !props.configExecutionTimeAlarm.okAction)) {
this.alarmExecutionTime.addOkAction(props.defaultOkAction);
}
if (props.defaultInsufficientDataAction &&
(!props.configExecutionTimeAlarm || !props.configExecutionTimeAlarm.insufficientDataAction)) {
this.alarmExecutionTime.addInsufficientDataAction(props.defaultInsufficientDataAction);
}
}
if (!props.excludeAlarms?.includes(SfRecommendedAlarmsMetrics.EXECUTION_THROTTLED)) {
this.alarmExecutionThrottled = new SfStateMachineExecutionThrottledAlarm(this, `${props.stateMachine.node.id}_ExecutionThrottled`, {
stateMachine: props.stateMachine,
treatMissingData: props.treatMissingData,
...props.configExecutionThrottledAlarm,
});
if (props.defaultAlarmAction &&
(!props.configExecutionThrottledAlarm || !props.configExecutionThrottledAlarm.alarmAction)) {
this.alarmExecutionThrottled.addAlarmAction(props.defaultAlarmAction);
}
if (props.defaultOkAction &&
(!props.configExecutionThrottledAlarm || !props.configExecutionThrottledAlarm.okAction)) {
this.alarmExecutionThrottled.addOkAction(props.defaultOkAction);
}
if (props.defaultInsufficientDataAction &&
(!props.configExecutionThrottledAlarm || !props.configExecutionThrottledAlarm.insufficientDataAction)) {
this.alarmExecutionThrottled.addInsufficientDataAction(props.defaultInsufficientDataAction);
}
}
if (!props.excludeAlarms?.includes(SfRecommendedAlarmsMetrics.EXECUTIONS_FAILED)) {
this.alarmExecutionsFailed = new SfStateMachineExecutionsFailedAlarm(this, `${props.stateMachine.node.id}_ExecutionsFailed`, {
stateMachine: props.stateMachine,
treatMissingData: props.treatMissingData,
...props.configExecutionsFailedAlarm,
});
if (props.defaultAlarmAction &&
(!props.configExecutionsFailedAlarm || !props.configExecutionsFailedAlarm.alarmAction)) {
this.alarmExecutionsFailed.addAlarmAction(props.defaultAlarmAction);
}
if (props.defaultOkAction &&
(!props.configExecutionsFailedAlarm || !props.configExecutionsFailedAlarm.okAction)) {
this.alarmExecutionsFailed.addOkAction(props.defaultOkAction);
}
if (props.defaultInsufficientDataAction &&
(!props.configExecutionsFailedAlarm || !props.configExecutionsFailedAlarm.insufficientDataAction)) {
this.alarmExecutionsFailed.addInsufficientDataAction(props.defaultInsufficientDataAction);
}
}
if (!props.excludeAlarms?.includes(SfRecommendedAlarmsMetrics.EXECUTIONS_TIMED_OUT)) {
this.alarmExecutionsTimedOut = new SfStateMachineExecutionsTimedOutAlarm(this, `${props.stateMachine.node.id}_ExecutionsTimedOut`, {
stateMachine: props.stateMachine,
treatMissingData: props.treatMissingData,
...props.configExecutionsTimedOutAlarm,
});
if (props.defaultAlarmAction &&
(!props.configExecutionsTimedOutAlarm || !props.configExecutionsTimedOutAlarm.alarmAction)) {
this.alarmExecutionsTimedOut.addAlarmAction(props.defaultAlarmAction);
}
if (props.defaultOkAction &&
(!props.configExecutionsTimedOutAlarm || !props.configExecutionsTimedOutAlarm.okAction)) {
this.alarmExecutionsTimedOut.addOkAction(props.defaultOkAction);
}
if (props.defaultInsufficientDataAction &&
(!props.configExecutionsTimedOutAlarm || !props.configExecutionsTimedOutAlarm.insufficientDataAction)) {
this.alarmExecutionsTimedOut.addInsufficientDataAction(props.defaultInsufficientDataAction);
}
}
}
}
exports.SfStateMachineRecommendedAlarms = SfStateMachineRecommendedAlarms;
_e = JSII_RTTI_SYMBOL_1;
SfStateMachineRecommendedAlarms[_e] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.SfStateMachineRecommendedAlarms", version: "0.0.13" };
/**
* An extension for the StateMachine construct that provides methods
* to create recommended alarms.
*/
class StateMachine extends aws_cdk_lib_1.aws_stepfunctions.StateMachine {
constructor(scope, id, props) {
super(scope, id, props);
}
/**
* Creates an alarm that monitors the ExecutionTime for the StepFunctions stateMachine.
*/
alarmExecutionTime(props) {
return new SfStateMachineExecutionTimeAlarm(this, 'ExecutionTimeAlarm', {
stateMachine: this,
...props,
});
}
/**
* Creates an alarm that monitors the ExecutionThrottled for the StepFunctions stateMachine.
*/
alarmExecutionThrottled(props) {
return new SfStateMachineExecutionThrottledAlarm(this, 'ExecutionThrottledAlarm', {
stateMachine: this,
...props,
});
}
/**
* Creates an alarm that monitors the ExecutionsFailed for the StepFunctions stateMachine.
*/
alarmExecutionsFailed(props) {
return new SfStateMachineExecutionsFailedAlarm(this, 'ExecutionsFailedAlarm', {
stateMachine: this,
...props,
});
}
/**
* Creates an alarm that monitors the ExecutionsTimedOut for the StepFunctions stateMachine.
*/
alarmExecutionsTimedOut(props) {
return new SfStateMachineExecutionsTimedOutAlarm(this, 'ExecutionsTimedOutAlarm', {
stateMachine: this,
...props,
});
}
/**
* Creates the recommended alarms for the StepFunctions StateMachine.
*/
applyRecommendedAlarms(props) {
return new SfStateMachineRecommendedAlarms(this, 'SfStateMachineRecommendedAlarms', {
stateMachine: this,
...props,
});
}
}
exports.StateMachine = StateMachine;
_f = JSII_RTTI_SYMBOL_1;
StateMachine[_f] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.StateMachine", version: "0.0.13" };
/**
* Configures the alarms for an StepFunctions StateMachine.
*/
class SfRecommendedAlarmsAspect {
constructor(props) {
this.props = props;
}
visit(node) {
if (node instanceof aws_cdk_lib_1.aws_stepfunctions.StateMachine) {
if (this.props.excludeResources && this.props.excludeResources.includes(node.node.id)) {
return;
}
else {
const stateMachine = node;
new SfStateMachineRecommendedAlarms(stateMachine, 'SfStateMachineRecommendedAlarmsFromAspect', {
stateMachine,
...this.props,
});
}
}
}
}
exports.SfRecommendedAlarmsAspect = SfRecommendedAlarmsAspect;
_g = JSII_RTTI_SYMBOL_1;
SfRecommendedAlarmsAspect[_g] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.SfRecommendedAlarmsAspect", version: "0.0.13" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUtxQjtBQUNyQiwyQ0FBbUQ7QUFDbkQscUNBQW9FO0FBRXBFOztHQUVHO0FBQ0gsSUFBWSwwQkFrQlg7QUFsQkQsV0FBWSwwQkFBMEI7SUFDcEM7O09BRUc7SUFDSCw4REFBZ0MsQ0FBQTtJQUNoQzs7O09BR0c7SUFDSCx3RUFBMEMsQ0FBQTtJQUMxQzs7T0FFRztJQUNILG9FQUFzQyxDQUFBO0lBQ3RDOztPQUVHO0lBQ0gseUVBQTJDLENBQUE7QUFDN0MsQ0FBQyxFQWxCVywwQkFBMEIsMENBQTFCLDBCQUEwQixRQWtCckM7QUFrRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBYSxnQ0FBaUMsU0FBUSw0QkFBVSxDQUFDLEtBQUs7SUFDcEUsWUFBWSxLQUFpQixFQUFFLEVBQVUsRUFBRSxLQUE0QztRQUNyRixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxJQUFJLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsTUFBTSwwQkFBMEIsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM3SCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ELE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixJQUFJLENBQUMsQ0FBQztRQUN2RCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLENBQUM7UUFDdkQsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUNsQyxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSw0QkFBVSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztRQUN2RixNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsSUFB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NEM7UUFDeEUsT0FBTyxJQUFJLCtCQUErQixDQUFDLElBQUksRUFBRSxpQ0FBaUMsRUFBRTtZQUNsRixZQUFZLEVBQUUsSUFBSTtZQUNsQixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXJESCxvQ0FzREM7OztBQUVEOztHQUVHO0FBQ0gsTUFBYSx5QkFBeUI7SUFDcEMsWUFBNkIsS0FBNEM7UUFBNUMsVUFBSyxHQUFMLEtBQUssQ0FBdUM7SUFBRyxDQUFDO0lBRXRFLEtBQUssQ0FBQyxJQUFnQjtRQUMzQixJQUFJLElBQUksWUFBWSwrQkFBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3JDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RGLE9BQU87WUFDVCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxZQUFZLEdBQUcsSUFBd0IsQ0FBQztnQkFFOUMsSUFBSSwrQkFBK0IsQ0FBQyxZQUFZLEVBQUUsMkNBQTJDLEVBQUU7b0JBQzdGLFlBQVk7b0JBQ1osR0FBRyxJQUFJLENBQUMsS0FBSztpQkFDZCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7O0FBaEJILDhEQWlCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIElBc3BlY3QsXG4gIGF3c19zdGVwZnVuY3Rpb25zIGFzIHNmbixcbiAgYXdzX2Nsb3Vkd2F0Y2ggYXMgY2xvdWR3YXRjaCxcbiAgRHVyYXRpb24sXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCwgSUNvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQWxhcm1CYXNlUHJvcHMsIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZCB9IGZyb20gJy4vY29tbW9uJztcblxuLyoqXG4gKiBUaGUgcmVjb21tZW5kZWQgbWV0cmljcyBmb3IgU3RlcEZ1bmN0aW9ucyBhbGFybXMuXG4gKi9cbmV4cG9ydCBlbnVtIFNmUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzIHtcbiAgLyoqXG4gICAqIEludGVydmFsLCBpbiBtaWxsaXNlY29uZHMsIGJldHdlZW4gdGhlIHRpbWUgdGhlIGV4ZWN1dGlvbiBzdGFydHMgYW5kIHRoZSB0aW1lIGl0IGNsb3Nlcy5cbiAgICovXG4gIEVYRUNVVElPTl9USU1FID0gJ0V4ZWN1dGlvblRpbWUnLFxuICAvKipcbiAgICogTnVtYmVyIG9mIFN0YXRlRW50ZXJlZCBldmVudHMgYW5kIHJldHJpZXMgdGhhdCBoYXZlIGJlZW4gdGhyb3R0bGVkLiBUaGlzIGlzIHJlbGF0ZWQgdG9cbiAgICogU3RhdGVUcmFuc2l0aW9uIHRocm90dGxpbmcuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgUXVvdGFzIHJlbGF0ZWQgdG8gc3RhdGUgdGhyb3R0bGluZy5cbiAgICovXG4gIEVYRUNVVElPTl9USFJPVFRMRUQgPSAnRXhlY3V0aW9uVGhyb3R0bGVkJyxcbiAgLyoqXG4gICAqIE51bWJlciBvZiBmYWlsZWQgZXhlY3V0aW9ucy5cbiAgICovXG4gIEVYRUNVVElPTlNfRkFJTEVEID0gJ0V4ZWN1dGlvbnNGYWlsZWQnLFxuICAvKipcbiAgICogTnVtYmVyIG9mIGV4ZWN1dGlvbnMgdGhhdCB0aW1lIG91dCBmb3IgYW55IHJlYXNvbi5cbiAgICovXG4gIEVYRUNVVElPTlNfVElNRURfT1VUID0gJ0V4ZWN1dGlvbnNUaW1lZE91dCcsXG59XG5cbi8qKlxuICogVGhlIGNvbW1vbiBvcHRpb25hbCBjb25maWd1cmF0aW9uIGZvciB0aGUgYWxhcm1zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNmQWxhcm1CYXNlQ29uZmlnIGV4dGVuZHMgQWxhcm1CYXNlUHJvcHMge1xuICAvKipcbiAgICogVGhlIHBlcmlvZCBvdmVyIHdoaWNoIHRoZSBzcGVjaWZpZWQgc3RhdGlzdGljIGlzIGFwcGxpZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLm1pbnV0ZXMoMSlcbiAgICovXG4gIHJlYWRvbmx5IHBlcmlvZD86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIFRoZSBjb21tb24gcHJvcGVydGllcyBmb3IgdGhlIFN0ZXBGdW5jdGlvbnMgU3RhdGVNYWNoaW5lIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZlN0YXRlTWFjaGluZUFsYXJtUHJvcHMge1xuICAvKipcbiAgICogVGhlIFN0YXRlTWFjaGluZSB0byBtb25pdG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGVNYWNoaW5lOiBzZm4uU3RhdGVNYWNoaW5lO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBFeGVjdXRpb25UaW1lIGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uVGltZUFsYXJtQ29uZmlnIGV4dGVuZHMgU2ZBbGFybUJhc2VDb25maWcge1xuICAvKipcbiAgICogQSBzdWRkZW4gaW5jcmVhc2UgaW4gZXhlY3V0aW9uIHRpbWUgbWlnaHQgaW5kaWNhdGUgaXNzdWVzIHdpdGggdGhlIHN0ZXBzIG9mIHRoZSByZXNvdXJjZXMgdGhleSBpbnRlcmFjdCB3aXRoLlxuICAgKiBDb25zaWRlciBzZXR0aW5nIGEgdGhyZXNob2xkIChpbiBtaWxsaXNlY29uZHMpIHRoYXQgaXMgYXBwcm9wcmlhdGUgZm9yIHRoZSBleHBlY3RlZCBleGVjdXRpb24gdGltZSBvZiB0aGUgc3RhdGUgbWFjaGluZS5cbiAgICpcbiAgICogQGRlZmF1bHQgTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgdGhyZXNob2xkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHBlcmlvZHMgb3ZlciB3aGljaCBkYXRhIGlzIGNvbXBhcmVkIHRvIHRoZSBzcGVjaWZpZWQgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICByZWFkb25seSBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBtdXN0IGJlIGJyZWFjaGluZyB0byB0cmlnZ2VyIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgNVxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm0/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYWxhcm0gbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdGF0ZU1hY2hpbmVOYW1lICsgJyAtIEV4ZWN1dGlvblRpbWUnXG4gICAqL1xuICByZWFkb25seSBhbGFybU5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgYWxhcm0gaXMgdXNlZCB0byBkZXRlY3Qgc3VkZGVuIGluY3JlYXNlcyBpbiBleGVjdXRpb24gdGltZS4uXG4gICAqL1xuICByZWFkb25seSBhbGFybURlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIGZvciB0aGUgU2ZTdGF0ZU1hY2hpbmVFeGVjdXRpb25UaW1lQWxhcm0gY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uVGltZUFsYXJtUHJvcHMgZXh0ZW5kcyBTZlN0YXRlTWFjaGluZUFsYXJtUHJvcHMsIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uVGltZUFsYXJtQ29uZmlnIHt9XG5cbi8qKlxuICogVGhpcyBtZXRyaWMgY2FuIGJlIGEgdmFsdWFibGUgdG9vbCBmb3IgZWFybHkgZGV0ZWN0aW9uIG9mIGlzc3VlcyB0aGF0IG1pZ2h0IG5vdCBiZSBpbW1lZGlhdGVseSBhcHBhcmVudCBmcm9tIG90aGVyIG1ldHJpY3MuXG4gKlxuICogQSBzdWRkZW4gaW5jcmVhc2UgaW4gZXhlY3V0aW9uIHRpbWUgbWlnaHQgaW5kaWNhdGUgaXNzdWVzIHdpdGggdGhlIHN0ZXBzIG9mIHRoZSByZXNvdXJjZXMgdGhleSBpbnRlcmFjdCB3aXRoLlxuICpcbiAqIFRoZSBhbGFybSBpcyB0cmlnZ2VyZWQgd2hlbiB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMgZXhjZWVkIHRoZSB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZlN0YXRlTWFjaGluZUV4ZWN1dGlvblRpbWVBbGFybSBleHRlbmRzIGNsb3Vkd2F0Y2guQWxhcm0ge1xuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uVGltZUFsYXJtUHJvcHMpIHtcbiAgICBjb25zdCBhbGFybU5hbWUgPSBwcm9wcy5hbGFybU5hbWUgPz8gYCR7cHJvcHMuc3RhdGVNYWNoaW5lLnN0YXRlTWFjaGluZU5hbWV9IC0gJHtTZlJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5FWEVDVVRJT05fVElNRX1gO1xuICAgIGNvbnN0IHBlcmlvZCA9IHByb3BzLnBlcmlvZCA/PyBEdXJhdGlvbi5taW51dGVzKDEpO1xuICAgIGNvbnN0IGV2YWx1YXRpb25QZXJpb2RzID0gcHJvcHMuZXZhbHVhdGlvblBlcmlvZHMgPz8gNTtcbiAgICBjb25zdCBkYXRhcG9pbnRzVG9BbGFybSA9IHByb3BzLmRhdGFwb2ludHNUb0FsYXJtID8/IDU7XG4gICAgY29uc3QgdGhyZXNob2xkID0gcHJvcHMudGhyZXNob2xkO1xuICAgIGNvbnN0IHRyZWF0TWlzc2luZ0RhdGEgPSBwcm9wcy50cmVhdE1pc3NpbmdEYXRhID8/IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HO1xuICAgIGNvbnN0IGFsYXJtRGVzY3JpcHRpb24gPSBwcm9wcy5hbGFybURlc2NyaXB0aW9uID8/ICdUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IHN1ZGRlbiBpbmNyZWFzZXMgaW4gZXhlY3V0aW9uIHRpbWUuJztcblxuICAgIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZChwZXJpb2QsIGV2YWx1YXRpb25QZXJpb2RzLCBhbGFybU5hbWUpO1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBhbGFybU5hbWUsXG4gICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgIG5hbWVzcGFjZTogJ0FXUy9TdGF0ZXMnLFxuICAgICAgICBtZXRyaWNOYW1lOiBTZlJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5FWEVDVVRJT05fVElNRSxcbiAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgIFN0YXRlTWFjaGluZUFybjogcHJvcHMuc3RhdGVNYWNoaW5lLnN0YXRlTWFjaGluZUFybixcbiAgICAgICAgfSxcbiAgICAgICAgcGVyaW9kLFxuICAgICAgICBzdGF0aXN0aWM6ICdBdmVyYWdlJyxcbiAgICAgIH0pLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICBkYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQsXG4gICAgICBhbGFybURlc2NyaXB0aW9uLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLmFsYXJtQWN0aW9uKSB0aGlzLmFkZEFsYXJtQWN0aW9uKHByb3BzLmFsYXJtQWN0aW9uKTtcbiAgICBpZiAocHJvcHMub2tBY3Rpb24pIHRoaXMuYWRkT2tBY3Rpb24ocHJvcHMub2tBY3Rpb24pO1xuICAgIGlmIChwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKSB0aGlzLmFkZEluc3VmZmljaWVudERhdGFBY3Rpb24ocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gIH1cbn07XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIEV4ZWN1dGlvblRocm90dGxlZCBhbGFybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZlN0YXRlTWFjaGluZUV4ZWN1dGlvblRocm90dGxlZEFsYXJtQ29uZmlnIGV4dGVuZHMgU2ZBbGFybUJhc2VDb25maWcge1xuICAvKipcbiAgICogVGhlIEV4ZWN1dGlvblRocm90dGxlZCBtZXRyaWMgdHJhY2tzIHRoZSBudW1iZXIgb2YgdGltZXMgc3RhdGUgbWFjaGluZSBleGVjdXRpb25zIGFyZSB0aHJvdHRsZWQgZHVlIHRvIGV4Y2VlZGluZyBBV1Mgc2VydmljZSBsaW1pdHMuXG4gICAqIE1vbml0b3JpbmcgdGhpcyBjYW4gaGVscCB5b3UgaWRlbnRpZnkgd2hlbiB5b3UgYXJlIGhpdHRpbmcgdGhpcyBsaW1pdHMsIHdoaWNoIGNvdWxkIHNpZ25hbCB0aGF0IGFkanVzdG1lbnRzIG5lZWQgdG8gYmUgbWFkZSBlaXRoZXIgaW5cbiAgICogdGhlIHByb2Nlc3MgZGVzaWduIG9yIGluIHRoZSBzZXJ2aWNlIGxpbWl0cyB0aGVtc2VsdmVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICByZWFkb25seSB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHBlcmlvZHMgb3ZlciB3aGljaCBkYXRhIGlzIGNvbXBhcmVkIHRvIHRoZSBzcGVjaWZpZWQgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICByZWFkb25seSBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBtdXN0IGJlIGJyZWFjaGluZyB0byB0cmlnZ2VyIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgNVxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm0/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYWxhcm0gbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdGF0ZU1hY2hpbmVOYW1lICsgJyAtIEV4ZWN1dGlvblRocm90dGxlZCdcbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB0aHJvdHRsZWQgZXhlY3V0aW9ucyBkdWUgdG8gZXhjZWVkaW5nIEFXUyBzZXJ2aWNlIGxpbWl0cy5cbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtRGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHByb3BlcnRpZXMgZm9yIHRoZSBTZlN0YXRlTWFjaGluZUV4ZWN1dGlvblRocm90dGxlZEFsYXJtIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZlN0YXRlTWFjaGluZUV4ZWN1dGlvblRocm90dGxlZEFsYXJtUHJvcHMgZXh0ZW5kcyBTZlN0YXRlTWFjaGluZUFsYXJtUHJvcHMsIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uVGhyb3R0bGVkQWxhcm1Db25maWcge31cblxuLyoqXG4gKiBUaGUgRXhlY3V0aW9uVGhyb3R0bGVkIG1ldHJpYyB0cmFja3MgdGhlIG51bWJlciBvZiB0aW1lcyBzdGF0ZSBtYWNoaW5lIGV4ZWN1dGlvbnMgYXJlIHRocm90dGxlZCBkdWUgdG8gZXhjZWVkaW5nIEFXUyBzZXJ2aWNlIGxpbWl0cy5cbiAqXG4gKiBNb25pdG9yaW5nIHRoaXMgY2FuIGhlbHAgeW91IGlkZW50aWZ5IHdoZW4geW91IGFyZSBoaXR0aW5nIHRoaXMgbGltaXRzLCB3aGljaCBjb3VsZCBzaWduYWwgdGhhdCBhZGp1c3RtZW50cyBuZWVkIHRvIGJlIG1hZGUgZWl0aGVyIGluXG4gKiB0aGUgcHJvY2VzcyBkZXNpZ24gb3IgaW4gdGhlIHNlcnZpY2UgbGltaXRzIHRoZW1zZWx2ZXMuXG4gKlxuICogVGhlIGFsYXJtIGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBudW1iZXIgb2YgZXhlY3V0aW9ucyB0aHJvdHRsZWQgZXhjZWVkIHRoZSB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZlN0YXRlTWFjaGluZUV4ZWN1dGlvblRocm90dGxlZEFsYXJtIGV4dGVuZHMgY2xvdWR3YXRjaC5BbGFybSB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU2ZTdGF0ZU1hY2hpbmVFeGVjdXRpb25UaHJvdHRsZWRBbGFybVByb3BzKSB7XG4gICAgY29uc3QgYWxhcm1OYW1lID0gcHJvcHMuYWxhcm1OYW1lID8/IGAke3Byb3BzLnN0YXRlTWFjaGluZS5zdGF0ZU1hY2hpbmVOYW1lfSAtICR7U2ZSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuRVhFQ1VUSU9OX1RIUk9UVExFRH1gO1xuICAgIGNvbnN0IHBlcmlvZCA9IHByb3BzLnBlcmlvZCA/PyBEdXJhdGlvbi5taW51dGVzKDEpO1xuICAgIGNvbnN0IGV2YWx1YXRpb25QZXJpb2RzID0gcHJvcHMuZXZhbHVhdGlvblBlcmlvZHMgPz8gNTtcbiAgICBjb25zdCBkYXRhcG9pbnRzVG9BbGFybSA9IHByb3BzLmRhdGFwb2ludHNUb0FsYXJtID8/IDU7XG4gICAgY29uc3QgdGhyZXNob2xkID0gcHJvcHMudGhyZXNob2xkID8/IDU7XG4gICAgY29uc3QgdHJlYXRNaXNzaW5nRGF0YSA9IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEgPz8gY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk1JU1NJTkc7XG4gICAgY29uc3QgYWxhcm1EZXNjcmlwdGlvbiA9IHByb3BzLmFsYXJtRGVzY3JpcHRpb24gPz8gJ1RoaXMgYWxhcm0gaXMgdXNlZCB0byBkZXRlY3QgdGhyb3R0bGVkIGV4ZWN1dGlvbnMgZHVlIHRvIGV4Y2VlZGluZyBBV1Mgc2VydmljZSBsaW1pdHMuJztcblxuICAgIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZChwZXJpb2QsIGV2YWx1YXRpb25QZXJpb2RzLCBhbGFybU5hbWUpO1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBhbGFybU5hbWUsXG4gICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgIG5hbWVzcGFjZTogJ0FXUy9TdGF0ZXMnLFxuICAgICAgICBtZXRyaWNOYW1lOiBTZlJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5FWEVDVVRJT05fVEhST1RUTEVELFxuICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgU3RhdGVNYWNoaW5lQXJuOiBwcm9wcy5zdGF0ZU1hY2hpbmUuc3RhdGVNYWNoaW5lQXJuLFxuICAgICAgICB9LFxuICAgICAgICBwZXJpb2QsXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICB9KSxcbiAgICAgIHRocmVzaG9sZCxcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICB0cmVhdE1pc3NpbmdEYXRhLFxuICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVEhSRVNIT0xELFxuICAgICAgYWxhcm1EZXNjcmlwdGlvbixcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcy5hbGFybUFjdGlvbikgdGhpcy5hZGRBbGFybUFjdGlvbihwcm9wcy5hbGFybUFjdGlvbik7XG4gICAgaWYgKHByb3BzLm9rQWN0aW9uKSB0aGlzLmFkZE9rQWN0aW9uKHByb3BzLm9rQWN0aW9uKTtcbiAgICBpZiAocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbikgdGhpcy5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pO1xuICB9XG59O1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBFeGVjdXRpb25zRmFpbGVkIGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uc0ZhaWxlZEFsYXJtQ29uZmlnIGV4dGVuZHMgU2ZBbGFybUJhc2VDb25maWcge1xuICAvKipcbiAgICogSXQgaGVscHMgaW4gdHJhY2tpbmcgdGhlIG51bWJlciBvZiBleGVjdXRpb25zIHRoYXQgZmFpbCBpbiBBV1MgU3RlcCBGdW5jdGlvbnMuIFRoaXMgaXMgY3J1Y2lhbCBmb3IgaWRlbnRpZnlpbmcgd29ya2Zsb3dzIHRoYXQgYXJlXG4gICAqIG5vdCBwZXJmb3JtaW5nIGFzIGV4cGVjdGVkIGFuZCByZXF1aXJlIGF0dGVudGlvbi4gQnkgbW9uaXRvcmluZyB0aGUgZmFpbHVyZXMsIGRldmVsb3BlcnMgY2FuIHByb2FjdGl2ZWx5IGlkZW50aWZ5IGFuZCByZXNvbHZlIGlzc3Vlc1xuICAgKiBiZWZvcmUgdGhleSBpbXBhY3QgdGhlIGJ1c2luZXNzIG9wZXJhdGlvbnMuIFRoaXMgcmVkdWNlcyBkb3dudGltZSBhbmQgaW1wcm92ZXMgdGhlIG92ZXJhbGwgc3RhYmlsaXR5IG9mIGFwcGxpY2F0aW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgNVxuICAgKi9cbiAgcmVhZG9ubHkgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBwZXJpb2RzIG92ZXIgd2hpY2ggZGF0YSBpcyBjb21wYXJlZCB0byB0aGUgc3BlY2lmaWVkIHRocmVzaG9sZC5cbiAgICpcbiAgICogQGRlZmF1bHQgNVxuICAgKi9cbiAgcmVhZG9ubHkgZXZhbHVhdGlvblBlcmlvZHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHRoYXQgbXVzdCBiZSBicmVhY2hpbmcgdG8gdHJpZ2dlciB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IDVcbiAgICovXG4gIHJlYWRvbmx5IGRhdGFwb2ludHNUb0FsYXJtPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGFsYXJtIG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc3RhdGVNYWNoaW5lTmFtZSArICcgLSBFeGVjdXRpb25zRmFpbGVkJ1xuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1OYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IHdvcmtmbG93cyB0aGF0IGFyZSBub3Qgd29ya2luZyBhcyBleHBlY3RlZC5cbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtRGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHByb3BlcnRpZXMgZm9yIHRoZSBTZlN0YXRlTWFjaGluZUV4ZWN1dGlvbnNGYWlsZWRBbGFybSBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2ZTdGF0ZU1hY2hpbmVFeGVjdXRpb25zRmFpbGVkQWxhcm1Qcm9wcyBleHRlbmRzIFNmU3RhdGVNYWNoaW5lQWxhcm1Qcm9wcywgU2ZTdGF0ZU1hY2hpbmVFeGVjdXRpb25zRmFpbGVkQWxhcm1Db25maWcge31cblxuLyoqXG4gKiBJdCBoZWxwcyBpbiB0cmFja2luZyB0aGUgbnVtYmVyIG9mIGV4ZWN1dGlvbnMgdGhhdCBmYWlsIGluIEFXUyBTdGVwIEZ1bmN0aW9ucy4gVGhpcyBpcyBjcnVjaWFsIGZvciBpZGVudGlmeWluZyB3b3JrZmxvd3MgdGhhdCBhcmVcbiAqIG5vdCBwZXJmb3JtaW5nIGFzIGV4cGVjdGVkIGFuZCByZXF1aXJlIGF0dGVudGlvbi5cbiAqXG4gKiBCeSBtb25pdG9yaW5nIHRoZSBmYWlsdXJlcywgZGV2ZWxvcGVycyBjYW4gcHJvYWN0aXZlbHkgaWRlbnRpZnkgYW5kIHJlc29sdmUgaXNzdWVzIGJlZm9yZSB0aGV5IGltcGFjdCB0aGUgYnVzaW5lc3Mgb3BlcmF0aW9ucy4gVGhpcyByZWR1Y2VzXG4gKiBkb3dudGltZSBhbmQgaW1wcm92ZXMgdGhlIG92ZXJhbGwgc3RhYmlsaXR5IG9mIGFwcGxpY2F0aW9ucy5cbiAqXG4gKiBUaGUgYWxhcm0gaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIG51bWJlciBvZiBmYWlsZWQgZXhlY3V0aW9ucyBleGNlZWQgdGhlIHRocmVzaG9sZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uc0ZhaWxlZEFsYXJtIGV4dGVuZHMgY2xvdWR3YXRjaC5BbGFybSB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU2ZTdGF0ZU1hY2hpbmVFeGVjdXRpb25zRmFpbGVkQWxhcm1Qcm9wcykge1xuICAgIGNvbnN0IGFsYXJtTmFtZSA9IHByb3BzLmFsYXJtTmFtZSA/PyBgJHtwcm9wcy5zdGF0ZU1hY2hpbmUuc3RhdGVNYWNoaW5lTmFtZX0gLSAke1NmUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLkVYRUNVVElPTlNfRkFJTEVEfWA7XG4gICAgY29uc3QgcGVyaW9kID0gcHJvcHMucGVyaW9kID8/IER1cmF0aW9uLm1pbnV0ZXMoMSk7XG4gICAgY29uc3QgZXZhbHVhdGlvblBlcmlvZHMgPSBwcm9wcy5ldmFsdWF0aW9uUGVyaW9kcyA/PyA1O1xuICAgIGNvbnN0IGRhdGFwb2ludHNUb0FsYXJtID0gcHJvcHMuZGF0YXBvaW50c1RvQWxhcm0gPz8gNTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSBwcm9wcy50aHJlc2hvbGQgPz8gNTtcbiAgICBjb25zdCB0cmVhdE1pc3NpbmdEYXRhID0gcHJvcHMudHJlYXRNaXNzaW5nRGF0YSA/PyBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTUlTU0lORztcbiAgICBjb25zdCBhbGFybURlc2NyaXB0aW9uID0gcHJvcHMuYWxhcm1EZXNjcmlwdGlvbiA/PyAnVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB3b3JrZmxvd3MgdGhhdCBhcmUgbm90IHdvcmtpbmcgYXMgZXhwZWN0ZWQuJztcblxuICAgIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZChwZXJpb2QsIGV2YWx1YXRpb25QZXJpb2RzLCBhbGFybU5hbWUpO1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBhbGFybU5hbWUsXG4gICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgIG5hbWVzcGFjZTogJ0FXUy9TdGF0ZXMnLFxuICAgICAgICBtZXRyaWNOYW1lOiBTZlJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5FWEVDVVRJT05TX0ZBSUxFRCxcbiAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgIFN0YXRlTWFjaGluZUFybjogcHJvcHMuc3RhdGVNYWNoaW5lLnN0YXRlTWFjaGluZUFybixcbiAgICAgICAgfSxcbiAgICAgICAgcGVyaW9kLFxuICAgICAgICBzdGF0aXN0aWM6ICdTdW0nLFxuICAgICAgfSksXG4gICAgICB0aHJlc2hvbGQsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuYWxhcm1BY3Rpb24pIHRoaXMuYWRkQWxhcm1BY3Rpb24ocHJvcHMuYWxhcm1BY3Rpb24pO1xuICAgIGlmIChwcm9wcy5va0FjdGlvbikgdGhpcy5hZGRPa0FjdGlvbihwcm9wcy5va0FjdGlvbik7XG4gICAgaWYgKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pIHRoaXMuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgRXhlY3V0aW9uc1RpbWVkT3V0IGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNmU3RhdGVNYWNoaW5lRXhlY3V0aW9uc1RpbWVkT3V0QWxhcm1Db25maWcgZXh0ZW5kcyBTZkFsYXJtQmFzZUNvbmZpZyB7XG4gIC8qKlxuICAgKiBJdCBoZWxwcyBpbiBpZGVudGlmeWluZyB0aW1lb3V0cyBpbiBzdGF0ZSBtYWNoaW5lIGV4ZWN1dGlvb