iam-floyd
Version:
AWS IAM policy statement generator with fluent interface
472 lines • 43 kB
JavaScript
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXBpcGVsaW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGF0YXBpcGVsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUV6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7T0FJRztJQUNILFlBQVksR0FBWTtRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFSTixrQkFBYSxHQUFHLGNBQWMsQ0FBQztRQTBUNUIsb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLGtCQUFrQjtnQkFDbEIsZ0JBQWdCO2dCQUNoQixvQkFBb0I7Z0JBQ3BCLGdCQUFnQjtnQkFDaEIsYUFBYTtnQkFDYixrQkFBa0I7Z0JBQ2xCLHVCQUF1QjtnQkFDdkIsb0JBQW9CO2dCQUNwQiwyQkFBMkI7Z0JBQzNCLFdBQVc7Z0JBQ1gsZUFBZTthQUNoQjtZQUNELE9BQU8sRUFBRTtnQkFDUCxTQUFTO2dCQUNULFlBQVk7YUFDYjtZQUNELElBQUksRUFBRTtnQkFDSixpQkFBaUI7Z0JBQ2pCLG1CQUFtQjtnQkFDbkIsb0JBQW9CO2dCQUNwQix1QkFBdUI7Z0JBQ3ZCLGNBQWM7Z0JBQ2QsNEJBQTRCO2FBQzdCO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLGtCQUFrQjtnQkFDbEIsZUFBZTthQUNoQjtTQUNGLENBQUM7SUEvVUYsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxnQkFBZ0I7UUFDckIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxpQkFBaUI7UUFDdEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxtQkFBbUI7UUFDeEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGtCQUFrQjtRQUN2QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSx1QkFBdUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGNBQWM7UUFDbkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxZQUFZO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksb0JBQW9CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSwyQkFBMkI7UUFDaEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDJCQUEyQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxXQUFXO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksZUFBZTtRQUNwQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksNEJBQTRCO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFrQ0Q7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksVUFBVSxDQUFDLFVBQWtCLEVBQUUsT0FBZ0IsRUFBRSxNQUFlLEVBQUUsU0FBa0I7UUFDekYsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQVEsU0FBUyxJQUFJLElBQUksQ0FBQyxnQkFBaUIsaUJBQWtCLE1BQU0sSUFBSSxJQUFJLENBQUMsYUFBYyxJQUFLLE9BQU8sSUFBSSxJQUFJLENBQUMsY0FBZSxhQUFjLFVBQVcsRUFBRSxDQUFDLENBQUM7SUFDNUssQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSSxlQUFlLENBQUMsTUFBYyxFQUFFLEtBQXdCLEVBQUUsUUFBNEI7UUFDM0YsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFtQixNQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2hGLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNJLGdCQUFnQixDQUFDLE1BQWMsRUFBRSxLQUF3QixFQUFFLFFBQTRCO1FBQzVGLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBb0IsTUFBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksWUFBWSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDeEUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXNCRztJQUNJLGlCQUFpQixDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDN0UsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGlCQUFpQixFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F3Qkc7SUFDSSxLQUFLLENBQUMsTUFBYyxFQUFFLEtBQXdCLEVBQUUsUUFBNEI7UUFDakYsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQVEsTUFBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0ksYUFBYSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDekUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Q0FDRjtBQTFlRCxvQ0EwZUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbZGF0YXBpcGVsaW5lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NkYXRhcGlwZWxpbmUuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhcGlwZWxpbmUgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdkYXRhcGlwZWxpbmUnO1xuXG4gIC8qKlxuICAgKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW2RhdGFwaXBlbGluZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzZGF0YXBpcGVsaW5lLmh0bWwpLlxuICAgKlxuICAgKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNpZD86IHN0cmluZykge1xuICAgIHN1cGVyKHNpZCk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmFsaWRhdGUgdGhlIHNwZWNpZmllZCBwaXBlbGluZSBhbmQgc3RhcnRzIHByb2Nlc3NpbmcgcGlwZWxpbmUgdGFza3MuIElmIHRoZSBwaXBlbGluZSBkb2VzIG5vdCBwYXNzIHZhbGlkYXRpb24sIGFjdGl2YXRpb24gZmFpbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQWN0aXZhdGVQaXBlbGluZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BY3RpdmF0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBY3RpdmF0ZVBpcGVsaW5lJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIG9yIG1vZGlmeSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9BZGRUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0FkZFRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0FkZFRhZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcsIGVtcHR5IHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBkYXRhcGlwZWxpbmU6QWRkVGFnc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVBpcGVsaW5lLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIERlYWN0aXZhdGUgdGhlIHNwZWNpZmllZCBydW5uaW5nIHBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqIC0gLmlmV29ya2VyR3JvdXAoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlYWN0aXZhdGVQaXBlbGluZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWFjdGl2YXRlUGlwZWxpbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlYWN0aXZhdGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHBpcGVsaW5lLCBpdHMgcGlwZWxpbmUgZGVmaW5pdGlvbiwgYW5kIGl0cyBydW4gaGlzdG9yeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVBpcGVsaW5lLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVBpcGVsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVQaXBlbGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgb2JqZWN0IGRlZmluaXRpb25zIGZvciBhIHNldCBvZiBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlT2JqZWN0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZU9iamVjdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlT2JqZWN0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlcyBtZXRhZGF0YSBhYm91dCBvbmUgb3IgbW9yZSBwaXBlbGluZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlUGlwZWxpbmVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlUGlwZWxpbmVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVBpcGVsaW5lcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRhc2sgcnVubmVycyB0byBjYWxsIEV2YWx1YXRlRXhwcmVzc2lvbiwgdG8gZXZhbHVhdGUgYSBzdHJpbmcgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNwZWNpZmllZCBvYmplY3RcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0V2YWx1YXRlRXhwcmVzc2lvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FdmFsdWF0ZUV4cHJlc3Npb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0V2YWx1YXRlRXhwcmVzc2lvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNhbGwgR2V0QWNjb3VudExpbWl0c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRBY2NvdW50TGltaXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEFjY291bnRMaW1pdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEFjY291bnRMaW1pdHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXRzIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRQaXBlbGluZURlZmluaXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0UGlwZWxpbmVEZWZpbml0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRQaXBlbGluZURlZmluaXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSBwaXBlbGluZSBpZGVudGlmaWVycyBmb3IgYWxsIGFjdGl2ZSBwaXBlbGluZXMgdGhhdCB5b3UgaGF2ZSBwZXJtaXNzaW9uIHRvIGFjY2Vzc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0UGlwZWxpbmVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RQaXBlbGluZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RQaXBlbGluZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0YXNrIHJ1bm5lcnMgdG8gY2FsbCBQb2xsRm9yVGFzaywgdG8gcmVjZWl2ZSBhIHRhc2sgdG8gcGVyZm9ybSBmcm9tIEFXUyBEYXRhIFBpcGVsaW5lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZXb3JrZXJHcm91cCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUG9sbEZvclRhc2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUG9sbEZvclRhc2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1BvbGxGb3JUYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY2FsbCBQdXRBY2NvdW50TGltaXRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRBY2NvdW50TGltaXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dEFjY291bnRMaW1pdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dEFjY291bnRMaW1pdHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgdGFza3MsIHNjaGVkdWxlcywgYW5kIHByZWNvbmRpdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRQaXBlbGluZURlZmluaXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0UGlwZWxpbmVEZWZpbml0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRQaXBlbGluZURlZmluaXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBxdWVyeSB0aGUgc3BlY2lmaWVkIHBpcGVsaW5lIGZvciB0aGUgbmFtZXMgb2Ygb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgc2V0IG9mIGNvbmRpdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1F1ZXJ5T2JqZWN0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9RdWVyeU9iamVjdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1F1ZXJ5T2JqZWN0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBleGlzdGluZyB0YWdzIGZyb20gdGhlIHNwZWNpZmllZCBwaXBlbGluZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZQaXBlbGluZUNyZWF0b3IoKVxuICAgKiAtIC5pZlRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVtb3ZlVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZW1vdmVUYWdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZW1vdmVUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFzayBydW5uZXJzIHRvIGNhbGwgUmVwb3J0VGFza1Byb2dyZXNzLCB3aGVuIHRoZXkgYXJlIGFzc2lnbmVkIGEgdGFzayB0byBhY2tub3dsZWRnZSB0aGF0IGl0IGhhcyB0aGUgdGFza1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVwb3J0VGFza1Byb2dyZXNzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlcG9ydFRhc2tQcm9ncmVzcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVwb3J0VGFza1Byb2dyZXNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFzayBydW5uZXJzIHRvIGNhbGwgUmVwb3J0VGFza1J1bm5lckhlYXJ0YmVhdCBldmVyeSAxNSBtaW51dGVzIHRvIGluZGljYXRlIHRoYXQgdGhleSBhcmUgb3BlcmF0aW9uYWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVwb3J0VGFza1J1bm5lckhlYXJ0YmVhdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVwb3J0VGFza1J1bm5lckhlYXJ0YmVhdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlcXVlc3RzIHRoYXQgdGhlIHN0YXR1cyBvZiB0aGUgc3BlY2lmaWVkIHBoeXNpY2FsIG9yIGxvZ2ljYWwgcGlwZWxpbmUgb2JqZWN0cyBiZSB1cGRhdGVkIGluIHRoZSBzcGVjaWZpZWQgcGlwZWxpbmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlBpcGVsaW5lQ3JlYXRvcigpXG4gICAqIC0gLmlmVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TZXRTdGF0dXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU2V0U3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTZXRTdGF0dXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0YXNrIHJ1bm5lcnMgdG8gY2FsbCBTZXRUYXNrU3RhdHVzIHRvIG5vdGlmeSBBV1MgRGF0YSBQaXBlbGluZSB0aGF0IGEgdGFzayBpcyBjb21wbGV0ZWQgYW5kIHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGZpbmFsIHN0YXR1c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU2V0VGFza1N0YXR1cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TZXRUYXNrU3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTZXRUYXNrU3RhdHVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmFsaWRhdGUgdGhlIHNwZWNpZmllZCBwaXBlbGluZSBkZWZpbml0aW9uIHRvIGVuc3VyZSB0aGF0IGl0IGlzIHdlbGwgZm9ybWVkIGFuZCBjYW4gYmUgcnVuIHdpdGhvdXQgZXJyb3JcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUGlwZWxpbmVDcmVhdG9yKClcbiAgICogLSAuaWZUYWcoKVxuICAgKiAtIC5pZldvcmtlckdyb3VwKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0FjdGl2YXRlUGlwZWxpbmUnLFxuICAgICAgJ0NyZWF0ZVBpcGVsaW5lJyxcbiAgICAgICdEZWFjdGl2YXRlUGlwZWxpbmUnLFxuICAgICAgJ0RlbGV0ZVBpcGVsaW5lJyxcbiAgICAgICdQb2xsRm9yVGFzaycsXG4gICAgICAnUHV0QWNjb3VudExpbWl0cycsXG4gICAgICAnUHV0UGlwZWxpbmVEZWZpbml0aW9uJyxcbiAgICAgICdSZXBvcnRUYXNrUHJvZ3Jlc3MnLFxuICAgICAgJ1JlcG9ydFRhc2tSdW5uZXJIZWFydGJlYXQnLFxuICAgICAgJ1NldFN0YXR1cycsXG4gICAgICAnU2V0VGFza1N0YXR1cydcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdBZGRUYWdzJyxcbiAgICAgICdSZW1vdmVUYWdzJ1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0Rlc2NyaWJlT2JqZWN0cycsXG4gICAgICAnRGVzY3JpYmVQaXBlbGluZXMnLFxuICAgICAgJ0V2YWx1YXRlRXhwcmVzc2lvbicsXG4gICAgICAnR2V0UGlwZWxpbmVEZWZpbml0aW9uJyxcbiAgICAgICdRdWVyeU9iamVjdHMnLFxuICAgICAgJ1ZhbGlkYXRlUGlwZWxpbmVEZWZpbml0aW9uJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0dldEFjY291bnRMaW1pdHMnLFxuICAgICAgJ0xpc3RQaXBlbGluZXMnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBwaXBlbGluZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2F3c2RhdGFwaXBlbGluZS5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBwaXBlbGluZUlkIC0gSWRlbnRpZmllciBmb3IgdGhlIHBpcGVsaW5lSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblBpcGVsaW5lKHBpcGVsaW5lSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpkYXRhcGlwZWxpbmU6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnBpcGVsaW5lLyR7IHBpcGVsaW5lSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0YWcga2V5LXZhbHVlIHBhaXJzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzKClcbiAgICogLSAudG9DcmVhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0YWcga2V5LXZhbHVlIHBhaXJzIGF0dGFjaGVkIHRvIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVzb3VyY2V0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBwaXBlbGluZVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVzb3VyY2VUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVzb3VyY2VUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgcHJlc2VuY2Ugb2YgdGFnIGtleXMgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXRhZ2tleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3MoKVxuICAgKiAtIC50b0NyZWF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9SZW1vdmVUYWdzKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBJQU0gdXNlciB0aGF0IGNyZWF0ZWQgdGhlIHBpcGVsaW5lXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9kYXRhcGlwZWxpbmUvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2RwLWV4YW1wbGUtdGFnLXBvbGljaWVzLmh0bWwjZXgzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BY3RpdmF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9BZGRUYWdzKClcbiAgICogLSAudG9EZWFjdGl2YXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0RlbGV0ZVBpcGVsaW5lKClcbiAgICogLSAudG9EZXNjcmliZU9iamVjdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUGlwZWxpbmVzKClcbiAgICogLSAudG9FdmFsdWF0ZUV4cHJlc3Npb24oKVxuICAgKiAtIC50b0dldFBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqIC0gLnRvUHV0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9RdWVyeU9iamVjdHMoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3MoKVxuICAgKiAtIC50b1NldFN0YXR1cygpXG4gICAqIC0gLnRvVmFsaWRhdGVQaXBlbGluZURlZmluaXRpb24oKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlBpcGVsaW5lQ3JlYXRvcih2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgUGlwZWxpbmVDcmVhdG9yYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgY3VzdG9tZXItc3BlY2lmaWVkIGtleS92YWx1ZSBwYWlyIHRoYXQgY2FuIGJlIGF0dGFjaGVkIHRvIGEgcmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2RhdGFwaXBlbGluZS9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZHAtaWFtLXJlc291cmNlYmFzZWQtYWNjZXNzLmh0bWwjZHAtY29udHJvbC1hY2Nlc3MtdGFnc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvQWRkVGFncygpXG4gICAqIC0gLnRvQ3JlYXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0RlYWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvRGVsZXRlUGlwZWxpbmUoKVxuICAgKiAtIC50b0Rlc2NyaWJlT2JqZWN0cygpXG4gICAqIC0gLnRvRGVzY3JpYmVQaXBlbGluZXMoKVxuICAgKiAtIC50b0V2YWx1YXRlRXhwcmVzc2lvbigpXG4gICAqIC0gLnRvR2V0UGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICogLSAudG9QdXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1F1ZXJ5T2JqZWN0cygpXG4gICAqIC0gLnRvUmVtb3ZlVGFncygpXG4gICAqIC0gLnRvU2V0U3RhdHVzKClcbiAgICogLSAudG9WYWxpZGF0ZVBpcGVsaW5lRGVmaW5pdGlvbigpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgbmFtZSBvZiBhIHdvcmtlciBncm91cCBmb3Igd2hpY2ggYSBUYXNrIFJ1bm5lciByZXRyaWV2ZXMgd29ya1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZGF0YXBpcGVsaW5lL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kcC1pYW0tcmVzb3VyY2ViYXNlZC1hY2Nlc3MuaHRtbCNkcC1jb250cm9sLWFjY2Vzcy13b3JrZXJncm91cFxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWN0aXZhdGVQaXBlbGluZSgpXG4gICAqIC0gLnRvRGVhY3RpdmF0ZVBpcGVsaW5lKClcbiAgICogLSAudG9HZXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1BvbGxGb3JUYXNrKClcbiAgICogLSAudG9QdXRQaXBlbGluZURlZmluaXRpb24oKVxuICAgKiAtIC50b1ZhbGlkYXRlUGlwZWxpbmVEZWZpbml0aW9uKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZXb3JrZXJHcm91cCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgd29ya2VyR3JvdXBgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxufVxuIl19