UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

586 lines 58.2 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Managedblockchain = void 0;
const shared_1 = require("../../shared");
/**
 * Statement provider for service [managedblockchain](https://docs.aws.amazon.com/service-authorization/latest/reference/list_managedblockchain.html).
 *
 * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
 */
class Managedblockchain extends shared_1.PolicyStatement {
    /**
     * Grants permission to create an Amazon Managed Blockchain accessor
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_CreateAccessor.html
     */
    toCreateAccessor() {
        return this.to('CreateAccessor');
    }
    /**
     * Grants permission to create a member of an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_CreateMember.html
     */
    toCreateMember() {
        return this.to('CreateMember');
    }
    /**
     * Grants permission to create an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_CreateNetwork.html
     */
    toCreateNetwork() {
        return this.to('CreateNetwork');
    }
    /**
     * Grants permission to create a node within a member of an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_CreateNode.html
     */
    toCreateNode() {
        return this.to('CreateNode');
    }
    /**
     * Grants permission to create a proposal that other blockchain network members can vote on to add or remove a member in an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_CreateProposal.html
     */
    toCreateProposal() {
        return this.to('CreateProposal');
    }
    /**
     * Grants permission to delete an Amazon Managed Blockchain accessor
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_DeleteAccessor.html
     */
    toDeleteAccessor() {
        return this.to('DeleteAccessor');
    }
    /**
     * Grants permission to delete a member and all associated resources from an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_DeleteMember.html
     */
    toDeleteMember() {
        return this.to('DeleteMember');
    }
    /**
     * Grants permission to delete a node from a member of an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_DeleteNode.html
     */
    toDeleteNode() {
        return this.to('DeleteNode');
    }
    /**
     * Grants permission to return detailed information about an Amazon Managed Blockchain accessor
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_GetAccessor.html
     */
    toGetAccessor() {
        return this.to('GetAccessor');
    }
    /**
     * Grants permission to return detailed information about a member of an Amazon Managed Blockchain network
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_GetMember.html
     */
    toGetMember() {
        return this.to('GetMember');
    }
    /**
     * Grants permission to return detailed information about an Amazon Managed Blockchain network
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_GetNetwork.html
     */
    toGetNetwork() {
        return this.to('GetNetwork');
    }
    /**
     * Grants permission to return detailed information about a node within a member of an Amazon Managed Blockchain network
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_GetNode.html
     */
    toGetNode() {
        return this.to('GetNode');
    }
    /**
     * Grants permission to return detailed information about a proposal of an Amazon Managed Blockchain network
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_GetProposal.html
     */
    toGetProposal() {
        return this.to('GetProposal');
    }
    /**
     * Grants permission to invoke the Bitcoin Mainnet RPCs
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ambbtc-dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-bitcoin-networks
     */
    toInvokeRpcBitcoinMainnet() {
        return this.to('InvokeRpcBitcoinMainnet');
    }
    /**
     * Grants permission to invoke the Bitcoin Testnet RPCs
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ambbtc-dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-bitcoin-networks
     */
    toInvokeRpcBitcoinTestnet() {
        return this.to('InvokeRpcBitcoinTestnet');
    }
    /**
     * Grants permission to invoke the Polygon Mainnet RPCs
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ambp-dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-polygon-networks
     */
    toInvokeRpcPolygonMainnet() {
        return this.to('InvokeRpcPolygonMainnet');
    }
    /**
     * Grants permission to invoke the Polygon Mumbai Testnet RPCs
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ambp-dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-polygon-networks
     */
    toInvokeRpcPolygonMumbaiTestnet() {
        return this.to('InvokeRpcPolygonMumbaiTestnet');
    }
    /**
     * Grants permission to list the Amazon Managed Blockchain accessors owned by the current AWS account
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListAccessors.html
     */
    toListAccessors() {
        return this.to('ListAccessors');
    }
    /**
     * Grants permission to list the invitations extended to the active AWS account from any Managed Blockchain network
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListInvitations.html
     */
    toListInvitations() {
        return this.to('ListInvitations');
    }
    /**
     * Grants permission to list the members of an Amazon Managed Blockchain network and the properties of their memberships
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListMembers.html
     */
    toListMembers() {
        return this.to('ListMembers');
    }
    /**
     * Grants permission to list the Amazon Managed Blockchain networks in which the current AWS account participates
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListNetworks.html
     */
    toListNetworks() {
        return this.to('ListNetworks');
    }
    /**
     * Grants permission to list the nodes within a member of an Amazon Managed Blockchain network
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListNodes.html
     */
    toListNodes() {
        return this.to('ListNodes');
    }
    /**
     * Grants permission to list all votes for a proposal, including the value of the vote and the unique identifier of the member that cast the vote for the given Amazon Managed Blockchain network
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListProposalVotes.html
     */
    toListProposalVotes() {
        return this.to('ListProposalVotes');
    }
    /**
     * Grants permission to list proposals for the given Amazon Managed Blockchain network
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListProposals.html
     */
    toListProposals() {
        return this.to('ListProposals');
    }
    /**
     * Grants permission to view tags associated with an Amazon Managed Blockchain resource
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_ListTagsForResource.html
     */
    toListTagsForResource() {
        return this.to('ListTagsForResource');
    }
    /**
     * Grants permission to reject the invitation to join the blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_RejectInvitation.html
     */
    toRejectInvitation() {
        return this.to('RejectInvitation');
    }
    /**
     * Grants permission to add tags to an Amazon Managed Blockchain resource
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_TagResource.html
     */
    toTagResource() {
        return this.to('TagResource');
    }
    /**
     * Grants permission to remove tags from an Amazon Managed Blockchain resource
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_UntagResource.html
     */
    toUntagResource() {
        return this.to('UntagResource');
    }
    /**
     * Grants permission to update a member of an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_UpdateMember.html
     */
    toUpdateMember() {
        return this.to('UpdateMember');
    }
    /**
     * Grants permission to update a node from a member of an Amazon Managed Blockchain network
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_UpdateNode.html
     */
    toUpdateNode() {
        return this.to('UpdateNode');
    }
    /**
     * Grants permission to cast a vote for a proposal on behalf of the blockchain network member specified
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/APIReference/API_VoteOnProposal.html
     */
    toVoteOnProposal() {
        return this.to('VoteOnProposal');
    }
    /**
     * Grants permission to send HTTP GET requests to an Ethereum node
     *
     * Access Level: Permissions management, Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ethereum-dev/security_iam_id-based-policy-examples.html
     */
    toGET() {
        return this.to('GET');
    }
    /**
     * Grants permission to create WebSocket connections to an Ethereum node
     *
     * Access Level: Permissions management, Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ethereum-dev/security_iam_id-based-policy-examples.html
     */
    toInvoke() {
        return this.to('Invoke');
    }
    /**
     * Grants permission to send HTTP POST requests to an Ethereum node
     *
     * Access Level: Permissions management, Write
     *
     * https://docs.aws.amazon.com/managed-blockchain/latest/ethereum-dev/security_iam_id-based-policy-examples.html
     */
    toPOST() {
        return this.to('POST');
    }
    /**
     * Adds a resource of type accessor to the statement
     *
     * @param accessorId - Identifier for the accessorId.
     * @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()
     */
    onAccessor(accessorId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:managedblockchain:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:accessors/${accessorId}`);
    }
    /**
     * Adds a resource of type invitation to the statement
     *
     * @param invitationId - Identifier for the invitationId.
     * @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()
     */
    onInvitation(invitationId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:managedblockchain:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:invitations/${invitationId}`);
    }
    /**
     * Adds a resource of type member to the statement
     *
     * @param memberId - Identifier for the memberId.
     * @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()
     */
    onMember(memberId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:managedblockchain:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:members/${memberId}`);
    }
    /**
     * Adds a resource of type network to the statement
     *
     * @param networkId - Identifier for the networkId.
     * @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()
     */
    onNetwork(networkId, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:managedblockchain:${region ?? this.defaultRegion}::networks/${networkId}`);
    }
    /**
     * Adds a resource of type node to the statement
     *
     * @param nodeId - Identifier for the nodeId.
     * @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()
     */
    onNode(nodeId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:managedblockchain:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:nodes/${nodeId}`);
    }
    /**
     * Adds a resource of type proposal to the statement
     *
     * @param proposalId - Identifier for the proposalId.
     * @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()
     */
    onProposal(proposalId, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:managedblockchain:${region ?? this.defaultRegion}::proposals/${proposalId}`);
    }
    /**
     * Filters actions based on the tags that are passed in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
     *
     * Applies to actions:
     * - .toCreateAccessor()
     * - .toCreateMember()
     * - .toCreateNetwork()
     * - .toCreateNode()
     * - .toCreateProposal()
     * - .toTagResource()
     *
     * @param tagKey The tag key to check
     * @param value The value(s) to check
     * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
     */
    ifAwsRequestTag(tagKey, value, operator) {
        return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike');
    }
    /**
     * Filters actions based on the tags associated with an Amazon Managed Blockchain resource
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
     *
     * Applies to actions:
     * - .toCreateMember()
     * - .toCreateNode()
     * - .toCreateProposal()
     * - .toDeleteAccessor()
     * - .toDeleteMember()
     * - .toDeleteNode()
     * - .toGetAccessor()
     * - .toGetMember()
     * - .toGetNetwork()
     * - .toGetNode()
     * - .toGetProposal()
     * - .toListMembers()
     * - .toListNodes()
     * - .toListProposalVotes()
     * - .toListProposals()
     * - .toListTagsForResource()
     * - .toRejectInvitation()
     * - .toTagResource()
     * - .toUntagResource()
     * - .toUpdateMember()
     * - .toUpdateNode()
     * - .toVoteOnProposal()
     *
     * Applies to resource types:
     * - accessor
     * - invitation
     * - member
     * - network
     * - node
     * - proposal
     *
     * @param tagKey The tag key to check
     * @param value The value(s) to check
     * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
     */
    ifAwsResourceTag(tagKey, value, operator) {
        return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike');
    }
    /**
     * Filters actions based on the tag keys that are passed in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
     *
     * Applies to actions:
     * - .toCreateAccessor()
     * - .toCreateMember()
     * - .toCreateNetwork()
     * - .toCreateNode()
     * - .toCreateProposal()
     * - .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 [managedblockchain](https://docs.aws.amazon.com/service-authorization/latest/reference/list_managedblockchain.html).
     *
     */
    constructor(props) {
        super(props);
        this.servicePrefix = 'managedblockchain';
        this.accessLevelList = {
            Write: [
                'CreateAccessor',
                'CreateMember',
                'CreateNetwork',
                'CreateNode',
                'CreateProposal',
                'DeleteAccessor',
                'DeleteMember',
                'DeleteNode',
                'RejectInvitation',
                'TagResource',
                'UntagResource',
                'UpdateMember',
                'UpdateNode',
                'VoteOnProposal',
                'GET',
                'Invoke',
                'POST'
            ],
            Read: [
                'GetAccessor',
                'GetMember',
                'GetNetwork',
                'GetNode',
                'GetProposal',
                'InvokeRpcBitcoinMainnet',
                'InvokeRpcBitcoinTestnet',
                'InvokeRpcPolygonMainnet',
                'InvokeRpcPolygonMumbaiTestnet',
                'ListProposalVotes',
                'ListTagsForResource'
            ],
            List: [
                'ListAccessors',
                'ListInvitations',
                'ListMembers',
                'ListNetworks',
                'ListNodes',
                'ListProposals'
            ],
            Tagging: [
                'TagResource',
                'UntagResource'
            ],
            'Permissions management': [
                'GET',
                'Invoke',
                'POST'
            ]
        };
    }
}
exports.Managedblockchain = Managedblockchain;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlZGJsb2NrY2hhaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYW5hZ2VkYmxvY2tjaGFpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFHekQ7Ozs7R0FJRztBQUNILE1BQWEsaUJBQWtCLFNBQVEsd0JBQWU7SUFHcEQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksY0FBYztRQUNuQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxlQUFlO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksWUFBWTtRQUNqQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxjQUFjO1FBQ25CLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksWUFBWTtRQUNqQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsRUFB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Z0JBQ1gsZUFBZTthQUNoQjtZQUNELE9BQU8sRUFBRTtnQkFDUCxhQUFhO2dCQUNiLGVBQWU7YUFDaEI7WUFDRCx3QkFBd0IsRUFBRTtnQkFDeEIsS0FBSztnQkFDTCxRQUFRO2dCQUNSLE1BQU07YUFDUDtTQUNGLENBQUM7SUF1TEYsQ0FBQztDQUNGO0FBM21CRCw4Q0EybUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFttYW5hZ2VkYmxvY2tjaGFpbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfbWFuYWdlZGJsb2NrY2hhaW4uaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNYW5hZ2VkYmxvY2tjaGFpbiBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ21hbmFnZWRibG9ja2NoYWluJztcblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGFuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gYWNjZXNzb3JcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUFjY2Vzc29yLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUFjY2Vzc29yKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVBY2Nlc3NvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIG1lbWJlciBvZiBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmtcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU1lbWJlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVNZW1iZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZU1lbWJlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmtcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU5ldHdvcmsuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlTmV0d29yaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlTmV0d29yaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIG5vZGUgd2l0aGluIGEgbWVtYmVyIG9mIGFuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29ya1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlTm9kZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVOb2RlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVOb2RlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgcHJvcG9zYWwgdGhhdCBvdGhlciBibG9ja2NoYWluIG5ldHdvcmsgbWVtYmVycyBjYW4gdm90ZSBvbiB0byBhZGQgb3IgcmVtb3ZlIGEgbWVtYmVyIGluIGFuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29ya1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlUHJvcG9zYWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlUHJvcG9zYWwoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVByb3Bvc2FsJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGFuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gYWNjZXNzb3JcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUFjY2Vzc29yLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUFjY2Vzc29yKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVBY2Nlc3NvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIG1lbWJlciBhbmQgYWxsIGFzc29jaWF0ZWQgcmVzb3VyY2VzIGZyb20gYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVNZW1iZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlTWVtYmVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVNZW1iZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBub2RlIGZyb20gYSBtZW1iZXIgb2YgYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVOb2RlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZU5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZU5vZGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXR1cm4gZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBhY2Nlc3NvclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRBY2Nlc3Nvci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRBY2Nlc3NvcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0QWNjZXNzb3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXR1cm4gZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBtZW1iZXIgb2YgYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldE1lbWJlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRNZW1iZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldE1lbWJlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmtcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0TmV0d29yay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXROZXR3b3JrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXROZXR3b3JrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0dXJuIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IGEgbm9kZSB3aXRoaW4gYSBtZW1iZXIgb2YgYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldE5vZGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0Tm9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0Tm9kZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhIHByb3Bvc2FsIG9mIGFuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29ya1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRQcm9wb3NhbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRQcm9wb3NhbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0UHJvcG9zYWwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbnZva2UgdGhlIEJpdGNvaW4gTWFpbm5ldCBSUENzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9hbWJidGMtZGcvc2VjdXJpdHlfaWFtX2lkLWJhc2VkLXBvbGljeS1leGFtcGxlcy5odG1sI3NlY3VyaXR5X2lhbV9pZC1iYXNlZC1wb2xpY3ktZXhhbXBsZXMtYWNjZXNzLWJpdGNvaW4tbmV0d29ya3NcbiAgICovXG4gIHB1YmxpYyB0b0ludm9rZVJwY0JpdGNvaW5NYWlubmV0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdJbnZva2VScGNCaXRjb2luTWFpbm5ldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGludm9rZSB0aGUgQml0Y29pbiBUZXN0bmV0IFJQQ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L2FtYmJ0Yy1kZy9zZWN1cml0eV9pYW1faWQtYmFzZWQtcG9saWN5LWV4YW1wbGVzLmh0bWwjc2VjdXJpdHlfaWFtX2lkLWJhc2VkLXBvbGljeS1leGFtcGxlcy1hY2Nlc3MtYml0Y29pbi1uZXR3b3Jrc1xuICAgKi9cbiAgcHVibGljIHRvSW52b2tlUnBjQml0Y29pblRlc3RuZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0ludm9rZVJwY0JpdGNvaW5UZXN0bmV0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW52b2tlIHRoZSBQb2x5Z29uIE1haW5uZXQgUlBDc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvYW1icC1kZy9zZWN1cml0eV9pYW1faWQtYmFzZWQtcG9saWN5LWV4YW1wbGVzLmh0bWwjc2VjdXJpdHlfaWFtX2lkLWJhc2VkLXBvbGljeS1leGFtcGxlcy1hY2Nlc3MtcG9seWdvbi1uZXR3b3Jrc1xuICAgKi9cbiAgcHVibGljIHRvSW52b2tlUnBjUG9seWdvbk1haW5uZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0ludm9rZVJwY1BvbHlnb25NYWlubmV0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW52b2tlIHRoZSBQb2x5Z29uIE11bWJhaSBUZXN0bmV0IFJQQ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L2FtYnAtZGcvc2VjdXJpdHlfaWFtX2lkLWJhc2VkLXBvbGljeS1leGFtcGxlcy5odG1sI3NlY3VyaXR5X2lhbV9pZC1iYXNlZC1wb2xpY3ktZXhhbXBsZXMtYWNjZXNzLXBvbHlnb24tbmV0d29ya3NcbiAgICovXG4gIHB1YmxpYyB0b0ludm9rZVJwY1BvbHlnb25NdW1iYWlUZXN0bmV0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdJbnZva2VScGNQb2x5Z29uTXVtYmFpVGVzdG5ldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gYWNjZXNzb3JzIG93bmVkIGJ5IHRoZSBjdXJyZW50IEFXUyBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RBY2Nlc3NvcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEFjY2Vzc29ycygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEFjY2Vzc29ycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIGludml0YXRpb25zIGV4dGVuZGVkIHRvIHRoZSBhY3RpdmUgQVdTIGFjY291bnQgZnJvbSBhbnkgTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmtcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdEludml0YXRpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RJbnZpdGF0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEludml0YXRpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgbWVtYmVycyBvZiBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmsgYW5kIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZWlyIG1lbWJlcnNoaXBzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RNZW1iZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RNZW1iZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0TWVtYmVycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29ya3MgaW4gd2hpY2ggdGhlIGN1cnJlbnQgQVdTIGFjY291bnQgcGFydGljaXBhdGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3ROZXR3b3Jrcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0TmV0d29ya3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3ROZXR3b3JrcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIG5vZGVzIHdpdGhpbiBhIG1lbWJlciBvZiBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmtcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdE5vZGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3ROb2RlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdE5vZGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhbGwgdm90ZXMgZm9yIGEgcHJvcG9zYWwsIGluY2x1ZGluZyB0aGUgdmFsdWUgb2YgdGhlIHZvdGUgYW5kIHRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgbWVtYmVyIHRoYXQgY2FzdCB0aGUgdm90ZSBmb3IgdGhlIGdpdmVuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29ya1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0UHJvcG9zYWxWb3Rlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UHJvcG9zYWxWb3RlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3Bvc2FsVm90ZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHByb3Bvc2FscyBmb3IgdGhlIGdpdmVuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29ya1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0UHJvcG9zYWxzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RQcm9wb3NhbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RQcm9wb3NhbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB2aWV3IHRhZ3MgYXNzb2NpYXRlZCB3aXRoIGFuIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW4gcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFnc0ZvclJlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVqZWN0IHRoZSBpbnZpdGF0aW9uIHRvIGpvaW4gdGhlIGJsb2NrY2hhaW4gbmV0d29ya1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVqZWN0SW52aXRhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZWplY3RJbnZpdGF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZWplY3RJbnZpdGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHRhZ3MgdG8gYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmcsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1RhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRhZ3MgZnJvbSBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZywgV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYSBtZW1iZXIgb2YgYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVNZW1iZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlTWVtYmVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVNZW1iZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYSBub2RlIGZyb20gYSBtZW1iZXIgb2YgYW4gQW1hem9uIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVOb2RlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZU5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZU5vZGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjYXN0IGEgdm90ZSBmb3IgYSBwcm9wb3NhbCBvbiBiZWhhbGYgb2YgdGhlIGJsb2NrY2hhaW4gbmV0d29yayBtZW1iZXIgc3BlY2lmaWVkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL21hbmFnZWQtYmxvY2tjaGFpbi9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Wb3RlT25Qcm9wb3NhbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Wb3RlT25Qcm9wb3NhbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVm90ZU9uUHJvcG9zYWwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzZW5kIEhUVFAgR0VUIHJlcXVlc3RzIHRvIGFuIEV0aGVyZXVtIG5vZGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBQZXJtaXNzaW9ucyBtYW5hZ2VtZW50LCBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWFuYWdlZC1ibG9ja2NoYWluL2xhdGVzdC9ldGhlcmV1bS1kZXYvc2VjdXJpdHlfaWFtX2lkLWJhc2VkLXBvbGljeS1leGFtcGxlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HRVQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dFVCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBXZWJTb2NrZXQgY29ubmVjdGlvbnMgdG8gYW4gRXRoZXJldW0gbm9kZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFBlcm1pc3Npb25zIG1hbmFnZW1lbnQsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L2V0aGVyZXVtLWRldi9zZWN1cml0eV9pYW1faWQtYmFzZWQtcG9saWN5LWV4YW1wbGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0ludm9rZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnSW52b2tlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc2VuZCBIVFRQIFBPU1QgcmVxdWVzdHMgdG8gYW4gRXRoZXJldW0gbm9kZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFBlcm1pc3Npb25zIG1hbmFnZW1lbnQsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tYW5hZ2VkLWJsb2NrY2hhaW4vbGF0ZXN0L2V0aGVyZXVtLWRldi9zZWN1cml0eV9pYW1faWQtYmFzZWQtcG9saWN5LWV4YW1wbGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1BPU1QoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1BPU1QnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0NyZWF0ZUFjY2Vzc29yJyxcbiAgICAgICdDcmVhdGVNZW1iZXInLFxuICAgICAgJ0NyZWF0ZU5ldHdvcmsnLFxuICAgICAgJ0NyZWF0ZU5vZGUnLFxuICAgICAgJ0NyZWF0ZVByb3Bvc2FsJyxcbiAgICAgICdEZWxldGVBY2Nlc3NvcicsXG4gICAgICAnRGVsZXRlTWVtYmVyJyxcbiAgICAgICdEZWxldGVOb2RlJyxcbiAgICAgICdSZWplY3RJbnZpdGF0aW9uJyxcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVW50YWdSZXNvdXJjZScsXG4gICAgICAnVXBkYXRlTWVtYmVyJyxcbiAgICAgICdVcGRhdGVOb2RlJyxcbiAgICAgICdWb3RlT25Qcm9wb3NhbCcsXG4gICAgICAnR0VUJyxcbiAgICAgICdJbnZva2UnLFxuICAgICAgJ1BPU1QnXG4gICAgXSxcbiAgICBSZWFkOiBbXG4gICAgICAnR2V0QWNjZXNzb3InLFxuICAgICAgJ0dldE1lbWJlcicsXG4gICAgICAnR2V0TmV0d29yaycsXG4gICAgICAnR2V0Tm9kZScsXG4gICAgICAnR2V0UHJvcG9zYWwnLFxuICAgICAgJ0ludm9rZVJwY0JpdGNvaW5NYWlubmV0JyxcbiAgICAgICdJbnZva2VScGNCaXRjb2luVGVzdG5ldCcsXG4gICAgICAnSW52b2tlUnBjUG9seWdvbk1haW5uZXQnLFxuICAgICAgJ0ludm9rZVJwY1BvbHlnb25NdW1iYWlUZXN0bmV0JyxcbiAgICAgICdMaXN0UHJvcG9zYWxWb3RlcycsXG4gICAgICAnTGlzdFRhZ3NGb3JSZXNvdXJjZSdcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdMaXN0QWNjZXNzb3JzJyxcbiAgICAgICdMaXN0SW52aXRhdGlvbnMnLFxuICAgICAgJ0xpc3RNZW1iZXJzJyxcbiAgICAgICdMaXN0TmV0d29ya3MnLFxuICAgICAgJ0xpc3ROb2RlcycsXG4gICAgICAnTGlzdFByb3Bvc2FscydcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVW50YWdSZXNvdXJjZSdcbiAgICBdLFxuICAgICdQZXJtaXNzaW9ucyBtYW5hZ2VtZW50JzogW1xuICAgICAgJ0dFVCcsXG4gICAgICAnSW52b2tlJyxcbiAgICAgICdQT1NUJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgYWNjZXNzb3IgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBAcGFyYW0gYWNjZXNzb3JJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBhY2Nlc3NvcklkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25BY2Nlc3NvcihhY2Nlc3NvcklkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06bWFuYWdlZGJsb2NrY2hhaW46JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OmFjY2Vzc29ycy8keyBhY2Nlc3NvcklkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBpbnZpdGF0aW9uIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIGludml0YXRpb25JZCAtIElkZW50aWZpZXIgZm9yIHRoZSBpbnZpdGF0aW9uSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkludml0YXRpb24oaW52aXRhdGlvbklkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06bWFuYWdlZGJsb2NrY2hhaW46JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9Omludml0YXRpb25zLyR7IGludml0YXRpb25JZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgbWVtYmVyIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIG1lbWJlcklkIC0gSWRlbnRpZmllciBmb3IgdGhlIG1lbWJlcklkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25NZW1iZXIobWVtYmVySWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTptYW5hZ2VkYmxvY2tjaGFpbjokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06bWVtYmVycy8keyBtZW1iZXJJZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgbmV0d29yayB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIEBwYXJhbSBuZXR3b3JrSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgbmV0d29ya0lkLlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uTmV0d29yayhuZXR3b3JrSWQ6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTptYW5hZ2VkYmxvY2tjaGFpbjokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06Om5ldHdvcmtzLyR7IG5ldHdvcmtJZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgbm9kZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIEBwYXJhbSBub2RlSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgbm9kZUlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25Ob2RlKG5vZGVJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9Om1hbmFnZWRibG9ja2NoYWluOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpub2Rlcy8keyBub2RlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHByb3Bvc2FsIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIHByb3Bvc2FsSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgcHJvcG9zYWxJZC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblByb3Bvc2FsKHByb3Bvc2FsSWQ6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTptYW5hZ2VkYmxvY2tjaGFpbjokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06OnByb3Bvc2Fscy8keyBwcm9wb3NhbElkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjdGlvbnMgYmFzZWQgb24gdGhlIHRhZ3MgdGhhdCBhcmUgcGFzc2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVBY2Nlc3NvcigpXG4gICAqIC0gLnRvQ3JlYXRlTWVtYmVyKClcbiAgICogLSAudG9DcmVhdGVOZXR3b3JrKClcbiAgICogLSAudG9DcmVhdGVOb2RlKClcbiAgICogLSAudG9DcmVhdGVQcm9wb3NhbCgpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVxdWVzdFRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXF1ZXN0VGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY3Rpb25zIGJhc2VkIG9uIHRoZSB0YWdzIGFzc29jaWF0ZWQgd2l0aCBhbiBBbWF6b24gTWFuYWdlZCBCbG9ja2NoYWluIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXNvdXJjZXRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlTWVtYmVyKClcbiAgICogLSAudG9DcmVhdGVOb2RlKClcbiAgICogLSAudG9DcmVhdGVQcm9wb3NhbCgpXG4gICAqIC0gLnRvRGVsZXRlQWNjZXNzb3IoKVxuICAgKiAtIC50b0RlbGV0ZU1lbWJlcigpXG4gICAqIC0gLnRvRGVsZXRlTm9kZSgpXG4gICAqIC0gLnRvR2V0QWNjZXNzb3IoKVxuICAgKiAtIC50b0dldE1lbWJlcigpXG4gICAqIC0gLnRvR2V0TmV0d29yaygpXG4gICAqIC0gLnRvR2V0Tm9kZSgpXG4gICAqIC0gLnRvR2V0UHJvcG9zYWwoKVxuICAgKiAtIC50b0xpc3RNZW1iZXJzKClcbiAgICogLSAudG9MaXN0Tm9kZXMoKVxuICAgKiAtIC50b0xpc3RQcm9wb3NhbFZvdGVzKClcbiAgICogLSAudG9MaXN0UHJvcG9zYWxzKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9SZWplY3RJbnZpdGF0aW9uKClcbiAgICogLSAudG9UYWdSZXNvdXJjZSgpXG4gICAqIC0gLnRvVW50YWdSZXNvdXJjZSgpXG4gICAqIC0gLnRvVXBkYXRlTWVtYmVyKClcbiAgICogLSAudG9VcGRhdGVOb2RlKClcbiAgICogLSAudG9Wb3RlT25Qcm9wb3NhbCgpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gYWNjZXNzb3JcbiAgICogLSBpbnZpdGF0aW9uXG4gICAqIC0gbWVtYmVyXG4gICAqIC0gbmV0d29ya1xuICAgKiAtIG5vZGVcbiAgICogLSBwcm9wb3NhbFxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVzb3VyY2VUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVzb3VyY2VUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjdGlvbnMgYmFzZWQgb24gdGhlIHRhZyBrZXlzIHRoYXQgYXJlIHBhc3NlZCBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtdGFna2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQWNjZXNzb3IoKVxuICAgKiAtIC50b0NyZWF0ZU1lbWJlcigpXG4gICAqIC0gLnRvQ3JlYXRlTmV0d29yaygpXG4gICAqIC0gLnRvQ3JlYXRlTm9kZSgpXG4gICAqIC0gLnRvQ3JlYXRlUHJvcG9zYWwoKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICogLSAudG9VbnRhZ1Jlc291cmNlKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbbWFuYWdlZGJsb2NrY2hhaW5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X21hbmFnZWRibG9ja2NoYWluLmh0bWwpLlxuICAgKlxuICAgKi9cbiAgY29uc3RydWN0b3IocHJvcHM/OiBpYW0uUG9saWN5U3RhdGVtZW50UHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gIH1cbn1cbiJdfQ==