UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

588 lines 54.7 kB
"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 * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeAttack.html */ toDescribeAttack() { return this.to('DescribeAttack'); } /** * 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: * - cloudfront:GetDistribution * - iam:CreateServiceLinkedRole * - iam:GetRole * * 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 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 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: * - .ifAwsRequestTag() * - .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 * * 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() * - .toUntagResource() * * @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', 'DescribeAttackStatistics', 'DescribeDRTAccess', 'DescribeEmergencyContactSettings', 'DescribeProtection', 'DescribeProtectionGroup', 'DescribeSubscription', 'GetSubscriptionState', 'ListTagsForResource' ], List: [ 'ListAttacks', 'ListProtectionGroups', 'ListProtections', 'ListResourcesInProtectionGroup' ], Tagging: [ 'TagResource', 'UntagResource' ] }; } } exports.Shield = Shield; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hpZWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2hpZWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxNQUFPLFNBQVEsd0JBQWU7SUFHekM7Ozs7Ozs7Ozs7T0FVRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLHNCQUFzQjtRQUMzQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0kscUNBQXFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksdUJBQXVCO1FBQzVCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGtCQUFrQjtRQUN2QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksdUJBQXVCO1FBQzVC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QUNsQixzQkFBc0I7Z0JBQ3RCLHFDQUFxQztnQkFDckMsa0JBQWtCO2dCQUNsQix1QkFBdUI7Z0JBQ3ZCLG9CQUFvQjtnQkFDcEIsa0JBQWtCO2dCQUNsQix1QkFBdUI7Z0JBQ3ZCLG9CQUFvQjtnQkFDcEIsMENBQTBDO2dCQUMxQyw0QkFBNEI7Z0JBQzVCLDBCQUEwQjtnQkFDMUIscUJBQXFCO2dCQUNyQix5QkFBeUI7Z0JBQ3pCLHlDQUF5QztnQkFDekMsMkJBQTJCO2dCQUMzQix5Q0FBeUM7Z0JBQ3pDLGdDQUFnQztnQkFDaEMsdUJBQXVCO2dCQUN2QixvQkFBb0I7YUFDckI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osZ0JBQWdCO2dCQUNoQiwwQkFBMEI7Z0JBQzFCLG1CQUFtQjtnQkFDbkIsa0NBQWtDO2dCQUNsQyxvQkFBb0I7Z0JBQ3BCLHlCQUF5QjtnQkFDekIsc0JBQXNCO2dCQUN0QixzQkFBc0I7Z0JBQ3RCLHFCQUFxQjthQUN0QjtZQUNELElBQUksRUFBRTtnQkFDSixhQUFhO2dCQUNiLHNCQUFzQjtnQkFDdEIsaUJBQWlCO2dCQUNqQixnQ0FBZ0M7YUFDakM7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsYUFBYTtnQkFDYixlQUFlO2FBQ2hCO1NBQ0YsQ0FBQztJQW9IRixDQUFDO0NBQ0Y7QUE1bUJELHdCQTRtQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgYXdzX2lhbSBhcyBpYW0gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3NoaWVsZF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzc2hpZWxkLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgU2hpZWxkIGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAnc2hpZWxkJztcblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXV0aG9yaXplIHRoZSBERG9TIFJlc3BvbnNlIHRlYW0gdG8gYWNjZXNzIHRoZSBzcGVjaWZpZWQgQW1hem9uIFMzIGJ1Y2tldCBjb250YWluaW5nIHlvdXIgZmxvdyBsb2dzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gczM6R2V0QnVja2V0UG9saWN5XG4gICAqIC0gczM6UHV0QnVja2V0UG9saWN5XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Fzc29jaWF0ZURSVExvZ0J1Y2tldC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Bc3NvY2lhdGVEUlRMb2dCdWNrZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZURSVExvZ0J1Y2tldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGF1dGhvcml6ZSB0aGUgRERvUyBSZXNwb25zZSB0ZWFtIHVzaW5nIHRoZSBzcGVjaWZpZWQgcm9sZSwgdG8gYWNjZXNzIHlvdXIgQVdTIGFjY291bnQgdG8gYXNzaXN0IHdpdGggRERvUyBhdHRhY2sgbWl0aWdhdGlvbiBkdXJpbmcgcG90ZW50aWFsIGF0dGFja3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBpYW06R2V0Um9sZVxuICAgKiAtIGlhbTpMaXN0QXR0YWNoZWRSb2xlUG9saWNpZXNcbiAgICogLSBpYW06UGFzc1JvbGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXNzb2NpYXRlRFJUUm9sZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Bc3NvY2lhdGVEUlRSb2xlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBc3NvY2lhdGVEUlRSb2xlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIGhlYWx0aC1iYXNlZCBkZXRlY3Rpb24gdG8gdGhlIFNoaWVsZCBBZHZhbmNlZCBwcm90ZWN0aW9uIGZvciBhIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHJvdXRlNTM6R2V0SGVhbHRoQ2hlY2tcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXNzb2NpYXRlSGVhbHRoQ2hlY2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXNzb2NpYXRlSGVhbHRoQ2hlY2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZUhlYWx0aENoZWNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW5pdGlhbGl6ZSBwcm9hY3RpdmUgZW5nYWdlbWVudCBhbmQgc2V0IHRoZSBsaXN0IG9mIGNvbnRhY3RzIGZvciB0aGUgRERvUyBSZXNwb25zZSBUZWFtIChEUlQpIHRvIHVzZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Fzc29jaWF0ZVByb2FjdGl2ZUVuZ2FnZW1lbnREZXRhaWxzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Fzc29jaWF0ZVByb2FjdGl2ZUVuZ2FnZW1lbnREZXRhaWxzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBc3NvY2lhdGVQcm9hY3RpdmVFbmdhZ2VtZW50RGV0YWlscycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFjdGl2YXRlIEREb1MgcHJvdGVjdGlvbiBzZXJ2aWNlIGZvciBhIGdpdmVuIHJlc291cmNlIEFSTlxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVByb3RlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlUHJvdGVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlUHJvdGVjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGdyb3VwaW5nIG9mIHByb3RlY3RlZCByZXNvdXJjZXMgc28gdGhleSBjYW4gYmUgaGFuZGxlZCBhcyBhIGNvbGxlY3RpdmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVQcm90ZWN0aW9uR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlUHJvdGVjdGlvbkdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQcm90ZWN0aW9uR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhY3RpdmF0ZSBzdWJzY3JpcHRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVTdWJzY3JpcHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVTdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYW4gZXhpc3RpbmcgcHJvdGVjdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVQcm90ZWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVByb3RlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVByb3RlY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIHNwZWNpZmllZCBwcm90ZWN0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlYWN0aXZhdGUgc3Vic2NyaXB0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU3Vic2NyaXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVN1YnNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlU3Vic2NyaXB0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGF0dGFjayBkZXRhaWxzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUF0dGFjay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUF0dGFjaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBdHRhY2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbnVtYmVyIGFuZCB0eXBlIG9mIGF0dGFja3MgQVdTIFNoaWVsZCBoYXMgZGV0ZWN0ZWQgaW4gdGhlIGxhc3QgeWVhclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVBdHRhY2tTdGF0aXN0aWNzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQXR0YWNrU3RhdGlzdGljcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBdHRhY2tTdGF0aXN0aWNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIGN1cnJlbnQgcm9sZSBhbmQgbGlzdCBvZiBBbWF6b24gUzMgbG9nIGJ1Y2tldHMgdXNlZCBieSB0aGUgRERvUyBSZXNwb25zZSB0ZWFtIHRvIGFjY2VzcyB5b3VyIEFXUyBhY2NvdW50IHdoaWxlIGFzc2lzdGluZyB3aXRoIGF0dGFjayBtaXRpZ2F0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZURSVEFjY2Vzcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZURSVEFjY2VzcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVEUlRBY2Nlc3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSBlbWFpbCBhZGRyZXNzZXMgdGhhdCB0aGUgRFJUIGNhbiB1c2UgdG8gY29udGFjdCB5b3UgZHVyaW5nIGEgc3VzcGVjdGVkIGF0dGFja1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVFbWVyZ2VuY3lDb250YWN0U2V0dGluZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVFbWVyZ2VuY3lDb250YWN0U2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHByb3RlY3Rpb24gZGV0YWlsc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlUHJvdGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVByb3RlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlUHJvdGVjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBzcGVjaWZpY2F0aW9uIGZvciB0aGUgc3BlY2lmaWVkIHByb3RlY3Rpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVQcm90ZWN0aW9uR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgc3Vic2NyaXB0aW9uIGRldGFpbHMsIHN1Y2ggYXMgc3RhcnQgdGltZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTdWJzY3JpcHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTdWJzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlU3Vic2NyaXB0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGlzYWJsZSBhcHBsaWNhdGlvbiBsYXllciBhdXRvbWF0aWMgcmVzcG9uc2UgZm9yIFNoaWVsZCBBZHZhbmNlZCBwcm90ZWN0aW9uIGZvciBhIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIGF1dGhvcml6YXRpb24gZnJvbSB0aGUgRERvUyBSZXNwb25zZSBUZWFtIChEUlQpIHRvIG5vdGlmeSBjb250YWN0cyBhYm91dCBlc2NhbGF0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rpc2FibGVQcm9hY3RpdmVFbmdhZ2VtZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2FibGVQcm9hY3RpdmVFbmdhZ2VtZW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhYmxlUHJvYWN0aXZlRW5nYWdlbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0aGUgRERvUyBSZXNwb25zZSB0ZWFtJ3MgYWNjZXNzIHRvIHRoZSBzcGVjaWZpZWQgQW1hem9uIFMzIGJ1Y2tldCBjb250YWluaW5nIHlvdXIgZmxvdyBsb2dzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gczM6RGVsZXRlQnVja2V0UG9saWN5XG4gICAqIC0gczM6R2V0QnVja2V0UG9saWN5XG4gICAqIC0gczM6UHV0QnVja2V0UG9saWN5XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rpc2Fzc29jaWF0ZURSVExvZ0J1Y2tldC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhc3NvY2lhdGVEUlRMb2dCdWNrZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2Fzc29jaWF0ZURSVExvZ0J1Y2tldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0aGUgRERvUyBSZXNwb25zZSB0ZWFtJ3MgYWNjZXNzIHRvIHlvdXIgQVdTIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhc3NvY2lhdGVEUlRSb2xlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2Fzc29jaWF0ZURSVFJvbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2Fzc29jaWF0ZURSVFJvbGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgaGVhbHRoLWJhc2VkIGRldGVjdGlvbiBmcm9tIHRoZSBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhc3NvY2lhdGVIZWFsdGhDaGVjay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhc3NvY2lhdGVIZWFsdGhDaGVjaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYXNzb2NpYXRlSGVhbHRoQ2hlY2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBlbmFibGUgYXBwbGljYXRpb24gbGF5ZXIgYXV0b21hdGljIHJlc3BvbnNlIGZvciBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGNsb3VkZnJvbnQ6R2V0RGlzdHJpYnV0aW9uXG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRW5hYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0VuYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRW5hYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXV0aG9yaXplIHRoZSBERG9TIFJlc3BvbnNlIFRlYW0gKERSVCkgdG8gdXNlIGVtYWlsIGFuZCBwaG9uZSB0byBub3RpZnkgY29udGFjdHMgYWJvdXQgZXNjYWxhdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9FbmFibGVQcm9hY3RpdmVFbmdhZ2VtZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgc3Vic2NyaXB0aW9uIHN0YXRlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9HZXRTdWJzY3JpcHRpb25TdGF0ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTdWJzY3JpcHRpb25TdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U3Vic2NyaXB0aW9uU3RhdGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBleGlzdGluZyBhdHRhY2tzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0QXR0YWNrcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0QXR0YWNrcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEF0dGFja3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSB0aGUgcHJvdGVjdGlvbiBncm91cHMgZm9yIHRoZSBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0UHJvdGVjdGlvbkdyb3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UHJvdGVjdGlvbkdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3RlY3Rpb25Hcm91cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBleGlzdGluZyBwcm90ZWN0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFByb3RlY3Rpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RQcm90ZWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3RlY3Rpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgdGhlIHJlc291cmNlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiB0aGUgcHJvdGVjdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RSZXNvdXJjZXNJblByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IEFXUyB0YWdzIGZvciBhIHNwZWNpZmllZCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgb3IgdXBkYXRlcyB0YWdzIGZvciBhIHJlc291cmNlIGluIEFXUyBTaGllbGRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0YWdzIGZyb20gYSByZXNvdXJjZSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYXBwbGljYXRpb24gbGF5ZXIgYXV0b21hdGljIHJlc3BvbnNlIGZvciBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgZGV0YWlscyBvZiB0aGUgbGlzdCBvZiBlbWFpbCBhZGRyZXNzZXMgdGhhdCB0aGUgRFJUIGNhbiB1c2UgdG8gY29udGFjdCB5b3UgZHVyaW5nIGEgc3VzcGVjdGVkIGF0dGFja1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVFbWVyZ2VuY3lDb250YWN0U2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhbiBleGlzdGluZyBwcm90ZWN0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZVByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgZGV0YWlscyBvZiBhbiBleGlzdGluZyBzdWJzY3JpcHRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVTdWJzY3JpcHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVTdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0Fzc29jaWF0ZURSVExvZ0J1Y2tldCcsXG4gICAgICAnQXNzb2NpYXRlRFJUUm9sZScsXG4gICAgICAnQXNzb2NpYXRlSGVhbHRoQ2hlY2snLFxuICAgICAgJ0Fzc29jaWF0ZVByb2FjdGl2ZUVuZ2FnZW1lbnREZXRhaWxzJyxcbiAgICAgICdDcmVhdGVQcm90ZWN0aW9uJyxcbiAgICAgICdDcmVhdGVQcm90ZWN0aW9uR3JvdXAnLFxuICAgICAgJ0NyZWF0ZVN1YnNjcmlwdGlvbicsXG4gICAgICAnRGVsZXRlUHJvdGVjdGlvbicsXG4gICAgICAnRGVsZXRlUHJvdGVjdGlvbkdyb3VwJyxcbiAgICAgICdEZWxldGVTdWJzY3JpcHRpb24nLFxuICAgICAgJ0Rpc2FibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UnLFxuICAgICAgJ0Rpc2FibGVQcm9hY3RpdmVFbmdhZ2VtZW50JyxcbiAgICAgICdEaXNhc3NvY2lhdGVEUlRMb2dCdWNrZXQnLFxuICAgICAgJ0Rpc2Fzc29jaWF0ZURSVFJvbGUnLFxuICAgICAgJ0Rpc2Fzc29jaWF0ZUhlYWx0aENoZWNrJyxcbiAgICAgICdFbmFibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UnLFxuICAgICAgJ0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQnLFxuICAgICAgJ1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZScsXG4gICAgICAnVXBkYXRlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzJyxcbiAgICAgICdVcGRhdGVQcm90ZWN0aW9uR3JvdXAnLFxuICAgICAgJ1VwZGF0ZVN1YnNjcmlwdGlvbidcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdEZXNjcmliZUF0dGFjaycsXG4gICAgICAnRGVzY3JpYmVBdHRhY2tTdGF0aXN0aWNzJyxcbiAgICAgICdEZXNjcmliZURSVEFjY2VzcycsXG4gICAgICAnRGVzY3JpYmVFbWVyZ2VuY3lDb250YWN0U2V0dGluZ3MnLFxuICAgICAgJ0Rlc2NyaWJlUHJvdGVjdGlvbicsXG4gICAgICAnRGVzY3JpYmVQcm90ZWN0aW9uR3JvdXAnLFxuICAgICAgJ0Rlc2NyaWJlU3Vic2NyaXB0aW9uJyxcbiAgICAgICdHZXRTdWJzY3JpcHRpb25TdGF0ZScsXG4gICAgICAnTGlzdFRhZ3NGb3JSZXNvdXJjZSdcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdMaXN0QXR0YWNrcycsXG4gICAgICAnTGlzdFByb3RlY3Rpb25Hcm91cHMnLFxuICAgICAgJ0xpc3RQcm90ZWN0aW9ucycsXG4gICAgICAnTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwJ1xuICAgIF0sXG4gICAgVGFnZ2luZzogW1xuICAgICAgJ1RhZ1Jlc291cmNlJyxcbiAgICAgICdVbnRhZ1Jlc291cmNlJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgYXR0YWNrIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXR0YWNrRGV0YWlsLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSWRlbnRpZmllciBmb3IgdGhlIGlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqL1xuICBwdWJsaWMgb25BdHRhY2soaWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06c2hpZWxkOjokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTphdHRhY2svJHsgaWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHByb3RlY3Rpb24gdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Qcm90ZWN0aW9uLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSWRlbnRpZmllciBmb3IgdGhlIGlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uUHJvdGVjdGlvbihpZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpzaGllbGQ6OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnByb3RlY3Rpb24vJHsgaWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHByb3RlY3Rpb24tZ3JvdXAgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Qcm90ZWN0aW9uR3JvdXAuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBJZGVudGlmaWVyIGZvciB0aGUgaWQuXG4gICAqIEBwYXJhbSBhY2