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