UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

568 lines 62.2 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Elasticloadbalancing = void 0;
const shared_1 = require("../../shared");
/**
 * Statement provider for service [elasticloadbalancing](https://docs.aws.amazon.com/service-authorization/latest/reference/list_elb.html).
 *
 * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
 */
class Elasticloadbalancing extends shared_1.PolicyStatement {
    /**
     * Grants permission to add the specified tags to the specified load balancer. Each load balancer can have a maximum of 10 tags
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_AddTags.html
     */
    toAddTags() {
        return this.to('AddTags');
    }
    /**
     * Grants permission to associate one or more security groups with your load balancer in a virtual private cloud (VPC)
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ApplySecurityGroupsToLoadBalancer.html
     */
    toApplySecurityGroupsToLoadBalancer() {
        return this.to('ApplySecurityGroupsToLoadBalancer');
    }
    /**
     * Grants permission to add one or more subnets to the set of configured subnets for the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_AttachLoadBalancerToSubnets.html
     */
    toAttachLoadBalancerToSubnets() {
        return this.to('AttachLoadBalancerToSubnets');
    }
    /**
     * Grants permission to specify the health check settings to use when evaluating the health state of your back-end instances
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ConfigureHealthCheck.html
     */
    toConfigureHealthCheck() {
        return this.to('ConfigureHealthCheck');
    }
    /**
     * Grants permission to generate a stickiness policy with sticky session lifetimes that follow that of an application-generated cookie
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateAppCookieStickinessPolicy.html
     */
    toCreateAppCookieStickinessPolicy() {
        return this.to('CreateAppCookieStickinessPolicy');
    }
    /**
     * Grants permission to generate a stickiness policy with sticky session lifetimes controlled by the lifetime of the browser (user-agent) or a specified expiration period
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLBCookieStickinessPolicy.html
     */
    toCreateLBCookieStickinessPolicy() {
        return this.to('CreateLBCookieStickinessPolicy');
    }
    /**
     * Grants permission to create a load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLoadBalancer.html
     */
    toCreateLoadBalancer() {
        return this.to('CreateLoadBalancer');
    }
    /**
     * Grants permission to create one or more listeners for the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLoadBalancerListeners.html
     */
    toCreateLoadBalancerListeners() {
        return this.to('CreateLoadBalancerListeners');
    }
    /**
     * Grants permission to create a policy with the specified attributes for the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLoadBalancerPolicy.html
     */
    toCreateLoadBalancerPolicy() {
        return this.to('CreateLoadBalancerPolicy');
    }
    /**
     * Grants permission to delete the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeleteLoadBalancer.html
     */
    toDeleteLoadBalancer() {
        return this.to('DeleteLoadBalancer');
    }
    /**
     * Grants permission to delete the specified listeners from the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeleteLoadBalancerListeners.html
     */
    toDeleteLoadBalancerListeners() {
        return this.to('DeleteLoadBalancerListeners');
    }
    /**
     * Grants permission to delete the specified policy from the specified load balancer. This policy must not be enabled for any listeners
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeleteLoadBalancerPolicy.html
     */
    toDeleteLoadBalancerPolicy() {
        return this.to('DeleteLoadBalancerPolicy');
    }
    /**
     * Grants permission to deregister the specified instances from the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeregisterInstancesFromLoadBalancer.html
     */
    toDeregisterInstancesFromLoadBalancer() {
        return this.to('DeregisterInstancesFromLoadBalancer');
    }
    /**
     * Grants permission to describe the state of the specified instances with respect to the specified load balancer
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeInstanceHealth.html
     */
    toDescribeInstanceHealth() {
        return this.to('DescribeInstanceHealth');
    }
    /**
     * Grants permission to describe the attributes for the specified load balancer
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancerAttributes.html
     */
    toDescribeLoadBalancerAttributes() {
        return this.to('DescribeLoadBalancerAttributes');
    }
    /**
     * Grants permission to describe the specified policies
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancerPolicies.html
     */
    toDescribeLoadBalancerPolicies() {
        return this.to('DescribeLoadBalancerPolicies');
    }
    /**
     * Grants permission to describe the specified load balancer policy types
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancerPolicyTypes.html
     */
    toDescribeLoadBalancerPolicyTypes() {
        return this.to('DescribeLoadBalancerPolicyTypes');
    }
    /**
     * Grants permission to describe the specified the load balancers. If no load balancers are specified, the call describes all of your load balancers
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancers.html
     */
    toDescribeLoadBalancers() {
        return this.to('DescribeLoadBalancers');
    }
    /**
     * Grants permission to describe the tags associated with the specified load balancers
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeTags.html
     */
    toDescribeTags() {
        return this.to('DescribeTags');
    }
    /**
     * Grants permission to remove the specified subnets from the set of configured subnets for the load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DetachLoadBalancerFromSubnets.html
     */
    toDetachLoadBalancerFromSubnets() {
        return this.to('DetachLoadBalancerFromSubnets');
    }
    /**
     * Grants permission to remove the specified Availability Zones from the set of Availability Zones for the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DisableAvailabilityZonesForLoadBalancer.html
     */
    toDisableAvailabilityZonesForLoadBalancer() {
        return this.to('DisableAvailabilityZonesForLoadBalancer');
    }
    /**
     * Grants permission to add the specified Availability Zones to the set of Availability Zones for the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_EnableAvailabilityZonesForLoadBalancer.html
     */
    toEnableAvailabilityZonesForLoadBalancer() {
        return this.to('EnableAvailabilityZonesForLoadBalancer');
    }
    /**
     * Grants permission to modify the attributes of the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ModifyLoadBalancerAttributes.html
     */
    toModifyLoadBalancerAttributes() {
        return this.to('ModifyLoadBalancerAttributes');
    }
    /**
     * Grants permission to add the specified instances to the specified load balancer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_RegisterInstancesWithLoadBalancer.html
     */
    toRegisterInstancesWithLoadBalancer() {
        return this.to('RegisterInstancesWithLoadBalancer');
    }
    /**
     * Grants permission to remove one or more tags from the specified load balancer
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_RemoveTags.html
     */
    toRemoveTags() {
        return this.to('RemoveTags');
    }
    /**
     * Grants permission to set the certificate that terminates the specified listener's SSL connections
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_SetLoadBalancerListenerSSLCertificate.html
     */
    toSetLoadBalancerListenerSSLCertificate() {
        return this.to('SetLoadBalancerListenerSSLCertificate');
    }
    /**
     * Grants permission to replace the set of policies associated with the specified port on which the back-end server is listening with a new set of policies
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_SetLoadBalancerPoliciesForBackendServer.html
     */
    toSetLoadBalancerPoliciesForBackendServer() {
        return this.to('SetLoadBalancerPoliciesForBackendServer');
    }
    /**
     * Grants permission to replace the current set of policies for the specified load balancer port with the specified set of policies
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_SetLoadBalancerPoliciesOfListener.html
     */
    toSetLoadBalancerPoliciesOfListener() {
        return this.to('SetLoadBalancerPoliciesOfListener');
    }
    /**
     * Adds a resource of type loadbalancer to the statement
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html
     *
     * @param loadBalancerName - Identifier for the loadBalancerName.
     * @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()
     * - .ifResourceTag()
     */
    onLoadbalancer(loadBalancerName, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:elasticloadbalancing:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:loadbalancer/${loadBalancerName}`);
    }
    /**
     * Filters access by a tag key and value pair that is allowed in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
     *
     * Applies to actions:
     * - .toAddTags()
     * - .toCreateLoadBalancer()
     * - .toRemoveTags()
     *
     * @param tagKey The tag key to check
     * @param value The value(s) to check
     * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
     */
    ifAwsRequestTag(tagKey, value, operator) {
        return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by a tag key and value pair of a resource
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
     *
     * Applies to actions:
     * - .toAddTags()
     * - .toApplySecurityGroupsToLoadBalancer()
     * - .toAttachLoadBalancerToSubnets()
     * - .toConfigureHealthCheck()
     * - .toCreateAppCookieStickinessPolicy()
     * - .toCreateLBCookieStickinessPolicy()
     * - .toCreateLoadBalancer()
     * - .toCreateLoadBalancerListeners()
     * - .toCreateLoadBalancerPolicy()
     * - .toDeleteLoadBalancer()
     * - .toDeleteLoadBalancerListeners()
     * - .toDeleteLoadBalancerPolicy()
     * - .toDeregisterInstancesFromLoadBalancer()
     * - .toDetachLoadBalancerFromSubnets()
     * - .toDisableAvailabilityZonesForLoadBalancer()
     * - .toEnableAvailabilityZonesForLoadBalancer()
     * - .toModifyLoadBalancerAttributes()
     * - .toRegisterInstancesWithLoadBalancer()
     * - .toRemoveTags()
     * - .toSetLoadBalancerListenerSSLCertificate()
     * - .toSetLoadBalancerPoliciesForBackendServer()
     * - .toSetLoadBalancerPoliciesOfListener()
     *
     * Applies to resource types:
     * - loadbalancer
     *
     * @param tagKey The tag key to check
     * @param value The value(s) to check
     * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
     */
    ifAwsResourceTag(tagKey, value, operator) {
        return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by a list of tag keys that are allowed in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
     *
     * Applies to actions:
     * - .toAddTags()
     * - .toCreateLoadBalancer()
     * - .toRemoveTags()
     *
     * @param value The value(s) to check
     * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
     */
    ifAwsTagKeys(value, operator) {
        return this.if(`aws:TagKeys`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the name of a resource-creating API action
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/tagging-resources-during-creation.html
     *
     * Applies to actions:
     * - .toAddTags()
     *
     * @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`
     */
    ifCreateAction(value, operator) {
        return this.if(`CreateAction`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the listener protocols that are allowed in the request
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#listenerprotocol-condition
     *
     * Applies to actions:
     * - .toCreateLoadBalancer()
     * - .toCreateLoadBalancerListeners()
     *
     * @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`
     */
    ifListenerProtocol(value, operator) {
        return this.if(`ListenerProtocol`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the preface string for a tag key and value pair that are attached to a resource
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
     *
     * @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`
     */
    ifResourceTagExists(value, operator) {
        return this.if(`ResourceTag/`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the preface string for a tag key and value pair that are attached to a resource
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
     *
     * Applies to actions:
     * - .toAddTags()
     * - .toApplySecurityGroupsToLoadBalancer()
     * - .toAttachLoadBalancerToSubnets()
     * - .toConfigureHealthCheck()
     * - .toCreateAppCookieStickinessPolicy()
     * - .toCreateLBCookieStickinessPolicy()
     * - .toCreateLoadBalancer()
     * - .toCreateLoadBalancerListeners()
     * - .toCreateLoadBalancerPolicy()
     * - .toDeleteLoadBalancer()
     * - .toDeleteLoadBalancerListeners()
     * - .toDeleteLoadBalancerPolicy()
     * - .toDeregisterInstancesFromLoadBalancer()
     * - .toDetachLoadBalancerFromSubnets()
     * - .toDisableAvailabilityZonesForLoadBalancer()
     * - .toEnableAvailabilityZonesForLoadBalancer()
     * - .toModifyLoadBalancerAttributes()
     * - .toRegisterInstancesWithLoadBalancer()
     * - .toRemoveTags()
     * - .toSetLoadBalancerListenerSSLCertificate()
     * - .toSetLoadBalancerPoliciesForBackendServer()
     * - .toSetLoadBalancerPoliciesOfListener()
     *
     * Applies to resource types:
     * - loadbalancer
     *
     * @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`
     */
    ifResourceTagTagKey(tagKey, value, operator) {
        return this.if(`ResourceTag/${tagKey}`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the load balancer scheme that are allowed in the request
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#scheme-condition
     *
     * Applies to actions:
     * - .toCreateLoadBalancer()
     *
     * @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`
     */
    ifScheme(value, operator) {
        return this.if(`Scheme`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the security-group IDs that are allowed in the request
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#securitygroup-condition
     *
     * Applies to actions:
     * - .toApplySecurityGroupsToLoadBalancer()
     * - .toCreateLoadBalancer()
     *
     * @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`
     */
    ifSecurityGroup(value, operator) {
        return this.if(`SecurityGroup`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the SSL Security Policies that are allowed in the request
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#securitypolicy-condition
     *
     * Applies to actions:
     * - .toCreateLoadBalancerPolicy()
     * - .toSetLoadBalancerPoliciesOfListener()
     *
     * @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`
     */
    ifSecurityPolicy(value, operator) {
        return this.if(`SecurityPolicy`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the subnet IDs that are allowed in the request
     *
     * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#subnet-condition
     *
     * Applies to actions:
     * - .toAttachLoadBalancerToSubnets()
     * - .toCreateLoadBalancer()
     *
     * @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`
     */
    ifSubnet(value, operator) {
        return this.if(`Subnet`, value, operator ?? 'StringLike');
    }
    /**
     * Statement provider for service [elasticloadbalancing](https://docs.aws.amazon.com/service-authorization/latest/reference/list_elb.html).
     *
     */
    constructor(props) {
        super(props);
        this.servicePrefix = 'elasticloadbalancing';
        this.accessLevelList = {
            Tagging: [
                'AddTags',
                'RemoveTags'
            ],
            Write: [
                'AddTags',
                'ApplySecurityGroupsToLoadBalancer',
                'AttachLoadBalancerToSubnets',
                'ConfigureHealthCheck',
                'CreateAppCookieStickinessPolicy',
                'CreateLBCookieStickinessPolicy',
                'CreateLoadBalancer',
                'CreateLoadBalancerListeners',
                'CreateLoadBalancerPolicy',
                'DeleteLoadBalancer',
                'DeleteLoadBalancerListeners',
                'DeleteLoadBalancerPolicy',
                'DeregisterInstancesFromLoadBalancer',
                'DetachLoadBalancerFromSubnets',
                'DisableAvailabilityZonesForLoadBalancer',
                'EnableAvailabilityZonesForLoadBalancer',
                'ModifyLoadBalancerAttributes',
                'RegisterInstancesWithLoadBalancer',
                'RemoveTags',
                'SetLoadBalancerListenerSSLCertificate',
                'SetLoadBalancerPoliciesForBackendServer',
                'SetLoadBalancerPoliciesOfListener'
            ],
            Read: [
                'DescribeInstanceHealth',
                'DescribeLoadBalancerAttributes',
                'DescribeLoadBalancerPolicies',
                'DescribeLoadBalancerPolicyTypes',
                'DescribeTags'
            ],
            List: [
                'DescribeLoadBalancers'
            ]
        };
    }
}
exports.Elasticloadbalancing = Elasticloadbalancing;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxiLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZWxiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxvQkFBcUIsU0FBUSx3QkFBZTtJQUd2RDs7Ozs7O09BTUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxtQ0FBbUM7UUFDeEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLDZCQUE2QjtRQUNsQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsNkJBQTZCLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksc0JBQXNCO1FBQzNCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxpQ0FBaUM7UUFDdEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGdDQUFnQztRQUNyQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksb0JBQW9CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSw2QkFBNkI7UUFDbEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDZCQUE2QixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLDBCQUEwQjtRQUMvQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsMEJBQTBCLENBQUMs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bmxCUixrQkFBYSxHQUFHLHNCQUFzQixDQUFDO1FBc1RwQyxvQkFBZSxHQUFvQjtZQUMzQyxPQUFPLEVBQUU7Z0JBQ1AsU0FBUztnQkFDVCxZQUFZO2FBQ2I7WUFDRCxLQUFLLEVBQUU7Z0JBQ0wsU0FBUztnQkFDVCxtQ0FBbUM7Z0JBQ25DLDZCQUE2QjtnQkFDN0Isc0JBQXNCO2dCQUN0QixpQ0FBaUM7Z0JBQ2pDLGdDQUFnQztnQkFDaEMsb0JBQW9CO2dCQUNwQiw2QkFBNkI7Z0JBQzdCLDBCQUEwQjtnQkFDMUIsb0JBQW9CO2dCQUNwQiw2QkFBNkI7Z0JBQzdCLDBCQUEwQjtnQkFDMUIscUNBQXFDO2dCQUNyQywrQkFBK0I7Z0JBQy9CLHlDQUF5QztnQkFDekMsd0NBQXdDO2dCQUN4Qyw4QkFBOEI7Z0JBQzlCLG1DQUFtQztnQkFDbkMsWUFBWTtnQkFDWix1Q0FBdUM7Z0JBQ3ZDLHlDQUF5QztnQkFDekMsbUNBQW1DO2FBQ3BDO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLHdCQUF3QjtnQkFDeEIsZ0NBQWdDO2dCQUNoQyw4QkFBOEI7Z0JBQzlCLGlDQUFpQztnQkFDakMsY0FBYzthQUNmO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLHVCQUF1QjthQUN4QjtTQUNGLENBQUM7SUF1UEYsQ0FBQztDQUNGO0FBdGxCRCxvREFzbEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtlbGFzdGljbG9hZGJhbGFuY2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfZWxiLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgRWxhc3RpY2xvYWRiYWxhbmNpbmcgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdlbGFzdGljbG9hZGJhbGFuY2luZyc7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCB0aGUgc3BlY2lmaWVkIHRhZ3MgdG8gdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyLiBFYWNoIGxvYWQgYmFsYW5jZXIgY2FuIGhhdmUgYSBtYXhpbXVtIG9mIDEwIHRhZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nLCBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0FkZFRhZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQWRkVGFncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQWRkVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFzc29jaWF0ZSBvbmUgb3IgbW9yZSBzZWN1cml0eSBncm91cHMgd2l0aCB5b3VyIGxvYWQgYmFsYW5jZXIgaW4gYSB2aXJ0dWFsIHByaXZhdGUgY2xvdWQgKFZQQylcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0FwcGx5U2VjdXJpdHlHcm91cHNUb0xvYWRCYWxhbmNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BcHBseVNlY3VyaXR5R3JvdXBzVG9Mb2FkQmFsYW5jZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0FwcGx5U2VjdXJpdHlHcm91cHNUb0xvYWRCYWxhbmNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCBvbmUgb3IgbW9yZSBzdWJuZXRzIHRvIHRoZSBzZXQgb2YgY29uZmlndXJlZCBzdWJuZXRzIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0F0dGFjaExvYWRCYWxhbmNlclRvU3VibmV0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BdHRhY2hMb2FkQmFsYW5jZXJUb1N1Ym5ldHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0F0dGFjaExvYWRCYWxhbmNlclRvU3VibmV0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHNwZWNpZnkgdGhlIGhlYWx0aCBjaGVjayBzZXR0aW5ncyB0byB1c2Ugd2hlbiBldmFsdWF0aW5nIHRoZSBoZWFsdGggc3RhdGUgb2YgeW91ciBiYWNrLWVuZCBpbnN0YW5jZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0NvbmZpZ3VyZUhlYWx0aENoZWNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NvbmZpZ3VyZUhlYWx0aENoZWNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDb25maWd1cmVIZWFsdGhDaGVjaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdlbmVyYXRlIGEgc3RpY2tpbmVzcyBwb2xpY3kgd2l0aCBzdGlja3kgc2Vzc2lvbiBsaWZldGltZXMgdGhhdCBmb2xsb3cgdGhhdCBvZiBhbiBhcHBsaWNhdGlvbi1nZW5lcmF0ZWQgY29va2llXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVBcHBDb29raWVTdGlja2luZXNzUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUFwcENvb2tpZVN0aWNraW5lc3NQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUFwcENvb2tpZVN0aWNraW5lc3NQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZW5lcmF0ZSBhIHN0aWNraW5lc3MgcG9saWN5IHdpdGggc3RpY2t5IHNlc3Npb24gbGlmZXRpbWVzIGNvbnRyb2xsZWQgYnkgdGhlIGxpZmV0aW1lIG9mIHRoZSBicm93c2VyICh1c2VyLWFnZW50KSBvciBhIHNwZWNpZmllZCBleHBpcmF0aW9uIHBlcmlvZFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlTEJDb29raWVTdGlja2luZXNzUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUxCQ29va2llU3RpY2tpbmVzc1BvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlTEJDb29raWVTdGlja2luZXNzUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUxvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlTG9hZEJhbGFuY2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIG9uZSBvciBtb3JlIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlTG9hZEJhbGFuY2VyTGlzdGVuZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBwb2xpY3kgd2l0aCB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZXMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlTG9hZEJhbGFuY2VyUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUxvYWRCYWxhbmNlclBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlTG9hZEJhbGFuY2VyUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUxvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlTG9hZEJhbGFuY2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXJzIGZyb20gdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlTG9hZEJhbGFuY2VyTGlzdGVuZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBwb2xpY3kgZnJvbSB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXIuIFRoaXMgcG9saWN5IG11c3Qgbm90IGJlIGVuYWJsZWQgZm9yIGFueSBsaXN0ZW5lcnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUxvYWRCYWxhbmNlclBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVMb2FkQmFsYW5jZXJQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUxvYWRCYWxhbmNlclBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlcmVnaXN0ZXIgdGhlIHNwZWNpZmllZCBpbnN0YW5jZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0RlcmVnaXN0ZXJJbnN0YW5jZXNGcm9tTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlcmVnaXN0ZXJJbnN0YW5jZXNGcm9tTG9hZEJhbGFuY2VyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXJlZ2lzdGVySW5zdGFuY2VzRnJvbUxvYWRCYWxhbmNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBzdGF0ZSBvZiB0aGUgc3BlY2lmaWVkIGluc3RhbmNlcyB3aXRoIHJlc3BlY3QgdG8gdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlSW5zdGFuY2VIZWFsdGguaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVJbnN0YW5jZUhlYWx0aCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVJbnN0YW5jZUhlYWx0aCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBhdHRyaWJ1dGVzIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJBdHRyaWJ1dGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTG9hZEJhbGFuY2VyQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVMb2FkQmFsYW5jZXJBdHRyaWJ1dGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHNwZWNpZmllZCBwb2xpY2llc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlclBvbGljaWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTG9hZEJhbGFuY2VyUG9saWNpZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTG9hZEJhbGFuY2VyUG9saWNpZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXIgcG9saWN5IHR5cGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2VyUG9saWN5VHlwZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVMb2FkQmFsYW5jZXJQb2xpY3lUeXBlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVMb2FkQmFsYW5jZXJQb2xpY3lUeXBlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBzcGVjaWZpZWQgdGhlIGxvYWQgYmFsYW5jZXJzLiBJZiBubyBsb2FkIGJhbGFuY2VycyBhcmUgc3BlY2lmaWVkLCB0aGUgY2FsbCBkZXNjcmliZXMgYWxsIG9mIHlvdXIgbG9hZCBiYWxhbmNlcnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTG9hZEJhbGFuY2VycygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVMb2FkQmFsYW5jZXJzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlcnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlVGFncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBzcGVjaWZpZWQgc3VibmV0cyBmcm9tIHRoZSBzZXQgb2YgY29uZmlndXJlZCBzdWJuZXRzIGZvciB0aGUgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGV0YWNoTG9hZEJhbGFuY2VyRnJvbVN1Ym5ldHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGV0YWNoTG9hZEJhbGFuY2VyRnJvbVN1Ym5ldHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RldGFjaExvYWRCYWxhbmNlckZyb21TdWJuZXRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBzcGVjaWZpZWQgQXZhaWxhYmlsaXR5IFpvbmVzIGZyb20gdGhlIHNldCBvZiBBdmFpbGFiaWxpdHkgWm9uZXMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGlzYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2FibGVBdmFpbGFiaWxpdHlab25lc0ZvckxvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHRoZSBzcGVjaWZpZWQgQXZhaWxhYmlsaXR5IFpvbmVzIHRvIHRoZSBzZXQgb2YgQXZhaWxhYmlsaXR5IFpvbmVzIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0VuYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0VuYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdFbmFibGVBdmFpbGFiaWxpdHlab25lc0ZvckxvYWRCYWxhbmNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIG1vZGlmeSB0aGUgYXR0cmlidXRlcyBvZiB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX01vZGlmeUxvYWRCYWxhbmNlckF0dHJpYnV0ZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTW9kaWZ5TG9hZEJhbGFuY2VyQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTW9kaWZ5TG9hZEJhbGFuY2VyQXR0cmlidXRlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCB0aGUgc3BlY2lmaWVkIGluc3RhbmNlcyB0byB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX1JlZ2lzdGVySW5zdGFuY2VzV2l0aExvYWRCYWxhbmNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZWdpc3Rlckluc3RhbmNlc1dpdGhMb2FkQmFsYW5jZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlZ2lzdGVySW5zdGFuY2VzV2l0aExvYWRCYWxhbmNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBvbmUgb3IgbW9yZSB0YWdzIGZyb20gdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZywgV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9SZW1vdmVUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlbW92ZVRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlbW92ZVRhZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzZXQgdGhlIGNlcnRpZmljYXRlIHRoYXQgdGVybWluYXRlcyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyJ3MgU1NMIGNvbm5lY3Rpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9TZXRMb2FkQmFsYW5jZXJMaXN0ZW5lclNTTENlcnRpZmljYXRlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1NldExvYWRCYWxhbmNlckxpc3RlbmVyU1NMQ2VydGlmaWNhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1NldExvYWRCYWxhbmNlckxpc3RlbmVyU1NMQ2VydGlmaWNhdGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXBsYWNlIHRoZSBzZXQgb2YgcG9saWNpZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgcG9ydCBvbiB3aGljaCB0aGUgYmFjay1lbmQgc2VydmVyIGlzIGxpc3RlbmluZyB3aXRoIGEgbmV3IHNldCBvZiBwb2xpY2llc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfU2V0TG9hZEJhbGFuY2VyUG9saWNpZXNGb3JCYWNrZW5kU2VydmVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1NldExvYWRCYWxhbmNlclBvbGljaWVzRm9yQmFja2VuZFNlcnZlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2V0TG9hZEJhbGFuY2VyUG9saWNpZXNGb3JCYWNrZW5kU2VydmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVwbGFjZSB0aGUgY3VycmVudCBzZXQgb2YgcG9saWNpZXMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlciBwb3J0IHdpdGggdGhlIHNwZWNpZmllZCBzZXQgb2YgcG9saWNpZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX1NldExvYWRCYWxhbmNlclBvbGljaWVzT2ZMaXN0ZW5lci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TZXRMb2FkQmFsYW5jZXJQb2xpY2llc09mTGlzdGVuZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1NldExvYWRCYWxhbmNlclBvbGljaWVzT2ZMaXN0ZW5lcicpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFjY2Vzc0xldmVsTGlzdDogQWNjZXNzTGV2ZWxMaXN0ID0ge1xuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdBZGRUYWdzJyxcbiAgICAgICdSZW1vdmVUYWdzJ1xuICAgIF0sXG4gICAgV3JpdGU6IFtcbiAgICAgICdBZGRUYWdzJyxcbiAgICAgICdBcHBseVNlY3VyaXR5R3JvdXBzVG9Mb2FkQmFsYW5jZXInLFxuICAgICAgJ0F0dGFjaExvYWRCYWxhbmNlclRvU3VibmV0cycsXG4gICAgICAnQ29uZmlndXJlSGVhbHRoQ2hlY2snLFxuICAgICAgJ0NyZWF0ZUFwcENvb2tpZVN0aWNraW5lc3NQb2xpY3knLFxuICAgICAgJ0NyZWF0ZUxCQ29va2llU3RpY2tpbmVzc1BvbGljeScsXG4gICAgICAnQ3JlYXRlTG9hZEJhbGFuY2VyJyxcbiAgICAgICdDcmVhdGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMnLFxuICAgICAgJ0NyZWF0ZUxvYWRCYWxhbmNlclBvbGljeScsXG4gICAgICAnRGVsZXRlTG9hZEJhbGFuY2VyJyxcbiAgICAgICdEZWxldGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMnLFxuICAgICAgJ0RlbGV0ZUxvYWRCYWxhbmNlclBvbGljeScsXG4gICAgICAnRGVyZWdpc3Rlckluc3RhbmNlc0Zyb21Mb2FkQmFsYW5jZXInLFxuICAgICAgJ0RldGFjaExvYWRCYWxhbmNlckZyb21TdWJuZXRzJyxcbiAgICAgICdEaXNhYmxlQXZhaWxhYmlsaXR5Wm9uZXNGb3JMb2FkQmFsYW5jZXInLFxuICAgICAgJ0VuYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyJyxcbiAgICAgICdNb2RpZnlMb2FkQmFsYW5jZXJBdHRyaWJ1dGVzJyxcbiAgICAgICdSZWdpc3Rlckluc3RhbmNlc1dpdGhMb2FkQmFsYW5jZXInLFxuICAgICAgJ1JlbW92ZVRhZ3MnLFxuICAgICAgJ1NldExvYWRCYWxhbmNlckxpc3RlbmVyU1NMQ2VydGlmaWNhdGUnLFxuICAgICAgJ1NldExvYWRCYWxhbmNlclBvbGljaWVzRm9yQmFja2VuZFNlcnZlcicsXG4gICAgICAnU2V0TG9hZEJhbGFuY2VyUG9saWNpZXNPZkxpc3RlbmVyJ1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0Rlc2NyaWJlSW5zdGFuY2VIZWFsdGgnLFxuICAgICAgJ0Rlc2NyaWJlTG9hZEJhbGFuY2VyQXR0cmlidXRlcycsXG4gICAgICAnRGVzY3JpYmVMb2FkQmFsYW5jZXJQb2xpY2llcycsXG4gICAgICAnRGVzY3JpYmVMb2FkQmFsYW5jZXJQb2xpY3lUeXBlcycsXG4gICAgICAnRGVzY3JpYmVUYWdzJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0Rlc2NyaWJlTG9hZEJhbGFuY2VycydcbiAgICBdXG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGxvYWRiYWxhbmNlciB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvdXNlcmd1aWRlL3doYXQtaXMtbG9hZC1iYWxhbmNpbmcuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gbG9hZEJhbGFuY2VyTmFtZSAtIElkZW50aWZpZXIgZm9yIHRoZSBsb2FkQmFsYW5jZXJOYW1lLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uTG9hZGJhbGFuY2VyKGxvYWRCYWxhbmNlck5hbWU6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTplbGFzdGljbG9hZGJhbGFuY2luZzokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06bG9hZGJhbGFuY2VyLyR7IGxvYWRCYWxhbmNlck5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGEgdGFnIGtleSBhbmQgdmFsdWUgcGFpciB0aGF0IGlzIGFsbG93ZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlcXVlc3R0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3MoKVxuICAgKiAtIC50b0NyZWF0ZUxvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIHRhZyBrZXkgYW5kIHZhbHVlIHBhaXIgb2YgYSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVzb3VyY2V0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3MoKVxuICAgKiAtIC50b0FwcGx5U2VjdXJpdHlHcm91cHNUb0xvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvQXR0YWNoTG9hZEJhbGFuY2VyVG9TdWJuZXRzKClcbiAgICogLSAudG9Db25maWd1cmVIZWFsdGhDaGVjaygpXG4gICAqIC0gLnRvQ3JlYXRlQXBwQ29va2llU3RpY2tpbmVzc1BvbGljeSgpXG4gICAqIC0gLnRvQ3JlYXRlTEJDb29raWVTdGlja2luZXNzUG9saWN5KClcbiAgICogLSAudG9DcmVhdGVMb2FkQmFsYW5jZXIoKVxuICAgKiAtIC50b0NyZWF0ZUxvYWRCYWxhbmNlckxpc3RlbmVycygpXG4gICAqIC0gLnRvQ3JlYXRlTG9hZEJhbGFuY2VyUG9saWN5KClcbiAgICogLSAudG9EZWxldGVMb2FkQmFsYW5jZXIoKVxuICAgKiAtIC50b0RlbGV0ZUxvYWRCYWxhbmNlckxpc3RlbmVycygpXG4gICAqIC0gLnRvRGVsZXRlTG9hZEJhbGFuY2VyUG9saWN5KClcbiAgICogLSAudG9EZXJlZ2lzdGVySW5zdGFuY2VzRnJvbUxvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvRGV0YWNoTG9hZEJhbGFuY2VyRnJvbVN1Ym5ldHMoKVxuICAgKiAtIC50b0Rpc2FibGVBdmFpbGFiaWxpdHlab25lc0ZvckxvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvRW5hYmxlQXZhaWxhYmlsaXR5Wm9uZXNGb3JMb2FkQmFsYW5jZXIoKVxuICAgKiAtIC50b01vZGlmeUxvYWRCYWxhbmNlckF0dHJpYnV0ZXMoKVxuICAgKiAtIC50b1JlZ2lzdGVySW5zdGFuY2VzV2l0aExvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqIC0gLnRvU2V0TG9hZEJhbGFuY2VyTGlzdGVuZXJTU0xDZXJ0aWZpY2F0ZSgpXG4gICAqIC0gLnRvU2V0TG9hZEJhbGFuY2VyUG9saWNpZXNGb3JCYWNrZW5kU2VydmVyKClcbiAgICogLSAudG9TZXRMb2FkQmFsYW5jZXJQb2xpY2llc09mTGlzdGVuZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGxvYWRiYWxhbmNlclxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVzb3VyY2VUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVzb3VyY2VUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIGxpc3Qgb2YgdGFnIGtleXMgdGhhdCBhcmUgYWxsb3dlZCBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtdGFna2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqIC0gLnRvQ3JlYXRlTG9hZEJhbGFuY2VyKClcbiAgICogLSAudG9SZW1vdmVUYWdzKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBuYW1lIG9mIGEgcmVzb3VyY2UtY3JlYXRpbmcgQVBJIGFjdGlvblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L3VzZXJndWlkZS90YWdnaW5nLXJlc291cmNlcy1kdXJpbmctY3JlYXRpb24uaHRtbFxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQ3JlYXRlQWN0aW9uKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBDcmVhdGVBY3Rpb25gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgbGlzdGVuZXIgcHJvdG9jb2xzIHRoYXQgYXJlIGFsbG93ZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC91c2VyZ3VpZGUvc2VjdXJpdHlfaWFtX3NlcnZpY2Utd2l0aC1pYW0uaHRtbCNsaXN0ZW5lcnByb3RvY29sLWNvbmRpdGlvblxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlTG9hZEJhbGFuY2VyKClcbiAgICogLSAudG9DcmVhdGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkxpc3RlbmVyUHJvdG9jb2wodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYExpc3RlbmVyUHJvdG9jb2xgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcHJlZmFjZSBzdHJpbmcgZm9yIGEgdGFnIGtleSBhbmQgdmFsdWUgcGFpciB0aGF0IGFyZSBhdHRhY2hlZCB0byBhIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXNvdXJjZXRhZ1xuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlJlc291cmNlVGFnRXhpc3RzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBSZXNvdXJjZVRhZy9gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcHJlZmFjZSBzdHJpbmcgZm9yIGEgdGFnIGtleSBhbmQgdmFsdWUgcGFpciB0aGF0IGFyZSBhdHRhY2hlZCB0byBhIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXNvdXJjZXRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqIC0gLnRvQXBwbHlTZWN1cml0eUdyb3Vwc1RvTG9hZEJhbGFuY2VyKClcbiAgICogLSAudG9BdHRhY2hMb2FkQmFsYW5jZXJUb1N1Ym5ldHMoKVxuICAgKiAtIC50b0NvbmZpZ3VyZUhlYWx0aENoZWNrKClcbiAgICogLSAudG9DcmVhdGVBcHBDb29raWVTdGlja2luZXNzUG9saWN5KClcbiAgICogLSAudG9DcmVhdGVMQkNvb2tpZVN0aWNraW5lc3NQb2xpY3koKVxuICAgKiAtIC50b0NyZWF0ZUxvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvQ3JlYXRlTG9hZEJhbGFuY2VyTGlzdGVuZXJzKClcbiAgICogLSAudG9DcmVhdGVMb2FkQmFsYW5jZXJQb2xpY3koKVxuICAgKiAtIC50b0RlbGV0ZUxvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvRGVsZXRlTG9hZEJhbGFuY2VyTGlzdGVuZXJzKClcbiAgICogLSAudG9EZWxldGVMb2FkQmFsYW5jZXJQb2xpY3koKVxuICAgKiAtIC50b0RlcmVnaXN0ZXJJbnN0YW5jZXNGcm9tTG9hZEJhbGFuY2VyKClcbiAgICogLSAudG9EZXRhY2hMb2FkQmFsYW5jZXJGcm9tU3VibmV0cygpXG4gICAqIC0gLnRvRGlzYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyKClcbiAgICogLSAudG9FbmFibGVBdmFpbGFiaWxpdHlab25lc0ZvckxvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvTW9kaWZ5TG9hZEJhbGFuY2VyQXR0cmlidXRlcygpXG4gICAqIC0gLnRvUmVnaXN0ZXJJbnN0YW5jZXNXaXRoTG9hZEJhbGFuY2VyKClcbiAgICogLSAudG9SZW1vdmVUYWdzKClcbiAgICogLSAudG9TZXRMb2FkQmFsYW5jZXJMaXN0ZW5lclNTTENlcnRpZmljYXRlKClcbiAgICogLSAudG9TZXRMb2FkQmFsYW5jZXJQb2xpY2llc0ZvckJhY2tlbmRTZXJ2ZXIoKVxuICAgKiAtIC50b1NldExvYWRCYWxhbmNlclBvbGljaWVzT2ZMaXN0ZW5lcigpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gbG9hZGJhbGFuY2VyXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZSZXNvdXJjZVRhZ1RhZ0tleSh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYFJlc291cmNlVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIGxvYWQgYmFsYW5jZXIgc2NoZW1lIHRoYXQgYXJlIGFsbG93ZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC91c2VyZ3VpZGUvc2VjdXJpdHlfaWFtX3NlcnZpY2Utd2l0aC1pYW0uaHRtbCNzY2hlbWUtY29uZGl0aW9uXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVMb2FkQmFsYW5jZXIoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlNjaGVtZSh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgU2NoZW1lYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHNlY3VyaXR5LWdyb3VwIElEcyB0aGF0IGFyZSBhbGxvd2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvdXNlcmd1aWRlL3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLmh0bWwjc2VjdXJpdHlncm91cC1jb25kaXRpb25cbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FwcGx5U2VjdXJpdHlHcm91cHNUb0xvYWRCYWxhbmNlcigpXG4gICAqIC0gLnRvQ3JlYXRlTG9hZEJhbGFuY2VyKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZTZWN1cml0eUdyb3VwKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBTZWN1cml0eUdyb3VwYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIFNTTCBTZWN1cml0eSBQb2xpY2llcyB0aGF0IGFyZSBhbGxvd2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvdXNlcmd1aWRlL3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLmh0bWwjc2VjdXJpdHlwb2xpY3ktY29uZGl0aW9uXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVMb2FkQmFsYW5jZXJQb2xpY3koKVxuICAgKiAtIC50b1NldExvYWRCYWxhbmNlclBvbGljaWVzT2ZMaXN0ZW5lcigpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmU2VjdXJpdHlQb2xpY3kodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYFNlY3VyaXR5UG9saWN5YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHN1Ym5ldCBJRHMgdGhhdCBhcmUgYWxsb3dlZCBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L3VzZXJndWlkZS9zZWN1cml0eV9pYW1fc2VydmljZS13aXRoLWlhbS5odG1sI3N1Ym5ldC1jb25kaXRpb25cbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0F0dGFjaExvYWRCYWxhbmNlclRvU3VibmV0cygpXG4gICAqIC0gLnRvQ3JlYXRlTG9hZEJhbGFuY2VyKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZTdWJuZXQodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYFN1Ym5ldGAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbZWxhc3RpY2xvYWRiYWxhbmNpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2VsYi5odG1sKS5cbiAgICpcbiAgICovXG4gIGNvbnN0cnVjdG9yKHByb3BzPzogaWFtLlBvbGljeVN0YXRlbWVudFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICB9XG59XG4iXX0=