@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.
239 lines • 40.5 kB
JavaScript
;
var _a, _b, _c, _d, _e;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EfsRecommendedAlarmsAspect = exports.FileSystem = exports.EfsFileSystemRecommendedAlarms = exports.EfsFileSystemBurstCreditBalanceAlarm = exports.EfsFileSystemPercentIOLimitAlarm = exports.EfsRecommendedAlarmsMetrics = 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 EFS alarms.
*/
var EfsRecommendedAlarmsMetrics;
(function (EfsRecommendedAlarmsMetrics) {
/**
* Percentage of how close a file system is to reaching the I/O limit of the General Purpose
* performance mode.
*/
EfsRecommendedAlarmsMetrics["PERCENT_IO_LIMIT"] = "PercentIOLimit";
/**
* The number of burst credits that a file system has. Burst credits allow a file system to burst
* to throughput levels above a file system's baseline level for periods of time.
*/
EfsRecommendedAlarmsMetrics["BURST_CREDIT_BALANCE"] = "BurstCreditBalance";
})(EfsRecommendedAlarmsMetrics || (exports.EfsRecommendedAlarmsMetrics = EfsRecommendedAlarmsMetrics = {}));
/**
* This alarm helps in ensuring that the workload stays within the I/O limit available to the file system.
*
* If the metric reaches its I/O limit consistently, consider moving the application to a file system that
* uses Max I/O performance as mode. For troubleshooting, check clients that are connected to the file system
* and applications of the clients that throttles the file system.
*
* The alarm is triggered when the percentage exceed or equals % threshold.
*/
class EfsFileSystemPercentIOLimitAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm {
constructor(scope, id, props) {
const alarmName = props.alarmName ?? `${props.fileSystem.fileSystemId} - ${EfsRecommendedAlarmsMetrics.PERCENT_IO_LIMIT}`;
const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1);
const evaluationPeriods = props.evaluationPeriods ?? 15;
const datapointsToAlarm = props.datapointsToAlarm ?? 15;
const threshold = props.threshold ?? 100;
const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING;
const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect how close the file system is to reach the'
+ ' I/O limit of the General Purpose performance mode. Consistent high I/O percentage can be an indicator of the file system'
+ ' cannot scale with respect to I/O requests enough and the file system can be a resource bottleneck for the applications'
+ ' that use the file system.';
(0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName);
super(scope, id, {
alarmName,
metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({
namespace: 'AWS/EFS',
metricName: EfsRecommendedAlarmsMetrics.PERCENT_IO_LIMIT,
dimensionsMap: {
FileSystemId: props.fileSystem.fileSystemId,
},
period,
statistic: 'Average',
}),
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.EfsFileSystemPercentIOLimitAlarm = EfsFileSystemPercentIOLimitAlarm;
_a = JSII_RTTI_SYMBOL_1;
EfsFileSystemPercentIOLimitAlarm[_a] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.EfsFileSystemPercentIOLimitAlarm", version: "0.0.17" };
;
/**
* This alarm helps in ensuring that there is available burst credit balance for the file system usage.
*
* When there is no available burst credit, applications access to the the file system will be limited due to low throughput.
* If the metric drops to 0 consistently, consider changing the throughput mode to Elastic or Provisioned throughput mode.
*
* The alarm is triggered when the percentage is lower or equals the threshold.
*/
class EfsFileSystemBurstCreditBalanceAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm {
constructor(scope, id, props) {
const alarmName = props.alarmName ?? `${props.fileSystem.fileSystemId} - ${EfsRecommendedAlarmsMetrics.BURST_CREDIT_BALANCE}`;
const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1);
const evaluationPeriods = props.evaluationPeriods ?? 15;
const datapointsToAlarm = props.datapointsToAlarm ?? 15;
const threshold = props.threshold ?? 0;
const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING;
const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect low burst credit balance of the file system.'
+ ' Consistent low burst credit balance can be an indicator of the slowing down in throughput and increase in I/O latency.';
(0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName);
super(scope, id, {
alarmName,
metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({
namespace: 'AWS/EFS',
metricName: EfsRecommendedAlarmsMetrics.BURST_CREDIT_BALANCE,
dimensionsMap: {
FileSystemId: props.fileSystem.fileSystemId,
},
period,
statistic: 'Average',
}),
threshold,
evaluationPeriods,
datapointsToAlarm,
treatMissingData,
comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.LESS_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.EfsFileSystemBurstCreditBalanceAlarm = EfsFileSystemBurstCreditBalanceAlarm;
_b = JSII_RTTI_SYMBOL_1;
EfsFileSystemBurstCreditBalanceAlarm[_b] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.EfsFileSystemBurstCreditBalanceAlarm", version: "0.0.17" };
;
/**
* A construct that creates the recommended alarms for an EFS FileSystem.
*
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#EFS
*/
class EfsFileSystemRecommendedAlarms extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
if (!props.excludeAlarms?.includes(EfsRecommendedAlarmsMetrics.PERCENT_IO_LIMIT)) {
this.alarmPercentIOLimit = new EfsFileSystemPercentIOLimitAlarm(this, `${props.fileSystem.node.id}_PercentIOLimit`, {
fileSystem: props.fileSystem,
treatMissingData: props.treatMissingData,
...props.configPercentIOLimitAlarm,
});
if (props.defaultAlarmAction && !props.configPercentIOLimitAlarm?.alarmAction) {
this.alarmPercentIOLimit.addAlarmAction(props.defaultAlarmAction);
}
if (props.defaultOkAction && !props.configPercentIOLimitAlarm?.okAction) {
this.alarmPercentIOLimit.addOkAction(props.defaultOkAction);
}
if (props.defaultInsufficientDataAction && !props.configPercentIOLimitAlarm?.insufficientDataAction) {
this.alarmPercentIOLimit.addInsufficientDataAction(props.defaultInsufficientDataAction);
}
}
if (!props.excludeAlarms?.includes(EfsRecommendedAlarmsMetrics.BURST_CREDIT_BALANCE)) {
this.alarmBurstCreditBalance = new EfsFileSystemBurstCreditBalanceAlarm(this, `${props.fileSystem.node.id}_BurstCreditBalance`, {
fileSystem: props.fileSystem,
treatMissingData: props.treatMissingData,
...props.configBurstCreditBalanceAlarm,
});
if (props.defaultAlarmAction && !props.configBurstCreditBalanceAlarm?.alarmAction) {
this.alarmBurstCreditBalance.addAlarmAction(props.defaultAlarmAction);
}
if (props.defaultOkAction && !props.configBurstCreditBalanceAlarm?.okAction) {
this.alarmBurstCreditBalance.addOkAction(props.defaultOkAction);
}
if (props.defaultInsufficientDataAction && !props.configBurstCreditBalanceAlarm?.insufficientDataAction) {
this.alarmBurstCreditBalance.addInsufficientDataAction(props.defaultInsufficientDataAction);
}
}
}
}
exports.EfsFileSystemRecommendedAlarms = EfsFileSystemRecommendedAlarms;
_c = JSII_RTTI_SYMBOL_1;
EfsFileSystemRecommendedAlarms[_c] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.EfsFileSystemRecommendedAlarms", version: "0.0.17" };
/**
* An extension for the FileSystem construct that provides methods
* to create recommended alarms.
*/
class FileSystem extends aws_cdk_lib_1.aws_efs.FileSystem {
constructor(scope, id, props) {
super(scope, id, props);
}
/**
* Creates an alarm that monitors the PercentIOLimit for the EFS fileSystem.
*/
alarmPercentIOLimit(props) {
return new EfsFileSystemPercentIOLimitAlarm(this, 'PercentIOLimitAlarm', {
fileSystem: this,
...props,
});
}
/**
* Creates an alarm that monitors the BurstCreditBalance for the EFS fileSystem.
*/
alarmBurstCreditBalance(props) {
return new EfsFileSystemBurstCreditBalanceAlarm(this, 'BurstCreditBalanceAlarm', {
fileSystem: this,
...props,
});
}
/**
* Creates the recommended alarms for the EFS FileSystem.
*
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#EFS
*/
applyRecommendedAlarms(props) {
return new EfsFileSystemRecommendedAlarms(this, 'EfsFileSystemRecommendedAlarms', {
fileSystem: this,
...props,
});
}
}
exports.FileSystem = FileSystem;
_d = JSII_RTTI_SYMBOL_1;
FileSystem[_d] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.FileSystem", version: "0.0.17" };
/**
* Configures the recommended alarms for an EFS FileSystem.
*
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#EFS
*/
class EfsRecommendedAlarmsAspect {
constructor(props) {
this.props = props;
}
visit(node) {
if (node instanceof aws_cdk_lib_1.aws_efs.FileSystem) {
if (this.props?.excludeResources && this.props.excludeResources.includes(node.node.id)) {
return;
}
else {
const fileSystem = node;
new EfsFileSystemRecommendedAlarms(fileSystem, 'EfsFileSystemRecommendedAlarmsFromAspect', {
fileSystem,
...this.props,
});
}
}
}
}
exports.EfsRecommendedAlarmsAspect = EfsRecommendedAlarmsAspect;
_e = JSII_RTTI_SYMBOL_1;
EfsRecommendedAlarmsAspect[_e] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.EfsRecommendedAlarmsAspect", version: "0.0.17" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Vmcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUtxQjtBQUNyQiwyQ0FBbUQ7QUFDbkQscUNBQW9FO0FBRXBFOztHQUVHO0FBQ0gsSUFBWSwyQkFXWDtBQVhELFdBQVksMkJBQTJCO0lBQ3JDOzs7T0FHRztJQUNILGtFQUFtQyxDQUFBO0lBQ25DOzs7T0FHRztJQUNILDBFQUEyQyxDQUFBO0FBQzdDLENBQUMsRUFYVywyQkFBMkIsMkNBQTNCLDJCQUEyQixRQVd0QztBQXVFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQWEsZ0NBQWlDLFNBQVEsNEJBQVUsQ0FBQyxLQUFLO0lBQ3BFLFlBQVksS0FBaUIsRUFBRSxFQUFVLEVBQUUsS0FBNEM7UUFDckYsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsWUFBWSxNQUFNLDJCQUEyQixDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDMUgsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxFQUFFLENBQUM7UUFDeEQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDO1FBQ3hELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLElBQUksR0FBRyxDQUFDO1FBQ3pDLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixJQUFJLDRCQUFVLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO1FBQ3ZGLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixJQUFJLHdFQUF3RTtjQUN2SCwySEFBMkg7Y0FDM0gseUhBQXlIO2NBQ3pILDRCQUE0QixDQUFDO1FB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QUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDdkYsT0FBTztZQUNULENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLFVBQVUsR0FBRyxJQUFzQixDQUFDO2dCQUUxQyxJQUFJLDhCQUE4QixDQUFDLFVBQVUsRUFBRSwwQ0FBMEMsRUFBRTtvQkFDekYsVUFBVTtvQkFDVixHQUFHLElBQUksQ0FBQyxLQUFLO2lCQUNkLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQzs7QUFoQkgsZ0VBaUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSUFzcGVjdCxcbiAgYXdzX2VmcyBhcyBlZnMsXG4gIGF3c19jbG91ZHdhdGNoIGFzIGNsb3Vkd2F0Y2gsXG4gIER1cmF0aW9uLFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QsIElDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEFsYXJtQmFzZVByb3BzLCB2YWxpZGF0ZVRvdGFsQWxhcm1QZXJpb2QgfSBmcm9tICcuL2NvbW1vbic7XG5cbi8qKlxuICogVGhlIHJlY29tbWVuZGVkIG1ldHJpY3MgZm9yIEVGUyBhbGFybXMuXG4gKi9cbmV4cG9ydCBlbnVtIEVmc1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcyB7XG4gIC8qKlxuICAgKiBQZXJjZW50YWdlIG9mIGhvdyBjbG9zZSBhIGZpbGUgc3lzdGVtIGlzIHRvIHJlYWNoaW5nIHRoZSBJL08gbGltaXQgb2YgdGhlIEdlbmVyYWwgUHVycG9zZVxuICAgKiBwZXJmb3JtYW5jZSBtb2RlLlxuICAgKi9cbiAgUEVSQ0VOVF9JT19MSU1JVCA9ICdQZXJjZW50SU9MaW1pdCcsXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGJ1cnN0IGNyZWRpdHMgdGhhdCBhIGZpbGUgc3lzdGVtIGhhcy4gQnVyc3QgY3JlZGl0cyBhbGxvdyBhIGZpbGUgc3lzdGVtIHRvIGJ1cnN0XG4gICAqIHRvIHRocm91Z2hwdXQgbGV2ZWxzIGFib3ZlIGEgZmlsZSBzeXN0ZW0ncyBiYXNlbGluZSBsZXZlbCBmb3IgcGVyaW9kcyBvZiB0aW1lLlxuICAgKi9cbiAgQlVSU1RfQ1JFRElUX0JBTEFOQ0UgPSAnQnVyc3RDcmVkaXRCYWxhbmNlJyxcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhbGFybXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWZzQWxhcm1CYXNlQ29uZmlnIGV4dGVuZHMgQWxhcm1CYXNlUHJvcHMge1xuICAvKipcbiAgICogVGhlIHBlcmlvZCBvdmVyIHdoaWNoIHRoZSBzcGVjaWZpZWQgc3RhdGlzdGljIGlzIGFwcGxpZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLm1pbnV0ZXMoMSlcbiAgICovXG4gIHJlYWRvbmx5IHBlcmlvZD86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIFRoZSBjb21tb24gcHJvcGVydGllcyBmb3IgdGhlIEVGUyBGaWxlU3lzdGVtIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFZnNGaWxlU3lzdGVtQWxhcm1Qcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgRUZTIEZpbGVTeXN0ZW0gdG8gbW9uaXRvci5cbiAgICovXG4gIHJlYWRvbmx5IGZpbGVTeXN0ZW06IGVmcy5GaWxlU3lzdGVtO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBQZXJjZW50SU9MaW1pdCBhbGFybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFZnNQZXJjZW50SU9MaW1pdEFsYXJtQ29uZmlnIGV4dGVuZHMgRWZzQWxhcm1CYXNlQ29uZmlnIHtcbiAgLyoqXG4gICAqIFdoZW4gdGhlIGZpbGUgc3lzdGVtIHJlYWNoZXMgaXRzIEkvTyBsaW1pdCwgaXQgbWF5IHJlc3BvbmQgdG8gcmVhZCBhbmQgd3JpdGUgcmVxdWVzdHMgc2xvd2VyLlxuICAgKiBUaGVyZWZvcmUsIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhlIG1ldHJpYyBpcyBtb25pdG9yZWQgdG8gYXZvaWQgaW1wYWN0aW5nIGFwcGxpY2F0aW9ucyB0aGF0XG4gICAqIHVzZSB0aGUgZmlsZSBzeXN0ZW0uIFRoZSB0aHJlc2hvbGQgY2FuIGJlIHNldCBhcm91bmQgMTAwJS4gSG93ZXZlciwgdGhpcyB2YWx1ZSBjYW4gYmUgYWRqdXN0ZWRcbiAgICogdG8gYSBsb3dlciB2YWx1ZSBiYXNlZCBvbiBmaWxlIHN5c3RlbSBjaGFyYWN0ZXJpc3RpY3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEwMFxuICAgKi9cbiAgcmVhZG9ubHkgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBwZXJpb2RzIG92ZXIgd2hpY2ggZGF0YSBpcyBjb21wYXJlZCB0byB0aGUgc3BlY2lmaWVkIHRocmVzaG9sZC5cbiAgICpcbiAgICogQGRlZmF1bHQgMTVcbiAgICovXG4gIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IG11c3QgYmUgYnJlYWNoaW5nIHRvIHRyaWdnZXIgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxNVxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm0/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYWxhcm0gbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBmaWxlU3lzdGVtSWQgKyAnIC0gUGVyY2VudElPTGltaXQnXG4gICAqL1xuICByZWFkb25seSBhbGFybU5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgYWxhcm0gaXMgdXNlZCB0byBkZXRlY3QgaG93IGNsb3NlIHRoZSBmaWxlIHN5c3RlbSBpcyB0byByZWFjaCB0aGUgSS9PIGxpbWl0IG9mIHRoZSBHZW5lcmFsXG4gICAqIFB1cnBvc2UgcGVyZm9ybWFuY2UgbW9kZS4gQ29uc2lzdGVudCBoaWdoIEkvTyBwZXJjZW50YWdlIGNhbiBiZSBhbiBpbmRpY2F0b3Igb2YgdGhlIGZpbGUgc3lzdGVtIGNhbm5vdCBzY2FsZVxuICAgKiB3aXRoIHJlc3BlY3QgdG8gSS9PIHJlcXVlc3RzIGVub3VnaCBhbmQgdGhlIGZpbGUgc3lzdGVtIGNhbiBiZSBhIHJlc291cmNlIGJvdHRsZW5lY2sgZm9yIHRoZSBhcHBsaWNhdGlvbnNcbiAgICogdGhhdCB1c2UgdGhlIGZpbGUgc3lzdGVtLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1EZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgcHJvcGVydGllcyBmb3IgdGhlIEVmc0ZpbGVTeXN0ZW1QZXJjZW50SU9MaW1pdEFsYXJtIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFZnNGaWxlU3lzdGVtUGVyY2VudElPTGltaXRBbGFybVByb3BzIGV4dGVuZHMgRWZzRmlsZVN5c3RlbUFsYXJtUHJvcHMsIEVmc1BlcmNlbnRJT0xpbWl0QWxhcm1Db25maWcge31cblxuLyoqXG4gKiBUaGlzIGFsYXJtIGhlbHBzIGluIGVuc3VyaW5nIHRoYXQgdGhlIHdvcmtsb2FkIHN0YXlzIHdpdGhpbiB0aGUgSS9PIGxpbWl0IGF2YWlsYWJsZSB0byB0aGUgZmlsZSBzeXN0ZW0uXG4gKlxuICogSWYgdGhlIG1ldHJpYyByZWFjaGVzIGl0cyBJL08gbGltaXQgY29uc2lzdGVudGx5LCBjb25zaWRlciBtb3ZpbmcgdGhlIGFwcGxpY2F0aW9uIHRvIGEgZmlsZSBzeXN0ZW0gdGhhdFxuICogdXNlcyBNYXggSS9PIHBlcmZvcm1hbmNlIGFzIG1vZGUuIEZvciB0cm91Ymxlc2hvb3RpbmcsIGNoZWNrIGNsaWVudHMgdGhhdCBhcmUgY29ubmVjdGVkIHRvIHRoZSBmaWxlIHN5c3RlbVxuICogYW5kIGFwcGxpY2F0aW9ucyBvZiB0aGUgY2xpZW50cyB0aGF0IHRocm90dGxlcyB0aGUgZmlsZSBzeXN0ZW0uXG4gKlxuICogVGhlIGFsYXJtIGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBwZXJjZW50YWdlIGV4Y2VlZCBvciBlcXVhbHMgJSB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFZnNGaWxlU3lzdGVtUGVyY2VudElPTGltaXRBbGFybSBleHRlbmRzIGNsb3Vkd2F0Y2guQWxhcm0ge1xuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEVmc0ZpbGVTeXN0ZW1QZXJjZW50SU9MaW1pdEFsYXJtUHJvcHMpIHtcbiAgICBjb25zdCBhbGFybU5hbWUgPSBwcm9wcy5hbGFybU5hbWUgPz8gYCR7cHJvcHMuZmlsZVN5c3RlbS5maWxlU3lzdGVtSWR9IC0gJHtFZnNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuUEVSQ0VOVF9JT19MSU1JVH1gO1xuICAgIGNvbnN0IHBlcmlvZCA9IHByb3BzLnBlcmlvZCA/PyBEdXJhdGlvbi5taW51dGVzKDEpO1xuICAgIGNvbnN0IGV2YWx1YXRpb25QZXJpb2RzID0gcHJvcHMuZXZhbHVhdGlvblBlcmlvZHMgPz8gMTU7XG4gICAgY29uc3QgZGF0YXBvaW50c1RvQWxhcm0gPSBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAxNTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSBwcm9wcy50aHJlc2hvbGQgPz8gMTAwO1xuICAgIGNvbnN0IHRyZWF0TWlzc2luZ0RhdGEgPSBwcm9wcy50cmVhdE1pc3NpbmdEYXRhID8/IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HO1xuICAgIGNvbnN0IGFsYXJtRGVzY3JpcHRpb24gPSBwcm9wcy5hbGFybURlc2NyaXB0aW9uID8/ICdUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IGhvdyBjbG9zZSB0aGUgZmlsZSBzeXN0ZW0gaXMgdG8gcmVhY2ggdGhlJ1xuICAgICAgKyAnIEkvTyBsaW1pdCBvZiB0aGUgR2VuZXJhbCBQdXJwb3NlIHBlcmZvcm1hbmNlIG1vZGUuIENvbnNpc3RlbnQgaGlnaCBJL08gcGVyY2VudGFnZSBjYW4gYmUgYW4gaW5kaWNhdG9yIG9mIHRoZSBmaWxlIHN5c3RlbSdcbiAgICAgICsgJyBjYW5ub3Qgc2NhbGUgd2l0aCByZXNwZWN0IHRvIEkvTyByZXF1ZXN0cyBlbm91Z2ggYW5kIHRoZSBmaWxlIHN5c3RlbSBjYW4gYmUgYSByZXNvdXJjZSBib3R0bGVuZWNrIGZvciB0aGUgYXBwbGljYXRpb25zJ1xuICAgICAgKyAnIHRoYXQgdXNlIHRoZSBmaWxlIHN5c3RlbS4nO1xuXG4gICAgdmFsaWRhdGVUb3RhbEFsYXJtUGVyaW9kKHBlcmlvZCwgZXZhbHVhdGlvblBlcmlvZHMsIGFsYXJtTmFtZSk7XG5cbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGFsYXJtTmFtZSxcbiAgICAgIG1ldHJpYzogbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgICAgbmFtZXNwYWNlOiAnQVdTL0VGUycsXG4gICAgICAgIG1ldHJpY05hbWU6IEVmc1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5QRVJDRU5UX0lPX0xJTUlULFxuICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgRmlsZVN5c3RlbUlkOiBwcm9wcy5maWxlU3lzdGVtLmZpbGVTeXN0ZW1JZCxcbiAgICAgICAgfSxcbiAgICAgICAgcGVyaW9kLFxuICAgICAgICBzdGF0aXN0aWM6ICdBdmVyYWdlJyxcbiAgICAgIH0pLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICBkYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICBhbGFybURlc2NyaXB0aW9uLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLmFsYXJtQWN0aW9uKSB0aGlzLmFkZEFsYXJtQWN0aW9uKHByb3BzLmFsYXJtQWN0aW9uKTtcbiAgICBpZiAocHJvcHMub2tBY3Rpb24pIHRoaXMuYWRkT2tBY3Rpb24ocHJvcHMub2tBY3Rpb24pO1xuICAgIGlmIChwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKSB0aGlzLmFkZEluc3VmZmljaWVudERhdGFBY3Rpb24ocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgQnVyc3RDcmVkaXRCYWxhbmNlIGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVmc0J1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtQ29uZmlnIGV4dGVuZHMgRWZzQWxhcm1CYXNlQ29uZmlnIHtcbiAgLyoqXG4gICAqIFdoZW4gdGhlIGZpbGUgc3lzdGVtIHJ1biBvdXQgb2YgYnVyc3QgY3JlZGl0cyBhbmQgZXZlbiBpZiB0aGUgYmFzZWxpbmUgdGhyb3VnaHB1dCByYXRlIGlzIGxvd2VyLFxuICAgKiBFRlMgY29udGludWVzIHRvIHByb3ZpZGUgYSBtZXRlcmVkIHRocm91Z2hwdXQgb2YgMSBNaUJwcyB0byBhbGwgZmlsZSBzeXN0ZW1zLiBIb3dldmVyLCBpdCBpcyByZWNvbW1lbmRlZFxuICAgKiB0aGF0IHRoZSBtZXRyaWMgaXMgbW9uaXRvcmVkIGZvciBsb3cgYnVyc3QgY3JlZGl0IGJhbGFuY2UgdG8gYXZvaWQgdGhlIGZpbGUgc3lzdGVtIGFjdGluZyBhcyByZXNvdXJjZVxuICAgKiBib3R0bGVuZWNrIGZvciB0aGUgYXBwbGljYXRpb25zLiBUaGUgdGhyZXNob2xkIGNhbiBiZSBzZXQgYXJvdW5kIDAgYnl0ZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIHJlYWRvbmx5IHRocmVzaG9sZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcGVyaW9kcyBvdmVyIHdoaWNoIGRhdGEgaXMgY29tcGFyZWQgdG8gdGhlIHNwZWNpZmllZCB0aHJlc2hvbGQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDE1XG4gICAqL1xuICByZWFkb25seSBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBtdXN0IGJlIGJyZWFjaGluZyB0byB0cmlnZ2VyIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgMTVcbiAgICovXG4gIHJlYWRvbmx5IGRhdGFwb2ludHNUb0FsYXJtPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGFsYXJtIG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmlsZVN5c3RlbUlkICsgJyAtIEJ1cnN0Q3JlZGl0QmFsYW5jZSdcbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCBsb3cgYnVyc3QgY3JlZGl0IGJhbGFuY2Ugb2YgdGhlIGZpbGUgc3lzdGVtLiBDb25zaXN0ZW50IGxvd1xuICAgKiBidXJzdCBjcmVkaXQgYmFsYW5jZSBjYW4gYmUgYW4gaW5kaWNhdG9yIG9mIHRoZSBzbG93aW5nIGRvd24gaW4gdGhyb3VnaHB1dCBhbmQgaW5jcmVhc2UgaW4gSS9PIGxhdGVuY3kuXG4gICAqL1xuICByZWFkb25seSBhbGFybURlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIGZvciB0aGUgRWZzRmlsZVN5c3RlbUJ1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFZnNGaWxlU3lzdGVtQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm1Qcm9wcyBleHRlbmRzIEVmc0ZpbGVTeXN0ZW1BbGFybVByb3BzLCBFZnNCdXJzdENyZWRpdEJhbGFuY2VBbGFybUNvbmZpZyB7fVxuXG4vKipcbiAqIFRoaXMgYWxhcm0gaGVscHMgaW4gZW5zdXJpbmcgdGhhdCB0aGVyZSBpcyBhdmFpbGFibGUgYnVyc3QgY3JlZGl0IGJhbGFuY2UgZm9yIHRoZSBmaWxlIHN5c3RlbSB1c2FnZS5cbiAqXG4gKiBXaGVuIHRoZXJlIGlzIG5vIGF2YWlsYWJsZSBidXJzdCBjcmVkaXQsIGFwcGxpY2F0aW9ucyBhY2Nlc3MgdG8gdGhlIHRoZSBmaWxlIHN5c3RlbSB3aWxsIGJlIGxpbWl0ZWQgZHVlIHRvIGxvdyB0aHJvdWdocHV0LlxuICogSWYgdGhlIG1ldHJpYyBkcm9wcyB0byAwIGNvbnNpc3RlbnRseSwgY29uc2lkZXIgY2hhbmdpbmcgdGhlIHRocm91Z2hwdXQgbW9kZSB0byBFbGFzdGljIG9yIFByb3Zpc2lvbmVkIHRocm91Z2hwdXQgbW9kZS5cbiAqXG4gKiBUaGUgYWxhcm0gaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIHBlcmNlbnRhZ2UgaXMgbG93ZXIgb3IgZXF1YWxzIHRoZSB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFZnNGaWxlU3lzdGVtQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm0gZXh0ZW5kcyBjbG91ZHdhdGNoLkFsYXJtIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IElDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBFZnNGaWxlU3lzdGVtQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm1Qcm9wcykge1xuICAgIGNvbnN0IGFsYXJtTmFtZSA9IHByb3BzLmFsYXJtTmFtZSA/PyBgJHtwcm9wcy5maWxlU3lzdGVtLmZpbGVTeXN0ZW1JZH0gLSAke0Vmc1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5CVVJTVF9DUkVESVRfQkFMQU5DRX1gO1xuICAgIGNvbnN0IHBlcmlvZCA9IHByb3BzLnBlcmlvZCA/PyBEdXJhdGlvbi5taW51dGVzKDEpO1xuICAgIGNvbnN0IGV2YWx1YXRpb25QZXJpb2RzID0gcHJvcHMuZXZhbHVhdGlvblBlcmlvZHMgPz8gMTU7XG4gICAgY29uc3QgZGF0YXBvaW50c1RvQWxhcm0gPSBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAxNTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSBwcm9wcy50aHJlc2hvbGQgPz8gMDtcbiAgICBjb25zdCB0cmVhdE1pc3NpbmdEYXRhID0gcHJvcHMudHJlYXRNaXNzaW5nRGF0YSA/PyBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTUlTU0lORztcbiAgICBjb25zdCBhbGFybURlc2NyaXB0aW9uID0gcHJvcHMuYWxhcm1EZXNjcmlwdGlvbiA/PyAnVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCBsb3cgYnVyc3QgY3JlZGl0IGJhbGFuY2Ugb2YgdGhlIGZpbGUgc3lzdGVtLidcbiAgICAgICsgJyBDb25zaXN0ZW50IGxvdyBidXJzdCBjcmVkaXQgYmFsYW5jZSBjYW4gYmUgYW4gaW5kaWNhdG9yIG9mIHRoZSBzbG93aW5nIGRvd24gaW4gdGhyb3VnaHB1dCBhbmQgaW5jcmVhc2UgaW4gSS9PIGxhdGVuY3kuJztcblxuICAgIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZChwZXJpb2QsIGV2YWx1YXRpb25QZXJpb2RzLCBhbGFybU5hbWUpO1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBhbGFybU5hbWUsXG4gICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgIG5hbWVzcGFjZTogJ0FXUy9FRlMnLFxuICAgICAgICBtZXRyaWNOYW1lOiBFZnNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuQlVSU1RfQ1JFRElUX0JBTEFOQ0UsXG4gICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICBGaWxlU3lzdGVtSWQ6IHByb3BzLmZpbGVTeXN0ZW0uZmlsZVN5c3RlbUlkLFxuICAgICAgICB9LFxuICAgICAgICBwZXJpb2QsXG4gICAgICAgIHN0YXRpc3RpYzogJ0F2ZXJhZ2UnLFxuICAgICAgfSksXG4gICAgICB0aHJlc2hvbGQsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuTEVTU19USEFOX09SX0VRVUFMX1RPX1RIUkVTSE9MRCxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuYWxhcm1BY3Rpb24pIHRoaXMuYWRkQWxhcm1BY3Rpb24ocHJvcHMuYWxhcm1BY3Rpb24pO1xuICAgIGlmIChwcm9wcy5va0FjdGlvbikgdGhpcy5hZGRPa0FjdGlvbihwcm9wcy5va0FjdGlvbik7XG4gICAgaWYgKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pIHRoaXMuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9ucyBmb3IgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgYW4gRUZTIFNlcnZpY2UuXG4gKlxuICogRGVmYXVsdCBhY3Rpb25zIGFyZSBvdmVycmlkZGVuIGJ5IHRoZSBhY3Rpb25zIHNwZWNpZmllZCBpbiB0aGVcbiAqIGluZGl2aWR1YWwgYWxhcm0gY29uZmlndXJhdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWZzRmlsZVN5c3RlbVJlY29tbWVuZGVkQWxhcm1zQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gaXMgdHJpZ2dlcmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRBbGFybUFjdGlvbj86IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uO1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgYWN0aW9uIHRvIHRha2Ugd2hlbiBhbiBhbGFybSBlbnRlcnMgdGhlIG9rIHN0YXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRPa0FjdGlvbj86IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uO1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgYWN0aW9uIHRvIHRha2Ugd2hlbiBhbiBhbGFybSBoYXMgaW5zdWZmaWNpZW50IGRhdGEuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdEluc3VmZmljaWVudERhdGFBY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIEhvdyB0byBoYW5kbGUgbWlzc2luZyBkYXRhIGZvciB0aGlzIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCBUcmVhdE1pc3NpbmdEYXRhLk1JU1NJTkdcbiAgICovXG4gIHJlYWRvbmx5IHRyZWF0TWlzc2luZ0RhdGE/OiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGE7XG4gIC8qKlxuICAgKiBBbGFybSBtZXRyaWNzIHRvIGV4Y2x1ZGUgZnJvbSB0aGUgcmVjb21tZW5kZWQgYWxhcm1zLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGVBbGFybXM/OiBFZnNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3NbXTtcbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZXMgdG8gZXhjbHVkZSBmcm9tIHRoZSByZWNvbW1lbmRlZCBhbGFybXMuXG4gICAqXG4gICAqIFVzZSBhIHJlc291cmNlcyBpZCB0byBleGNsdWRlIGEgc3BlY2lmaWMgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlUmVzb3VyY2VzPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIFBlcmNlbnRJT0xpbWl0IGFsYXJtLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnUGVyY2VudElPTGltaXRBbGFybT86IEVmc1BlcmNlbnRJT0xpbWl0QWxhcm1Db25maWc7XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIEJ1cnN0Q3JlZGl0QmFsYW5jZSBhbGFybS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbmZpZ0J1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtPzogRWZzQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm1Db25maWc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgdGhlIEVmc0ZpbGVTeXN0ZW1SZWNvbW1lbmRlZEFsYXJtcyBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWZzRmlsZVN5c3RlbVJlY29tbWVuZGVkQWxhcm1zUHJvcHMgZXh0ZW5kcyBFZnNGaWxlU3lzdGVtUmVjb21tZW5kZWRBbGFybXNDb25maWcge1xuICAvKipcbiAgICogVGhlIEVGUyBGaWxlU3lzdGVtIHRvIG1vbml0b3IuXG4gICAqL1xuICByZWFkb25seSBmaWxlU3lzdGVtOiBlZnMuRmlsZVN5c3RlbTtcbn1cblxuLyoqXG4gKiBBIGNvbnN0cnVjdCB0aGF0IGNyZWF0ZXMgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgYW4gRUZTIEZpbGVTeXN0ZW0uXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbW9uaXRvcmluZy9CZXN0X1ByYWN0aWNlX1JlY29tbWVuZGVkX0FsYXJtc19BV1NfU2VydmljZXMuaHRtbCNFRlNcbiAqL1xuZXhwb3J0IGNsYXNzIEVmc0ZpbGVTeXN0ZW1SZWNvbW1lbmRlZEFsYXJtcyBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgUGVyY2VudElPTGltaXQgYWxhcm0uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWxhcm1QZXJjZW50SU9MaW1pdD86IEVmc0ZpbGVTeXN0ZW1QZXJjZW50SU9MaW1pdEFsYXJtO1xuXG4gIC8qKlxuICAgKiBUaGUgQnVyc3RDcmVkaXRCYWxhbmNlIGFsYXJtLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFsYXJtQnVyc3RDcmVkaXRCYWxhbmNlPzogRWZzRmlsZVN5c3RlbUJ1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBFZnNGaWxlU3lzdGVtUmVjb21tZW5kZWRBbGFybXNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBpZiAoIXByb3BzLmV4Y2x1ZGVBbGFybXM/LmluY2x1ZGVzKEVmc1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5QRVJDRU5UX0lPX0xJTUlUKSkge1xuICAgICAgdGhpcy5hbGFybVBlcmNlbnRJT0xpbWl0ID0gbmV3IEVmc0ZpbGVTeXN0ZW1QZXJjZW50SU9MaW1pdEFsYXJtKHRoaXMsIGAke3Byb3BzLmZpbGVTeXN0ZW0ubm9kZS5pZH1fUGVyY2VudElPTGltaXRgLCB7XG4gICAgICAgIGZpbGVTeXN0ZW06IHByb3BzLmZpbGVTeXN0ZW0sXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICAgIC4uLnByb3BzLmNvbmZpZ1BlcmNlbnRJT0xpbWl0QWxhcm0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKHByb3BzLmRlZmF1bHRBbGFybUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnUGVyY2VudElPTGltaXRBbGFybT8uYWxhcm1BY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybVBlcmNlbnRJT0xpbWl0LmFkZEFsYXJtQWN0aW9uKHByb3BzLmRlZmF1bHRBbGFybUFjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0T2tBY3Rpb24gJiYgIXByb3BzLmNvbmZpZ1BlcmNlbnRJT0xpbWl0QWxhcm0/Lm9rQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuYWxhcm1QZXJjZW50SU9MaW1pdC5hZGRPa0FjdGlvbihwcm9wcy5kZWZhdWx0T2tBY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdEluc3VmZmljaWVudERhdGFBY3Rpb24gJiYgIXByb3BzLmNvbmZpZ1BlcmNlbnRJT0xpbWl0QWxhcm0/Lmluc3VmZmljaWVudERhdGFBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybVBlcmNlbnRJT0xpbWl0LmFkZEluc3VmZmljaWVudERhdGFBY3Rpb24ocHJvcHMuZGVmYXVsdEluc3VmZmljaWVudERhdGFBY3Rpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcHJvcHMuZXhjbHVkZUFsYXJtcz8uaW5jbHVkZXMoRWZzUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLkJVUlNUX0NSRURJVF9CQUxBTkNFKSkge1xuICAgICAgdGhpcy5hbGFybUJ1cnN0Q3JlZGl0QmFsYW5jZSA9IG5ldyBFZnNGaWxlU3lzdGVtQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm0odGhpcywgYCR7cHJvcHMuZmlsZVN5c3RlbS5ub2RlLmlkfV9CdXJzdENyZWRpdEJhbGFuY2VgLCB7XG4gICAgICAgIGZpbGVTeXN0ZW06IHByb3BzLmZpbGVTeXN0ZW0sXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICAgIC4uLnByb3BzLmNvbmZpZ0J1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0QWxhcm1BY3Rpb24gJiYgIXByb3BzLmNvbmZpZ0J1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtPy5hbGFybUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtQnVyc3RDcmVkaXRCYWxhbmNlLmFkZEFsYXJtQWN0aW9uKHByb3BzLmRlZmF1bHRBbGFybUFjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0T2tBY3Rpb24gJiYgIXByb3BzLmNvbmZpZ0J1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtPy5va0FjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtQnVyc3RDcmVkaXRCYWxhbmNlLmFkZE9rQWN0aW9uKHByb3BzLmRlZmF1bHRPa0FjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm0/Lmluc3VmZmljaWVudERhdGFBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybUJ1cnN0Q3JlZGl0QmFsYW5jZS5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBbiBleHRlbnNpb24gZm9yIHRoZSBGaWxlU3lzdGVtIGNvbnN0cnVjdCB0aGF0IHByb3ZpZGVzIG1ldGhvZHNcbiAqIHRvIGNyZWF0ZSByZWNvbW1lbmRlZCBhbGFybXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWxlU3lzdGVtIGV4dGVuZHMgZWZzLkZpbGVTeXN0ZW0ge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogZWZzLkZpbGVTeXN0ZW1Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWxhcm0gdGhhdCBtb25pdG9ycyB0aGUgUGVyY2VudElPTGltaXQgZm9yIHRoZSBFRlMgZmlsZVN5c3RlbS5cbiAgICovXG4gIHB1YmxpYyBhbGFybVBlcmNlbnRJT0xpbWl0KHByb3BzPzogRWZzUGVyY2VudElPTGltaXRBbGFybUNvbmZpZyk6IEVmc0ZpbGVTeXN0ZW1QZXJjZW50SU9MaW1pdEFsYXJtIHtcbiAgICByZXR1cm4gbmV3IEVmc0ZpbGVTeXN0ZW1QZXJjZW50SU9MaW1pdEFsYXJtKHRoaXMsICdQZXJjZW50SU9MaW1pdEFsYXJtJywge1xuICAgICAgZmlsZVN5c3RlbTogdGhpcyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWxhcm0gdGhhdCBtb25pdG9ycyB0aGUgQnVyc3RDcmVkaXRCYWxhbmNlIGZvciB0aGUgRUZTIGZpbGVTeXN0ZW0uXG4gICAqL1xuICBwdWJsaWMgYWxhcm1CdXJzdENyZWRpdEJhbGFuY2UocHJvcHM/OiBFZnNCdXJzdENyZWRpdEJhbGFuY2VBbGFybUNvbmZpZyk6IEVmc0ZpbGVTeXN0ZW1CdXJzdENyZWRpdEJhbGFuY2VBbGFybSB7XG4gICAgcmV0dXJuIG5ldyBFZnNGaWxlU3lzdGVtQnVyc3RDcmVkaXRCYWxhbmNlQWxhcm0odGhpcywgJ0J1cnN0Q3JlZGl0QmFsYW5jZUFsYXJtJywge1xuICAgICAgZmlsZVN5c3RlbTogdGhpcyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgdGhlIEVGUyBGaWxlU3lzdGVtLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL0Jlc3RfUHJhY3RpY2VfUmVjb21tZW5kZWRfQWxhcm1zX0FXU19TZXJ2aWNlcy5odG1sI0VGU1xuICAgKi9cbiAgcHVibGljIGFwcGx5UmVjb21tZW5kZWRBbGFybXMocHJvcHM/OiBFZnNGaWxlU3lzdGVtUmVjb21tZW5kZWRBbGFybXNDb25maWcpOiBFZnNGaWxlU3lzdGVtUmVjb21tZW5kZWRBbGFybXMge1xuICAgIHJldHVybiBuZXcgRWZzRmlsZVN5c3RlbVJlY29tbWVuZGVkQWxhcm1zKHRoaXMsICdFZnNGaWxlU3lzdGVtUmVjb21tZW5kZWRBbGFybXMnLCB7XG4gICAgICBmaWxlU3lzdGVtOiB0aGlzLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDb25maWd1cmVzIHRoZSByZWNvbW1lbmRlZCBhbGFybXMgZm9yIGFuIEVGUyBGaWxlU3lzdGVtLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvQmVzdF9QcmFjdGljZV9SZWNvbW1lbmRlZF9BbGFybXNfQVdTX1NlcnZpY2VzLmh0bWwjRUZTXG4gKi9cbmV4cG9ydCBjbGFzcyBFZnNSZWNvbW1lbmRlZEFsYXJtc0FzcGVjdCBpbXBsZW1lbnRzIElBc3BlY3Qge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzPzogRWZzRmlsZVN5c3RlbVJlY29tbWVuZGVkQWxhcm1zQ29uZmlnKSB7fVxuXG4gIHB1YmxpYyB2aXNpdChub2RlOiBJQ29uc3RydWN0KTogdm9pZCB7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBlZnMuRmlsZVN5c3RlbSkge1xuICAgICAgaWYgKHRoaXMucHJvcHM/LmV4Y2x1ZGVSZXNvdXJjZXMgJiYgdGhpcy5wcm9wcy5leGNsdWRlUmVzb3VyY2VzLmluY2x1ZGVzKG5vZGUubm9kZS5pZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZmlsZVN5c3RlbSA9IG5vZGUgYXMgZWZzLkZpbGVTeXN0ZW07XG5cbiAgICAgICAgbmV3IEVmc0ZpbGVTeXN0ZW1SZWNvbW1lbmRlZEFsYXJtcyhmaWxlU3lzdGVtLCAnRWZzRmlsZVN5c3RlbVJlY29tbWVuZGVkQWxhcm1zRnJvbUFzcGVjdCcsIHtcbiAgICAgICAgICBmaWxlU3lzdGVtLFxuICAgICAgICAgIC4uLnRoaXMucHJvcHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19