UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

660 lines 64.5 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Kinesis = void 0;
const shared_1 = require("../../shared");
/**
 * Statement provider for service [kinesis](https://docs.aws.amazon.com/service-authorization/latest/reference/list_kinesis.html).
 *
 * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
 */
class Kinesis extends shared_1.PolicyStatement {
    /**
     * Grants permission to add or update tags for the specified Amazon Kinesis stream. Each stream can have up to 50 tags
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_AddTagsToStream.html
     */
    toAddTagsToStream() {
        return this.to('AddTagsToStream');
    }
    /**
     * Grants permission to create a Amazon Kinesis stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_CreateStream.html
     */
    toCreateStream() {
        return this.to('CreateStream');
    }
    /**
     * Grants permission to decrease the stream's retention period, which is the length of time data records are accessible after they are added to the stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DecreaseStreamRetentionPeriod.html
     */
    toDecreaseStreamRetentionPeriod() {
        return this.to('DecreaseStreamRetentionPeriod');
    }
    /**
     * Grants permission to delete a resource policy associated with a specified stream or consumer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeleteResourcePolicy.html
     */
    toDeleteResourcePolicy() {
        return this.to('DeleteResourcePolicy');
    }
    /**
     * Grants permission to delete a stream and all its shards and data
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeleteStream.html
     */
    toDeleteStream() {
        return this.to('DeleteStream');
    }
    /**
     * Grants permission to deregister a stream consumer with a Kinesis data stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeregisterStreamConsumer.html
     */
    toDeregisterStreamConsumer() {
        return this.to('DeregisterStreamConsumer');
    }
    /**
     * Grants permission to describe the account-level settings for Amazon Kinesis Data Streams
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeAccountSettings.html
     */
    toDescribeAccountSettings() {
        return this.to('DescribeAccountSettings');
    }
    /**
     * Grants permission to describe the shard limits and usage for the account
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeLimits.html
     */
    toDescribeLimits() {
        return this.to('DescribeLimits');
    }
    /**
     * Grants permission to describe the specified stream
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStream.html
     */
    toDescribeStream() {
        return this.to('DescribeStream');
    }
    /**
     * Grants permission to get the description of a registered stream consumer
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStreamConsumer.html
     */
    toDescribeStreamConsumer() {
        return this.to('DescribeStreamConsumer');
    }
    /**
     * Grants permission to provide a summarized description of the specified Kinesis data stream without the shard list
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStreamSummary.html
     */
    toDescribeStreamSummary() {
        return this.to('DescribeStreamSummary');
    }
    /**
     * Grants permission to disables enhanced monitoring
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DisableEnhancedMonitoring.html
     */
    toDisableEnhancedMonitoring() {
        return this.to('DisableEnhancedMonitoring');
    }
    /**
     * Grants permission to enable enhanced Kinesis data stream monitoring for shard-level metrics
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_EnableEnhancedMonitoring.html
     */
    toEnableEnhancedMonitoring() {
        return this.to('EnableEnhancedMonitoring');
    }
    /**
     * Grants permission to get data records from a shard
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html
     */
    toGetRecords() {
        return this.to('GetRecords');
    }
    /**
     * Grants permission to get a resource policy associated with a specified stream or consumer
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetResourcePolicy.html
     */
    toGetResourcePolicy() {
        return this.to('GetResourcePolicy');
    }
    /**
     * Grants permission to get a shard iterator. A shard iterator expires five minutes after it is returned to the requester
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetShardIterator.html
     */
    toGetShardIterator() {
        return this.to('GetShardIterator');
    }
    /**
     * Grants permission to increase the stream's retention period, which is the length of time data records are accessible after they are added to the stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_IncreaseStreamRetentionPeriod.html
     */
    toIncreaseStreamRetentionPeriod() {
        return this.to('IncreaseStreamRetentionPeriod');
    }
    /**
     * Grants permission to list the shards in a stream and provides information about each shard
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListShards.html
     */
    toListShards() {
        return this.to('ListShards');
    }
    /**
     * Grants permission to list the stream consumers registered to receive data from a Kinesis stream using enhanced fan-out, and provides information about each consumer
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListStreamConsumers.html
     */
    toListStreamConsumers() {
        return this.to('ListStreamConsumers');
    }
    /**
     * Grants permission to list your streams
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListStreams.html
     */
    toListStreams() {
        return this.to('ListStreams');
    }
    /**
     * Grants permission to list the tags for the specified Amazon Kinesis resource
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListTagsForResource.html
     */
    toListTagsForResource() {
        return this.to('ListTagsForResource');
    }
    /**
     * Grants permission to list the tags for the specified Amazon Kinesis stream
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListTagsForStream.html
     */
    toListTagsForStream() {
        return this.to('ListTagsForStream');
    }
    /**
     * Grants permission to merge two adjacent shards in a stream and combines them into a single shard to reduce the stream's capacity to ingest and transport data
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_MergeShards.html
     */
    toMergeShards() {
        return this.to('MergeShards');
    }
    /**
     * Grants permission to write a single data record from a producer into an Amazon Kinesis stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html
     */
    toPutRecord() {
        return this.to('PutRecord');
    }
    /**
     * Grants permission to write multiple data records from a producer into an Amazon Kinesis stream in a single call (also referred to as a PutRecords request)
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html
     */
    toPutRecords() {
        return this.to('PutRecords');
    }
    /**
     * Grants permission to attach a resource policy to a specified stream or consumer
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutResourcePolicy.html
     */
    toPutResourcePolicy() {
        return this.to('PutResourcePolicy');
    }
    /**
     * Grants permission to register a stream consumer with a Kinesis data stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RegisterStreamConsumer.html
     */
    toRegisterStreamConsumer() {
        return this.to('RegisterStreamConsumer');
    }
    /**
     * Grants permission to remove tags from the specified Kinesis data stream. Removed tags are deleted and cannot be recovered after this operation successfully completes
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RemoveTagsFromStream.html
     */
    toRemoveTagsFromStream() {
        return this.to('RemoveTagsFromStream');
    }
    /**
     * Grants permission to split a shard into two new shards in the Kinesis data stream, to increase the stream's capacity to ingest and transport data
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SplitShard.html
     */
    toSplitShard() {
        return this.to('SplitShard');
    }
    /**
     * Grants permission to enable or update server-side encryption using an AWS KMS key for a specified stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_StartStreamEncryption.html
     */
    toStartStreamEncryption() {
        return this.to('StartStreamEncryption');
    }
    /**
     * Grants permission to disable server-side encryption for a specified stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_StopStreamEncryption.html
     */
    toStopStreamEncryption() {
        return this.to('StopStreamEncryption');
    }
    /**
     * Grants permission to listen to a specific shard with enhanced fan-out
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SubscribeToShard.html
     */
    toSubscribeToShard() {
        return this.to('SubscribeToShard');
    }
    /**
     * Grants permission to add or update tags for the specified Amazon Kinesis resource. Each resource can have up to 50 tags
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_TagResource.html
     */
    toTagResource() {
        return this.to('TagResource');
    }
    /**
     * Grants permission to remove tags from the specified Kinesis data resource. Removed tags are deleted and cannot be recovered after this operation successfully completes
     *
     * Access Level: Tagging, Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UntagResource.html
     */
    toUntagResource() {
        return this.to('UntagResource');
    }
    /**
     * Grants permission to update the account-level settings for Amazon Kinesis Data Streams
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateAccountSettings.html
     */
    toUpdateAccountSettings() {
        return this.to('UpdateAccountSettings');
    }
    /**
     * Grants permission to update the maximum record size for a Kinesis data stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateMaxRecordSize.html
     */
    toUpdateMaxRecordSize() {
        return this.to('UpdateMaxRecordSize');
    }
    /**
     * Grants permission to update the shard count of the specified stream to the specified number of shards
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateShardCount.html
     */
    toUpdateShardCount() {
        return this.to('UpdateShardCount');
    }
    /**
     * Grants permission to update the capacity mode of the data stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateStreamMode.html
     */
    toUpdateStreamMode() {
        return this.to('UpdateStreamMode');
    }
    /**
     * Grants permission to update the warm throughput for a Kinesis on-demand data stream
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateStreamWarmThroughput.html
     */
    toUpdateStreamWarmThroughput() {
        return this.to('UpdateStreamWarmThroughput');
    }
    /**
     * Grants permission to temporarily inject errors for target API requests
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifFisActionId()
     * - .ifFisInjectPercentage()
     * - .ifFisTargetArns()
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
     */
    toInjectApiError() {
        return this.to('InjectApiError');
    }
    /**
     * Adds a resource of type consumer to the statement
     *
     * https://docs.aws.amazon.com/streams/latest/dev/key-concepts.html#enabled-application
     *
     * @param streamType - Identifier for the streamType.
     * @param streamName - Identifier for the streamName.
     * @param consumerName - Identifier for the consumerName.
     * @param consumerCreationTimpstamp - Identifier for the consumerCreationTimpstamp.
     * @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()
     */
    onConsumer(streamType, streamName, consumerName, consumerCreationTimpstamp, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:kinesis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:${streamType}/${streamName}/consumer/${consumerName}:${consumerCreationTimpstamp}`);
    }
    /**
     * Adds a resource of type kmsKey to the statement
     *
     * https://docs.aws.amazon.com/streams/latest/dev/server-side-encryption.html
     *
     * @param keyId - Identifier for the keyId.
     * @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()
     */
    onKmsKey(keyId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:kms:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:key/${keyId}`);
    }
    /**
     * Adds a resource of type stream to the statement
     *
     * https://docs.aws.amazon.com/streams/latest/dev/key-concepts.html#stream
     *
     * @param streamName - Identifier for the streamName.
     * @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()
     */
    onStream(streamName, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:kinesis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:stream/${streamName}`);
    }
    /**
     * Filters access by the presence of tag key-value pairs in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
     *
     * Applies to actions:
     * - .toAddTagsToStream()
     * - .toCreateStream()
     * - .toRegisterStreamConsumer()
     * - .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 access by tag key-value pairs attached to the resource
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
     *
     * Applies to actions:
     * - .toAddTagsToStream()
     * - .toCreateStream()
     * - .toDecreaseStreamRetentionPeriod()
     * - .toDeleteResourcePolicy()
     * - .toDeleteStream()
     * - .toDeregisterStreamConsumer()
     * - .toDescribeStream()
     * - .toDescribeStreamConsumer()
     * - .toDescribeStreamSummary()
     * - .toGetRecords()
     * - .toGetResourcePolicy()
     * - .toGetShardIterator()
     * - .toIncreaseStreamRetentionPeriod()
     * - .toListShards()
     * - .toListStreamConsumers()
     * - .toListTagsForResource()
     * - .toListTagsForStream()
     * - .toMergeShards()
     * - .toPutRecord()
     * - .toPutRecords()
     * - .toPutResourcePolicy()
     * - .toRegisterStreamConsumer()
     * - .toRemoveTagsFromStream()
     * - .toSplitShard()
     * - .toStartStreamEncryption()
     * - .toStopStreamEncryption()
     * - .toSubscribeToShard()
     * - .toTagResource()
     * - .toUntagResource()
     * - .toUpdateMaxRecordSize()
     * - .toUpdateStreamWarmThroughput()
     *
     * Applies to resource types:
     * - consumer
     * - kmsKey
     * - stream
     *
     * @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 the presence of tag keys in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
     *
     * Applies to actions:
     * - .toAddTagsToStream()
     * - .toCreateStream()
     * - .toRegisterStreamConsumer()
     * - .toRemoveTagsFromStream()
     * - .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');
    }
    /**
     * Filters access by the ID of an AWS FIS action
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
     *
     * Applies to actions:
     * - .toInjectApiError()
     *
     * @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`
     */
    ifFisActionId(value, operator) {
        return this.if(`FisActionId`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by the percentage of calls being affected by an AWS FIS action
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
     *
     * Applies to actions:
     * - .toInjectApiError()
     *
     * @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`
     */
    ifFisInjectPercentage(value, operator) {
        return this.if(`FisInjectPercentage`, value, operator ?? 'NumericEquals');
    }
    /**
     * Filters access by the ARN of an AWS FIS target
     *
     * https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
     *
     * Applies to actions:
     * - .toInjectApiError()
     *
     * @param value The value(s) to check
     * @param operator Works with [arn operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN). **Default:** `ArnLike`
     */
    ifFisTargetArns(value, operator) {
        return this.if(`FisTargetArns`, value, operator ?? 'ArnLike');
    }
    /**
     * Statement provider for service [kinesis](https://docs.aws.amazon.com/service-authorization/latest/reference/list_kinesis.html).
     *
     */
    constructor(props) {
        super(props);
        this.servicePrefix = 'kinesis';
        this.accessLevelList = {
            Tagging: [
                'AddTagsToStream',
                'RemoveTagsFromStream',
                'TagResource',
                'UntagResource'
            ],
            Write: [
                'AddTagsToStream',
                'CreateStream',
                'DecreaseStreamRetentionPeriod',
                'DeleteResourcePolicy',
                'DeleteStream',
                'DeregisterStreamConsumer',
                'DisableEnhancedMonitoring',
                'EnableEnhancedMonitoring',
                'IncreaseStreamRetentionPeriod',
                'MergeShards',
                'PutRecord',
                'PutRecords',
                'PutResourcePolicy',
                'RegisterStreamConsumer',
                'RemoveTagsFromStream',
                'SplitShard',
                'StartStreamEncryption',
                'StopStreamEncryption',
                'TagResource',
                'UntagResource',
                'UpdateAccountSettings',
                'UpdateMaxRecordSize',
                'UpdateShardCount',
                'UpdateStreamMode',
                'UpdateStreamWarmThroughput',
                'InjectApiError'
            ],
            Read: [
                'DescribeAccountSettings',
                'DescribeLimits',
                'DescribeStream',
                'DescribeStreamConsumer',
                'DescribeStreamSummary',
                'GetRecords',
                'GetResourcePolicy',
                'GetShardIterator',
                'ListTagsForResource',
                'ListTagsForStream',
                'SubscribeToShard'
            ],
            List: [
                'ListShards',
                'ListStreamConsumers',
                'ListStreams'
            ]
        };
    }
}
exports.Kinesis = Kinesis;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2luZXNpcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImtpbmVzaXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBR3pEOzs7O0dBSUc7QUFDSCxNQUFhLE9BQVEsU0FBUSx3QkFBZTtJQUcxQzs7Ozs7O09BTUc7SUFDSSxpQkFBaUI7UUFDdEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGNBQWM7UUFDbkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSwrQkFBK0I7UUFDcEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLCtCQUErQixDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHNCQUFzQjtRQUMzQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksY0FBYztRQUNuQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLDBCQUEwQjtRQUMvQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsMEJBQTBCLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0kseUJBQXlCO1FBQzlCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxnQkFBZ0I7UUFDckIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENB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QixhQUFhO2dCQUNiLGVBQWU7YUFDaEI7WUFDRCxLQUFLLEVBQUU7Z0JBQ0wsaUJBQWlCO2dCQUNqQixjQUFjO2dCQUNkLCtCQUErQjtnQkFDL0Isc0JBQXNCO2dCQUN0QixjQUFjO2dCQUNkLDBCQUEwQjtnQkFDMUIsMkJBQTJCO2dCQUMzQiwwQkFBMEI7Z0JBQzFCLCtCQUErQjtnQkFDL0IsYUFBYTtnQkFDYixXQUFXO2dCQUNYLFlBQVk7Z0JBQ1osbUJBQW1CO2dCQUNuQix3QkFBd0I7Z0JBQ3hCLHNCQUFzQjtnQkFDdEIsWUFBWTtnQkFDWix1QkFBdUI7Z0JBQ3ZCLHNCQUFzQjtnQkFDdEIsYUFBYTtnQkFDYixlQUFlO2dCQUNmLHVCQUF1QjtnQkFDdkIscUJBQXFCO2dCQUNyQixrQkFBa0I7Z0JBQ2xCLGtCQUFrQjtnQkFDbEIsNEJBQTRCO2dCQUM1QixnQkFBZ0I7YUFDakI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0oseUJBQXlCO2dCQUN6QixnQkFBZ0I7Z0JBQ2hCLGdCQUFnQjtnQkFDaEIsd0JBQXdCO2dCQUN4Qix1QkFBdUI7Z0JBQ3ZCLFlBQVk7Z0JBQ1osbUJBQW1CO2dCQUNuQixrQkFBa0I7Z0JBQ2xCLHFCQUFxQjtnQkFDckIsbUJBQW1CO2dCQUNuQixrQkFBa0I7YUFDbkI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osWUFBWTtnQkFDWixxQkFBcUI7Z0JBQ3JCLGFBQWE7YUFDZDtTQUNGLENBQUM7SUFxTUYsQ0FBQztDQUNGO0FBM3JCRCwwQkEyckJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtraW5lc2lzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9raW5lc2lzLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgS2luZXNpcyBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ2tpbmVzaXMnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgb3IgdXBkYXRlIHRhZ3MgZm9yIHRoZSBzcGVjaWZpZWQgQW1hem9uIEtpbmVzaXMgc3RyZWFtLiBFYWNoIHN0cmVhbSBjYW4gaGF2ZSB1cCB0byA1MCB0YWdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZywgV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQWRkVGFnc1RvU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0FkZFRhZ3NUb1N0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQWRkVGFnc1RvU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgQW1hem9uIEtpbmVzaXMgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVjcmVhc2UgdGhlIHN0cmVhbSdzIHJldGVudGlvbiBwZXJpb2QsIHdoaWNoIGlzIHRoZSBsZW5ndGggb2YgdGltZSBkYXRhIHJlY29yZHMgYXJlIGFjY2Vzc2libGUgYWZ0ZXIgdGhleSBhcmUgYWRkZWQgdG8gdGhlIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWNyZWFzZVN0cmVhbVJldGVudGlvblBlcmlvZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHJlc291cmNlIHBvbGljeSBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgc3RyZWFtIG9yIGNvbnN1bWVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUmVzb3VyY2VQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlUmVzb3VyY2VQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVJlc291cmNlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgc3RyZWFtIGFuZCBhbGwgaXRzIHNoYXJkcyBhbmQgZGF0YVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVN0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTdHJlYW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVN0cmVhbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlcmVnaXN0ZXIgYSBzdHJlYW0gY29uc3VtZXIgd2l0aCBhIEtpbmVzaXMgZGF0YSBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXJlZ2lzdGVyU3RyZWFtQ29uc3VtZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVyZWdpc3RlclN0cmVhbUNvbnN1bWVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXJlZ2lzdGVyU3RyZWFtQ29uc3VtZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgYWNjb3VudC1sZXZlbCBzZXR0aW5ncyBmb3IgQW1hem9uIEtpbmVzaXMgRGF0YSBTdHJlYW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUFjY291bnRTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUFjY291bnRTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBY2NvdW50U2V0dGluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc2hhcmQgbGltaXRzIGFuZCB1c2FnZSBmb3IgdGhlIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTGltaXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTGltaXRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxpbWl0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBzcGVjaWZpZWQgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVN0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTdHJlYW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgdGhlIGRlc2NyaXB0aW9uIG9mIGEgcmVnaXN0ZXJlZCBzdHJlYW0gY29uc3VtZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlU3RyZWFtQ29uc3VtZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTdHJlYW1Db25zdW1lcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTdHJlYW1Db25zdW1lcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHByb3ZpZGUgYSBzdW1tYXJpemVkIGRlc2NyaXB0aW9uIG9mIHRoZSBzcGVjaWZpZWQgS2luZXNpcyBkYXRhIHN0cmVhbSB3aXRob3V0IHRoZSBzaGFyZCBsaXN0XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVN0cmVhbVN1bW1hcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTdHJlYW1TdW1tYXJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVN0cmVhbVN1bW1hcnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNhYmxlcyBlbmhhbmNlZCBtb25pdG9yaW5nXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGlzYWJsZUVuaGFuY2VkTW9uaXRvcmluZy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhYmxlRW5oYW5jZWRNb25pdG9yaW5nKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhYmxlRW5oYW5jZWRNb25pdG9yaW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZW5hYmxlIGVuaGFuY2VkIEtpbmVzaXMgZGF0YSBzdHJlYW0gbW9uaXRvcmluZyBmb3Igc2hhcmQtbGV2ZWwgbWV0cmljc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0VuYWJsZUVuaGFuY2VkTW9uaXRvcmluZy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FbmFibGVFbmhhbmNlZE1vbml0b3JpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0VuYWJsZUVuaGFuY2VkTW9uaXRvcmluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBkYXRhIHJlY29yZHMgZnJvbSBhIHNoYXJkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRSZWNvcmRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFJlY29yZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFJlY29yZHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYSByZXNvdXJjZSBwb2xpY3kgYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWVkIHN0cmVhbSBvciBjb25zdW1lclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0UmVzb3VyY2VQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0UmVzb3VyY2VQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFJlc291cmNlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGEgc2hhcmQgaXRlcmF0b3IuIEEgc2hhcmQgaXRlcmF0b3IgZXhwaXJlcyBmaXZlIG1pbnV0ZXMgYWZ0ZXIgaXQgaXMgcmV0dXJuZWQgdG8gdGhlIHJlcXVlc3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0U2hhcmRJdGVyYXRvci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTaGFyZEl0ZXJhdG9yKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTaGFyZEl0ZXJhdG9yJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW5jcmVhc2UgdGhlIHN0cmVhbSdzIHJldGVudGlvbiBwZXJpb2QsIHdoaWNoIGlzIHRoZSBsZW5ndGggb2YgdGltZSBkYXRhIHJlY29yZHMgYXJlIGFjY2Vzc2libGUgYWZ0ZXIgdGhleSBhcmUgYWRkZWQgdG8gdGhlIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0luY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0luY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdJbmNyZWFzZVN0cmVhbVJldGVudGlvblBlcmlvZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIHNoYXJkcyBpbiBhIHN0cmVhbSBhbmQgcHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgZWFjaCBzaGFyZFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFNoYXJkcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U2hhcmRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0U2hhcmRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgc3RyZWFtIGNvbnN1bWVycyByZWdpc3RlcmVkIHRvIHJlY2VpdmUgZGF0YSBmcm9tIGEgS2luZXNpcyBzdHJlYW0gdXNpbmcgZW5oYW5jZWQgZmFuLW91dCwgYW5kIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggY29uc3VtZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RTdHJlYW1Db25zdW1lcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFN0cmVhbUNvbnN1bWVycygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFN0cmVhbUNvbnN1bWVycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgeW91ciBzdHJlYW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0U3RyZWFtcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U3RyZWFtcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFN0cmVhbXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIEFtYXpvbiBLaW5lc2lzIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIEFtYXpvbiBLaW5lc2lzIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JTdHJlYW0uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JTdHJlYW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbWVyZ2UgdHdvIGFkamFjZW50IHNoYXJkcyBpbiBhIHN0cmVhbSBhbmQgY29tYmluZXMgdGhlbSBpbnRvIGEgc2luZ2xlIHNoYXJkIHRvIHJlZHVjZSB0aGUgc3RyZWFtJ3MgY2FwYWNpdHkgdG8gaW5nZXN0IGFuZCB0cmFuc3BvcnQgZGF0YVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX01lcmdlU2hhcmRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b01lcmdlU2hhcmRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdNZXJnZVNoYXJkcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHdyaXRlIGEgc2luZ2xlIGRhdGEgcmVjb3JkIGZyb20gYSBwcm9kdWNlciBpbnRvIGFuIEFtYXpvbiBLaW5lc2lzIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1B1dFJlY29yZC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRSZWNvcmQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dFJlY29yZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHdyaXRlIG11bHRpcGxlIGRhdGEgcmVjb3JkcyBmcm9tIGEgcHJvZHVjZXIgaW50byBhbiBBbWF6b24gS2luZXNpcyBzdHJlYW0gaW4gYSBzaW5nbGUgY2FsbCAoYWxzbyByZWZlcnJlZCB0byBhcyBhIFB1dFJlY29yZHMgcmVxdWVzdClcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRSZWNvcmRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dFJlY29yZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dFJlY29yZHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdHRhY2ggYSByZXNvdXJjZSBwb2xpY3kgdG8gYSBzcGVjaWZpZWQgc3RyZWFtIG9yIGNvbnN1bWVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0UmVzb3VyY2VQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0UmVzb3VyY2VQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dFJlc291cmNlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVnaXN0ZXIgYSBzdHJlYW0gY29uc3VtZXIgd2l0aCBhIEtpbmVzaXMgZGF0YSBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9SZWdpc3RlclN0cmVhbUNvbnN1bWVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlZ2lzdGVyU3RyZWFtQ29uc3VtZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlZ2lzdGVyU3RyZWFtQ29uc3VtZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGFncyBmcm9tIHRoZSBzcGVjaWZpZWQgS2luZXNpcyBkYXRhIHN0cmVhbS4gUmVtb3ZlZCB0YWdzIGFyZSBkZWxldGVkIGFuZCBjYW5ub3QgYmUgcmVjb3ZlcmVkIGFmdGVyIHRoaXMgb3BlcmF0aW9uIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nLCBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9SZW1vdmVUYWdzRnJvbVN0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZW1vdmVUYWdzRnJvbVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVtb3ZlVGFnc0Zyb21TdHJlYW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzcGxpdCBhIHNoYXJkIGludG8gdHdvIG5ldyBzaGFyZHMgaW4gdGhlIEtpbmVzaXMgZGF0YSBzdHJlYW0sIHRvIGluY3JlYXNlIHRoZSBzdHJlYW0ncyBjYXBhY2l0eSB0byBpbmdlc3QgYW5kIHRyYW5zcG9ydCBkYXRhXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3BsaXRTaGFyZC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TcGxpdFNoYXJkKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTcGxpdFNoYXJkJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZW5hYmxlIG9yIHVwZGF0ZSBzZXJ2ZXItc2lkZSBlbmNyeXB0aW9uIHVzaW5nIGFuIEFXUyBLTVMga2V5IGZvciBhIHNwZWNpZmllZCBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TdGFydFN0cmVhbUVuY3J5cHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU3RhcnRTdHJlYW1FbmNyeXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdGFydFN0cmVhbUVuY3J5cHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNhYmxlIHNlcnZlci1zaWRlIGVuY3J5cHRpb24gZm9yIGEgc3BlY2lmaWVkIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1N0b3BTdHJlYW1FbmNyeXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0b3BTdHJlYW1FbmNyeXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdG9wU3RyZWFtRW5jcnlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3RlbiB0byBhIHNwZWNpZmljIHNoYXJkIHdpdGggZW5oYW5jZWQgZmFuLW91dFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3Vic2NyaWJlVG9TaGFyZC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TdWJzY3JpYmVUb1NoYXJkKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdWJzY3JpYmVUb1NoYXJkJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIG9yIHVwZGF0ZSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIEFtYXpvbiBLaW5lc2lzIHJlc291cmNlLiBFYWNoIHJlc291cmNlIGNhbiBoYXZlIHVwIHRvIDUwIHRhZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nLCBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGFncyBmcm9tIHRoZSBzcGVjaWZpZWQgS2luZXNpcyBkYXRhIHJlc291cmNlLiBSZW1vdmVkIHRhZ3MgYXJlIGRlbGV0ZWQgYW5kIGNhbm5vdCBiZSByZWNvdmVyZWQgYWZ0ZXIgdGhpcyBvcGVyYXRpb24gc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmcsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VudGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVW50YWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVW50YWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgYWNjb3VudC1sZXZlbCBzZXR0aW5ncyBmb3IgQW1hem9uIEtpbmVzaXMgRGF0YSBTdHJlYW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQWNjb3VudFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUFjY291bnRTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlQWNjb3VudFNldHRpbmdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIHRoZSBtYXhpbXVtIHJlY29yZCBzaXplIGZvciBhIEtpbmVzaXMgZGF0YSBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVNYXhSZWNvcmRTaXplLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZU1heFJlY29yZFNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZU1heFJlY29yZFNpemUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIHNoYXJkIGNvdW50IG9mIHRoZSBzcGVjaWZpZWQgc3RyZWFtIHRvIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHNoYXJkc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VwZGF0ZVNoYXJkQ291bnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlU2hhcmRDb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlU2hhcmRDb3VudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgY2FwYWNpdHkgbW9kZSBvZiB0aGUgZGF0YSBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVTdHJlYW1Nb2RlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVN0cmVhbU1vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVN0cmVhbU1vZGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIHdhcm0gdGhyb3VnaHB1dCBmb3IgYSBLaW5lc2lzIG9uLWRlbWFuZCBkYXRhIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VwZGF0ZVN0cmVhbVdhcm1UaHJvdWdocHV0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVN0cmVhbVdhcm1UaHJvdWdocHV0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVTdHJlYW1XYXJtVGhyb3VnaHB1dCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRlbXBvcmFyaWx5IGluamVjdCBlcnJvcnMgZm9yIHRhcmdldCBBUEkgcmVxdWVzdHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkZpc0FjdGlvbklkKClcbiAgICogLSAuaWZGaXNJbmplY3RQZXJjZW50YWdlKClcbiAgICogLSAuaWZGaXNUYXJnZXRBcm5zKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9JbmplY3RBcGlFcnJvcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnSW5qZWN0QXBpRXJyb3InKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBUYWdnaW5nOiBbXG4gICAgICAnQWRkVGFnc1RvU3RyZWFtJyxcbiAgICAgICdSZW1vdmVUYWdzRnJvbVN0cmVhbScsXG4gICAgICAnVGFnUmVzb3VyY2UnLFxuICAgICAgJ1VudGFnUmVzb3VyY2UnXG4gICAgXSxcbiAgICBXcml0ZTogW1xuICAgICAgJ0FkZFRhZ3NUb1N0cmVhbScsXG4gICAgICAnQ3JlYXRlU3RyZWFtJyxcbiAgICAgICdEZWNyZWFzZVN0cmVhbVJldGVudGlvblBlcmlvZCcsXG4gICAgICAnRGVsZXRlUmVzb3VyY2VQb2xpY3knLFxuICAgICAgJ0RlbGV0ZVN0cmVhbScsXG4gICAgICAnRGVyZWdpc3RlclN0cmVhbUNvbnN1bWVyJyxcbiAgICAgICdEaXNhYmxlRW5oYW5jZWRNb25pdG9yaW5nJyxcbiAgICAgICdFbmFibGVFbmhhbmNlZE1vbml0b3JpbmcnLFxuICAgICAgJ0luY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kJyxcbiAgICAgICdNZXJnZVNoYXJkcycsXG4gICAgICAnUHV0UmVjb3JkJyxcbiAgICAgICdQdXRSZWNvcmRzJyxcbiAgICAgICdQdXRSZXNvdXJjZVBvbGljeScsXG4gICAgICAnUmVnaXN0ZXJTdHJlYW1Db25zdW1lcicsXG4gICAgICAnUmVtb3ZlVGFnc0Zyb21TdHJlYW0nLFxuICAgICAgJ1NwbGl0U2hhcmQnLFxuICAgICAgJ1N0YXJ0U3RyZWFtRW5jcnlwdGlvbicsXG4gICAgICAnU3RvcFN0cmVhbUVuY3J5cHRpb24nLFxuICAgICAgJ1RhZ1Jlc291cmNlJyxcbiAgICAgICdVbnRhZ1Jlc291cmNlJyxcbiAgICAgICdVcGRhdGVBY2NvdW50U2V0dGluZ3MnLFxuICAgICAgJ1VwZGF0ZU1heFJlY29yZFNpemUnLFxuICAgICAgJ1VwZGF0ZVNoYXJkQ291bnQnLFxuICAgICAgJ1VwZGF0ZVN0cmVhbU1vZGUnLFxuICAgICAgJ1VwZGF0ZVN0cmVhbVdhcm1UaHJvdWdocHV0JyxcbiAgICAgICdJbmplY3RBcGlFcnJvcidcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdEZXNjcmliZUFjY291bnRTZXR0aW5ncycsXG4gICAgICAnRGVzY3JpYmVMaW1pdHMnLFxuICAgICAgJ0Rlc2NyaWJlU3RyZWFtJyxcbiAgICAgICdEZXNjcmliZVN0cmVhbUNvbnN1bWVyJyxcbiAgICAgICdEZXNjcmliZVN0cmVhbVN1bW1hcnknLFxuICAgICAgJ0dldFJlY29yZHMnLFxuICAgICAgJ0dldFJlc291cmNlUG9saWN5JyxcbiAgICAgICdHZXRTaGFyZEl0ZXJhdG9yJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICdMaXN0VGFnc0ZvclN0cmVhbScsXG4gICAgICAnU3Vic2NyaWJlVG9TaGFyZCdcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdMaXN0U2hhcmRzJyxcbiAgICAgICdMaXN0U3RyZWFtQ29uc3VtZXJzJyxcbiAgICAgICdMaXN0U3RyZWFtcydcbiAgICBdXG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGNvbnN1bWVyIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3N0cmVhbXMvbGF0ZXN0L2Rldi9rZXktY29uY2VwdHMuaHRtbCNlbmFibGVkLWFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBzdHJlYW1UeXBlIC0gSWRlbnRpZmllciBmb3IgdGhlIHN0cmVhbVR5cGUuXG4gICAqIEBwYXJhbSBzdHJlYW1OYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIHN0cmVhbU5hbWUuXG4gICAqIEBwYXJhbSBjb25zdW1lck5hbWUgLSBJZGVudGlmaWVyIGZvciB0aGUgY29uc3VtZXJOYW1lLlxuICAgKiBAcGFyYW0gY29uc3VtZXJDcmVhdGlvblRpbXBzdGFtcCAtIElkZW50aWZpZXIgZm9yIHRoZSBjb25zdW1lckNyZWF0aW9uVGltcHN0YW1wLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25Db25zdW1lcihzdHJlYW1UeXBlOiBzdHJpbmcsIHN0cmVhbU5hbWU6IHN0cmluZywgY29uc3VtZXJOYW1lOiBzdHJpbmcsIGNvbnN1bWVyQ3JlYXRpb25UaW1wc3RhbXA6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpraW5lc2lzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTokeyBzdHJlYW1UeXBlIH0vJHsgc3RyZWFtTmFtZSB9L2NvbnN1bWVyLyR7IGNvbnN1bWVyTmFtZSB9OiR7IGNvbnN1bWVyQ3JlYXRpb25UaW1wc3RhbXAgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGttc0tleSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zdHJlYW1zL2xhdGVzdC9kZXYvc2VydmVyLXNpZGUtZW5jcnlwdGlvbi5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBrZXlJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBrZXlJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uS21zS2V5KGtleUlkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06a21zOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTprZXkvJHsga2V5SWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHN0cmVhbSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zdHJlYW1zL2xhdGVzdC9kZXYva2V5LWNvbmNlcHRzLmh0bWwjc3RyZWFtXG4gICAqXG4gICAqIEBwYXJhbSBzdHJlYW1OYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIHN0cmVhbU5hbWUuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblN0cmVhbShzdHJlYW1OYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06a2luZXNpczokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06c3RyZWFtLyR7IHN0cmVhbU5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0YWcga2V5LXZhbHVlIHBhaXJzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9TdHJlYW0oKVxuICAgKiAtIC50b0NyZWF0ZVN0cmVhbSgpXG4gICAqIC0gLnRvUmVnaXN0ZXJTdHJlYW1Db25zdW1lcigpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVxdWVzdFRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXF1ZXN0VGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGFnIGtleS12YWx1ZSBwYWlycyBhdHRhY2hlZCB0byB0aGUgcmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlc291cmNldGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9TdHJlYW0oKVxuICAgKiAtIC50b0NyZWF0ZVN0cmVhbSgpXG4gICAqIC0gLnRvRGVjcmVhc2VTdHJlYW1SZXRlbnRpb25QZXJpb2QoKVxuICAgKiAtIC50b0RlbGV0ZVJlc291cmNlUG9saWN5KClcbiAgICogLSAudG9EZWxldGVTdHJlYW0oKVxuICAgKiAtIC50b0RlcmVnaXN0ZXJTdHJlYW1Db25zdW1lcigpXG4gICAqIC0gLnRvRGVzY3JpYmVTdHJlYW0oKVxuICAgKiAtIC50b0Rlc2NyaWJlU3RyZWFtQ29uc3VtZXIoKVxuICAgKiAtIC50b0Rlc2NyaWJlU3RyZWFtU3VtbWFyeSgpXG4gICAqIC0gLnRvR2V0UmVjb3JkcygpXG4gICAqIC0gLnRvR2V0UmVzb3VyY2VQb2xpY3koKVxuICAgKiAtIC50b0dldFNoYXJkSXRlcmF0b3IoKVxuICAgKiAtIC50b0luY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kKClcbiAgICogLSAudG9MaXN0U2hhcmRzKClcbiAgICogLSAudG9MaXN0U3RyZWFtQ29uc3VtZXJzKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclN0cmVhbSgpXG4gICAqIC0gLnRvTWVyZ2VTaGFyZHMoKVxuICAgKiAtIC50b1B1dFJlY29yZCgpXG4gICAqIC0gLnRvUHV0UmVjb3JkcygpXG4gICAqIC0gLnRvUHV0UmVzb3VyY2VQb2xpY3koKVxuICAgKiAtIC50b1JlZ2lzdGVyU3RyZWFtQ29uc3VtZXIoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tU3RyZWFtKClcbiAgICogLSAudG9TcGxpdFNoYXJkKClcbiAgICogLSAudG9TdGFydFN0cmVhbUVuY3J5cHRpb24oKVxuICAgKiAtIC50b1N0b3BTdHJlYW1FbmNyeXB0aW9uKClcbiAgICogLSAudG9TdWJzY3JpYmVUb1NoYXJkKClcbiAgICogLSAudG9UYWdSZXNvdXJjZSgpXG4gICAqIC0gLnRvVW50YWdSZXNvdXJjZSgpXG4gICAqIC0gLnRvVXBkYXRlTWF4UmVjb3JkU2l6ZSgpXG4gICAqIC0gLnRvVXBkYXRlU3RyZWFtV2FybVRocm91Z2hwdXQoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNvbnN1bWVyXG4gICAqIC0ga21zS2V5XG4gICAqIC0gc3RyZWFtXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0YWcga2V5cyBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtdGFna2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvU3RyZWFtKClcbiAgICogLSAudG9DcmVhdGVTdHJlYW0oKVxuICAgKiAtIC50b1JlZ2lzdGVyU3RyZWFtQ29uc3VtZXIoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tU3RyZWFtKClcbiAgICogLSAudG9UYWdSZXNvdXJjZSgpXG4gICAqIC0gLnRvVW50YWdSZXNvdXJjZSgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzVGFnS2V5cyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlRhZ0tleXNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgSUQgb2YgYW4gQVdTIEZJUyBhY3Rpb25cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9JbmplY3RBcGlFcnJvcigpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmRmlzQWN0aW9uSWQodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEZpc0FjdGlvbklkYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHBlcmNlbnRhZ2Ugb2YgY2FsbHMgYmVpbmcgYWZmZWN0ZWQgYnkgYW4gQVdTIEZJUyBhY3Rpb25cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9JbmplY3RBcGlFcnJvcigpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZGaXNJbmplY3RQZXJjZW50YWdlKHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBGaXNJbmplY3RQZXJjZW50YWdlYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdOdW1lcmljRXF1YWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIEFSTiBvZiBhbiBBV1MgRklTIHRhcmdldFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZmlzL2xhdGVzdC91c2VyZ3VpZGUvZmlzLWFjdGlvbnMtcmVmZXJlbmNlLmh0bWxcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0luamVjdEFwaUVycm9yKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbYXJuIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19BUk4pLiAqKkRlZmF1bHQ6KiogYEFybkxpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZGaXNUYXJnZXRBcm5zKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBGaXNUYXJnZXRBcm5zYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdBcm5MaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtraW5lc2lzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9raW5lc2lzLmh0bWwpLlxuICAgKlxuICAgKi9cbiAgY29uc3RydWN0b3IocHJvcHM/OiBpYW0uUG9saWN5U3RhdGVtZW50UHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gIH1cbn1cbiJdfQ==