cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
631 lines • 59.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Shield = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [shield](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Shield extends shared_1.PolicyStatement {
/**
* Grants permission to authorize the DDoS Response team to access the specified Amazon S3 bucket containing your flow logs
*
* Access Level: Write
*
* Dependent actions:
* - s3:GetBucketPolicy
* - s3:PutBucketPolicy
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateDRTLogBucket.html
*/
toAssociateDRTLogBucket() {
return this.to('AssociateDRTLogBucket');
}
/**
* Grants permission to authorize the DDoS Response team using the specified role, to access your AWS account to assist with DDoS attack mitigation during potential attacks
*
* Access Level: Write
*
* Dependent actions:
* - iam:GetRole
* - iam:ListAttachedRolePolicies
* - iam:PassRole
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateDRTRole.html
*/
toAssociateDRTRole() {
return this.to('AssociateDRTRole');
}
/**
* Grants permission to add health-based detection to the Shield Advanced protection for a resource
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* Dependent actions:
* - route53:GetHealthCheck
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateHealthCheck.html
*/
toAssociateHealthCheck() {
return this.to('AssociateHealthCheck');
}
/**
* Grants permission to initialize proactive engagement and set the list of contacts for the DDoS Response Team (DRT) to use
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateProactiveEngagementDetails.html
*/
toAssociateProactiveEngagementDetails() {
return this.to('AssociateProactiveEngagementDetails');
}
/**
* Grants permission to activate DDoS protection service for a given resource ARN
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_CreateProtection.html
*/
toCreateProtection() {
return this.to('CreateProtection');
}
/**
* Grants permission to create a grouping of protected resources so they can be handled as a collective
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_CreateProtectionGroup.html
*/
toCreateProtectionGroup() {
return this.to('CreateProtectionGroup');
}
/**
* Grants permission to activate subscription
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_CreateSubscription.html
*/
toCreateSubscription() {
return this.to('CreateSubscription');
}
/**
* Grants permission to delete an existing protection
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DeleteProtection.html
*/
toDeleteProtection() {
return this.to('DeleteProtection');
}
/**
* Grants permission to remove the specified protection group
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DeleteProtectionGroup.html
*/
toDeleteProtectionGroup() {
return this.to('DeleteProtectionGroup');
}
/**
* Grants permission to deactivate subscription
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DeleteSubscription.html
*/
toDeleteSubscription() {
return this.to('DeleteSubscription');
}
/**
* Grants permission to get attack details. For getting attack details protected by AWS WAF anti-DDoS managed rule group, this action additionally calls wafv2:DescribeTopContributorsByEvent to retrieve application layer attack contributors, which requires to have wafv2:DescribeTopContributorsByEvent permission in IAM policy
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeAttack.html
*/
toDescribeAttack() {
return this.to('DescribeAttack');
}
/**
* Grants permission to get detailed information about the contributors to a specific DDoS attack
*
* Access Level: Read
*
* https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html
*/
toDescribeAttackContributors() {
return this.to('DescribeAttackContributors');
}
/**
* Grants permission to describe information about the number and type of attacks AWS Shield has detected in the last year
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeAttackStatistics.html
*/
toDescribeAttackStatistics() {
return this.to('DescribeAttackStatistics');
}
/**
* Grants permission to describe the current role and list of Amazon S3 log buckets used by the DDoS Response team to access your AWS account while assisting with attack mitigation
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeDRTAccess.html
*/
toDescribeDRTAccess() {
return this.to('DescribeDRTAccess');
}
/**
* Grants permission to list the email addresses that the DRT can use to contact you during a suspected attack
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeEmergencyContactSettings.html
*/
toDescribeEmergencyContactSettings() {
return this.to('DescribeEmergencyContactSettings');
}
/**
* Grants permission to get protection details
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeProtection.html
*/
toDescribeProtection() {
return this.to('DescribeProtection');
}
/**
* Grants permission to describe the specification for the specified protection group
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeProtectionGroup.html
*/
toDescribeProtectionGroup() {
return this.to('DescribeProtectionGroup');
}
/**
* Grants permission to get subscription details, such as start time
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeSubscription.html
*/
toDescribeSubscription() {
return this.to('DescribeSubscription');
}
/**
* Grants permission to disable application layer automatic response for Shield Advanced protection for a resource
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisableApplicationLayerAutomaticResponse.html
*/
toDisableApplicationLayerAutomaticResponse() {
return this.to('DisableApplicationLayerAutomaticResponse');
}
/**
* Grants permission to remove authorization from the DDoS Response Team (DRT) to notify contacts about escalations
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisableProactiveEngagement.html
*/
toDisableProactiveEngagement() {
return this.to('DisableProactiveEngagement');
}
/**
* Grants permission to remove the DDoS Response team's access to the specified Amazon S3 bucket containing your flow logs
*
* Access Level: Write
*
* Dependent actions:
* - s3:DeleteBucketPolicy
* - s3:GetBucketPolicy
* - s3:PutBucketPolicy
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisassociateDRTLogBucket.html
*/
toDisassociateDRTLogBucket() {
return this.to('DisassociateDRTLogBucket');
}
/**
* Grants permission to remove the DDoS Response team's access to your AWS account
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisassociateDRTRole.html
*/
toDisassociateDRTRole() {
return this.to('DisassociateDRTRole');
}
/**
* Grants permission to remove health-based detection from the Shield Advanced protection for a resource
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisassociateHealthCheck.html
*/
toDisassociateHealthCheck() {
return this.to('DisassociateHealthCheck');
}
/**
* Grants permission to enable application layer automatic response for Shield Advanced protection for a resource
*
* Access Level: Write
*
* Dependent actions:
* - apprunner:DescribeWebAclForService
* - cloudfront:GetDistribution
* - cognito-idp:GetWebACLForResource
* - ec2:GetVerifiedAccessInstanceWebAcl
* - iam:CreateServiceLinkedRole
* - iam:GetRole
* - wafv2:GetWebACL
* - wafv2:GetWebACLForResource
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_EnableApplicationLayerAutomaticResponse.html
*/
toEnableApplicationLayerAutomaticResponse() {
return this.to('EnableApplicationLayerAutomaticResponse');
}
/**
* Grants permission to authorize the DDoS Response Team (DRT) to use email and phone to notify contacts about escalations
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_EnableProactiveEngagement.html
*/
toEnableProactiveEngagement() {
return this.to('EnableProactiveEngagement');
}
/**
* Grants permission to retrieve global threat intelligence data and trends from AWS Shield's threat monitoring systems
*
* Access Level: Read
*
* https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html
*/
toGetGlobalThreatData() {
return this.to('GetGlobalThreatData');
}
/**
* Grants permission to get subscription state
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_GetSubscriptionState.html
*/
toGetSubscriptionState() {
return this.to('GetSubscriptionState');
}
/**
* Grants permission to list all existing attacks
*
* Access Level: List
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListAttacks.html
*/
toListAttacks() {
return this.to('ListAttacks');
}
/**
* Grants permission to retrieve a list of mitigation actions that have been applied during DDoS attacks
*
* Access Level: List
*
* https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html
*/
toListMitigations() {
return this.to('ListMitigations');
}
/**
* Grants permission to retrieve the protection groups for the account
*
* Access Level: List
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListProtectionGroups.html
*/
toListProtectionGroups() {
return this.to('ListProtectionGroups');
}
/**
* Grants permission to list all existing protections
*
* Access Level: List
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListProtections.html
*/
toListProtections() {
return this.to('ListProtections');
}
/**
* Grants permission to retrieve the resources that are included in the protection group
*
* Access Level: List
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListResourcesInProtectionGroup.html
*/
toListResourcesInProtectionGroup() {
return this.to('ListResourcesInProtectionGroup');
}
/**
* Grants permission to get information about AWS tags for a specified Amazon Resource Name (ARN) in AWS Shield
*
* Access Level: Read
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to add or updates tags for a resource in AWS Shield
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to remove tags from a resource in AWS Shield
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to update application layer automatic response for Shield Advanced protection for a resource
*
* Access Level: Write
*
* Dependent actions:
* - apprunner:DescribeWebAclForService
* - cognito-idp:GetWebACLForResource
* - ec2:GetVerifiedAccessInstanceWebAcl
* - wafv2:GetWebACL
* - wafv2:GetWebACLForResource
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateApplicationLayerAutomaticResponse.html
*/
toUpdateApplicationLayerAutomaticResponse() {
return this.to('UpdateApplicationLayerAutomaticResponse');
}
/**
* Grants permission to update the details of the list of email addresses that the DRT can use to contact you during a suspected attack
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateEmergencyContactSettings.html
*/
toUpdateEmergencyContactSettings() {
return this.to('UpdateEmergencyContactSettings');
}
/**
* Grants permission to update an existing protection group
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateProtectionGroup.html
*/
toUpdateProtectionGroup() {
return this.to('UpdateProtectionGroup');
}
/**
* Grants permission to update the details of an existing subscription
*
* Access Level: Write
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateSubscription.html
*/
toUpdateSubscription() {
return this.to('UpdateSubscription');
}
/**
* Adds a resource of type attack to the statement
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AttackDetail.html
*
* @param id - Identifier for the id.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @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.
*/
onAttack(id, account, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:shield::${account ?? this.defaultAccount}:attack/${id}`);
}
/**
* Adds a resource of type protection to the statement
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_Protection.html
*
* @param id - Identifier for the id.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @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()
*/
onProtection(id, account, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:shield::${account ?? this.defaultAccount}:protection/${id}`);
}
/**
* Adds a resource of type protection-group to the statement
*
* https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ProtectionGroup.html
*
* @param id - Identifier for the id.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @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()
*/
onProtectionGroup(id, account, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:shield::${account ?? this.defaultAccount}:protection-group/${id}`);
}
/**
* Filters actions based on 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:
* - .toCreateProtection()
* - .toCreateProtectionGroup()
* - .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 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 actions:
* - .toAssociateHealthCheck()
* - .toDeleteProtection()
* - .toDeleteProtectionGroup()
* - .toDescribeProtection()
* - .toDescribeProtectionGroup()
* - .toDisassociateHealthCheck()
* - .toUpdateProtectionGroup()
*
* Applies to resource types:
* - protection
* - protection-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 actions based on 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:
* - .toCreateProtection()
* - .toCreateProtectionGroup()
* - .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');
}
/**
* Statement provider for service [shield](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'shield';
this.accessLevelList = {
Write: [
'AssociateDRTLogBucket',
'AssociateDRTRole',
'AssociateHealthCheck',
'AssociateProactiveEngagementDetails',
'CreateProtection',
'CreateProtectionGroup',
'CreateSubscription',
'DeleteProtection',
'DeleteProtectionGroup',
'DeleteSubscription',
'DisableApplicationLayerAutomaticResponse',
'DisableProactiveEngagement',
'DisassociateDRTLogBucket',
'DisassociateDRTRole',
'DisassociateHealthCheck',
'EnableApplicationLayerAutomaticResponse',
'EnableProactiveEngagement',
'UpdateApplicationLayerAutomaticResponse',
'UpdateEmergencyContactSettings',
'UpdateProtectionGroup',
'UpdateSubscription'
],
Read: [
'DescribeAttack',
'DescribeAttackContributors',
'DescribeAttackStatistics',
'DescribeDRTAccess',
'DescribeEmergencyContactSettings',
'DescribeProtection',
'DescribeProtectionGroup',
'DescribeSubscription',
'GetGlobalThreatData',
'GetSubscriptionState',
'ListTagsForResource'
],
List: [
'ListAttacks',
'ListMitigations',
'ListProtectionGroups',
'ListProtections',
'ListResourcesInProtectionGroup'
],
Tagging: [
'TagResource',
'UntagResource'
]
};
}
}
exports.Shield = Shield;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hpZWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2hpZWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxNQUFPLFNBQVEsd0JBQWU7SUFHekM7Ozs7Ozs7Ozs7T0FVRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLHNCQUFzQjtRQUMzQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0kscUNBQXFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksdUJBQXVCO1FBQzVCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGtCQUFrQjtRQUN2QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksdUJBQXVCO1FBQzVC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IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBhd3NfaWFtIGFzIGlhbSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbc2hpZWxkXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTaGllbGQgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdzaGllbGQnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRob3JpemUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSB0byBhY2Nlc3MgdGhlIHNwZWNpZmllZCBBbWF6b24gUzMgYnVja2V0IGNvbnRhaW5pbmcgeW91ciBmbG93IGxvZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBzMzpHZXRCdWNrZXRQb2xpY3lcbiAgICogLSBzMzpQdXRCdWNrZXRQb2xpY3lcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXNzb2NpYXRlRFJUTG9nQnVja2V0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Fzc29jaWF0ZURSVExvZ0J1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXNzb2NpYXRlRFJUTG9nQnVja2V0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXV0aG9yaXplIHRoZSBERG9TIFJlc3BvbnNlIHRlYW0gdXNpbmcgdGhlIHNwZWNpZmllZCByb2xlLCB0byBhY2Nlc3MgeW91ciBBV1MgYWNjb3VudCB0byBhc3Npc3Qgd2l0aCBERG9TIGF0dGFjayBtaXRpZ2F0aW9uIGR1cmluZyBwb3RlbnRpYWwgYXR0YWNrc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGlhbTpHZXRSb2xlXG4gICAqIC0gaWFtOkxpc3RBdHRhY2hlZFJvbGVQb2xpY2llc1xuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Bc3NvY2lhdGVEUlRSb2xlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Fzc29jaWF0ZURSVFJvbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZURSVFJvbGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgaGVhbHRoLWJhc2VkIGRldGVjdGlvbiB0byB0aGUgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gcm91dGU1MzpHZXRIZWFsdGhDaGVja1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Bc3NvY2lhdGVIZWFsdGhDaGVjay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Bc3NvY2lhdGVIZWFsdGhDaGVjaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXNzb2NpYXRlSGVhbHRoQ2hlY2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbml0aWFsaXplIHByb2FjdGl2ZSBlbmdhZ2VtZW50IGFuZCBzZXQgdGhlIGxpc3Qgb2YgY29udGFjdHMgZm9yIHRoZSBERG9TIFJlc3BvbnNlIFRlYW0gKERSVCkgdG8gdXNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXNzb2NpYXRlUHJvYWN0aXZlRW5nYWdlbWVudERldGFpbHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXNzb2NpYXRlUHJvYWN0aXZlRW5nYWdlbWVudERldGFpbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZVByb2FjdGl2ZUVuZ2FnZW1lbnREZXRhaWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWN0aXZhdGUgRERvUyBwcm90ZWN0aW9uIHNlcnZpY2UgZm9yIGEgZ2l2ZW4gcmVzb3VyY2UgQVJOXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlUHJvdGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQcm90ZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQcm90ZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgZ3JvdXBpbmcgb2YgcHJvdGVjdGVkIHJlc291cmNlcyBzbyB0aGV5IGNhbiBiZSBoYW5kbGVkIGFzIGEgY29sbGVjdGl2ZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFjdGl2YXRlIHN1YnNjcmlwdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVTdWJzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhbiBleGlzdGluZyBwcm90ZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVByb3RlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlUHJvdGVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUHJvdGVjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0aGUgc3BlY2lmaWVkIHByb3RlY3Rpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVhY3RpdmF0ZSBzdWJzY3JpcHRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVTdWJzY3JpcHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVTdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYXR0YWNrIGRldGFpbHMuIEZvciBnZXR0aW5nIGF0dGFjayBkZXRhaWxzIHByb3RlY3RlZCBieSBBV1MgV0FGIGFudGktRERvUyBtYW5hZ2VkIHJ1bGUgZ3JvdXAsIHRoaXMgYWN0aW9uIGFkZGl0aW9uYWxseSBjYWxscyB3YWZ2MjpEZXNjcmliZVRvcENvbnRyaWJ1dG9yc0J5RXZlbnQgdG8gcmV0cmlldmUgYXBwbGljYXRpb24gbGF5ZXIgYXR0YWNrIGNvbnRyaWJ1dG9ycywgd2hpY2ggcmVxdWlyZXMgdG8gaGF2ZSB3YWZ2MjpEZXNjcmliZVRvcENvbnRyaWJ1dG9yc0J5RXZlbnQgcGVybWlzc2lvbiBpbiBJQU0gcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUF0dGFjay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUF0dGFjaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBdHRhY2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRyaWJ1dG9ycyB0byBhIHNwZWNpZmljIEREb1MgYXR0YWNrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVBdHRhY2tDb250cmlidXRvcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQXR0YWNrQ29udHJpYnV0b3JzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBhbmQgdHlwZSBvZiBhdHRhY2tzIEFXUyBTaGllbGQgaGFzIGRldGVjdGVkIGluIHRoZSBsYXN0IHllYXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQXR0YWNrU3RhdGlzdGljcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUF0dGFja1N0YXRpc3RpY3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQXR0YWNrU3RhdGlzdGljcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBjdXJyZW50IHJvbGUgYW5kIGxpc3Qgb2YgQW1hem9uIFMzIGxvZyBidWNrZXRzIHVzZWQgYnkgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSB0byBhY2Nlc3MgeW91ciBBV1MgYWNjb3VudCB3aGlsZSBhc3Npc3Rpbmcgd2l0aCBhdHRhY2sgbWl0aWdhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVEUlRBY2Nlc3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVEUlRBY2Nlc3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlRFJUQWNjZXNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgZW1haWwgYWRkcmVzc2VzIHRoYXQgdGhlIERSVCBjYW4gdXNlIHRvIGNvbnRhY3QgeW91IGR1cmluZyBhIHN1c3BlY3RlZCBhdHRhY2tcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBwcm90ZWN0aW9uIGRldGFpbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVByb3RlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVQcm90ZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVByb3RlY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBwcm90ZWN0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVQcm90ZWN0aW9uR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHN1YnNjcmlwdGlvbiBkZXRhaWxzLCBzdWNoIGFzIHN0YXJ0IHRpbWVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlU3Vic2NyaXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRpc2FibGUgYXBwbGljYXRpb24gbGF5ZXIgYXV0b21hdGljIHJlc3BvbnNlIGZvciBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rpc2FibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBhdXRob3JpemF0aW9uIGZyb20gdGhlIEREb1MgUmVzcG9uc2UgVGVhbSAoRFJUKSB0byBub3RpZnkgY29udGFjdHMgYWJvdXQgZXNjYWxhdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhYmxlUHJvYWN0aXZlRW5nYWdlbWVudC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhYmxlUHJvYWN0aXZlRW5nYWdlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSdzIGFjY2VzcyB0byB0aGUgc3BlY2lmaWVkIEFtYXpvbiBTMyBidWNrZXQgY29udGFpbmluZyB5b3VyIGZsb3cgbG9nc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHMzOkRlbGV0ZUJ1Y2tldFBvbGljeVxuICAgKiAtIHMzOkdldEJ1Y2tldFBvbGljeVxuICAgKiAtIHMzOlB1dEJ1Y2tldFBvbGljeVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhc3NvY2lhdGVEUlRMb2dCdWNrZXQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYXNzb2NpYXRlRFJUTG9nQnVja2V0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhc3NvY2lhdGVEUlRMb2dCdWNrZXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSdzIGFjY2VzcyB0byB5b3VyIEFXUyBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYXNzb2NpYXRlRFJUUm9sZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhc3NvY2lhdGVEUlRSb2xlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhc3NvY2lhdGVEUlRSb2xlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIGhlYWx0aC1iYXNlZCBkZXRlY3Rpb24gZnJvbSB0aGUgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYXNzb2NpYXRlSGVhbHRoQ2hlY2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYXNzb2NpYXRlSGVhbHRoQ2hlY2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2Fzc29jaWF0ZUhlYWx0aENoZWNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZW5hYmxlIGFwcGxpY2F0aW9uIGxheWVyIGF1dG9tYXRpYyByZXNwb25zZSBmb3IgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBhcHBydW5uZXI6RGVzY3JpYmVXZWJBY2xGb3JTZXJ2aWNlXG4gICAqIC0gY2xvdWRmcm9udDpHZXREaXN0cmlidXRpb25cbiAgICogLSBjb2duaXRvLWlkcDpHZXRXZWJBQ0xGb3JSZXNvdXJjZVxuICAgKiAtIGVjMjpHZXRWZXJpZmllZEFjY2Vzc0luc3RhbmNlV2ViQWNsXG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSB3YWZ2MjpHZXRXZWJBQ0xcbiAgICogLSB3YWZ2MjpHZXRXZWJBQ0xGb3JSZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9FbmFibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRW5hYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdFbmFibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRob3JpemUgdGhlIEREb1MgUmVzcG9uc2UgVGVhbSAoRFJUKSB0byB1c2UgZW1haWwgYW5kIHBob25lIHRvIG5vdGlmeSBjb250YWN0cyBhYm91dCBlc2NhbGF0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRW5hYmxlUHJvYWN0aXZlRW5nYWdlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRW5hYmxlUHJvYWN0aXZlRW5nYWdlbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGdsb2JhbCB0aHJlYXQgaW50ZWxsaWdlbmNlIGRhdGEgYW5kIHRyZW5kcyBmcm9tIEFXUyBTaGllbGQncyB0aHJlYXQgbW9uaXRvcmluZyBzeXN0ZW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0R2xvYmFsVGhyZWF0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0R2xvYmFsVGhyZWF0RGF0YScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBzdWJzY3JpcHRpb24gc3RhdGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0dldFN1YnNjcmlwdGlvblN0YXRlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFN1YnNjcmlwdGlvblN0YXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTdWJzY3JpcHRpb25TdGF0ZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYWxsIGV4aXN0aW5nIGF0dGFja3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0xpc3RBdHRhY2tzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RBdHRhY2tzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0QXR0YWNrcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGEgbGlzdCBvZiBtaXRpZ2F0aW9uIGFjdGlvbnMgdGhhdCBoYXZlIGJlZW4gYXBwbGllZCBkdXJpbmcgRERvUyBhdHRhY2tzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdE1pdGlnYXRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0TWl0aWdhdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSB0aGUgcHJvdGVjdGlvbiBncm91cHMgZm9yIHRoZSBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0UHJvdGVjdGlvbkdyb3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UHJvdGVjdGlvbkdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3RlY3Rpb25Hcm91cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBleGlzdGluZyBwcm90ZWN0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFByb3RlY3Rpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RQcm90ZWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3RlY3Rpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgdGhlIHJlc291cmNlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiB0aGUgcHJvdGVjdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RSZXNvdXJjZXNJblByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IEFXUyB0YWdzIGZvciBhIHNwZWNpZmllZCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgb3IgdXBkYXRlcyB0YWdzIGZvciBhIHJlc291cmNlIGluIEFXUyBTaGllbGRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0YWdzIGZyb20gYSByZXNvdXJjZSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYXBwbGljYXRpb24gbGF5ZXIgYXV0b21hdGljIHJlc3BvbnNlIGZvciBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGFwcHJ1bm5lcjpEZXNjcmliZVdlYkFjbEZvclNlcnZpY2VcbiAgICogLSBjb2duaXRvLWlkcDpHZXRXZWJBQ0xGb3JSZXNvdXJjZVxuICAgKiAtIGVjMjpHZXRWZXJpZmllZEFjY2Vzc0luc3RhbmNlV2ViQWNsXG4gICAqIC0gd2FmdjI6R2V0V2ViQUNMXG4gICAqIC0gd2FmdjI6R2V0V2ViQUNMRm9yUmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIHRoZSBkZXRhaWxzIG9mIHRoZSBsaXN0IG9mIGVtYWlsIGFkZHJlc3NlcyB0aGF0IHRoZSBEUlQgY2FuIHVzZSB0byBjb250YWN0IHlvdSBkdXJpbmcgYSBzdXNwZWN0ZWQgYXR0YWNrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGFuIGV4aXN0aW5nIHByb3RlY3Rpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3