cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
458 lines • 46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimestreamInfluxdb = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [timestream-influxdb](https://docs.aws.amazon.com/service-authorization/latest/reference/list_timestream-influxdb.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class TimestreamInfluxdb extends shared_1.PolicyStatement {
/**
* Grants permission to create a Timestream InfluxDB Backup for a DbInstance or DbCluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_CreateDbBackup.html
*/
toCreateDbBackup() {
return this.to('CreateDbBackup');
}
/**
* Grants permission to create a new Timestream InfluxDB Cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_CreateDbCluster.html
*/
toCreateDbCluster() {
return this.to('CreateDbCluster');
}
/**
* Grants permission to create a new Timestream InfluxDB instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_CreateDbInstance.html
*/
toCreateDbInstance() {
return this.to('CreateDbInstance');
}
/**
* Grants permission to create a new Timestream InfluxDB parameter group
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_CreateDbParameterGroup.html
*/
toCreateDbParameterGroup() {
return this.to('CreateDbParameterGroup');
}
/**
* Grants permission to delete a Timestream InfluxDB backup
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DeleteDbBackup.html
*/
toDeleteDbBackup() {
return this.to('DeleteDbBackup');
}
/**
* Grants permission to delete a Timestream InfluxDB Cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DeleteDbCluster.html
*/
toDeleteDbCluster() {
return this.to('DeleteDbCluster');
}
/**
* Grants permission to delete a Timestream InfluxDB instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DeleteDbInstance.html
*/
toDeleteDbInstance() {
return this.to('DeleteDbInstance');
}
/**
* Grants permission to get information about a Timestream InfluxDB Backup
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_GetDbBackup.html
*/
toGetDbBackup() {
return this.to('GetDbBackup');
}
/**
* Grants permission to get information about a Timestream InfluxDB Cluster
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_GetDbCluster.html
*/
toGetDbCluster() {
return this.to('GetDbCluster');
}
/**
* Grants permission to get information about a Timestream InfluxDB instance
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_GetDbInstance.html
*/
toGetDbInstance() {
return this.to('GetDbInstance');
}
/**
* Grants permission to get information about a Timestream InfluxDB parameter group
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_GetDbParameterGroup.html
*/
toGetDbParameterGroup() {
return this.to('GetDbParameterGroup');
}
/**
* Grants permission to list information about all Timestream InfluxDB backups in the account
*
* Access Level: List
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_ListDbBackups.html
*/
toListDbBackups() {
return this.to('ListDbBackups');
}
/**
* Grants permission to list information about all Timestream InfluxDB clusters in the account
*
* Access Level: List
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_ListDbClusters.html
*/
toListDbClusters() {
return this.to('ListDbClusters');
}
/**
* Grants permission to list information about all Timestream InfluxDB instances in the account
*
* Access Level: List
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_ListDbInstances.html
*/
toListDbInstances() {
return this.to('ListDbInstances');
}
/**
* Grants permission to list information about all Timestream InfluxDB Instances belonging to a cluster
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_ListDbInstancesForCluster.html
*/
toListDbInstancesForCluster() {
return this.to('ListDbInstancesForCluster');
}
/**
* Grants permission to list information about all Timestream InfluxDB parameter groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_ListDbParameterGroups.html
*/
toListDbParameterGroups() {
return this.to('ListDbParameterGroups');
}
/**
* Grants permission to list tags for a Timestream InfluxDB resource
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to reboot a Timestream InfluxDB Cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_RebootDbCluster.html
*/
toRebootDbCluster() {
return this.to('RebootDbCluster');
}
/**
* Grants permission to reboot a Timestream InfluxDB instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_RebootDbInstance.html
*/
toRebootDbInstance() {
return this.to('RebootDbInstance');
}
/**
* Grants permission to restore from a Timestream InfluxDB backup
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_RestoreFromDbBackup.html
*/
toRestoreFromDbBackup() {
return this.to('RestoreFromDbBackup');
}
/**
* Grants permission to tag a Timestream InfluxDB resource
*
* Access Level: Tagging, Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to untag a Timestream InfluxDB resource
*
* Access Level: Tagging, Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to update a Timestream InfluxDB Cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_UpdateDbCluster.html
*/
toUpdateDbCluster() {
return this.to('UpdateDbCluster');
}
/**
* Grants permission to update a Timestream InfluxDB instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_UpdateDbInstance.html
*/
toUpdateDbInstance() {
return this.to('UpdateDbInstance');
}
/**
* Adds a resource of type db-backup to the statement
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DbBackupSummary.html
*
* @param dbBackupId - Identifier for the dbBackupId.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region.
* @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition.
*
* Possible conditions:
* - .ifAwsResourceTag()
*/
onDbBackup(dbBackupId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:timestream-influxdb:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:db-backup/${dbBackupId}`);
}
/**
* Adds a resource of type db-cluster to the statement
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DbClusterSummary.html
*
* @param dbClusterId - Identifier for the dbClusterId.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region.
* @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition.
*
* Possible conditions:
* - .ifAwsResourceTag()
*/
onDbCluster(dbClusterId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:timestream-influxdb:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:db-cluster/${dbClusterId}`);
}
/**
* Adds a resource of type db-instance to the statement
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DbInstanceSummary.html
*
* @param dbInstanceIdentifier - Identifier for the dbInstanceIdentifier.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region.
* @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition.
*
* Possible conditions:
* - .ifAwsResourceTag()
*/
onDbInstance(dbInstanceIdentifier, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:timestream-influxdb:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:db-instance/${dbInstanceIdentifier}`);
}
/**
* Adds a resource of type db-parameter-group to the statement
*
* https://docs.aws.amazon.com/ts-influxdb/latest/ts-influxdb-api/API_DbParameterGroupSummary.html
*
* @param dbParameterGroupIdentifier - Identifier for the dbParameterGroupIdentifier.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region.
* @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition.
*
* Possible conditions:
* - .ifAwsResourceTag()
*/
onDbParameterGroup(dbParameterGroupIdentifier, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:timestream-influxdb:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:db-parameter-group/${dbParameterGroupIdentifier}`);
}
/**
* Filters access by a tag key and value pair that is allowed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
*
* Applies to actions:
* - .toCreateDbBackup()
* - .toCreateDbCluster()
* - .toCreateDbInstance()
* - .toCreateDbParameterGroup()
* - .toRestoreFromDbBackup()
* - .toTagResource()
*
* @param tagKey The tag key to check
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsRequestTag(tagKey, value, operator) {
return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike');
}
/**
* Filters access by a tag key and value pair of a resource
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
*
* Applies to actions:
* - .toCreateDbBackup()
* - .toCreateDbCluster()
* - .toCreateDbInstance()
* - .toDeleteDbBackup()
* - .toDeleteDbCluster()
* - .toDeleteDbInstance()
* - .toGetDbBackup()
* - .toGetDbCluster()
* - .toGetDbInstance()
* - .toGetDbParameterGroup()
* - .toListDbInstancesForCluster()
* - .toListTagsForResource()
* - .toRebootDbCluster()
* - .toRebootDbInstance()
* - .toRestoreFromDbBackup()
* - .toTagResource()
* - .toUntagResource()
* - .toUpdateDbCluster()
* - .toUpdateDbInstance()
*
* Applies to resource types:
* - db-backup
* - db-cluster
* - db-instance
* - db-parameter-group
*
* @param tagKey The tag key to check
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsResourceTag(tagKey, value, operator) {
return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike');
}
/**
* Filters access by a list of tag keys that are allowed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
*
* Applies to actions:
* - .toCreateDbBackup()
* - .toCreateDbCluster()
* - .toCreateDbInstance()
* - .toCreateDbParameterGroup()
* - .toRestoreFromDbBackup()
* - .toTagResource()
* - .toUntagResource()
*
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsTagKeys(value, operator) {
return this.if(`aws:TagKeys`, value, operator ?? 'StringLike');
}
/**
* Filters access by the restore mode specified in the request
*
* https://docs.aws.amazon.com/timestream/latest/developerguide/security-iam.html
*
* Applies to actions:
* - .toRestoreFromDbBackup()
*
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifRestoreMode(value, operator) {
return this.if(`RestoreMode`, value, operator ?? 'StringLike');
}
/**
* Statement provider for service [timestream-influxdb](https://docs.aws.amazon.com/service-authorization/latest/reference/list_timestream-influxdb.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'timestream-influxdb';
this.accessLevelList = {
Write: [
'CreateDbBackup',
'CreateDbCluster',
'CreateDbInstance',
'CreateDbParameterGroup',
'DeleteDbBackup',
'DeleteDbCluster',
'DeleteDbInstance',
'RebootDbCluster',
'RebootDbInstance',
'RestoreFromDbBackup',
'TagResource',
'UntagResource',
'UpdateDbCluster',
'UpdateDbInstance'
],
Read: [
'GetDbBackup',
'GetDbCluster',
'GetDbInstance',
'GetDbParameterGroup',
'ListDbInstancesForCluster',
'ListTagsForResource'
],
List: [
'ListDbBackups',
'ListDbClusters',
'ListDbInstances',
'ListDbParameterGroups'
],
Tagging: [
'TagResource',
'UntagResource'
]
};
}
}
exports.TimestreamInfluxdb = TimestreamInfluxdb;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXN0cmVhbS1pbmZsdXhkYi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRpbWVzdHJlYW0taW5mbHV4ZGIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBR3pEOzs7O0dBSUc7QUFDSCxNQUFhLGtCQUFtQixTQUFRLHdCQUFlO0lBR3JEOzs7Ozs7T0FNRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksaUJBQWlCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSx3QkFBd0I7UUFDN0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksaUJBQWlCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxjQUFjO1FBQ25CLE9B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LElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxhQUFhLENBQUMsS0FBd0IsRUFBRSxRQUE0QjtRQUN6RSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVEOzs7T0FHRztJQUNILFlBQVksS0FBZ0M7UUFDMUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBN2RSLGtCQUFhLEdBQUcscUJBQXFCLENBQUM7UUE4UW5DLG9CQUFlLEdBQW9CO1lBQzNDLEtBQUssRUFBRTtnQkFDTCxnQkFBZ0I7Z0JBQ2hCLGlCQUFpQjtnQkFDakIsa0JBQWtCO2dCQUNsQix3QkFBd0I7Z0JBQ3hCLGdCQUFnQjtnQkFDaEIsaUJBQWlCO2dCQUNqQixrQkFBa0I7Z0JBQ2xCLGlCQUFpQjtnQkFDakIsa0JBQWtCO2dCQUNsQixxQkFBcUI7Z0JBQ3JCLGFBQWE7Z0JBQ2IsZUFBZTtnQkFDZixpQkFBaUI7Z0JBQ2pCLGtCQUFrQjthQUNuQjtZQUNELElBQUksRUFBRTtnQkFDSixhQUFhO2dCQUNiLGNBQWM7Z0JBQ2QsZUFBZTtnQkFDZixxQkFBcUI7Z0JBQ3JCLDJCQUEyQjtnQkFDM0IscUJBQXFCO2FBQ3RCO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLGVBQWU7Z0JBQ2YsZ0JBQWdCO2dCQUNoQixpQkFBaUI7Z0JBQ2pCLHVCQUF1QjthQUN4QjtZQUNELE9BQU8sRUFBRTtnQkFDUCxhQUFhO2dCQUNiLGVBQWU7YUFDaEI7U0FDRixDQUFDO0lBNktGLENBQUM7Q0FDRjtBQWhlRCxnREFnZUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgYXdzX2lhbSBhcyBpYW0gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3RpbWVzdHJlYW0taW5mbHV4ZGJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X3RpbWVzdHJlYW0taW5mbHV4ZGIuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lc3RyZWFtSW5mbHV4ZGIgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICd0aW1lc3RyZWFtLWluZmx1eGRiJztcblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgVGltZXN0cmVhbSBJbmZsdXhEQiBCYWNrdXAgZm9yIGEgRGJJbnN0YW5jZSBvciBEYkNsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfQ3JlYXRlRGJCYWNrdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlRGJCYWNrdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZURiQmFja3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3IFRpbWVzdHJlYW0gSW5mbHV4REIgQ2x1c3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9DcmVhdGVEYkNsdXN0ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlRGJDbHVzdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVEYkNsdXN0ZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcgVGltZXN0cmVhbSBJbmZsdXhEQiBpbnN0YW5jZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9DcmVhdGVEYkluc3RhbmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZURiSW5zdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZURiSW5zdGFuY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcgVGltZXN0cmVhbSBJbmZsdXhEQiBwYXJhbWV0ZXIgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfQ3JlYXRlRGJQYXJhbWV0ZXJHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVEYlBhcmFtZXRlckdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVEYlBhcmFtZXRlckdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgVGltZXN0cmVhbSBJbmZsdXhEQiBiYWNrdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfRGVsZXRlRGJCYWNrdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlRGJCYWNrdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZURiQmFja3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgVGltZXN0cmVhbSBJbmZsdXhEQiBDbHVzdGVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RzLWluZmx1eGRiL2xhdGVzdC90cy1pbmZsdXhkYi1hcGkvQVBJX0RlbGV0ZURiQ2x1c3Rlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVEYkNsdXN0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZURiQ2x1c3RlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIFRpbWVzdHJlYW0gSW5mbHV4REIgaW5zdGFuY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfRGVsZXRlRGJJbnN0YW5jZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVEYkluc3RhbmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVEYkluc3RhbmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGEgVGltZXN0cmVhbSBJbmZsdXhEQiBCYWNrdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9HZXREYkJhY2t1cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXREYkJhY2t1cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0RGJCYWNrdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBUaW1lc3RyZWFtIEluZmx1eERCIENsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9HZXREYkNsdXN0ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0RGJDbHVzdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXREYkNsdXN0ZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBUaW1lc3RyZWFtIEluZmx1eERCIGluc3RhbmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfR2V0RGJJbnN0YW5jZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXREYkluc3RhbmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXREYkluc3RhbmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGEgVGltZXN0cmVhbSBJbmZsdXhEQiBwYXJhbWV0ZXIgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9HZXREYlBhcmFtZXRlckdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldERiUGFyYW1ldGVyR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldERiUGFyYW1ldGVyR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IGFsbCBUaW1lc3RyZWFtIEluZmx1eERCIGJhY2t1cHMgaW4gdGhlIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9MaXN0RGJCYWNrdXBzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3REYkJhY2t1cHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3REYkJhY2t1cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IGFsbCBUaW1lc3RyZWFtIEluZmx1eERCIGNsdXN0ZXJzIGluIHRoZSBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfTGlzdERiQ2x1c3RlcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdERiQ2x1c3RlcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3REYkNsdXN0ZXJzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgVGltZXN0cmVhbSBJbmZsdXhEQiBpbnN0YW5jZXMgaW4gdGhlIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9MaXN0RGJJbnN0YW5jZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdERiSW5zdGFuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RGJJbnN0YW5jZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IGFsbCBUaW1lc3RyZWFtIEluZmx1eERCIEluc3RhbmNlcyBiZWxvbmdpbmcgdG8gYSBjbHVzdGVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfTGlzdERiSW5zdGFuY2VzRm9yQ2x1c3Rlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0RGJJbnN0YW5jZXNGb3JDbHVzdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RGJJbnN0YW5jZXNGb3JDbHVzdGVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgVGltZXN0cmVhbSBJbmZsdXhEQiBwYXJhbWV0ZXIgZ3JvdXBzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfTGlzdERiUGFyYW1ldGVyR3JvdXBzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3REYlBhcmFtZXRlckdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdERiUGFyYW1ldGVyR3JvdXBzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0YWdzIGZvciBhIFRpbWVzdHJlYW0gSW5mbHV4REIgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZWJvb3QgYSBUaW1lc3RyZWFtIEluZmx1eERCIENsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfUmVib290RGJDbHVzdGVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlYm9vdERiQ2x1c3RlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVib290RGJDbHVzdGVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVib290IGEgVGltZXN0cmVhbSBJbmZsdXhEQiBpbnN0YW5jZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9SZWJvb3REYkluc3RhbmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlYm9vdERiSW5zdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlYm9vdERiSW5zdGFuY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXN0b3JlIGZyb20gYSBUaW1lc3RyZWFtIEluZmx1eERCIGJhY2t1cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9SZXN0b3JlRnJvbURiQmFja3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1Jlc3RvcmVGcm9tRGJCYWNrdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1Jlc3RvcmVGcm9tRGJCYWNrdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0YWcgYSBUaW1lc3RyZWFtIEluZmx1eERCIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZywgV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RzLWluZmx1eGRiL2xhdGVzdC90cy1pbmZsdXhkYi1hcGkvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVudGFnIGEgVGltZXN0cmVhbSBJbmZsdXhEQiByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmcsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYSBUaW1lc3RyZWFtIEluZmx1eERCIENsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfVXBkYXRlRGJDbHVzdGVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZURiQ2x1c3RlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlRGJDbHVzdGVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGEgVGltZXN0cmVhbSBJbmZsdXhEQiBpbnN0YW5jZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9VcGRhdGVEYkluc3RhbmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZURiSW5zdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZURiSW5zdGFuY2UnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0NyZWF0ZURiQmFja3VwJyxcbiAgICAgICdDcmVhdGVEYkNsdXN0ZXInLFxuICAgICAgJ0NyZWF0ZURiSW5zdGFuY2UnLFxuICAgICAgJ0NyZWF0ZURiUGFyYW1ldGVyR3JvdXAnLFxuICAgICAgJ0RlbGV0ZURiQmFja3VwJyxcbiAgICAgICdEZWxldGVEYkNsdXN0ZXInLFxuICAgICAgJ0RlbGV0ZURiSW5zdGFuY2UnLFxuICAgICAgJ1JlYm9vdERiQ2x1c3RlcicsXG4gICAgICAnUmVib290RGJJbnN0YW5jZScsXG4gICAgICAnUmVzdG9yZUZyb21EYkJhY2t1cCcsXG4gICAgICAnVGFnUmVzb3VyY2UnLFxuICAgICAgJ1VudGFnUmVzb3VyY2UnLFxuICAgICAgJ1VwZGF0ZURiQ2x1c3RlcicsXG4gICAgICAnVXBkYXRlRGJJbnN0YW5jZSdcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdHZXREYkJhY2t1cCcsXG4gICAgICAnR2V0RGJDbHVzdGVyJyxcbiAgICAgICdHZXREYkluc3RhbmNlJyxcbiAgICAgICdHZXREYlBhcmFtZXRlckdyb3VwJyxcbiAgICAgICdMaXN0RGJJbnN0YW5jZXNGb3JDbHVzdGVyJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0xpc3REYkJhY2t1cHMnLFxuICAgICAgJ0xpc3REYkNsdXN0ZXJzJyxcbiAgICAgICdMaXN0RGJJbnN0YW5jZXMnLFxuICAgICAgJ0xpc3REYlBhcmFtZXRlckdyb3VwcydcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVW50YWdSZXNvdXJjZSdcbiAgICBdXG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGRiLWJhY2t1cCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90cy1pbmZsdXhkYi9sYXRlc3QvdHMtaW5mbHV4ZGItYXBpL0FQSV9EYkJhY2t1cFN1bW1hcnkuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gZGJCYWNrdXBJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBkYkJhY2t1cElkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25EYkJhY2t1cChkYkJhY2t1cElkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06dGltZXN0cmVhbS1pbmZsdXhkYjokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06ZGItYmFja3VwLyR7IGRiQmFja3VwSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGRiLWNsdXN0ZXIgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfRGJDbHVzdGVyU3VtbWFyeS5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBkYkNsdXN0ZXJJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBkYkNsdXN0ZXJJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uRGJDbHVzdGVyKGRiQ2x1c3RlcklkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06dGltZXN0cmVhbS1pbmZsdXhkYjokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06ZGItY2x1c3Rlci8keyBkYkNsdXN0ZXJJZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgZGItaW5zdGFuY2UgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdHMtaW5mbHV4ZGIvbGF0ZXN0L3RzLWluZmx1eGRiLWFwaS9BUElfRGJJbnN0YW5jZVN1bW1hcnkuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gZGJJbnN0YW5jZUlkZW50aWZpZXIgLSBJZGVudGlmaWVyIGZvciB0aGUgZGJJbnN0YW5jZUlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkRiSW5zdGFuY2UoZGJJbnN0YW5jZUlkZW50aWZpZXI6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTp0aW1lc3RyZWFtLWluZmx1eGRiOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpkYi1pbnN0YW5jZS8keyBkYkluc3RhbmNlSWRlbnRpZmllciB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgZGItcGFyYW1ldGVyLWdyb3VwIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RzLWluZmx1eGRiL2xhdGVzdC90cy1pbmZsdXhkYi1hcGkvQVBJX0RiUGFyYW1ldGVyR3JvdXBTdW1tYXJ5Lmh0bWxcbiAgICpcbiAgICogQHBhcmFtIGRiUGFyYW1ldGVyR3JvdXBJZGVudGlmaWVyIC0gSWRlbnRpZmllciBmb3IgdGhlIGRiUGFyYW1ldGVyR3JvdXBJZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25EYlBhcmFtZXRlckdyb3VwKGRiUGFyYW1ldGVyR3JvdXBJZGVudGlmaWVyOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06dGltZXN0cmVhbS1pbmZsdXhkYjokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06ZGItcGFyYW1ldGVyLWdyb3VwLyR7IGRiUGFyYW1ldGVyR3JvdXBJZGVudGlmaWVyIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIHRhZyBrZXkgYW5kIHZhbHVlIHBhaXIgdGhhdCBpcyBhbGxvd2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVEYkJhY2t1cCgpXG4gICAqIC0gLnRvQ3JlYXRlRGJDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVEYkluc3RhbmNlKClcbiAgICogLSAudG9DcmVhdGVEYlBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9SZXN0b3JlRnJvbURiQmFja3VwKClcbiAgICogLSAudG9UYWdSZXNvdXJjZSgpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIHRhZyBrZXkgYW5kIHZhbHVlIHBhaXIgb2YgYSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVzb3VyY2V0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZURiQmFja3VwKClcbiAgICogLSAudG9DcmVhdGVEYkNsdXN0ZXIoKVxuICAgKiAtIC50b0NyZWF0ZURiSW5zdGFuY2UoKVxuICAgKiAtIC50b0RlbGV0ZURiQmFja3VwKClcbiAgICogLSAudG9EZWxldGVEYkNsdXN0ZXIoKVxuICAgKiAtIC50b0RlbGV0ZURiSW5zdGFuY2UoKVxuICAgKiAtIC50b0dldERiQmFja3VwKClcbiAgICogLSAudG9HZXREYkNsdXN0ZXIoKVxuICAgKiAtIC50b0dldERiSW5zdGFuY2UoKVxuICAgKiAtIC50b0dldERiUGFyYW1ldGVyR3JvdXAoKVxuICAgKiAtIC50b0xpc3REYkluc3RhbmNlc0ZvckNsdXN0ZXIoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b1JlYm9vdERiQ2x1c3RlcigpXG4gICAqIC0gLnRvUmVib290RGJJbnN0YW5jZSgpXG4gICAqIC0gLnRvUmVzdG9yZUZyb21EYkJhY2t1cCgpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKiAtIC50b1VudGFnUmVzb3VyY2UoKVxuICAgKiAtIC50b1VwZGF0ZURiQ2x1c3RlcigpXG4gICAqIC0gLnRvVXBkYXRlRGJJbnN0YW5jZSgpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gZGItYmFja3VwXG4gICAqIC0gZGItY2x1c3RlclxuICAgKiAtIGRiLWluc3RhbmNlXG4gICAqIC0gZGItcGFyYW1ldGVyLWdyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGEgbGlzdCBvZiB0YWcga2V5cyB0aGF0IGFyZSBhbGxvd2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy10YWdrZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVEYkJhY2t1cCgpXG4gICAqIC0gLnRvQ3JlYXRlRGJDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVEYkluc3RhbmNlKClcbiAgICogLSAudG9DcmVhdGVEYlBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9SZXN0b3JlRnJvbURiQmFja3VwKClcbiAgICogLSAudG9UYWdSZXNvdXJjZSgpXG4gICAqIC0gLnRvVW50YWdSZXNvdXJjZSgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzVGFnS2V5cyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlRhZ0tleXNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcmVzdG9yZSBtb2RlIHNwZWNpZmllZCBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvc2VjdXJpdHktaWFtLmh0bWxcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b1Jlc3RvcmVGcm9tRGJCYWNrdXAoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlJlc3RvcmVNb2RlKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBSZXN0b3JlTW9kZWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbdGltZXN0cmVhbS1pbmZsdXhkYl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfdGltZXN0cmVhbS1pbmZsdXhkYi5odG1sKS5cbiAgICpcbiAgICovXG4gIGNvbnN0cnVjdG9yKHByb3BzPzogaWFtLlBvbGljeVN0YXRlbWVudFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICB9XG59XG4iXX0=