UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

471 lines 42.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Datapipeline = void 0; const shared_1 = require("../../shared"); /** * Statement provider for service [datapipeline](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsdatapipeline.html). * * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement */ class Datapipeline extends shared_1.PolicyStatement { /** * Grants permission to validate the specified pipeline and starts processing pipeline tasks. If the pipeline does not pass validation, activation fails * * Access Level: Write * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifWorkerGroup() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_ActivatePipeline.html */ toActivatePipeline() { return this.to('ActivatePipeline'); } /** * Grants permission to add or modify tags for the specified pipeline * * Access Level: Tagging * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifAwsTagKeys() * - .ifAwsRequestTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_AddTags.html */ toAddTags() { return this.to('AddTags'); } /** * Grants permission to create a new, empty pipeline * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * - .ifTag() * * Dependent actions: * - datapipeline:AddTags * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_CreatePipeline.html */ toCreatePipeline() { return this.to('CreatePipeline'); } /** * Grants permission to Deactivate the specified running pipeline * * Access Level: Write * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifWorkerGroup() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_DeactivatePipeline.html */ toDeactivatePipeline() { return this.to('DeactivatePipeline'); } /** * Grants permission to delete a pipeline, its pipeline definition, and its run history * * Access Level: Write * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_DeletePipeline.html */ toDeletePipeline() { return this.to('DeletePipeline'); } /** * Grants permission to get the object definitions for a set of objects associated with the pipeline * * Access Level: Read * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_DescribeObjects.html */ toDescribeObjects() { return this.to('DescribeObjects'); } /** * Grants permission to retrieves metadata about one or more pipelines * * Access Level: Read * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_DescribePipelines.html */ toDescribePipelines() { return this.to('DescribePipelines'); } /** * Grants permission to task runners to call EvaluateExpression, to evaluate a string in the context of the specified object * * Access Level: Read * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_EvaluateExpression.html */ toEvaluateExpression() { return this.to('EvaluateExpression'); } /** * Grants permission to call GetAccountLimits * * Access Level: List * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_GetAccountLimits.html */ toGetAccountLimits() { return this.to('GetAccountLimits'); } /** * Grants permission to gets the definition of the specified pipeline * * Access Level: Read * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifWorkerGroup() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_GetPipelineDefinition.html */ toGetPipelineDefinition() { return this.to('GetPipelineDefinition'); } /** * Grants permission to list the pipeline identifiers for all active pipelines that you have permission to access * * Access Level: List * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_ListPipelines.html */ toListPipelines() { return this.to('ListPipelines'); } /** * Grants permission to task runners to call PollForTask, to receive a task to perform from AWS Data Pipeline * * Access Level: Write * * Possible conditions: * - .ifWorkerGroup() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_PollForTask.html */ toPollForTask() { return this.to('PollForTask'); } /** * Grants permission to call PutAccountLimits * * Access Level: Write * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_PutAccountLimits.html */ toPutAccountLimits() { return this.to('PutAccountLimits'); } /** * Grants permission to add tasks, schedules, and preconditions to the specified pipeline * * Access Level: Write * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifWorkerGroup() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_PutPipelineDefinition.html */ toPutPipelineDefinition() { return this.to('PutPipelineDefinition'); } /** * Grants permission to query the specified pipeline for the names of objects that match the specified set of conditions * * Access Level: Read * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_QueryObjects.html */ toQueryObjects() { return this.to('QueryObjects'); } /** * Grants permission to remove existing tags from the specified pipeline * * Access Level: Tagging * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifAwsTagKeys() * - .ifAwsRequestTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_RemoveTags.html */ toRemoveTags() { return this.to('RemoveTags'); } /** * Grants permission to task runners to call ReportTaskProgress, when they are assigned a task to acknowledge that it has the task * * Access Level: Write * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_ReportTaskProgress.html */ toReportTaskProgress() { return this.to('ReportTaskProgress'); } /** * Grants permission to task runners to call ReportTaskRunnerHeartbeat every 15 minutes to indicate that they are operational * * Access Level: Write * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_ReportTaskRunnerHeartbeat.html */ toReportTaskRunnerHeartbeat() { return this.to('ReportTaskRunnerHeartbeat'); } /** * Grants permission to requests that the status of the specified physical or logical pipeline objects be updated in the specified pipeline * * Access Level: Write * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_SetStatus.html */ toSetStatus() { return this.to('SetStatus'); } /** * Grants permission to task runners to call SetTaskStatus to notify AWS Data Pipeline that a task is completed and provide information about the final status * * Access Level: Write * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_SetTaskStatus.html */ toSetTaskStatus() { return this.to('SetTaskStatus'); } /** * Grants permission to validate the specified pipeline definition to ensure that it is well formed and can be run without error * * Access Level: Read * * Possible conditions: * - .ifPipelineCreator() * - .ifTag() * - .ifWorkerGroup() * * https://docs.aws.amazon.com/datapipeline/latest/APIReference/API_ValidatePipelineDefinition.html */ toValidatePipelineDefinition() { return this.to('ValidatePipelineDefinition'); } /** * Adds a resource of type pipeline to the statement * * https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsdatapipeline.html * * @param pipelineId - Identifier for the pipelineId. * @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() */ onPipeline(pipelineId, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:datapipeline:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:pipeline/${pipelineId}`); } /** * 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: * - .toAddTags() * - .toCreatePipeline() * - .toRemoveTags() * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsRequestTag(tagKey, value, operator) { return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by 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 resource types: * - pipeline * * @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: * - .toAddTags() * - .toCreatePipeline() * - .toRemoveTags() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsTagKeys(value, operator) { return this.if(`aws:TagKeys`, value, operator ?? 'StringLike'); } /** * Filters access by the IAM user that created the pipeline * * https://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-example-tag-policies.html#ex3 * * Applies to actions: * - .toActivatePipeline() * - .toAddTags() * - .toDeactivatePipeline() * - .toDeletePipeline() * - .toDescribeObjects() * - .toDescribePipelines() * - .toEvaluateExpression() * - .toGetPipelineDefinition() * - .toPutPipelineDefinition() * - .toQueryObjects() * - .toRemoveTags() * - .toSetStatus() * - .toValidatePipelineDefinition() * * @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` */ ifPipelineCreator(value, operator) { return this.if(`PipelineCreator`, value, operator ?? 'StringLike'); } /** * Filters access by customer-specified key/value pair that can be attached to a resource * * https://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-iam-resourcebased-access.html#dp-control-access-tags * * Applies to actions: * - .toActivatePipeline() * - .toAddTags() * - .toCreatePipeline() * - .toDeactivatePipeline() * - .toDeletePipeline() * - .toDescribeObjects() * - .toDescribePipelines() * - .toEvaluateExpression() * - .toGetPipelineDefinition() * - .toPutPipelineDefinition() * - .toQueryObjects() * - .toRemoveTags() * - .toSetStatus() * - .toValidatePipelineDefinition() * * @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` */ ifTag(tagKey, value, operator) { return this.if(`Tag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by the name of a worker group for which a Task Runner retrieves work * * https://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-iam-resourcebased-access.html#dp-control-access-workergroup * * Applies to actions: * - .toActivatePipeline() * - .toDeactivatePipeline() * - .toGetPipelineDefinition() * - .toPollForTask() * - .toPutPipelineDefinition() * - .toValidatePipelineDefinition() * * @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` */ ifWorkerGroup(value, operator) { return this.if(`workerGroup`, value, operator ?? 'StringLike'); } /** * Statement provider for service [datapipeline](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsdatapipeline.html). * */ constructor(props) { super(props); this.servicePrefix = 'datapipeline'; this.accessLevelList = { Write: [ 'ActivatePipeline', 'CreatePipeline', 'DeactivatePipeline', 'DeletePipeline', 'PollForTask', 'PutAccountLimits', 'PutPipelineDefinition', 'ReportTaskProgress', 'ReportTaskRunnerHeartbeat', 'SetStatus', 'SetTaskStatus' ], Tagging: [ 'AddTags', 'RemoveTags' ], Read: [ 'DescribeObjects', 'DescribePipelines', 'EvaluateExpression', 'GetPipelineDefinition', 'QueryObjects', 'ValidatePipelineDefinition' ], List: [ 'GetAccountLimits', 'ListPipelines' ] }; } } exports.Datapipeline = Datapipeline; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXBpcGVsaW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGF0YXBpcGVsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLFNBQVM7UUFDZCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNJLG9CQUFvQjtRQUN6QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGlCQUFpQjtRQUN0QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLG1CQUFtQjtRQUN4QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLG9CQUFvQjtRQUN6QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7OztPQU1H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WUFDRCxJQUFJLEVBQUU7Z0JBQ0osa0JBQWtCO2dCQUNsQixlQUFlO2FBQ2hCO1NBQ0YsQ0FBQztJQXdKRixDQUFDO0NBQ0Y7QUF6ZUQsb0NBeWVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtkYXRhcGlwZWxpbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2F3c2RhdGFwaXBlbGluZS5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIERhdGFwaXBlbGluZSBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ2RhdGFwaXBlbGluZSc7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHZhbGlkYXRlIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmUgYW5kIHN0YXJ0cyBwcm9jZXNzaW5nIHBpcGVsaW5lIHRhc2tzLiBJZiB0aGUgcGlwZWxpbmUgZG9lcyBub3QgcGFzcyB2YWxpZGF0aW9uLCBhY3RpdmF0aW9uIGZhaWxzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqIC0gLmlmV29ya2VyR3JvdXAoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0FjdGl2YXRlUGlwZWxpbmUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQWN0aXZhdGVQaXBlbGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQWN0aXZhdGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCBvciBtb2RpZnkgdGFncyBmb3IgdGhlIHNwZWNpZmllZCBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQWRkVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BZGRUYWdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBZGRUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3LCBlbXB0eSBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZGF0YXBpcGVsaW5lOkFkZFRhZ3NcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVQaXBlbGluZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQaXBlbGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlUGlwZWxpbmUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBEZWFjdGl2YXRlIHRoZSBzcGVjaWZpZWQgcnVubmluZyBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWFjdGl2YXRlUGlwZWxpbmUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVhY3RpdmF0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWFjdGl2YXRlUGlwZWxpbmUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBwaXBlbGluZSwgaXRzIHBpcGVsaW5lIGRlZmluaXRpb24sIGFuZCBpdHMgcnVuIGhpc3RvcnlcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVQaXBlbGluZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVQaXBlbGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUGlwZWxpbmUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgdGhlIG9iamVjdCBkZWZpbml0aW9ucyBmb3IgYSBzZXQgb2Ygb2JqZWN0cyBhc3NvY2lhdGVkIHdpdGggdGhlIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZU9iamVjdHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZU9iamVjdHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZXMgbWV0YWRhdGEgYWJvdXQgb25lIG9yIG1vcmUgcGlwZWxpbmVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVBpcGVsaW5lcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVBpcGVsaW5lcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVQaXBlbGluZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0YXNrIHJ1bm5lcnMgdG8gY2FsbCBFdmFsdWF0ZUV4cHJlc3Npb24sIHRvIGV2YWx1YXRlIGEgc3RyaW5nIGluIHRoZSBjb250ZXh0IG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9FdmFsdWF0ZUV4cHJlc3Npb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRXZhbHVhdGVFeHByZXNzaW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdFdmFsdWF0ZUV4cHJlc3Npb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjYWxsIEdldEFjY291bnRMaW1pdHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0QWNjb3VudExpbWl0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRBY2NvdW50TGltaXRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRBY2NvdW50TGltaXRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0cyB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0UGlwZWxpbmVEZWZpbml0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFBpcGVsaW5lRGVmaW5pdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0UGlwZWxpbmVEZWZpbml0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgcGlwZWxpbmUgaWRlbnRpZmllcnMgZm9yIGFsbCBhY3RpdmUgcGlwZWxpbmVzIHRoYXQgeW91IGhhdmUgcGVybWlzc2lvbiB0byBhY2Nlc3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFBpcGVsaW5lcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UGlwZWxpbmVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0UGlwZWxpbmVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFzayBydW5uZXJzIHRvIGNhbGwgUG9sbEZvclRhc2ssIHRvIHJlY2VpdmUgYSB0YXNrIHRvIHBlcmZvcm0gZnJvbSBBV1MgRGF0YSBQaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmV29ya2VyR3JvdXAoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1BvbGxGb3JUYXNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1BvbGxGb3JUYXNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQb2xsRm9yVGFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNhbGwgUHV0QWNjb3VudExpbWl0c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0QWNjb3VudExpbWl0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRBY2NvdW50TGltaXRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRBY2NvdW50TGltaXRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHRhc2tzLCBzY2hlZHVsZXMsIGFuZCBwcmVjb25kaXRpb25zIHRvIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0UGlwZWxpbmVEZWZpbml0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dFBpcGVsaW5lRGVmaW5pdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0UGlwZWxpbmVEZWZpbml0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcXVlcnkgdGhlIHNwZWNpZmllZCBwaXBlbGluZSBmb3IgdGhlIG5hbWVzIG9mIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgc3BlY2lmaWVkIHNldCBvZiBjb25kaXRpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9RdWVyeU9iamVjdHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUXVlcnlPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdRdWVyeU9iamVjdHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgZXhpc3RpbmcgdGFncyBmcm9tIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlbW92ZVRhZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVtb3ZlVGFncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVtb3ZlVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRhc2sgcnVubmVycyB0byBjYWxsIFJlcG9ydFRhc2tQcm9ncmVzcywgd2hlbiB0aGV5IGFyZSBhc3NpZ25lZCBhIHRhc2sgdG8gYWNrbm93bGVkZ2UgdGhhdCBpdCBoYXMgdGhlIHRhc2tcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlcG9ydFRhc2tQcm9ncmVzcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZXBvcnRUYXNrUHJvZ3Jlc3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlcG9ydFRhc2tQcm9ncmVzcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRhc2sgcnVubmVycyB0byBjYWxsIFJlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQgZXZlcnkgMTUgbWludXRlcyB0byBpbmRpY2F0ZSB0aGF0IHRoZXkgYXJlIG9wZXJhdGlvbmFsXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9SZXBvcnRUYXNrUnVubmVySGVhcnRiZWF0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXF1ZXN0cyB0aGF0IHRoZSBzdGF0dXMgb2YgdGhlIHNwZWNpZmllZCBwaHlzaWNhbCBvciBsb2dpY2FsIHBpcGVsaW5lIG9iamVjdHMgYmUgdXBkYXRlZCBpbiB0aGUgc3BlY2lmaWVkIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU2V0U3RhdHVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1NldFN0YXR1cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2V0U3RhdHVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFzayBydW5uZXJzIHRvIGNhbGwgU2V0VGFza1N0YXR1cyB0byBub3RpZnkgQVdTIERhdGEgUGlwZWxpbmUgdGhhdCBhIHRhc2sgaXMgY29tcGxldGVkIGFuZCBwcm92aWRlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaW5hbCBzdGF0dXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1NldFRhc2tTdGF0dXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU2V0VGFza1N0YXR1cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2V0VGFza1N0YXR1cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHZhbGlkYXRlIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmUgZGVmaW5pdGlvbiB0byBlbnN1cmUgdGhhdCBpdCBpcyB3ZWxsIGZvcm1lZCBhbmQgY2FuIGJlIHJ1biB3aXRob3V0IGVycm9yXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1ZhbGlkYXRlUGlwZWxpbmVEZWZpbml0aW9uJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdBY3RpdmF0ZVBpcGVsaW5lJyxcbiAgICAgICdDcmVhdGVQaXBlbGluZScsXG4gICAgICAnRGVhY3RpdmF0ZVBpcGVsaW5lJyxcbiAgICAgICdEZWxldGVQaXBlbGluZScsXG4gICAgICAnUG9sbEZvclRhc2snLFxuICAgICAgJ1B1dEFjY291bnRMaW1pdHMnLFxuICAgICAgJ1B1dFBpcGVsaW5lRGVmaW5pdGlvbicsXG4gICAgICAnUmVwb3J0VGFza1Byb2dyZXNzJyxcbiAgICAgICdSZXBvcnRUYXNrUnVubmVySGVhcnRiZWF0JyxcbiAgICAgICdTZXRTdGF0dXMnLFxuICAgICAgJ1NldFRhc2tTdGF0dXMnXG4gICAgXSxcbiAgICBUYWdnaW5nOiBbXG4gICAgICAnQWRkVGFncycsXG4gICAgICAnUmVtb3ZlVGFncydcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdEZXNjcmliZU9iamVjdHMnLFxuICAgICAgJ0Rlc2NyaWJlUGlwZWxpbmVzJyxcbiAgICAgICdFdmFsdWF0ZUV4cHJlc3Npb24nLFxuICAgICAgJ0dldFBpcGVsaW5lRGVmaW5pdGlvbicsXG4gICAgICAnUXVlcnlPYmplY3RzJyxcbiAgICAgICdWYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbidcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdHZXRBY2NvdW50TGltaXRzJyxcbiAgICAgICdMaXN0UGlwZWxpbmVzJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgcGlwZWxpbmUgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NkYXRhcGlwZWxpbmUuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gcGlwZWxpbmVJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBwaXBlbGluZUlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25QaXBlbGluZShwaXBlbGluZUlkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06ZGF0YXBpcGVsaW5lOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpwaXBlbGluZS8keyBwaXBlbGluZUlkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcHJlc2VuY2Ugb2YgdGFnIGtleS12YWx1ZSBwYWlycyBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVxdWVzdHRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqIC0gLnRvQ3JlYXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3MoKVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVxdWVzdFRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXF1ZXN0VGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGFnIGtleS12YWx1ZSBwYWlycyBhdHRhY2hlZCB0byB0aGUgcmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlc291cmNldGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gcGlwZWxpbmVcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1Jlc291cmNlVGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlc291cmNlVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHByZXNlbmNlIG9mIHRhZyBrZXlzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy10YWdrZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzKClcbiAgICogLSAudG9DcmVhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzVGFnS2V5cyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlRhZ0tleXNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgSUFNIHVzZXIgdGhhdCBjcmVhdGVkIHRoZSBwaXBlbGluZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kcC1leGFtcGxlLXRhZy1wb2xpY2llcy5odG1sI2V4M1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqIC0gLnRvRGVhY3RpdmF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9EZWxldGVQaXBlbGluZSgpXG4gICAqIC0gLnRvRGVzY3JpYmVPYmplY3RzKClcbiAgICogLSAudG9EZXNjcmliZVBpcGVsaW5lcygpXG4gICAqIC0gLnRvRXZhbHVhdGVFeHByZXNzaW9uKClcbiAgICogLSAudG9HZXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1B1dFBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqIC0gLnRvUXVlcnlPYmplY3RzKClcbiAgICogLSAudG9SZW1vdmVUYWdzKClcbiAgICogLSAudG9TZXRTdGF0dXMoKVxuICAgKiAtIC50b1ZhbGlkYXRlUGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZQaXBlbGluZUNyZWF0b3IodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYFBpcGVsaW5lQ3JlYXRvcmAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGN1c3RvbWVyLXNwZWNpZmllZCBrZXkvdmFsdWUgcGFpciB0aGF0IGNhbiBiZSBhdHRhY2hlZCB0byBhIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2RwLWlhbS1yZXNvdXJjZWJhc2VkLWFjY2Vzcy5odG1sI2RwLWNvbnRyb2wtYWNjZXNzLXRhZ3NcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FjdGl2YXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0FkZFRhZ3MoKVxuICAgKiAtIC50b0NyZWF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9EZWFjdGl2YXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0RlbGV0ZVBpcGVsaW5lKClcbiAgICogLSAudG9EZXNjcmliZU9iamVjdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUGlwZWxpbmVzKClcbiAgICogLSAudG9FdmFsdWF0ZUV4cHJlc3Npb24oKVxuICAgKiAtIC50b0dldFBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqIC0gLnRvUHV0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9RdWVyeU9iamVjdHMoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3MoKVxuICAgKiAtIC50b1NldFN0YXR1cygpXG4gICAqIC0gLnRvVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24oKVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmVGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIG5hbWUgb2YgYSB3b3JrZXIgZ3JvdXAgZm9yIHdoaWNoIGEgVGFzayBSdW5uZXIgcmV0cmlldmVzIHdvcmtcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZHAtaWFtLXJlc291cmNlYmFzZWQtYWNjZXNzLmh0bWwjZHAtY29udHJvbC1hY2Nlc3Mtd29ya2VyZ3JvdXBcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FjdGl2YXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0RlYWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvR2V0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9Qb2xsRm9yVGFzaygpXG4gICAqIC0gLnRvUHV0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmV29ya2VyR3JvdXAodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYHdvcmtlckdyb3VwYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtkYXRhcGlwZWxpbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2F3c2RhdGFwaXBlbGluZS5odG1sKS5cbiAgICpcbiAgICovXG4gIGNvbnN0cnVjdG9yKHByb3BzPzogaWFtLlBvbGljeVN0YXRlbWVudFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICB9XG59XG4iXX0=