cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
610 lines • 57.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Servicediscovery = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [servicediscovery](https://docs.aws.amazon.com/service-authorization/latest/reference/list_servicediscovery.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Servicediscovery extends shared_1.PolicyStatement {
/**
* Grants permission to create an HTTP namespace
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_CreateHttpNamespace.html
*/
toCreateHttpNamespace() {
return this.to('CreateHttpNamespace');
}
/**
* Grants permission to create a private namespace based on DNS, which will be visible only inside a specified Amazon VPC
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_CreatePrivateDnsNamespace.html
*/
toCreatePrivateDnsNamespace() {
return this.to('CreatePrivateDnsNamespace');
}
/**
* Grants permission to create a public namespace based on DNS, which will be visible on the internet
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_CreatePublicDnsNamespace.html
*/
toCreatePublicDnsNamespace() {
return this.to('CreatePublicDnsNamespace');
}
/**
* Grants permission to create a service
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_CreateService.html
*/
toCreateService() {
return this.to('CreateService');
}
/**
* Grants permission to delete a specified namespace
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_DeleteNamespace.html
*/
toDeleteNamespace() {
return this.to('DeleteNamespace');
}
/**
* Grants permission to delete a specified service
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_DeleteService.html
*/
toDeleteService() {
return this.to('DeleteService');
}
/**
* Grants permission to delete specified attributes from a service
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_DeleteServiceAttributes.html
*/
toDeleteServiceAttributes() {
return this.to('DeleteServiceAttributes');
}
/**
* Grants permission to delete the records and the health check, if any, that Amazon Route 53 created for the specified instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_DeregisterInstance.html
*/
toDeregisterInstance() {
return this.to('DeregisterInstance');
}
/**
* Grants permission to discover registered instances for a specified namespace and service
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_DiscoverInstances.html
*/
toDiscoverInstances() {
return this.to('DiscoverInstances');
}
/**
* Grants permission to discover the revision of the instances for a specified namespace and service
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_DiscoverInstancesRevision.html
*/
toDiscoverInstancesRevision() {
return this.to('DiscoverInstancesRevision');
}
/**
* Grants permission to get information about a specified instance
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_GetInstance.html
*/
toGetInstance() {
return this.to('GetInstance');
}
/**
* Grants permission to get the current health status (Healthy, Unhealthy, or Unknown) of one or more instances
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_GetInstancesHealthStatus.html
*/
toGetInstancesHealthStatus() {
return this.to('GetInstancesHealthStatus');
}
/**
* Grants permission to get information about a namespace
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_GetNamespace.html
*/
toGetNamespace() {
return this.to('GetNamespace');
}
/**
* Grants permission to get information about a specific operation
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_GetOperation.html
*/
toGetOperation() {
return this.to('GetOperation');
}
/**
* Grants permission to get the settings for a specified service
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_GetService.html
*/
toGetService() {
return this.to('GetService');
}
/**
* Grants permission to get the attributes for a specified service
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_GetServiceAttributes.html
*/
toGetServiceAttributes() {
return this.to('GetServiceAttributes');
}
/**
* Grants permission to get summary information about the instances that were registered with a specified service
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_ListInstances.html
*/
toListInstances() {
return this.to('ListInstances');
}
/**
* Grants permission to get information about the namespaces
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_ListNamespaces.html
*/
toListNamespaces() {
return this.to('ListNamespaces');
}
/**
* Grants permission to list operations that match the criteria that you specify
*
* Access Level: List
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_ListOperations.html
*/
toListOperations() {
return this.to('ListOperations');
}
/**
* Grants permission to get settings for all the services that match specified filters
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_ListServices.html
*/
toListServices() {
return this.to('ListServices');
}
/**
* Grants permission to lists tags for the specified resource
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to register an instance based on the settings in a specified service
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_RegisterInstance.html
*/
toRegisterInstance() {
return this.to('RegisterInstance');
}
/**
* Grants permission to add one or more tags to the specified resource
*
* Access Level: Tagging, Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to remove one or more tags from the specified resource
*
* Access Level: Tagging, Write
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to update the settings for a HTTP namespace
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UpdateHttpNamespace.html
*/
toUpdateHttpNamespace() {
return this.to('UpdateHttpNamespace');
}
/**
* Grants permission to update the current health status for an instance that has a custom health check
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UpdateInstanceCustomHealthStatus.html
*/
toUpdateInstanceCustomHealthStatus() {
return this.to('UpdateInstanceCustomHealthStatus');
}
/**
* Grants permission to update the settings for a private DNS namespace
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UpdatePrivateDnsNamespace.html
*/
toUpdatePrivateDnsNamespace() {
return this.to('UpdatePrivateDnsNamespace');
}
/**
* Grants permission to update the settings for a public DNS namespace
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UpdatePublicDnsNamespace.html
*/
toUpdatePublicDnsNamespace() {
return this.to('UpdatePublicDnsNamespace');
}
/**
* Grants permission to update the settings in a specified service
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UpdateService.html
*/
toUpdateService() {
return this.to('UpdateService');
}
/**
* Grants permission to update the attributes in a specified service
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/api/API_UpdateServiceAttributes.html
*/
toUpdateServiceAttributes() {
return this.to('UpdateServiceAttributes');
}
/**
* Grants permission to delete the RAM access control policy for a namespace
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html
*/
toDeleteResourcePolicy() {
return this.to('DeleteResourcePolicy');
}
/**
* Grants permission to read the RAM access control policy for a namespace
*
* Access Level: Read
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html
*/
toGetResourcePolicy() {
return this.to('GetResourcePolicy');
}
/**
* Grants permission to define the RAM access control policy for a namespace
*
* Access Level: Write
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/sharing-namespaces.html
*/
toPutResourcePolicy() {
return this.to('PutResourcePolicy');
}
/**
* Adds a resource of type namespace to the statement
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/API_Namespace.html
*
* @param namespaceId - Identifier for the namespaceId.
* @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()
*/
onNamespace(namespaceId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:servicediscovery:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:namespace/${namespaceId}`);
}
/**
* Adds a resource of type service to the statement
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/API_Service.html
*
* @param serviceId - Identifier for the serviceId.
* @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()
*/
onService(serviceId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:servicediscovery:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:service/${serviceId}`);
}
/**
* Filters actions based on the tags that are passed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
*
* Applies to actions:
* - .toCreateHttpNamespace()
* - .toCreatePrivateDnsNamespace()
* - .toCreatePublicDnsNamespace()
* - .toCreateService()
* - .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 actions based on the tags associated with the resource
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
*
* Applies to actions:
* - .toCreateService()
* - .toDeleteNamespace()
* - .toDeleteService()
* - .toDeleteServiceAttributes()
* - .toDeregisterInstance()
* - .toDiscoverInstances()
* - .toDiscoverInstancesRevision()
* - .toGetInstance()
* - .toGetInstancesHealthStatus()
* - .toGetNamespace()
* - .toGetOperation()
* - .toGetService()
* - .toGetServiceAttributes()
* - .toListInstances()
* - .toRegisterInstance()
* - .toUpdateHttpNamespace()
* - .toUpdateInstanceCustomHealthStatus()
* - .toUpdatePrivateDnsNamespace()
* - .toUpdatePublicDnsNamespace()
* - .toUpdateService()
* - .toUpdateServiceAttributes()
* - .toDeleteResourcePolicy()
* - .toGetResourcePolicy()
* - .toPutResourcePolicy()
*
* Applies to resource types:
* - namespace
* - service
*
* @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 actions based on the tag keys that are passed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
*
* Applies to actions:
* - .toCreateHttpNamespace()
* - .toCreatePrivateDnsNamespace()
* - .toCreatePublicDnsNamespace()
* - .toCreateService()
* - .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 specifying the Amazon Resource Name (ARN) for the related namespace
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/access-control-overview.html#specifying-conditions
*
* Applies to actions:
* - .toCreateService()
*
* @param value The value(s) to check
* @param operator Works with [arn operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN). **Default:** `ArnLike`
*/
ifNamespaceArn(value, operator) {
return this.if(`NamespaceArn`, value, operator ?? 'ArnLike');
}
/**
* Filters access by specifying the name of the related namespace
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/access-control-overview.html#specifying-conditions
*
* Applies to actions:
* - .toDiscoverInstances()
* - .toDiscoverInstancesRevision()
*
* @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`
*/
ifNamespaceName(value, operator) {
return this.if(`NamespaceName`, value, operator ?? 'StringLike');
}
/**
* Filters access by specifying the Amazon Resource Name (ARN) for the related service
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/access-control-overview.html#specifying-conditions
*
* Applies to actions:
* - .toDeregisterInstance()
* - .toGetInstance()
* - .toGetInstancesHealthStatus()
* - .toListInstances()
* - .toRegisterInstance()
* - .toUpdateInstanceCustomHealthStatus()
*
* @param value The value(s) to check
* @param operator Works with [arn operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN). **Default:** `ArnLike`
*/
ifServiceArn(value, operator) {
return this.if(`ServiceArn`, value, operator ?? 'ArnLike');
}
/**
* Filters access by specifying the account id of the related service creator
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/access-control-overview.html#specifying-conditions
*
* Applies to actions:
* - .toDeleteService()
* - .toDeleteServiceAttributes()
* - .toDeregisterInstance()
* - .toRegisterInstance()
* - .toUpdateInstanceCustomHealthStatus()
* - .toUpdateService()
* - .toUpdateServiceAttributes()
*
* @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`
*/
ifServiceCreatedByAccount(value, operator) {
return this.if(`ServiceCreatedByAccount`, value, operator ?? 'StringLike');
}
/**
* Filters access by specifying the name of the related service
*
* https://docs.aws.amazon.com/cloud-map/latest/dg/access-control-overview.html#specifying-conditions
*
* Applies to actions:
* - .toDiscoverInstances()
* - .toDiscoverInstancesRevision()
*
* @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`
*/
ifServiceName(value, operator) {
return this.if(`ServiceName`, value, operator ?? 'StringLike');
}
/**
* Statement provider for service [servicediscovery](https://docs.aws.amazon.com/service-authorization/latest/reference/list_servicediscovery.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'servicediscovery';
this.accessLevelList = {
Write: [
'CreateHttpNamespace',
'CreatePrivateDnsNamespace',
'CreatePublicDnsNamespace',
'CreateService',
'DeleteNamespace',
'DeleteService',
'DeleteServiceAttributes',
'DeregisterInstance',
'RegisterInstance',
'TagResource',
'UntagResource',
'UpdateHttpNamespace',
'UpdateInstanceCustomHealthStatus',
'UpdatePrivateDnsNamespace',
'UpdatePublicDnsNamespace',
'UpdateService',
'UpdateServiceAttributes',
'DeleteResourcePolicy',
'PutResourcePolicy'
],
Read: [
'DiscoverInstances',
'DiscoverInstancesRevision',
'GetInstance',
'GetInstancesHealthStatus',
'GetNamespace',
'GetOperation',
'GetService',
'GetServiceAttributes',
'ListInstances',
'ListNamespaces',
'ListServices',
'ListTagsForResource',
'GetResourcePolicy'
],
List: [
'ListOperations'
],
Tagging: [
'TagResource',
'UntagResource'
]
};
}
}
exports.Servicediscovery = Servicediscovery;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZWRpc2NvdmVyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNlcnZpY2VkaXNjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBR3pEOzs7O0dBSUc7QUFDSCxNQUFhLGdCQUFpQixTQUFRLHdCQUFlO0lBR25EOzs7Ozs7Ozs7O09BVUc7SUFDSSxxQkFBcUI7UUFDMUIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSwyQkFBMkI7UUFDaEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDJCQUEyQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSwwQkFBMEI7UUFDL0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxpQkFBaUI7UUFDdEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSx5QkFBeUI7UUFDOUIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLG9CQUFvQjtRQUN6QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksbUJBQW1CO1FBQ3hCLE9B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Li8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgYXdzX2lhbSBhcyBpYW0gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3NlcnZpY2VkaXNjb3ZlcnldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X3NlcnZpY2VkaXNjb3ZlcnkuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlZGlzY292ZXJ5IGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAnc2VydmljZWRpc2NvdmVyeSc7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhbiBIVFRQIG5hbWVzcGFjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2FwaS9BUElfQ3JlYXRlSHR0cE5hbWVzcGFjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVIdHRwTmFtZXNwYWNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVIdHRwTmFtZXNwYWNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgcHJpdmF0ZSBuYW1lc3BhY2UgYmFzZWQgb24gRE5TLCB3aGljaCB3aWxsIGJlIHZpc2libGUgb25seSBpbnNpZGUgYSBzcGVjaWZpZWQgQW1hem9uIFZQQ1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2FwaS9BUElfQ3JlYXRlUHJpdmF0ZURuc05hbWVzcGFjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQcml2YXRlRG5zTmFtZXNwYWNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQcml2YXRlRG5zTmFtZXNwYWNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgcHVibGljIG5hbWVzcGFjZSBiYXNlZCBvbiBETlMsIHdoaWNoIHdpbGwgYmUgdmlzaWJsZSBvbiB0aGUgaW50ZXJuZXRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0NyZWF0ZVB1YmxpY0Ruc05hbWVzcGFjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQdWJsaWNEbnNOYW1lc3BhY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVB1YmxpY0Ruc05hbWVzcGFjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHNlcnZpY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0NyZWF0ZVNlcnZpY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU2VydmljZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU2VydmljZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHNwZWNpZmllZCBuYW1lc3BhY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0RlbGV0ZU5hbWVzcGFjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVOYW1lc3BhY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZU5hbWVzcGFjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHNwZWNpZmllZCBzZXJ2aWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9EZWxldGVTZXJ2aWNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVNlcnZpY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVNlcnZpY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgc3BlY2lmaWVkIGF0dHJpYnV0ZXMgZnJvbSBhIHNlcnZpY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0RlbGV0ZVNlcnZpY2VBdHRyaWJ1dGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVNlcnZpY2VBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVTZXJ2aWNlQXR0cmlidXRlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgcmVjb3JkcyBhbmQgdGhlIGhlYWx0aCBjaGVjaywgaWYgYW55LCB0aGF0IEFtYXpvbiBSb3V0ZSA1MyBjcmVhdGVkIGZvciB0aGUgc3BlY2lmaWVkIGluc3RhbmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9EZXJlZ2lzdGVySW5zdGFuY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVyZWdpc3Rlckluc3RhbmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXJlZ2lzdGVySW5zdGFuY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNjb3ZlciByZWdpc3RlcmVkIGluc3RhbmNlcyBmb3IgYSBzcGVjaWZpZWQgbmFtZXNwYWNlIGFuZCBzZXJ2aWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0Rpc2NvdmVySW5zdGFuY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2NvdmVySW5zdGFuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNjb3Zlckluc3RhbmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRpc2NvdmVyIHRoZSByZXZpc2lvbiBvZiB0aGUgaW5zdGFuY2VzIGZvciBhIHNwZWNpZmllZCBuYW1lc3BhY2UgYW5kIHNlcnZpY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2FwaS9BUElfRGlzY292ZXJJbnN0YW5jZXNSZXZpc2lvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNjb3Zlckluc3RhbmNlc1JldmlzaW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNjb3Zlckluc3RhbmNlc1JldmlzaW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGEgc3BlY2lmaWVkIGluc3RhbmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0dldEluc3RhbmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEluc3RhbmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRJbnN0YW5jZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgY3VycmVudCBoZWFsdGggc3RhdHVzIChIZWFsdGh5LCBVbmhlYWx0aHksIG9yIFVua25vd24pIG9mIG9uZSBvciBtb3JlIGluc3RhbmNlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9HZXRJbnN0YW5jZXNIZWFsdGhTdGF0dXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0SW5zdGFuY2VzSGVhbHRoU3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRJbnN0YW5jZXNIZWFsdGhTdGF0dXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBuYW1lc3BhY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2FwaS9BUElfR2V0TmFtZXNwYWNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldE5hbWVzcGFjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0TmFtZXNwYWNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGEgc3BlY2lmaWMgb3BlcmF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0dldE9wZXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRPcGVyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldE9wZXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgc2V0dGluZ3MgZm9yIGEgc3BlY2lmaWVkIHNlcnZpY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2FwaS9BUElfR2V0U2VydmljZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTZXJ2aWNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTZXJ2aWNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHRoZSBhdHRyaWJ1dGVzIGZvciBhIHNwZWNpZmllZCBzZXJ2aWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0dldFNlcnZpY2VBdHRyaWJ1dGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFNlcnZpY2VBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTZXJ2aWNlQXR0cmlidXRlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBzdW1tYXJ5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBpbnN0YW5jZXMgdGhhdCB3ZXJlIHJlZ2lzdGVyZWQgd2l0aCBhIHNwZWNpZmllZCBzZXJ2aWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0xpc3RJbnN0YW5jZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEluc3RhbmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEluc3RhbmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbmFtZXNwYWNlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9MaXN0TmFtZXNwYWNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0TmFtZXNwYWNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdE5hbWVzcGFjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IG9wZXJhdGlvbnMgdGhhdCBtYXRjaCB0aGUgY3JpdGVyaWEgdGhhdCB5b3Ugc3BlY2lmeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9MaXN0T3BlcmF0aW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0T3BlcmF0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdE9wZXJhdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgc2V0dGluZ3MgZm9yIGFsbCB0aGUgc2VydmljZXMgdGhhdCBtYXRjaCBzcGVjaWZpZWQgZmlsdGVyc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9MaXN0U2VydmljZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFNlcnZpY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0U2VydmljZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0cyB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX0xpc3RUYWdzRm9yUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ3NGb3JSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlZ2lzdGVyIGFuIGluc3RhbmNlIGJhc2VkIG9uIHRoZSBzZXR0aW5ncyBpbiBhIHNwZWNpZmllZCBzZXJ2aWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9SZWdpc3Rlckluc3RhbmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlZ2lzdGVySW5zdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlZ2lzdGVySW5zdGFuY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgb25lIG9yIG1vcmUgdGFncyB0byB0aGUgc3BlY2lmaWVkIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZywgV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgb25lIG9yIG1vcmUgdGFncyBmcm9tIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nLCBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX1VudGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVW50YWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVW50YWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgc2V0dGluZ3MgZm9yIGEgSFRUUCBuYW1lc3BhY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX1VwZGF0ZUh0dHBOYW1lc3BhY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlSHR0cE5hbWVzcGFjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlSHR0cE5hbWVzcGFjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgY3VycmVudCBoZWFsdGggc3RhdHVzIGZvciBhbiBpbnN0YW5jZSB0aGF0IGhhcyBhIGN1c3RvbSBoZWFsdGggY2hlY2tcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX1VwZGF0ZUluc3RhbmNlQ3VzdG9tSGVhbHRoU3RhdHVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUluc3RhbmNlQ3VzdG9tSGVhbHRoU3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVJbnN0YW5jZUN1c3RvbUhlYWx0aFN0YXR1cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgc2V0dGluZ3MgZm9yIGEgcHJpdmF0ZSBETlMgbmFtZXNwYWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9VcGRhdGVQcml2YXRlRG5zTmFtZXNwYWNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVByaXZhdGVEbnNOYW1lc3BhY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVByaXZhdGVEbnNOYW1lc3BhY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIHNldHRpbmdzIGZvciBhIHB1YmxpYyBETlMgbmFtZXNwYWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9VcGRhdGVQdWJsaWNEbnNOYW1lc3BhY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlUHVibGljRG5zTmFtZXNwYWNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVQdWJsaWNEbnNOYW1lc3BhY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIHNldHRpbmdzIGluIGEgc3BlY2lmaWVkIHNlcnZpY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9hcGkvQVBJX1VwZGF0ZVNlcnZpY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlU2VydmljZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlU2VydmljZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgYXR0cmlidXRlcyBpbiBhIHNwZWNpZmllZCBzZXJ2aWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvYXBpL0FQSV9VcGRhdGVTZXJ2aWNlQXR0cmlidXRlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVTZXJ2aWNlQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlU2VydmljZUF0dHJpYnV0ZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIFJBTSBhY2Nlc3MgY29udHJvbCBwb2xpY3kgZm9yIGEgbmFtZXNwYWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nsb3VkLW1hcC9sYXRlc3QvZGcvc2hhcmluZy1uYW1lc3BhY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVJlc291cmNlUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVSZXNvdXJjZVBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlYWQgdGhlIFJBTSBhY2Nlc3MgY29udHJvbCBwb2xpY3kgZm9yIGEgbmFtZXNwYWNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWQtbWFwL2xhdGVzdC9kZy9zaGFyaW5nLW5hbWVzcGFjZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0UmVzb3VyY2VQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFJlc291cmNlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVmaW5lIHRoZSBSQU0gYWNjZXNzIGNvbnRyb2wgcG9saWN5IGZvciBhIG5hbWVzcGFjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2RnL3NoYXJpbmctbmFtZXNwYWNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRSZXNvdXJjZVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0UmVzb3VyY2VQb2xpY3knKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0NyZWF0ZUh0dHBOYW1lc3BhY2UnLFxuICAgICAgJ0NyZWF0ZVByaXZhdGVEbnNOYW1lc3BhY2UnLFxuICAgICAgJ0NyZWF0ZVB1YmxpY0Ruc05hbWVzcGFjZScsXG4gICAgICAnQ3JlYXRlU2VydmljZScsXG4gICAgICAnRGVsZXRlTmFtZXNwYWNlJyxcbiAgICAgICdEZWxldGVTZXJ2aWNlJyxcbiAgICAgICdEZWxldGVTZXJ2aWNlQXR0cmlidXRlcycsXG4gICAgICAnRGVyZWdpc3Rlckluc3RhbmNlJyxcbiAgICAgICdSZWdpc3Rlckluc3RhbmNlJyxcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVW50YWdSZXNvdXJjZScsXG4gICAgICAnVXBkYXRlSHR0cE5hbWVzcGFjZScsXG4gICAgICAnVXBkYXRlSW5zdGFuY2VDdXN0b21IZWFsdGhTdGF0dXMnLFxuICAgICAgJ1VwZGF0ZVByaXZhdGVEbnNOYW1lc3BhY2UnLFxuICAgICAgJ1VwZGF0ZVB1YmxpY0Ruc05hbWVzcGFjZScsXG4gICAgICAnVXBkYXRlU2VydmljZScsXG4gICAgICAnVXBkYXRlU2VydmljZUF0dHJpYnV0ZXMnLFxuICAgICAgJ0RlbGV0ZVJlc291cmNlUG9saWN5JyxcbiAgICAgICdQdXRSZXNvdXJjZVBvbGljeSdcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdEaXNjb3Zlckluc3RhbmNlcycsXG4gICAgICAnRGlzY292ZXJJbnN0YW5jZXNSZXZpc2lvbicsXG4gICAgICAnR2V0SW5zdGFuY2UnLFxuICAgICAgJ0dldEluc3RhbmNlc0hlYWx0aFN0YXR1cycsXG4gICAgICAnR2V0TmFtZXNwYWNlJyxcbiAgICAgICdHZXRPcGVyYXRpb24nLFxuICAgICAgJ0dldFNlcnZpY2UnLFxuICAgICAgJ0dldFNlcnZpY2VBdHRyaWJ1dGVzJyxcbiAgICAgICdMaXN0SW5zdGFuY2VzJyxcbiAgICAgICdMaXN0TmFtZXNwYWNlcycsXG4gICAgICAnTGlzdFNlcnZpY2VzJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICdHZXRSZXNvdXJjZVBvbGljeSdcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdMaXN0T3BlcmF0aW9ucydcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVW50YWdSZXNvdXJjZSdcbiAgICBdXG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIG5hbWVzcGFjZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2RnL0FQSV9OYW1lc3BhY2UuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gbmFtZXNwYWNlSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgbmFtZXNwYWNlSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbk5hbWVzcGFjZShuYW1lc3BhY2VJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OnNlcnZpY2VkaXNjb3Zlcnk6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9Om5hbWVzcGFjZS8keyBuYW1lc3BhY2VJZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgc2VydmljZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZC1tYXAvbGF0ZXN0L2RnL0FQSV9TZXJ2aWNlLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIHNlcnZpY2VJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBzZXJ2aWNlSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblNlcnZpY2Uoc2VydmljZUlkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06c2VydmljZWRpc2NvdmVyeTokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06c2VydmljZS8keyBzZXJ2aWNlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWN0aW9ucyBiYXNlZCBvbiB0aGUgdGFncyB0aGF0IGFyZSBwYXNzZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlcXVlc3R0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUh0dHBOYW1lc3BhY2UoKVxuICAgKiAtIC50b0NyZWF0ZVByaXZhdGVEbnNOYW1lc3BhY2UoKVxuICAgKiAtIC50b0NyZWF0ZVB1YmxpY0Ruc05hbWVzcGFjZSgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmljZSgpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVxdWVzdFRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXF1ZXN0VGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY3Rpb25zIGJhc2VkIG9uIHRoZSB0YWdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlc291cmNldGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVTZXJ2aWNlKClcbiAgICogLSAudG9EZWxldGVOYW1lc3BhY2UoKVxuICAgKiAtIC50b0RlbGV0ZVNlcnZpY2UoKVxuICAgKiAtIC50b0RlbGV0ZVNlcnZpY2VBdHRyaWJ1dGVzKClcbiAgICogLSAudG9EZXJlZ2lzdGVySW5zdGFuY2UoKVxuICAgKiAtIC50b0Rpc2NvdmVySW5zdGFuY2VzKClcbiAgICogLSAudG9EaXNjb3Zlckluc3RhbmNlc1JldmlzaW9uKClcbiAgICogLSAudG9HZXRJbnN0YW5jZSgpXG4gICAqIC0gLnRvR2V0SW5zdGFuY2VzSGVhbHRoU3RhdHVzKClcbiAgICogLSAudG9HZXROYW1lc3BhY2UoKVxuICAgKiAtIC50b0dldE9wZXJhdGlvbigpXG4gICAqIC0gLnRvR2V0U2VydmljZSgpXG4gICAqIC0gLnRvR2V0U2VydmljZUF0dHJpYnV0ZXMoKVxuICAgKiAtIC50b0xpc3RJbnN0YW5jZXMoKVxuICAgKiAtIC50b1JlZ2lzdGVySW5zdGFuY2UoKVxuICAgKiAtIC50b1VwZGF0ZUh0dHBOYW1lc3BhY2UoKVxuICAgKiAtIC50b1VwZGF0ZUluc3RhbmNlQ3VzdG9tSGVhbHRoU3RhdHVzKClcbiAgICogLSAudG9VcGRhdGVQcml2YXRlRG5zTmFtZXNwYWNlKClcbiAgICogLSAudG9VcGRhdGVQdWJsaWNEbnNOYW1lc3BhY2UoKVxuICAgKiAtIC50b1VwZGF0ZVNlcnZpY2UoKVxuICAgKiAtIC50b1VwZGF0ZVNlcnZpY2VBdHRyaWJ1dGVzKClcbiAgICogLSAudG9EZWxldGVSZXNvdXJjZVBvbGljeSgpXG4gICAqIC0gLnRvR2V0UmVzb3VyY2VQb2xpY3koKVxuICAgKiAtIC50b1B1dFJlc291cmNlUG9saWN5KClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBuYW1lc3BhY2VcbiAgICogLSBzZXJ2aWNlXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZ