UNPKG

iam-floyd

Version:

AWS IAM policy statement generator with fluent interface

472 lines 43 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 { /** * 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 */ constructor(sid) { super(sid); 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' ] }; } /** * 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'); } } exports.Datapipeline = Datapipeline; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXBpcGVsaW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGF0YXBpcGVsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUV6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7T0FJRztJQUNILFlBQVksR0FBWTtRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFSTixrQkFBYSxHQUFHLGNBQWMsQ0FBQztRQTBUNUIsb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLGtCQUFrQjtnQkFDbEIsZ0JBQWdCO2dCQUNoQixvQkFBb0I7Z0JBQ3BCLGdCQUFnQjtnQkFDaEIsYUFBYTtnQkFDYixrQkFBa0I7Z0JBQ2xCLHVCQUF1QjtnQkFDdkIsb0JBQW9CO2dCQUNwQiwyQkFBMkI7Z0JBQzNCLFdBQVc7Z0JBQ1gsZUFBZTthQUNoQjtZQUNELE9BQU8sRUFBRTtnQkFDUCxTQUFTO2dCQUNULFlBQVk7YUFDYjtZQUNELElBQUksRUFBRTtnQkFDSixpQkFBaUI7Z0JBQ2pCLG1CQUFtQjtnQkFDbkIsb0JBQW9CO2dCQUNwQix1QkFBdUI7Z0JBQ3ZCLGNBQWM7Z0JBQ2QsNEJBQTRCO2FBQzdCO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLGtCQUFrQjtnQkFDbEIsZUFBZTthQUNoQjtTQUNGLENBQUM7SUEvVUYsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMs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RUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Q0FDRjtBQTFlRCxvQ0EwZUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbZGF0YXBpcGVsaW5lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NkYXRhcGlwZWxpbmUuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhcGlwZWxpbmUgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdkYXRhcGlwZWxpbmUnO1xuXG4gIC8qKlxuICAgKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW2RhdGFwaXBlbGluZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzZGF0YXBpcGVsaW5lLmh0bWwpLlxuICAgKlxuICAgKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNpZD86IHN0cmluZykge1xuICAgIHN1cGVyKHNpZCk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmFsaWRhdGUgdGhlIHNwZWNpZmllZCBwaXBlbGluZSBhbmQgc3RhcnRzIHByb2Nlc3NpbmcgcGlwZWxpbmUgdGFza3MuIElmIHRoZSBwaXBlbGluZSBkb2VzIG5vdCBwYXNzIHZhbGlkYXRpb24sIGFjdGl2YXRpb24gZmFpbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQWN0aXZhdGVQaXBlbGluZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BY3RpdmF0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBY3RpdmF0ZVBpcGVsaW5lJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIG9yIG1vZGlmeSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9BZGRUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0FkZFRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0FkZFRhZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcsIGVtcHR5IHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBkYXRhcGlwZWxpbmU6QWRkVGFnc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVBpcGVsaW5lLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIERlYWN0aXZhdGUgdGhlIHNwZWNpZmllZCBydW5uaW5nIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqIC0gLmlmV29ya2VyR3JvdXAoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlYWN0aXZhdGVQaXBlbGluZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWFjdGl2YXRlUGlwZWxpbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlYWN0aXZhdGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHBpcGVsaW5lLCBpdHMgcGlwZWxpbmUgZGVmaW5pdGlvbiwgYW5kIGl0cyBydW4gaGlzdG9yeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVBpcGVsaW5lLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgb2JqZWN0IGRlZmluaXRpb25zIGZvciBhIHNldCBvZiBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlT2JqZWN0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZU9iamVjdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlT2JqZWN0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlcyBtZXRhZGF0YSBhYm91dCBvbmUgb3IgbW9yZSBwaXBlbGluZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlUGlwZWxpbmVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlUGlwZWxpbmVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVBpcGVsaW5lcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRhc2sgcnVubmVycyB0byBjYWxsIEV2YWx1YXRlRXhwcmVzc2lvbiwgdG8gZXZhbHVhdGUgYSBzdHJpbmcgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCBvYmplY3RcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0V2YWx1YXRlRXhwcmVzc2lvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FdmFsdWF0ZUV4cHJlc3Npb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0V2YWx1YXRlRXhwcmVzc2lvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNhbGwgR2V0QWNjb3VudExpbWl0c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRBY2NvdW50TGltaXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEFjY291bnRMaW1pdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEFjY291bnRMaW1pdHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXRzIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRQaXBlbGluZURlZmluaXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0UGlwZWxpbmVEZWZpbml0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRQaXBlbGluZURlZmluaXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSBwaXBlbGluZSBpZGVudGlmaWVycyBmb3IgYWxsIGFjdGl2ZSBwaXBlbGluZXMgdGhhdCB5b3UgaGF2ZSBwZXJtaXNzaW9uIHRvIGFjY2Vzc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0UGlwZWxpbmVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RQaXBlbGluZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RQaXBlbGluZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0YXNrIHJ1bm5lcnMgdG8gY2FsbCBQb2xsRm9yVGFzaywgdG8gcmVjZWl2ZSBhIHRhc2sgdG8gcGVyZm9ybSBmcm9tIEFXUyBEYXRhIFBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUG9sbEZvclRhc2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUG9sbEZvclRhc2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1BvbGxGb3JUYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY2FsbCBQdXRBY2NvdW50TGltaXRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRBY2NvdW50TGltaXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dEFjY291bnRMaW1pdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dEFjY291bnRMaW1pdHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgdGFza3MsIHNjaGVkdWxlcywgYW5kIHByZWNvbmRpdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRQaXBlbGluZURlZmluaXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0UGlwZWxpbmVEZWZpbml0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRQaXBlbGluZURlZmluaXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBxdWVyeSB0aGUgc3BlY2lmaWVkIHBpcGVsaW5lIGZvciB0aGUgbmFtZXMgb2Ygb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgc2V0IG9mIGNvbmRpdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1F1ZXJ5T2JqZWN0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9RdWVyeU9iamVjdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1F1ZXJ5T2JqZWN0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBleGlzdGluZyB0YWdzIGZyb20gdGhlIHNwZWNpZmllZCBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVtb3ZlVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZW1vdmVUYWdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZW1vdmVUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFzayBydW5uZXJzIHRvIGNhbGwgUmVwb3J0VGFza1Byb2dyZXNzLCB3aGVuIHRoZXkgYXJlIGFzc2lnbmVkIGEgdGFzayB0byBhY2tub3dsZWRnZSB0aGF0IGl0IGhhcyB0aGUgdGFza1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVwb3J0VGFza1Byb2dyZXNzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlcG9ydFRhc2tQcm9ncmVzcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVwb3J0VGFza1Byb2dyZXNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFzayBydW5uZXJzIHRvIGNhbGwgUmVwb3J0VGFza1J1bm5lckhlYXJ0YmVhdCBldmVyeSAxNSBtaW51dGVzIHRvIGluZGljYXRlIHRoYXQgdGhleSBhcmUgb3BlcmF0aW9uYWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVwb3J0VGFza1J1bm5lckhlYXJ0YmVhdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVwb3J0VGFza1J1bm5lckhlYXJ0YmVhdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlcXVlc3RzIHRoYXQgdGhlIHN0YXR1cyBvZiB0aGUgc3BlY2lmaWVkIHBoeXNpY2FsIG9yIGxvZ2ljYWwgcGlwZWxpbmUgb2JqZWN0cyBiZSB1cGRhdGVkIGluIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TZXRTdGF0dXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU2V0U3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTZXRTdGF0dXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0YXNrIHJ1bm5lcnMgdG8gY2FsbCBTZXRUYXNrU3RhdHVzIHRvIG5vdGlmeSBBV1MgRGF0YSBQaXBlbGluZSB0aGF0IGEgdGFzayBpcyBjb21wbGV0ZWQgYW5kIHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGZpbmFsIHN0YXR1c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU2V0VGFza1N0YXR1cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TZXRUYXNrU3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTZXRUYXNrU3RhdHVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmFsaWRhdGUgdGhlIHNwZWNpZmllZCBwaXBlbGluZSBkZWZpbml0aW9uIHRvIGVuc3VyZSB0aGF0IGl0IGlzIHdlbGwgZm9ybWVkIGFuZCBjYW4gYmUgcnVuIHdpdGhvdXQgZXJyb3JcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0FjdGl2YXRlUGlwZWxpbmUnLFxuICAgICAgJ0NyZWF0ZVBpcGVsaW5lJyxcbiAgICAgICdEZWFjdGl2YXRlUGlwZWxpbmUnLFxuICAgICAgJ0RlbGV0ZVBpcGVsaW5lJyxcbiAgICAgICdQb2xsRm9yVGFzaycsXG4gICAgICAnUHV0QWNjb3VudExpbWl0cycsXG4gICAgICAnUHV0UGlwZWxpbmVEZWZpbml0aW9uJyxcbiAgICAgICdSZXBvcnRUYXNrUHJvZ3Jlc3MnLFxuICAgICAgJ1JlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQnLFxuICAgICAgJ1NldFN0YXR1cycsXG4gICAgICAnU2V0VGFza1N0YXR1cydcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdBZGRUYWdzJyxcbiAgICAgICdSZW1vdmVUYWdzJ1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0Rlc2NyaWJlT2JqZWN0cycsXG4gICAgICAnRGVzY3JpYmVQaXBlbGluZXMnLFxuICAgICAgJ0V2YWx1YXRlRXhwcmVzc2lvbicsXG4gICAgICAnR2V0UGlwZWxpbmVEZWZpbml0aW9uJyxcbiAgICAgICdRdWVyeU9iamVjdHMnLFxuICAgICAgJ1ZhbGlkYXRlUGlwZWxpbmVEZWZpbml0aW9uJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0dldEFjY291bnRMaW1pdHMnLFxuICAgICAgJ0xpc3RQaXBlbGluZXMnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBwaXBlbGluZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2F3c2RhdGFwaXBlbGluZS5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBwaXBlbGluZUlkIC0gSWRlbnRpZmllciBmb3IgdGhlIHBpcGVsaW5lSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblBpcGVsaW5lKHBpcGVsaW5lSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpkYXRhcGlwZWxpbmU6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnBpcGVsaW5lLyR7IHBpcGVsaW5lSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0YWcga2V5LXZhbHVlIHBhaXJzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzKClcbiAgICogLSAudG9DcmVhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0YWcga2V5LXZhbHVlIHBhaXJzIGF0dGFjaGVkIHRvIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVzb3VyY2V0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBwaXBlbGluZVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVzb3VyY2VUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVzb3VyY2VUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcHJlc2VuY2Ugb2YgdGFnIGtleXMgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXRhZ2tleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3MoKVxuICAgKiAtIC50b0NyZWF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9SZW1vdmVUYWdzKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBJQU0gdXNlciB0aGF0IGNyZWF0ZWQgdGhlIHBpcGVsaW5lXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2RwLWV4YW1wbGUtdGFnLXBvbGljaWVzLmh0bWwjZXgzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BY3RpdmF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9BZGRUYWdzKClcbiAgICogLSAudG9EZWFjdGl2YXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0RlbGV0ZVBpcGVsaW5lKClcbiAgICogLSAudG9EZXNjcmliZU9iamVjdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUGlwZWxpbmVzKClcbiAgICogLSAudG9FdmFsdWF0ZUV4cHJlc3Npb24oKVxuICAgKiAtIC50b0dldFBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqIC0gLnRvUHV0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9RdWVyeU9iamVjdHMoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3MoKVxuICAgKiAtIC50b1NldFN0YXR1cygpXG4gICAqIC0gLnRvVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24oKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlBpcGVsaW5lQ3JlYXRvcih2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgUGlwZWxpbmVDcmVhdG9yYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgY3VzdG9tZXItc3BlY2lmaWVkIGtleS92YWx1ZSBwYWlyIHRoYXQgY2FuIGJlIGF0dGFjaGVkIHRvIGEgcmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZHAtaWFtLXJlc291cmNlYmFzZWQtYWNjZXNzLmh0bWwjZHAtY29udHJvbC1hY2Nlc3MtdGFnc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqIC0gLnRvQ3JlYXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0RlYWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvRGVsZXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0Rlc2NyaWJlT2JqZWN0cygpXG4gICAqIC0gLnRvRGVzY3JpYmVQaXBlbGluZXMoKVxuICAgKiAtIC50b0V2YWx1YXRlRXhwcmVzc2lvbigpXG4gICAqIC0gLnRvR2V0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9QdXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1F1ZXJ5T2JqZWN0cygpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqIC0gLnRvU2V0U3RhdHVzKClcbiAgICogLSAudG9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgbmFtZSBvZiBhIHdvcmtlciBncm91cCBmb3Igd2hpY2ggYSBUYXNrIFJ1bm5lciByZXRyaWV2ZXMgd29ya1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kcC1pYW0tcmVzb3VyY2ViYXNlZC1hY2Nlc3MuaHRtbCNkcC1jb250cm9sLWFjY2Vzcy13b3JrZXJncm91cFxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvRGVhY3RpdmF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9HZXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1BvbGxGb3JUYXNrKClcbiAgICogLSAudG9QdXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1ZhbGlkYXRlUGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZXb3JrZXJHcm91cCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgd29ya2VyR3JvdXBgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxufVxuIl19