UNPKG

iam-floyd

Version:

AWS IAM policy statement generator with fluent interface

583 lines 57.1 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fis = void 0;
const shared_1 = require("../../shared");
/**
 * Statement provider for service [fis](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsfaultinjectionservice.html).
 *
 * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
 */
class Fis extends shared_1.PolicyStatement {
    /**
     * Statement provider for service [fis](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsfaultinjectionservice.html).
     *
     * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
     */
    constructor(sid) {
        super(sid);
        this.servicePrefix = 'fis';
        this.accessLevelList = {
            Write: [
                'CreateExperimentTemplate',
                'CreateTargetAccountConfiguration',
                'DeleteExperimentTemplate',
                'DeleteTargetAccountConfiguration',
                'InjectApiInternalError',
                'InjectApiThrottleError',
                'InjectApiUnavailableError',
                'StartExperiment',
                'StopExperiment',
                'UpdateExperimentTemplate',
                'UpdateSafetyLeverState',
                'UpdateTargetAccountConfiguration'
            ],
            Read: [
                'GetAction',
                'GetExperiment',
                'GetExperimentTargetAccountConfiguration',
                'GetExperimentTemplate',
                'GetSafetyLever',
                'GetTargetAccountConfiguration',
                'GetTargetResourceType',
                'ListTagsForResource'
            ],
            List: [
                'ListActions',
                'ListExperimentResolvedTargets',
                'ListExperimentTargetAccountConfigurations',
                'ListExperimentTemplates',
                'ListExperiments',
                'ListTargetAccountConfigurations',
                'ListTargetResourceTypes'
            ],
            Tagging: [
                'TagResource',
                'UntagResource'
            ]
        };
    }
    /**
     * Grants permission to create an AWS FIS experiment template
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_CreateExperimentTemplate.html
     */
    toCreateExperimentTemplate() {
        return this.to('CreateExperimentTemplate');
    }
    /**
     * Grants permission to create an AWS FIS target account configuration
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_CreateTargetAccountConfiguration.html
     */
    toCreateTargetAccountConfiguration() {
        return this.to('CreateTargetAccountConfiguration');
    }
    /**
     * Grants permission to delete the AWS FIS experiment template
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_DeleteExperimentTemplate.html
     */
    toDeleteExperimentTemplate() {
        return this.to('DeleteExperimentTemplate');
    }
    /**
     * Grants permission to delete an AWS FIS target account configuration
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_DeleteTargetAccountConfiguration.html
     */
    toDeleteTargetAccountConfiguration() {
        return this.to('DeleteTargetAccountConfiguration');
    }
    /**
     * Grants permission to retrieve an AWS FIS action
     *
     * Access Level: Read
     *
     * Possible conditions:
     * - .ifAwsResourceTag()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetAction.html
     */
    toGetAction() {
        return this.to('GetAction');
    }
    /**
     * Grants permission to retrieve an AWS FIS experiment
     *
     * Access Level: Read
     *
     * Possible conditions:
     * - .ifAwsResourceTag()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetExperiment.html
     */
    toGetExperiment() {
        return this.to('GetExperiment');
    }
    /**
     * Grants permission to retrieve an AWS FIS target account configuration for an AWS FIS experiment
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetExperimentTargetAccountConfiguration.html
     */
    toGetExperimentTargetAccountConfiguration() {
        return this.to('GetExperimentTargetAccountConfiguration');
    }
    /**
     * Grants permission to retrieve an AWS FIS Experiment Template
     *
     * Access Level: Read
     *
     * Possible conditions:
     * - .ifAwsResourceTag()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetExperimentTemplate.html
     */
    toGetExperimentTemplate() {
        return this.to('GetExperimentTemplate');
    }
    /**
     * Grants permission to get information about the safety lever
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetSafetyLever.html
     */
    toGetSafetyLever() {
        return this.to('GetSafetyLever');
    }
    /**
     * Grants permission to retrieve an AWS FIS target account configuration for an AWS FIS experiment template
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetTargetAccountConfiguration.html
     */
    toGetTargetAccountConfiguration() {
        return this.to('GetTargetAccountConfiguration');
    }
    /**
     * Grants permission to get information about the specified resource type
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_GetTargetResourceType.html
     */
    toGetTargetResourceType() {
        return this.to('GetTargetResourceType');
    }
    /**
     * Grants permission to inject an API internal error on the provided AWS service from an FIS Experiment
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifService()
     * - .ifOperations()
     * - .ifPercentage()
     * - .ifTargets()
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html#fis-actions-reference-fis
     */
    toInjectApiInternalError() {
        return this.to('InjectApiInternalError');
    }
    /**
     * Grants permission to inject an API throttle error on the provided AWS service from an FIS Experiment
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifService()
     * - .ifOperations()
     * - .ifPercentage()
     * - .ifTargets()
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html#fis-actions-reference-fis
     */
    toInjectApiThrottleError() {
        return this.to('InjectApiThrottleError');
    }
    /**
     * Grants permission to inject an API unavailable error on the provided AWS service from an FIS Experiment
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifService()
     * - .ifOperations()
     * - .ifPercentage()
     * - .ifTargets()
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html#fis-actions-reference-fis
     */
    toInjectApiUnavailableError() {
        return this.to('InjectApiUnavailableError');
    }
    /**
     * Grants permission to list all available AWS FIS actions
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListActions.html
     */
    toListActions() {
        return this.to('ListActions');
    }
    /**
     * Grants permission to list resolved targets for AWS FIS experiments
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListExperimentResolvedTargets.html
     */
    toListExperimentResolvedTargets() {
        return this.to('ListExperimentResolvedTargets');
    }
    /**
     * Grants permission to list target account configurations for AWS FIS experiments
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListExperimentTargetAccountConfigurations.html
     */
    toListExperimentTargetAccountConfigurations() {
        return this.to('ListExperimentTargetAccountConfigurations');
    }
    /**
     * Grants permission to list all available AWS FIS experiment templates
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListExperimentTemplates.html
     */
    toListExperimentTemplates() {
        return this.to('ListExperimentTemplates');
    }
    /**
     * Grants permission to list all available AWS FIS experiments
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListExperiments.html
     */
    toListExperiments() {
        return this.to('ListExperiments');
    }
    /**
     * Grants permission to list the tags for an AWS FIS resource
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListTagsForResource.html
     */
    toListTagsForResource() {
        return this.to('ListTagsForResource');
    }
    /**
     * Grants permission to list target account configurations for AWS FIS experiment templates
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListTargetAccountConfigurations.html
     */
    toListTargetAccountConfigurations() {
        return this.to('ListTargetAccountConfigurations');
    }
    /**
     * Grants permission to list the resource types
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_ListTargetResourceTypes.html
     */
    toListTargetResourceTypes() {
        return this.to('ListTargetResourceTypes');
    }
    /**
     * Grants permission to run an AWS FIS experiment
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * Dependent actions:
     * - iam:CreateServiceLinkedRole
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_StartExperiment.html
     */
    toStartExperiment() {
        return this.to('StartExperiment');
    }
    /**
     * Grants permission to stop an AWS FIS experiment
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_StopExperiment.html
     */
    toStopExperiment() {
        return this.to('StopExperiment');
    }
    /**
     * Grants permission to tag AWS FIS resources
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsTagKeys()
     * - .ifAwsRequestTag()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_TagResource.html
     */
    toTagResource() {
        return this.to('TagResource');
    }
    /**
     * Grants permission to untag AWS FIS resources
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_UntagResource.html
     */
    toUntagResource() {
        return this.to('UntagResource');
    }
    /**
     * Grants permission to update the specified AWS FIS experiment template
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_UpdateExperimentTemplate.html
     */
    toUpdateExperimentTemplate() {
        return this.to('UpdateExperimentTemplate');
    }
    /**
     * Grants permission to update the state of the safety lever
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_UpdateSafetyLeverState.html
     */
    toUpdateSafetyLeverState() {
        return this.to('UpdateSafetyLeverState');
    }
    /**
     * Grants permission to update an AWS FIS target account configuration
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/fis/latest/APIReference/API_UpdateTargetAccountConfiguration.html
     */
    toUpdateTargetAccountConfiguration() {
        return this.to('UpdateTargetAccountConfiguration');
    }
    /**
     * Adds a resource of type action to the statement
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/actions.html
     *
     * @param id - Identifier for the id.
     * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
     * @param 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()
     */
    onAction(id, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:fis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:action/${id}`);
    }
    /**
     * Adds a resource of type experiment to the statement
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/experiments.html
     *
     * @param id - Identifier for the id.
     * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
     * @param 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()
     */
    onExperiment(id, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:fis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:experiment/${id}`);
    }
    /**
     * Adds a resource of type experiment-template to the statement
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/working-with-templates.html
     *
     * @param id - Identifier for the id.
     * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
     * @param 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()
     */
    onExperimentTemplate(id, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:fis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:experiment-template/${id}`);
    }
    /**
     * Adds a resource of type safety-lever to the statement
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/safety-lever.html
     *
     * @param id - Identifier for the id.
     * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
     * @param 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.
     */
    onSafetyLever(id, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:fis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:safety-lever/${id}`);
    }
    /**
     * 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:
     * - .toCreateExperimentTemplate()
     * - .toStartExperiment()
     * - .toTagResource()
     * - .toUpdateExperimentTemplate()
     *
     * @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:
     * - .toGetAction()
     * - .toGetExperiment()
     * - .toGetExperimentTemplate()
     *
     * Applies to resource types:
     * - action
     * - experiment
     * - experiment-template
     *
     * @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:
     * - .toCreateExperimentTemplate()
     * - .toStartExperiment()
     * - .toTagResource()
     * - .toUntagResource()
     * - .toUpdateExperimentTemplate()
     *
     * @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 list of operations on the AWS service that is being affected by the AWS FIS action
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/security_iam_service-with-iam.html
     *
     * Applies to actions:
     * - .toInjectApiInternalError()
     * - .toInjectApiThrottleError()
     * - .toInjectApiUnavailableError()
     *
     * @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`
     */
    ifOperations(value, operator) {
        return this.if(`Operations`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the percentage of calls being affected by the AWS FIS action
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/security_iam_service-with-iam.html
     *
     * Applies to actions:
     * - .toInjectApiInternalError()
     * - .toInjectApiThrottleError()
     * - .toInjectApiUnavailableError()
     *
     * @param value The value(s) to check
     * @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
     */
    ifPercentage(value, operator) {
        return this.if(`Percentage`, value, operator ?? 'NumericEquals');
    }
    /**
     * Filters access by the AWS service that is being affected by the AWS FIS action
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/security_iam_service-with-iam.html
     *
     * Applies to actions:
     * - .toInjectApiInternalError()
     * - .toInjectApiThrottleError()
     * - .toInjectApiUnavailableError()
     *
     * @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`
     */
    ifService(value, operator) {
        return this.if(`Service`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the list of resource ARNs being targeted by the AWS FIS action
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/security_iam_service-with-iam.html
     *
     * Applies to actions:
     * - .toInjectApiInternalError()
     * - .toInjectApiThrottleError()
     * - .toInjectApiUnavailableError()
     *
     * @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`
     */
    ifTargets(value, operator) {
        return this.if(`Targets`, value, operator ?? 'StringLike');
    }
}
exports.Fis = Fis;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmF1bHRpbmplY3Rpb25zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZmF1bHRpbmplY3Rpb25zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUV6RDs7OztHQUlHO0FBQ0gsTUFBYSxHQUFJLFNBQVEsd0JBQWU7SUFHdEM7Ozs7T0FJRztJQUNILFlBQVksR0FBWTtRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFSTixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQTJYbkIsb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLDBCQUEwQjtnQkFDMUIsa0NBQWtDO2dCQUNsQywwQkFBMEI7Z0JBQzFCLGtDQUFrQztnQkFDbEMsd0JBQXdCO2dCQUN4Qix3QkFBd0I7Z0JBQ3hCLDJCQUEyQjtnQkFDM0IsaUJBQWlCO2dCQUNqQixnQkFBZ0I7Z0JBQ2hCLDBCQUEwQjtnQkFDMUIsd0JBQXdCO2dCQUN4QixrQ0FBa0M7YUFDbkM7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osV0FBVztnQkFDWCxlQUFlO2dCQUNmLHlDQUF5QztnQkFDekMsdUJBQXVCO2dCQUN2QixnQkFBZ0I7Z0JBQ2hCLCtCQUErQjtnQkFDL0IsdUJBQXVCO2dCQUN2QixxQkFBcUI7YUFDdEI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osYUFBYTtnQkFDYiwrQkFBK0I7Z0JBQy9CLDJDQUEyQztnQkFDM0MseUJBQXlCO2dCQUN6QixpQkFBaUI7Z0JBQ2pCLGlDQUFpQztnQkFDakMseUJBQXlCO2FBQzFCO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLGFBQWE7Z0JBQ2IsZUFBZTthQUNoQjtTQUNGLENBQUM7SUF4WkYsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSwwQkFBMEI7UUFDL0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGtDQUFrQztRQUN2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QyxtQkFBb0IsTUFBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSSxZQUFZLENBQUMsS0FBd0IsRUFBRSxRQUE0QjtRQUN4RSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLFlBQVksQ0FBQyxLQUF3QixFQUFFLFFBQTRCO1FBQ3hFLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksWUFBWSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDeEUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLGVBQWUsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxTQUFTLENBQUMsS0FBd0IsRUFBRSxRQUE0QjtRQUNyRSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLFNBQVMsQ0FBQyxLQUF3QixFQUFFLFFBQTRCO1FBQ3JFLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUM3RCxDQUFDO0NBQ0Y7QUFybUJELGtCQXFtQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbZmlzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NmYXVsdGluamVjdGlvbnNlcnZpY2UuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGaXMgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdmaXMnO1xuXG4gIC8qKlxuICAgKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW2Zpc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzZmF1bHRpbmplY3Rpb25zZXJ2aWNlLmh0bWwpLlxuICAgKlxuICAgKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNpZD86IHN0cmluZykge1xuICAgIHN1cGVyKHNpZCk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGFuIEFXUyBGSVMgZXhwZXJpbWVudCB0ZW1wbGF0ZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlRXhwZXJpbWVudFRlbXBsYXRlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUV4cGVyaW1lbnRUZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlRXhwZXJpbWVudFRlbXBsYXRlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGFuIEFXUyBGSVMgdGFyZ2V0IGFjY291bnQgY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlVGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlVGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHRoZSBBV1MgRklTIGV4cGVyaW1lbnQgdGVtcGxhdGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUV4cGVyaW1lbnRUZW1wbGF0ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVFeHBlcmltZW50VGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUV4cGVyaW1lbnRUZW1wbGF0ZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhbiBBV1MgRklTIHRhcmdldCBhY2NvdW50IGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGFuIEFXUyBGSVMgYWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRBY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0QWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSBhbiBBV1MgRklTIGV4cGVyaW1lbnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldEV4cGVyaW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0RXhwZXJpbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0RXhwZXJpbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGFuIEFXUyBGSVMgdGFyZ2V0IGFjY291bnQgY29uZmlndXJhdGlvbiBmb3IgYW4gQVdTIEZJUyBleHBlcmltZW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldEV4cGVyaW1lbnRUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRFeHBlcmltZW50VGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEV4cGVyaW1lbnRUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGFuIEFXUyBGSVMgRXhwZXJpbWVudCBUZW1wbGF0ZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0RXhwZXJpbWVudFRlbXBsYXRlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEV4cGVyaW1lbnRUZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0RXhwZXJpbWVudFRlbXBsYXRlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IHRoZSBzYWZldHkgbGV2ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0U2FmZXR5TGV2ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0U2FmZXR5TGV2ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFNhZmV0eUxldmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgYW4gQVdTIEZJUyB0YXJnZXQgYWNjb3VudCBjb25maWd1cmF0aW9uIGZvciBhbiBBV1MgRklTIGV4cGVyaW1lbnQgdGVtcGxhdGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0VGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0VGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UgdHlwZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRUYXJnZXRSZXNvdXJjZVR5cGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0VGFyZ2V0UmVzb3VyY2VUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRUYXJnZXRSZXNvdXJjZVR5cGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbmplY3QgYW4gQVBJIGludGVybmFsIGVycm9yIG9uIHRoZSBwcm92aWRlZCBBV1Mgc2VydmljZSBmcm9tIGFuIEZJUyBFeHBlcmltZW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZTZXJ2aWNlKClcbiAgICogLSAuaWZPcGVyYXRpb25zKClcbiAgICogLSAuaWZQZXJjZW50YWdlKClcbiAgICogLSAuaWZUYXJnZXRzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sI2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS1maXNcbiAgICovXG4gIHB1YmxpYyB0b0luamVjdEFwaUludGVybmFsRXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0luamVjdEFwaUludGVybmFsRXJyb3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbmplY3QgYW4gQVBJIHRocm90dGxlIGVycm9yIG9uIHRoZSBwcm92aWRlZCBBV1Mgc2VydmljZSBmcm9tIGFuIEZJUyBFeHBlcmltZW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZTZXJ2aWNlKClcbiAgICogLSAuaWZPcGVyYXRpb25zKClcbiAgICogLSAuaWZQZXJjZW50YWdlKClcbiAgICogLSAuaWZUYXJnZXRzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sI2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS1maXNcbiAgICovXG4gIHB1YmxpYyB0b0luamVjdEFwaVRocm90dGxlRXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0luamVjdEFwaVRocm90dGxlRXJyb3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbmplY3QgYW4gQVBJIHVuYXZhaWxhYmxlIGVycm9yIG9uIHRoZSBwcm92aWRlZCBBV1Mgc2VydmljZSBmcm9tIGFuIEZJUyBFeHBlcmltZW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZTZXJ2aWNlKClcbiAgICogLSAuaWZPcGVyYXRpb25zKClcbiAgICogLSAuaWZQZXJjZW50YWdlKClcbiAgICogLSAuaWZUYXJnZXRzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sI2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS1maXNcbiAgICovXG4gIHB1YmxpYyB0b0luamVjdEFwaVVuYXZhaWxhYmxlRXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0luamVjdEFwaVVuYXZhaWxhYmxlRXJyb3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBhdmFpbGFibGUgQVdTIEZJUyBhY3Rpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RBY3Rpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RBY3Rpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0QWN0aW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgcmVzb2x2ZWQgdGFyZ2V0cyBmb3IgQVdTIEZJUyBleHBlcmltZW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0RXhwZXJpbWVudFJlc29sdmVkVGFyZ2V0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0RXhwZXJpbWVudFJlc29sdmVkVGFyZ2V0cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEV4cGVyaW1lbnRSZXNvbHZlZFRhcmdldHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRhcmdldCBhY2NvdW50IGNvbmZpZ3VyYXRpb25zIGZvciBBV1MgRklTIGV4cGVyaW1lbnRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RFeHBlcmltZW50VGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RFeHBlcmltZW50VGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RXhwZXJpbWVudFRhcmdldEFjY291bnRDb25maWd1cmF0aW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYWxsIGF2YWlsYWJsZSBBV1MgRklTIGV4cGVyaW1lbnQgdGVtcGxhdGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RFeHBlcmltZW50VGVtcGxhdGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RFeHBlcmltZW50VGVtcGxhdGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RXhwZXJpbWVudFRlbXBsYXRlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYWxsIGF2YWlsYWJsZSBBV1MgRklTIGV4cGVyaW1lbnRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RFeHBlcmltZW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0RXhwZXJpbWVudHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RFeHBlcmltZW50cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIHRhZ3MgZm9yIGFuIEFXUyBGSVMgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFnc0ZvclJlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0YXJnZXQgYWNjb3VudCBjb25maWd1cmF0aW9ucyBmb3IgQVdTIEZJUyBleHBlcmltZW50IHRlbXBsYXRlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSByZXNvdXJjZSB0eXBlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFyZ2V0UmVzb3VyY2VUeXBlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFyZ2V0UmVzb3VyY2VUeXBlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhcmdldFJlc291cmNlVHlwZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBydW4gYW4gQVdTIEZJUyBleHBlcmltZW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3RhcnRFeHBlcmltZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0YXJ0RXhwZXJpbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU3RhcnRFeHBlcmltZW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc3RvcCBhbiBBV1MgRklTIGV4cGVyaW1lbnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1N0b3BFeHBlcmltZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0b3BFeHBlcmltZW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdG9wRXhwZXJpbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRhZyBBV1MgRklTIHJlc291cmNlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1bnRhZyBBV1MgRklTIHJlc291cmNlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIHNwZWNpZmllZCBBV1MgRklTIGV4cGVyaW1lbnQgdGVtcGxhdGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUV4cGVyaW1lbnRUZW1wbGF0ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVFeHBlcmltZW50VGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUV4cGVyaW1lbnRUZW1wbGF0ZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgc3RhdGUgb2YgdGhlIHNhZmV0eSBsZXZlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlU2FmZXR5TGV2ZXJTdGF0ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVTYWZldHlMZXZlclN0YXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVTYWZldHlMZXZlclN0YXRlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGFuIEFXUyBGSVMgdGFyZ2V0IGFjY291bnQgY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlVGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlVGFyZ2V0QWNjb3VudENvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdDcmVhdGVFeHBlcmltZW50VGVtcGxhdGUnLFxuICAgICAgJ0NyZWF0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJyxcbiAgICAgICdEZWxldGVFeHBlcmltZW50VGVtcGxhdGUnLFxuICAgICAgJ0RlbGV0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJyxcbiAgICAgICdJbmplY3RBcGlJbnRlcm5hbEVycm9yJyxcbiAgICAgICdJbmplY3RBcGlUaHJvdHRsZUVycm9yJyxcbiAgICAgICdJbmplY3RBcGlVbmF2YWlsYWJsZUVycm9yJyxcbiAgICAgICdTdGFydEV4cGVyaW1lbnQnLFxuICAgICAgJ1N0b3BFeHBlcmltZW50JyxcbiAgICAgICdVcGRhdGVFeHBlcmltZW50VGVtcGxhdGUnLFxuICAgICAgJ1VwZGF0ZVNhZmV0eUxldmVyU3RhdGUnLFxuICAgICAgJ1VwZGF0ZVRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJ1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0dldEFjdGlvbicsXG4gICAgICAnR2V0RXhwZXJpbWVudCcsXG4gICAgICAnR2V0RXhwZXJpbWVudFRhcmdldEFjY291bnRDb25maWd1cmF0aW9uJyxcbiAgICAgICdHZXRFeHBlcmltZW50VGVtcGxhdGUnLFxuICAgICAgJ0dldFNhZmV0eUxldmVyJyxcbiAgICAgICdHZXRUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbicsXG4gICAgICAnR2V0VGFyZ2V0UmVzb3VyY2VUeXBlJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0xpc3RBY3Rpb25zJyxcbiAgICAgICdMaXN0RXhwZXJpbWVudFJlc29sdmVkVGFyZ2V0cycsXG4gICAgICAnTGlzdEV4cGVyaW1lbnRUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbnMnLFxuICAgICAgJ0xpc3RFeHBlcmltZW50VGVtcGxhdGVzJyxcbiAgICAgICdMaXN0RXhwZXJpbWVudHMnLFxuICAgICAgJ0xpc3RUYXJnZXRBY2NvdW50Q29uZmlndXJhdGlvbnMnLFxuICAgICAgJ0xpc3RUYXJnZXRSZXNvdXJjZVR5cGVzJ1xuICAgIF0sXG4gICAgVGFnZ2luZzogW1xuICAgICAgJ1RhZ1Jlc291cmNlJyxcbiAgICAgICdVbnRhZ1Jlc291cmNlJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgYWN0aW9uIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2FjdGlvbnMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBJZGVudGlmaWVyIGZvciB0aGUgaWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkFjdGlvbihpZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmZpczokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06YWN0aW9uLyR7IGlkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBleHBlcmltZW50IHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2V4cGVyaW1lbnRzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSWRlbnRpZmllciBmb3IgdGhlIGlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25FeHBlcmltZW50KGlkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06ZmlzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpleHBlcmltZW50LyR7IGlkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBleHBlcmltZW50LXRlbXBsYXRlIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL3dvcmtpbmctd2l0aC10ZW1wbGF0ZXMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBJZGVudGlmaWVyIGZvciB0aGUgaWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkV4cGVyaW1lbnRUZW1wbGF0ZShpZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmZpczokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06ZXhwZXJpbWVudC10ZW1wbGF0ZS8keyBpZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgc2FmZXR5LWxldmVyIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL3NhZmV0eS1sZXZlci5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBpZCAtIElkZW50aWZpZXIgZm9yIHRoZSBpZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqL1xuICBwdWJsaWMgb25TYWZldHlMZXZlcihpZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmZpczokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06c2FmZXR5LWxldmVyLyR7IGlkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIHRhZyBrZXkgYW5kIHZhbHVlIHBhaXIgdGhhdCBpcyBhbGxvd2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVFeHBlcmltZW50VGVtcGxhdGUoKVxuICAgKiAtIC50b1N0YXJ0RXhwZXJpbWVudCgpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKiAtIC50b1VwZGF0ZUV4cGVyaW1lbnRUZW1wbGF0ZSgpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIHRhZyBrZXkgYW5kIHZhbHVlIHBhaXIgb2YgYSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVzb3VyY2V0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0dldEFjdGlvbigpXG4gICAqIC0gLnRvR2V0RXhwZXJpbWVudCgpXG4gICAqIC0gLnRvR2V0RXhwZXJpbWVudFRlbXBsYXRlKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBhY3Rpb25cbiAgICogLSBleHBlcmltZW50XG4gICAqIC0gZXhwZXJpbWVudC10ZW1wbGF0ZVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVzb3VyY2VUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVzb3VyY2VUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBhIGxpc3Qgb2YgdGFnIGtleXMgdGhhdCBhcmUgYWxsb3dlZCBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtdGFna2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlRXhwZXJpbWVudFRlbXBsYXRlKClcbiAgICogLSAudG9TdGFydEV4cGVyaW1lbnQoKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICogLSAudG9VbnRhZ1Jlc291cmNlKClcbiAgICogLSAudG9VcGRhdGVFeHBlcmltZW50VGVtcGxhdGUoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1RhZ0tleXModmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpUYWdLZXlzYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIGxpc3Qgb2Ygb3BlcmF0aW9ucyBvbiB0aGUgQVdTIHNlcnZpY2UgdGhhdCBpcyBiZWluZyBhZmZlY3RlZCBieSB0aGUgQVdTIEZJUyBhY3Rpb25cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLmh0bWxcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0luamVjdEFwaUludGVybmFsRXJyb3IoKVxuICAgKiAtIC50b0luamVjdEFwaVRocm90dGxlRXJyb3IoKVxuICAgKiAtIC50b0luamVjdEFwaVVuYXZhaWxhYmxlRXJyb3IoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZk9wZXJhdGlvbnModmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYE9wZXJhdGlvbnNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcGVyY2VudGFnZSBvZiBjYWxscyBiZWluZyBhZmZlY3RlZCBieSB0aGUgQVdTIEZJUyBhY3Rpb25cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLmh0bWxcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0luamVjdEFwaUludGVybmFsRXJyb3IoKVxuICAgKiAtIC50b0luamVjdEFwaVRocm90dGxlRXJyb3IoKVxuICAgKiAtIC50b0luamVjdEFwaVVuYXZhaWxhYmxlRXJyb3IoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtudW1lcmljIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19OdW1lcmljKS4gKipEZWZhdWx0OioqIGBOdW1lcmljRXF1YWxzYFxuICAgKi9cbiAgcHVibGljIGlmUGVyY2VudGFnZSh2YWx1ZTogbnVtYmVyIHwgbnVtYmVyW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgUGVyY2VudGFnZWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnTnVtZXJpY0VxdWFscycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBBV1Mgc2VydmljZSB0aGF0IGlzIGJlaW5nIGFmZmVjdGVkIGJ5IHRoZSBBV1MgRklTIGFjdGlvblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC91c2VyZ3VpZGUvc2VjdXJpdHlfaWFtX3NlcnZpY2Utd2l0aC1pYW0uaHRtbFxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvSW5qZWN0QXBpSW50ZXJuYWxFcnJvcigpXG4gICAqIC0gLnRvSW5qZWN0QXBpVGhyb3R0bGVFcnJvcigpXG4gICAqIC0gLnRvSW5qZWN0QXBpVW5hdmFpbGFibGVFcnJvcigpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmU2VydmljZSh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgU2VydmljZWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBsaXN0IG9mIHJlc291cmNlIEFSTnMgYmVpbmcgdGFyZ2V0ZWQgYnkgdGhlIEFXUyBGSVMgYWN0aW9uXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L3VzZXJndWlkZS9zZWN1cml0eV9pYW1fc2VydmljZS13aXRoLWlhbS5odG1sXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9JbmplY3RBcGlJbnRlcm5hbEVycm9yKClcbiAgICogLSAudG9JbmplY3RBcGlUaHJvdHRsZUVycm9yKClcbiAgICogLSAudG9JbmplY3RBcGlVbmF2YWlsYWJsZUVycm9yKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZUYXJnZXRzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBUYXJnZXRzYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cbn1cbiJdfQ==