iam-floyd
Version:
AWS IAM policy statement generator with fluent interface
477 lines • 42.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceGroups = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [resource-groups](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsresourcegroups.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class ResourceGroups extends shared_1.PolicyStatement {
/**
* Statement provider for service [resource-groups](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsresourcegroups.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
constructor(sid) {
super(sid);
this.servicePrefix = 'resource-groups';
this.accessLevelList = {
Write: [
'AssociateResource',
'CancelTagSyncTask',
'CreateGroup',
'DeleteGroup',
'DeleteGroupPolicy',
'DisassociateResource',
'GroupResources',
'PutGroupConfiguration',
'PutGroupPolicy',
'StartTagSyncTask',
'UngroupResources',
'UpdateAccountSettings',
'UpdateGroup',
'UpdateGroupQuery'
],
Read: [
'GetAccountSettings',
'GetGroup',
'GetGroupConfiguration',
'GetGroupPolicy',
'GetGroupQuery',
'GetTagSyncTask',
'GetTags'
],
List: [
'ListGroupResources',
'ListGroupingStatuses',
'ListGroups',
'ListResourceTypes',
'ListTagSyncTasks',
'SearchResources'
],
Tagging: [
'Tag',
'Untag'
]
};
}
/**
* Grants permission to associate a resource to an Application
*
* Access Level: Write
*
* https://docs.aws.amazon.com/servicecatalog/latest/arguide/associate-resources.html
*/
toAssociateResource() {
return this.to('AssociateResource');
}
/**
* Grants permission to cancel a tag-sync task for an application group
*
* Access Level: Write
*
* Dependent actions:
* - resource-groups:DeleteGroup
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_CancelTagSyncTask.html
*/
toCancelTagSyncTask() {
return this.to('CancelTagSyncTask');
}
/**
* Grants permission to create a resource group with a specified name, description, and resource query
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* Dependent actions:
* - cloudformation:DescribeStacks
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_CreateGroup.html
*/
toCreateGroup() {
return this.to('CreateGroup');
}
/**
* Grants permission to delete a specified resource group
*
* Access Level: Write
*
* Dependent actions:
* - tag:GetResources
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_DeleteGroup.html
*/
toDeleteGroup() {
return this.to('DeleteGroup');
}
/**
* Grants permission to delete a resource-based policy for the specified group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/license-manager/latest/userguide/management-role.html#service-linked-role-permissions-management-role
*/
toDeleteGroupPolicy() {
return this.to('DeleteGroupPolicy');
}
/**
* Grants permission to disassociate a resource from an Application
*
* Access Level: Write
*
* https://docs.aws.amazon.com/servicecatalog/latest/arguide/associate-resources.html
*/
toDisassociateResource() {
return this.to('DisassociateResource');
}
/**
* Grants permission to get the current status of optional features in Resource Groups
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GetAccountSettings.html
*/
toGetAccountSettings() {
return this.to('GetAccountSettings');
}
/**
* Grants permission to get information of a specified resource group
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GetGroup.html
*/
toGetGroup() {
return this.to('GetGroup');
}
/**
* Grants permission to get the service configuration associated with the specified resource group
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GetGroupConfiguration.html
*/
toGetGroupConfiguration() {
return this.to('GetGroupConfiguration');
}
/**
* Grants permission to get a resource-based policy for the specified group
*
* Access Level: Read
*
* https://docs.aws.amazon.com/license-manager/latest/userguide/management-role.html#service-linked-role-permissions-management-role
*/
toGetGroupPolicy() {
return this.to('GetGroupPolicy');
}
/**
* Grants permission to get the query associated with a specified resource group
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GetGroupQuery.html
*/
toGetGroupQuery() {
return this.to('GetGroupQuery');
}
/**
* Grants permission to get information of a specified tag-sync task
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GetTagSyncTask.html
*/
toGetTagSyncTask() {
return this.to('GetTagSyncTask');
}
/**
* Grants permission to get the tags associated with a specified resource group
*
* Access Level: Read
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GetTags.html
*/
toGetTags() {
return this.to('GetTags');
}
/**
* Grants permission to add the specified resources to the specified group
*
* Access Level: Write
*
* Dependent actions:
* - resource-groups:Tag
* - tag:TagResources
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_GroupResources.html
*/
toGroupResources() {
return this.to('GroupResources');
}
/**
* Grants permission to list the resources that are members of a specified resource group
*
* Access Level: List
*
* Dependent actions:
* - cloudformation:DescribeStacks
* - cloudformation:ListStackResources
* - tag:GetResources
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_ListGroupResources.html
*/
toListGroupResources() {
return this.to('ListGroupResources');
}
/**
* Grants permission to list grouping statuses for a specified application group
*
* Access Level: List
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_ListGroupingStatuses.html
*/
toListGroupingStatuses() {
return this.to('ListGroupingStatuses');
}
/**
* Grants permission to list all resource groups in your account
*
* Access Level: List
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_ListGroups.html
*/
toListGroups() {
return this.to('ListGroups');
}
/**
* Grants permission to list supported resource types
*
* Access Level: List
*
* https://docs.aws.amazon.com/ARG/latest/userguide/gettingstarted-query.html
*/
toListResourceTypes() {
return this.to('ListResourceTypes');
}
/**
* Grants permission to list all tag-sync tasks in your account
*
* Access Level: List
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_ListTagSyncTasks.html
*/
toListTagSyncTasks() {
return this.to('ListTagSyncTasks');
}
/**
* Grants permission to put the service configuration associated with the specified resource group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_PutGroupConfiguration.html
*/
toPutGroupConfiguration() {
return this.to('PutGroupConfiguration');
}
/**
* Grants permission to add a resource-based policy for the specified group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/license-manager/latest/userguide/management-role.html#service-linked-role-permissions-management-role
*/
toPutGroupPolicy() {
return this.to('PutGroupPolicy');
}
/**
* Grants permission to search for AWS resources matching the given query
*
* Access Level: List
*
* Dependent actions:
* - cloudformation:DescribeStacks
* - cloudformation:ListStackResources
* - tag:GetResources
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_SearchResources.html
*/
toSearchResources() {
return this.to('SearchResources');
}
/**
* Grants permission to create a tag-sync task for an application group
*
* Access Level: Write
*
* Dependent actions:
* - iam:PassRole
* - resource-groups:CreateGroup
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_StartTagSyncTask.html
*/
toStartTagSyncTask() {
return this.to('StartTagSyncTask');
}
/**
* Grants permission to tag a specified resource group
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_Tag.html
*/
toTag() {
return this.to('Tag');
}
/**
* Grants permission to remove the specified resources from the specified group
*
* Access Level: Write
*
* Dependent actions:
* - resource-groups:Untag
* - tag:UntagResources
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_UngroupResources.html
*/
toUngroupResources() {
return this.to('UngroupResources');
}
/**
* Grants permission to remove tags associated with a specified resource group
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_Untag.html
*/
toUntag() {
return this.to('Untag');
}
/**
* Grants permission to update optional features in Resource Groups
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_UpdateAccountSettings.html
*/
toUpdateAccountSettings() {
return this.to('UpdateAccountSettings');
}
/**
* Grants permission to update a specified resource group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_UpdateGroup.html
*/
toUpdateGroup() {
return this.to('UpdateGroup');
}
/**
* Grants permission to update the query associated with a specified resource group
*
* Access Level: Write
*
* Dependent actions:
* - cloudformation:DescribeStacks
*
* https://docs.aws.amazon.com/ARG/latest/APIReference/API_UpdateGroupQuery.html
*/
toUpdateGroupQuery() {
return this.to('UpdateGroupQuery');
}
/**
* Adds a resource of type group to the statement
*
* https://docs.aws.amazon.com/ARG/latest/userguide/resource-groups.html
*
* @param groupName - Identifier for the groupName.
* @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()
*/
onGroup(groupName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:resource-groups:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:group/${groupName}`);
}
/**
* Adds a resource of type tagSyncTask to the statement
*
* https://docs.aws.amazon.com/servicecatalog/latest/arguide/app-tag-sync.html
*
* @param groupName - Identifier for the groupName.
* @param taskId - Identifier for the taskId.
* @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()
*/
onTagSyncTask(groupName, taskId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:resource-groups:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:group/${groupName}/tag-sync-task/${taskId}`);
}
/**
* Filters access by the presence of tag key-value pairs in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
*
* Applies to actions:
* - .toCreateGroup()
* - .toTag()
*
* @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 tag key-value pairs attached to the resource
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
*
* Applies to resource types:
* - group
* - tagSyncTask
*
* @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 the presence of tag keys in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
*
* Applies to actions:
* - .toCreateGroup()
* - .toTag()
* - .toUntag()
*
* @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');
}
}
exports.ResourceGroups = ResourceGroups;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2Vncm91cHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJyZXNvdXJjZWdyb3Vwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFFekQ7Ozs7R0FJRztBQUNILE1BQWEsY0FBZSxTQUFRLHdCQUFlO0lBR2pEOzs7O09BSUc7SUFDSCxZQUFZLEdBQVk7UUFDdEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBUk4sa0JBQWEsR0FBRyxpQkFBaUIsQ0FBQztRQXVYL0Isb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLG1CQUFtQjtnQkFDbkIsbUJBQW1CO2dCQUNuQixhQUFhO2dCQUNiLGFBQWE7Z0JBQ2IsbUJBQW1CO2dCQUNuQixzQkFBc0I7Z0JBQ3RCLGdCQUFnQjtnQkFDaEIsdUJBQXVCO2dCQUN2QixnQkFBZ0I7Z0JBQ2hCLGtCQUFrQjtnQkFDbEIsa0JBQWtCO2dCQUNsQix1QkFBdUI7Z0JBQ3ZCLGFBQWE7Z0JBQ2Isa0JBQWtCO2FBQ25CO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLG9CQUFvQjtnQkFDcEIsVUFBVTtnQkFDVix1QkFBdUI7Z0JBQ3ZCLGdCQUFnQjtnQkFDaEIsZUFBZTtnQkFDZixnQkFBZ0I7Z0JBQ2hCLFNBQVM7YUFDVjtZQUNELElBQUksRUFBRTtnQkFDSixvQkFBb0I7Z0JBQ3BCLHNCQUFzQjtnQkFDdEIsWUFBWTtnQkFDWixtQkFBbUI7Z0JBQ25CLGtCQUFrQjtnQkFDbEIsaUJBQWlCO2FBQ2xCO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLEtBQUs7Z0JBQ0wsT0FBTzthQUNSO1NBQ0YsQ0FBQztJQXBaRixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksbUJBQW1CO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxtQkFBbUI7UUFDeEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFD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Q0FBQyxPQUFRLFNBQVMsSUFBSSxJQUFJLENBQUMsZ0JBQWlCLG9CQUFxQixNQUFNLElBQUksSUFBSSxDQUFDLGFBQWMsSUFBSyxPQUFPLElBQUksSUFBSSxDQUFDLGNBQWUsVUFBVyxTQUFVLGtCQUFtQixNQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ3JNLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxlQUFlLENBQUMsTUFBYyxFQUFFLEtBQXdCLEVBQUUsUUFBNEI7UUFDM0YsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFtQixNQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2hGLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxnQkFBZ0IsQ0FBQyxNQUFjLEVBQUUsS0FBd0IsRUFBRSxRQUE0QjtRQUM1RixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW9CLE1BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLFlBQVksQ0FBQyxLQUF3QixFQUFFLFFBQTRCO1FBQ3hFLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUNqRSxDQUFDO0NBQ0Y7QUFyZkQsd0NBcWZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3Jlc291cmNlLWdyb3Vwc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzcmVzb3VyY2Vncm91cHMuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZUdyb3VwcyBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ3Jlc291cmNlLWdyb3Vwcyc7XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbcmVzb3VyY2UtZ3JvdXBzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NyZXNvdXJjZWdyb3Vwcy5odG1sKS5cbiAgICpcbiAgICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvcihzaWQ/OiBzdHJpbmcpIHtcbiAgICBzdXBlcihzaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFzc29jaWF0ZSBhIHJlc291cmNlIHRvIGFuIEFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2VjYXRhbG9nL2xhdGVzdC9hcmd1aWRlL2Fzc29jaWF0ZS1yZXNvdXJjZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXNzb2NpYXRlUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZVJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY2FuY2VsIGEgdGFnLXN5bmMgdGFzayBmb3IgYW4gYXBwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSByZXNvdXJjZS1ncm91cHM6RGVsZXRlR3JvdXBcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DYW5jZWxUYWdTeW5jVGFzay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DYW5jZWxUYWdTeW5jVGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ2FuY2VsVGFnU3luY1Rhc2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSByZXNvdXJjZSBncm91cCB3aXRoIGEgc3BlY2lmaWVkIG5hbWUsIGRlc2NyaXB0aW9uLCBhbmQgcmVzb3VyY2UgcXVlcnlcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBjbG91ZGZvcm1hdGlvbjpEZXNjcmliZVN0YWNrc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVHcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHNwZWNpZmllZCByZXNvdXJjZSBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRhZzpHZXRSZXNvdXJjZXNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSByZXNvdXJjZS1iYXNlZCBwb2xpY3kgZm9yIHRoZSBzcGVjaWZpZWQgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGljZW5zZS1tYW5hZ2VyL2xhdGVzdC91c2VyZ3VpZGUvbWFuYWdlbWVudC1yb2xlLmh0bWwjc2VydmljZS1saW5rZWQtcm9sZS1wZXJtaXNzaW9ucy1tYW5hZ2VtZW50LXJvbGVcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUdyb3VwUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVHcm91cFBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRpc2Fzc29jaWF0ZSBhIHJlc291cmNlIGZyb20gYW4gQXBwbGljYXRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZWNhdGFsb2cvbGF0ZXN0L2FyZ3VpZGUvYXNzb2NpYXRlLXJlc291cmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhc3NvY2lhdGVSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYXNzb2NpYXRlUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIG9wdGlvbmFsIGZlYXR1cmVzIGluIFJlc291cmNlIEdyb3Vwc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRBY2NvdW50U2V0dGluZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0QWNjb3VudFNldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRBY2NvdW50U2V0dGluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgaW5mb3JtYXRpb24gb2YgYSBzcGVjaWZpZWQgcmVzb3VyY2UgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0R3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0R3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHRoZSBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0R3JvdXBDb25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEdyb3VwQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0R3JvdXBDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGEgcmVzb3VyY2UtYmFzZWQgcG9saWN5IGZvciB0aGUgc3BlY2lmaWVkIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGljZW5zZS1tYW5hZ2VyL2xhdGVzdC91c2VyZ3VpZGUvbWFuYWdlbWVudC1yb2xlLmh0bWwjc2VydmljZS1saW5rZWQtcm9sZS1wZXJtaXNzaW9ucy1tYW5hZ2VtZW50LXJvbGVcbiAgICovXG4gIHB1YmxpYyB0b0dldEdyb3VwUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRHcm91cFBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgcXVlcnkgYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWVkIHJlc291cmNlIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldEdyb3VwUXVlcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0R3JvdXBRdWVyeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0R3JvdXBRdWVyeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBpbmZvcm1hdGlvbiBvZiBhIHNwZWNpZmllZCB0YWctc3luYyB0YXNrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldFRhZ1N5bmNUYXNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFRhZ1N5bmNUYXNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRUYWdTeW5jVGFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgdGFncyBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgcmVzb3VyY2UgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0VGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRUYWdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2VzIHRvIHRoZSBzcGVjaWZpZWQgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSByZXNvdXJjZS1ncm91cHM6VGFnXG4gICAqIC0gdGFnOlRhZ1Jlc291cmNlc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dyb3VwUmVzb3VyY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dyb3VwUmVzb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHcm91cFJlc291cmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIHJlc291cmNlcyB0aGF0IGFyZSBtZW1iZXJzIG9mIGEgc3BlY2lmaWVkIHJlc291cmNlIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBjbG91ZGZvcm1hdGlvbjpEZXNjcmliZVN0YWNrc1xuICAgKiAtIGNsb3VkZm9ybWF0aW9uOkxpc3RTdGFja1Jlc291cmNlc1xuICAgKiAtIHRhZzpHZXRSZXNvdXJjZXNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0R3JvdXBSZXNvdXJjZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEdyb3VwUmVzb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0R3JvdXBSZXNvdXJjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGdyb3VwaW5nIHN0YXR1c2VzIGZvciBhIHNwZWNpZmllZCBhcHBsaWNhdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0R3JvdXBpbmdTdGF0dXNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0R3JvdXBpbmdTdGF0dXNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEdyb3VwaW5nU3RhdHVzZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCByZXNvdXJjZSBncm91cHMgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RHcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3Qgc3VwcG9ydGVkIHJlc291cmNlIHR5cGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC91c2VyZ3VpZGUvZ2V0dGluZ3N0YXJ0ZWQtcXVlcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFJlc291cmNlVHlwZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RSZXNvdXJjZVR5cGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhbGwgdGFnLXN5bmMgdGFza3MgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RUYWdTeW5jVGFza3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ1N5bmNUYXNrcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ1N5bmNUYXNrcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHB1dCB0aGUgc2VydmljZSBjb25maWd1cmF0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHJlc291cmNlIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRHcm91cENvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0R3JvdXBDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRHcm91cENvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgYSByZXNvdXJjZS1iYXNlZCBwb2xpY3kgZm9yIHRoZSBzcGVjaWZpZWQgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGljZW5zZS1tYW5hZ2VyL2xhdGVzdC91c2VyZ3VpZGUvbWFuYWdlbWVudC1yb2xlLmh0bWwjc2VydmljZS1saW5rZWQtcm9sZS1wZXJtaXNzaW9ucy1tYW5hZ2VtZW50LXJvbGVcbiAgICovXG4gIHB1YmxpYyB0b1B1dEdyb3VwUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRHcm91cFBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHNlYXJjaCBmb3IgQVdTIHJlc291cmNlcyBtYXRjaGluZyB0aGUgZ2l2ZW4gcXVlcnlcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGNsb3VkZm9ybWF0aW9uOkRlc2NyaWJlU3RhY2tzXG4gICAqIC0gY2xvdWRmb3JtYXRpb246TGlzdFN0YWNrUmVzb3VyY2VzXG4gICAqIC0gdGFnOkdldFJlc291cmNlc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1NlYXJjaFJlc291cmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TZWFyY2hSZXNvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1NlYXJjaFJlc291cmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHRhZy1zeW5jIHRhc2sgZm9yIGFuIGFwcGxpY2F0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOlBhc3NSb2xlXG4gICAqIC0gcmVzb3VyY2UtZ3JvdXBzOkNyZWF0ZUdyb3VwXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3RhcnRUYWdTeW5jVGFzay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TdGFydFRhZ1N5bmNUYXNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdGFydFRhZ1N5bmNUYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFnIGEgc3BlY2lmaWVkIHJlc291cmNlIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVJHL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1RhZy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1RhZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0aGUgc3BlY2lmaWVkIHJlc291cmNlcyBmcm9tIHRoZSBzcGVjaWZpZWQgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSByZXNvdXJjZS1ncm91cHM6VW50YWdcbiAgICogLSB0YWc6VW50YWdSZXNvdXJjZXNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Vbmdyb3VwUmVzb3VyY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VuZ3JvdXBSZXNvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VuZ3JvdXBSZXNvdXJjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGFncyBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgcmVzb3VyY2UgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVW50YWcuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVW50YWcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIG9wdGlvbmFsIGZlYXR1cmVzIGluIFJlc291cmNlIEdyb3Vwc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQWNjb3VudFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUFjY291bnRTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlQWNjb3VudFNldHRpbmdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGEgc3BlY2lmaWVkIHJlc291cmNlIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FSRy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIHF1ZXJ5IGFzc29jaWF0ZWQgd2l0aCBhIHNwZWNpZmllZCByZXNvdXJjZSBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGNsb3VkZm9ybWF0aW9uOkRlc2NyaWJlU3RhY2tzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlR3JvdXBRdWVyeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVHcm91cFF1ZXJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVHcm91cFF1ZXJ5Jyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdBc3NvY2lhdGVSZXNvdXJjZScsXG4gICAgICAnQ2FuY2VsVGFnU3luY1Rhc2snLFxuICAgICAgJ0NyZWF0ZUdyb3VwJyxcbiAgICAgICdEZWxldGVHcm91cCcsXG4gICAgICAnRGVsZXRlR3JvdXBQb2xpY3knLFxuICAgICAgJ0Rpc2Fzc29jaWF0ZVJlc291cmNlJyxcbiAgICAgICdHcm91cFJlc291cmNlcycsXG4gICAgICAnUHV0R3JvdXBDb25maWd1cmF0aW9uJyxcbiAgICAgICdQdXRHcm91cFBvbGljeScsXG4gICAgICAnU3RhcnRUYWdTeW5jVGFzaycsXG4gICAgICAnVW5ncm91cFJlc291cmNlcycsXG4gICAgICAnVXBkYXRlQWNjb3VudFNldHRpbmdzJyxcbiAgICAgICdVcGRhdGVHcm91cCcsXG4gICAgICAnVXBkYXRlR3JvdXBRdWVyeSdcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdHZXRBY2NvdW50U2V0dGluZ3MnLFxuICAgICAgJ0dldEdyb3VwJyxcbiAgICAgICdHZXRHcm91cENvbmZpZ3VyYXRpb24nLFxuICAgICAgJ0dldEdyb3VwUG9saWN5JyxcbiAgICAgICdHZXRHcm91cFF1ZXJ5JyxcbiAgICAgICdHZXRUYWdTeW5jVGFzaycsXG4gICAgICAnR2V0VGFncydcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdMaXN0R3JvdXBSZXNvdXJjZXMnLFxuICAgICAgJ0xpc3RHcm91cGluZ1N0YXR1c2VzJyxcbiAgICAgICdMaXN0R3JvdXBzJyxcbiAgICAgICdMaXN0UmVzb3VyY2VUeXBlcycsXG4gICAgICAnTGlzdFRhZ1N5bmNUYXNrcycsXG4gICAgICAnU2VhcmNoUmVzb3VyY2VzJ1xuICAgIF0sXG4gICAgVGFnZ2luZzogW1xuICAgICAgJ1RhZycsXG4gICAgICAnVW50YWcnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBncm91cCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BUkcvbGF0ZXN0L3VzZXJndWlkZS9yZXNvdXJjZS1ncm91cHMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gZ3JvdXBOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGdyb3VwTmFtZS5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uR3JvdXAoZ3JvdXBOYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06cmVzb3VyY2UtZ3JvdXBzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpncm91cC8keyBncm91cE5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHRhZ1N5bmNUYXNrIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2VjYXRhbG9nL2xhdGVzdC9hcmd1aWRlL2FwcC10YWctc3luYy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBncm91cE5hbWUgLSBJZGVudGlmaWVyIGZvciB0aGUgZ3JvdXBOYW1lLlxuICAgKiBAcGFyYW0gdGFza0lkIC0gSWRlbnRpZmllciBmb3IgdGhlIHRhc2tJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uVGFnU3luY1Rhc2soZ3JvdXBOYW1lOiBzdHJpbmcsIHRhc2tJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OnJlc291cmNlLWdyb3VwczokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06Z3JvdXAvJHsgZ3JvdXBOYW1lIH0vdGFnLXN5bmMtdGFzay8keyB0YXNrSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0YWcga2V5LXZhbHVlIHBhaXJzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVHcm91cCgpXG4gICAqIC0gLnRvVGFnKClcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1JlcXVlc3RUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVxdWVzdFRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRhZyBrZXktdmFsdWUgcGFpcnMgYXR0YWNoZWQgdG8gdGhlIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXNvdXJjZXRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGdyb3VwXG4gICAqIC0gdGFnU3luY1Rhc2tcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1Jlc291cmNlVGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlc291cmNlVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHByZXNlbmNlIG9mIHRhZyBrZXlzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy10YWdrZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVHcm91cCgpXG4gICAqIC0gLnRvVGFnKClcbiAgICogLSAudG9VbnRhZygpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzVGFnS2V5cyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlRhZ0tleXNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxufVxuIl19