iam-floyd
Version:
AWS IAM policy statement generator with fluent interface
692 lines • 61.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Securitylake = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [securitylake](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsecuritylake.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Securitylake extends shared_1.PolicyStatement {
/**
* Statement provider for service [securitylake](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsecuritylake.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 = 'securitylake';
this.accessLevelList = {
Write: [
'CreateAwsLogSource',
'CreateCustomLogSource',
'CreateDataLake',
'CreateDataLakeExceptionSubscription',
'CreateDataLakeOrganizationConfiguration',
'CreateSubscriber',
'CreateSubscriberNotification',
'DeleteAwsLogSource',
'DeleteCustomLogSource',
'DeleteDataLake',
'DeleteDataLakeExceptionSubscription',
'DeleteDataLakeOrganizationConfiguration',
'DeleteSubscriber',
'DeleteSubscriberNotification',
'DeregisterDataLakeDelegatedAdministrator',
'RegisterDataLakeDelegatedAdministrator',
'UpdateDataLake',
'UpdateDataLakeExceptionSubscription',
'UpdateSubscriber',
'UpdateSubscriberNotification'
],
Read: [
'GetDataLakeExceptionSubscription',
'GetDataLakeOrganizationConfiguration',
'GetDataLakeSources',
'GetSubscriber'
],
List: [
'ListDataLakeExceptions',
'ListDataLakes',
'ListLogSources',
'ListSubscribers',
'ListTagsForResource'
],
Tagging: [
'TagResource',
'UntagResource'
]
};
}
/**
* Grants permission to enable any source type in any region for accounts that are either part of a trusted organization or standalone account
*
* Access Level: Write
*
* Dependent actions:
* - glue:CreateDatabase
* - glue:CreateTable
* - glue:GetDatabase
* - glue:GetTable
* - iam:CreateServiceLinkedRole
* - kms:CreateGrant
* - kms:DescribeKey
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateAwsLogSource.html
*/
toCreateAwsLogSource() {
return this.to('CreateAwsLogSource');
}
/**
* Grants permission to add a custom source
*
* Access Level: Write
*
* Dependent actions:
* - glue:CreateCrawler
* - glue:CreateDatabase
* - glue:CreateTable
* - glue:StartCrawlerSchedule
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:PassRole
* - iam:PutRolePolicy
* - kms:CreateGrant
* - kms:DescribeKey
* - kms:GenerateDataKey
* - lakeformation:GrantPermissions
* - lakeformation:RegisterResource
* - s3:ListBucket
* - s3:PutObject
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateCustomLogSource.html
*/
toCreateCustomLogSource() {
return this.to('CreateCustomLogSource');
}
/**
* Grants permission to create a new security data lake
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* Dependent actions:
* - events:PutRule
* - events:PutTargets
* - iam:CreateServiceLinkedRole
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:ListAttachedRolePolicies
* - iam:PassRole
* - iam:PutRolePolicy
* - kms:CreateGrant
* - kms:DescribeKey
* - lakeformation:GetDataLakeSettings
* - lakeformation:PutDataLakeSettings
* - lambda:AddPermission
* - lambda:CreateEventSourceMapping
* - lambda:CreateFunction
* - organizations:DescribeOrganization
* - organizations:ListAccounts
* - organizations:ListDelegatedServicesForAccount
* - s3:CreateBucket
* - s3:GetObject
* - s3:GetObjectVersion
* - s3:ListBucket
* - s3:PutBucketPolicy
* - s3:PutBucketPublicAccessBlock
* - s3:PutBucketVersioning
* - sqs:CreateQueue
* - sqs:GetQueueAttributes
* - sqs:SetQueueAttributes
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateDataLake.html
*/
toCreateDataLake() {
return this.to('CreateDataLake');
}
/**
* Grants permission to get instant notifications about exceptions. Subscribes to the SNS topics for exception notifications
*
* Access Level: Write
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateDataLakeExceptionSubscription.html
*/
toCreateDataLakeExceptionSubscription() {
return this.to('CreateDataLakeExceptionSubscription');
}
/**
* Grants permission to automatically enable Amazon Security Lake for new member accounts in your organization
*
* Access Level: Write
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateDataLakeOrganizationConfiguration.html
*/
toCreateDataLakeOrganizationConfiguration() {
return this.to('CreateDataLakeOrganizationConfiguration');
}
/**
* Grants permission to create a subscriber
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
*
* Dependent actions:
* - iam:CreateRole
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:PutRolePolicy
* - lakeformation:GrantPermissions
* - lakeformation:ListPermissions
* - lakeformation:RegisterResource
* - lakeformation:RevokePermissions
* - ram:GetResourceShareAssociations
* - ram:GetResourceShares
* - ram:UpdateResourceShare
* - s3:PutObject
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateSubscriber.html
*/
toCreateSubscriber() {
return this.to('CreateSubscriber');
}
/**
* Grants permission to create a webhook invocation to notify a client when there is new data in the data lake
*
* Access Level: Write
*
* Dependent actions:
* - events:CreateApiDestination
* - events:CreateConnection
* - events:DescribeRule
* - events:ListApiDestinations
* - events:ListConnections
* - events:PutRule
* - events:PutTargets
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:PassRole
* - s3:GetBucketNotification
* - s3:PutBucketNotification
* - sqs:CreateQueue
* - sqs:DeleteQueue
* - sqs:GetQueueAttributes
* - sqs:GetQueueUrl
* - sqs:SetQueueAttributes
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_CreateSubscriberNotification.html
*/
toCreateSubscriberNotification() {
return this.to('CreateSubscriberNotification');
}
/**
* Grants permission to disable any source type in any region for accounts that are part of a trusted organization or standalone accounts
*
* Access Level: Write
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteAwsLogSource.html
*/
toDeleteAwsLogSource() {
return this.to('DeleteAwsLogSource');
}
/**
* Grants permission to remove a custom source
*
* Access Level: Write
*
* Dependent actions:
* - glue:StopCrawlerSchedule
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteCustomLogSource.html
*/
toDeleteCustomLogSource() {
return this.to('DeleteCustomLogSource');
}
/**
* Grants permission to delete security data lake
*
* Access Level: Write
*
* Dependent actions:
* - organizations:DescribeOrganization
* - organizations:ListDelegatedAdministrators
* - organizations:ListDelegatedServicesForAccount
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteDataLake.html
*/
toDeleteDataLake() {
return this.to('DeleteDataLake');
}
/**
* Grants permission to unsubscribe from SNS topics for exception notifications. Removes exception notifications for the SNS topic
*
* Access Level: Write
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteDataLakeExceptionSubscription.html
*/
toDeleteDataLakeExceptionSubscription() {
return this.to('DeleteDataLakeExceptionSubscription');
}
/**
* Grants permission to remove the automatic enablement of Amazon Security Lake access for new organization accounts
*
* Access Level: Write
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteDataLakeOrganizationConfiguration.html
*/
toDeleteDataLakeOrganizationConfiguration() {
return this.to('DeleteDataLakeOrganizationConfiguration');
}
/**
* Grants permission to delete the specified subscriber
*
* Access Level: Write
*
* Dependent actions:
* - events:DeleteApiDestination
* - events:DeleteConnection
* - events:DeleteRule
* - events:DescribeRule
* - events:ListApiDestinations
* - events:ListTargetsByRule
* - events:RemoveTargets
* - iam:DeleteRole
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:ListRolePolicies
* - lakeformation:ListPermissions
* - lakeformation:RevokePermissions
* - sqs:DeleteQueue
* - sqs:GetQueueUrl
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteSubscriber.html
*/
toDeleteSubscriber() {
return this.to('DeleteSubscriber');
}
/**
* Grants permission to remove a webhook invocation to notify a client when there is new data in the data lake
*
* Access Level: Write
*
* Dependent actions:
* - events:DeleteApiDestination
* - events:DeleteConnection
* - events:DeleteRule
* - events:DescribeRule
* - events:ListApiDestinations
* - events:ListTargetsByRule
* - events:RemoveTargets
* - iam:DeleteRole
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:ListRolePolicies
* - lakeformation:RevokePermissions
* - sqs:DeleteQueue
* - sqs:GetQueueUrl
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeleteSubscriberNotification.html
*/
toDeleteSubscriberNotification() {
return this.to('DeleteSubscriberNotification');
}
/**
* Grants permission to remove the Delegated Administrator account and disable Amazon Security Lake as a service for this organization
*
* Access Level: Write
*
* Dependent actions:
* - organizations:DeregisterDelegatedAdministrator
* - organizations:DescribeOrganization
* - organizations:ListDelegatedServicesForAccount
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DeregisterDataLakeDelegatedAdministrator.html
*/
toDeregisterDataLakeDelegatedAdministrator() {
return this.to('DeregisterDataLakeDelegatedAdministrator');
}
/**
* Grants permission to query the protocol and endpoint that were provided when subscribing to SNS topics for exception notifications
*
* Access Level: Read
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_GetDataLakeExceptionSubscription.html
*/
toGetDataLakeExceptionSubscription() {
return this.to('GetDataLakeExceptionSubscription');
}
/**
* Grants permission to get an organization's configuration setting for automatically enabling Amazon Security Lake access for new organization accounts
*
* Access Level: Read
*
* Dependent actions:
* - organizations:DescribeOrganization
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_GetDataLakeOrganizationConfiguration.html
*/
toGetDataLakeOrganizationConfiguration() {
return this.to('GetDataLakeOrganizationConfiguration');
}
/**
* Grants permission to get a static snapshot of the security data lake in the current region. The snapshot includes enabled accounts and log sources
*
* Access Level: Read
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_GetDataLakeSources.html
*/
toGetDataLakeSources() {
return this.to('GetDataLakeSources');
}
/**
* Grants permission to get information about subscriber that is already created
*
* Access Level: Read
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_GetSubscriber.html
*/
toGetSubscriber() {
return this.to('GetSubscriber');
}
/**
* Grants permission to get the list of all non-retryable failures
*
* Access Level: List
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_ListDataLakeExceptions.html
*/
toListDataLakeExceptions() {
return this.to('ListDataLakeExceptions');
}
/**
* Grants permission to list information about the security data lakes
*
* Access Level: List
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_ListDataLakes.html
*/
toListDataLakes() {
return this.to('ListDataLakes');
}
/**
* Grants permission to view the enabled accounts. You can view the enabled sources in the enabled regions
*
* Access Level: List
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_ListLogSources.html
*/
toListLogSources() {
return this.to('ListLogSources');
}
/**
* Grants permission to list all subscribers
*
* Access Level: List
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_ListSubscribers.html
*/
toListSubscribers() {
return this.to('ListSubscribers');
}
/**
* Grants permission to list all tags for the resource
*
* Access Level: List
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to designate an account as the Amazon Security Lake administrator account for the organization
*
* Access Level: Write
*
* Dependent actions:
* - iam:CreateServiceLinkedRole
* - organizations:DescribeOrganization
* - organizations:EnableAWSServiceAccess
* - organizations:ListDelegatedAdministrators
* - organizations:ListDelegatedServicesForAccount
* - organizations:RegisterDelegatedAdministrator
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_RegisterDataLakeDelegatedAdministrator.html
*/
toRegisterDataLakeDelegatedAdministrator() {
return this.to('RegisterDataLakeDelegatedAdministrator');
}
/**
* Grants permission to add tags to the resource
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to remove tags from the resource
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to update a security data lake
*
* Access Level: Write
*
* Dependent actions:
* - events:PutRule
* - events:PutTargets
* - iam:CreateServiceLinkedRole
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:ListAttachedRolePolicies
* - iam:PutRolePolicy
* - kms:CreateGrant
* - kms:DescribeKey
* - lakeformation:GetDataLakeSettings
* - lakeformation:PutDataLakeSettings
* - lambda:AddPermission
* - lambda:CreateEventSourceMapping
* - lambda:CreateFunction
* - organizations:DescribeOrganization
* - organizations:ListDelegatedServicesForAccount
* - s3:CreateBucket
* - s3:GetObject
* - s3:GetObjectVersion
* - s3:ListBucket
* - s3:PutBucketPolicy
* - s3:PutBucketPublicAccessBlock
* - s3:PutBucketVersioning
* - sqs:CreateQueue
* - sqs:GetQueueAttributes
* - sqs:SetQueueAttributes
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_UpdateDataLake.html
*/
toUpdateDataLake() {
return this.to('UpdateDataLake');
}
/**
* Grants permission to update subscriptions to the SNS topics for exception notifications
*
* Access Level: Write
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_UpdateDataLakeExceptionSubscription.html
*/
toUpdateDataLakeExceptionSubscription() {
return this.to('UpdateDataLakeExceptionSubscription');
}
/**
* Grants permission to update subscriber
*
* Access Level: Write
*
* Dependent actions:
* - events:CreateApiDestination
* - events:CreateConnection
* - events:DescribeRule
* - events:ListApiDestinations
* - events:ListConnections
* - events:PutRule
* - events:PutTargets
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:PutRolePolicy
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_UpdateSubscriber.html
*/
toUpdateSubscriber() {
return this.to('UpdateSubscriber');
}
/**
* Grants permission to update a webhook invocation to notify a client when there is new data in the data lake
*
* Access Level: Write
*
* Dependent actions:
* - events:CreateApiDestination
* - events:CreateConnection
* - events:DescribeRule
* - events:ListApiDestinations
* - events:ListConnections
* - events:PutRule
* - events:PutTargets
* - iam:CreateServiceLinkedRole
* - iam:DeleteRolePolicy
* - iam:GetRole
* - iam:PassRole
* - iam:PutRolePolicy
* - s3:CreateBucket
* - s3:GetBucketNotification
* - s3:ListBucket
* - s3:PutBucketNotification
* - s3:PutBucketPolicy
* - s3:PutBucketPublicAccessBlock
* - s3:PutBucketVersioning
* - s3:PutLifecycleConfiguration
* - sqs:CreateQueue
* - sqs:DeleteQueue
* - sqs:GetQueueAttributes
* - sqs:GetQueueUrl
* - sqs:SetQueueAttributes
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_UpdateSubscriberNotification.html
*/
toUpdateSubscriberNotification() {
return this.to('UpdateSubscriberNotification');
}
/**
* Adds a resource of type data-lake to the statement
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_DataLakeResource.html
*
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
*/
onDataLake(account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:securitylake:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:data-lake/default`);
}
/**
* Adds a resource of type subscriber to the statement
*
* https://docs.aws.amazon.com/security-lake/latest/APIReference/API_SubscriberResource.html
*
* @param subscriberId - Identifier for the subscriberId.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
*/
onSubscriber(subscriberId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:securitylake:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:subscriber/${subscriberId}`);
}
/**
* Filters access by tags that are passed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
*
* Applies to actions:
* - .toCreateDataLake()
* - .toCreateSubscriber()
* - .toTagResource()
*
* Applies to resource types:
* - data-lake
* - subscriber
*
* @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:
* - .toCreateSubscriber()
*
* Applies to resource types:
* - data-lake
* - subscriber
*
* @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 tag keys that are passed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
*
* Applies to actions:
* - .toCreateDataLake()
* - .toCreateSubscriber()
* - .toTagResource()
* - .toUntagResource()
*
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsTagKeys(value, operator) {
return this.if(`aws:TagKeys`, value, operator ?? 'StringLike');
}
}
exports.Securitylake = Securitylake;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHlsYWtlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2VjdXJpdHlsYWtlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUV6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7T0FJRztJQUNILFlBQVksR0FBWTtRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFSTixrQkFBYSxHQUFHLGNBQWMsQ0FBQztRQXFrQjVCLG9CQUFlLEdBQW9CO1lBQzNDLEtBQUssRUFBRTtnQkFDTCxvQkFBb0I7Z0JBQ3BCLHVCQUF1QjtnQkFDdkIsZ0JBQWdCO2dCQUNoQixxQ0FBcUM7Z0JBQ3JDLHlDQUF5QztnQkFDekMsa0JBQWtCO2dCQUNsQiw4QkFBOEI7Z0JBQzlCLG9CQUFvQjtnQkFDcEIsdUJBQXVCO2dCQUN2QixnQkFBZ0I7Z0JBQ2hCLHFDQUFxQztnQkFDckMseUNBQXlDO2dCQUN6QyxrQkFBa0I7Z0JBQ2xCLDhCQUE4QjtnQkFDOUIsMENBQTBDO2dCQUMxQyx3Q0FBd0M7Z0JBQ3hDLGdCQUFnQjtnQkFDaEIscUNBQXFDO2dCQUNyQyxrQkFBa0I7Z0JBQ2xCLDhCQUE4QjthQUMvQjtZQUNELElBQUksRUFBRTtnQkFDSixrQ0FBa0M7Z0JBQ2xDLHNDQUFzQztnQkFDdEMsb0JBQW9CO2dCQUNwQixlQUFlO2FBQ2hCO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLHdCQUF3QjtnQkFDeEIsZUFBZTtnQkFDZixnQkFBZ0I7Z0JBQ2hCLGlCQUFpQjtnQkFDakIscUJBQXFCO2FBQ3RCO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLGFBQWE7Z0JBQ2IsZUFBZTthQUNoQjtTQUNGLENBQUM7SUFwbUJGLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7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QUFZLENBQUMsS0FBd0IsRUFBRSxRQUE0QjtRQUN4RSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztDQUNGO0FBOXNCRCxvQ0E4c0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3NlY3VyaXR5bGFrZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9uc2VjdXJpdHlsYWtlLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgU2VjdXJpdHlsYWtlIGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAnc2VjdXJpdHlsYWtlJztcblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtzZWN1cml0eWxha2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2FtYXpvbnNlY3VyaXR5bGFrZS5odG1sKS5cbiAgICpcbiAgICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvcihzaWQ/OiBzdHJpbmcpIHtcbiAgICBzdXBlcihzaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGVuYWJsZSBhbnkgc291cmNlIHR5cGUgaW4gYW55IHJlZ2lvbiBmb3IgYWNjb3VudHMgdGhhdCBhcmUgZWl0aGVyIHBhcnQgb2YgYSB0cnVzdGVkIG9yZ2FuaXphdGlvbiBvciBzdGFuZGFsb25lIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBnbHVlOkNyZWF0ZURhdGFiYXNlXG4gICAqIC0gZ2x1ZTpDcmVhdGVUYWJsZVxuICAgKiAtIGdsdWU6R2V0RGF0YWJhc2VcbiAgICogLSBnbHVlOkdldFRhYmxlXG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0ga21zOkNyZWF0ZUdyYW50XG4gICAqIC0ga21zOkRlc2NyaWJlS2V5XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUF3c0xvZ1NvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVBd3NMb2dTb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUF3c0xvZ1NvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCBhIGN1c3RvbSBzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBnbHVlOkNyZWF0ZUNyYXdsZXJcbiAgICogLSBnbHVlOkNyZWF0ZURhdGFiYXNlXG4gICAqIC0gZ2x1ZTpDcmVhdGVUYWJsZVxuICAgKiAtIGdsdWU6U3RhcnRDcmF3bGVyU2NoZWR1bGVcbiAgICogLSBpYW06RGVsZXRlUm9sZVBvbGljeVxuICAgKiAtIGlhbTpHZXRSb2xlXG4gICAqIC0gaWFtOlBhc3NSb2xlXG4gICAqIC0gaWFtOlB1dFJvbGVQb2xpY3lcbiAgICogLSBrbXM6Q3JlYXRlR3JhbnRcbiAgICogLSBrbXM6RGVzY3JpYmVLZXlcbiAgICogLSBrbXM6R2VuZXJhdGVEYXRhS2V5XG4gICAqIC0gbGFrZWZvcm1hdGlvbjpHcmFudFBlcm1pc3Npb25zXG4gICAqIC0gbGFrZWZvcm1hdGlvbjpSZWdpc3RlclJlc291cmNlXG4gICAqIC0gczM6TGlzdEJ1Y2tldFxuICAgKiAtIHMzOlB1dE9iamVjdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVDdXN0b21Mb2dTb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQ3VzdG9tTG9nU291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVDdXN0b21Mb2dTb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcgc2VjdXJpdHkgZGF0YSBsYWtlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZXZlbnRzOlB1dFJ1bGVcbiAgICogLSBldmVudHM6UHV0VGFyZ2V0c1xuICAgKiAtIGlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVxuICAgKiAtIGlhbTpEZWxldGVSb2xlUG9saWN5XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06TGlzdEF0dGFjaGVkUm9sZVBvbGljaWVzXG4gICAqIC0gaWFtOlBhc3NSb2xlXG4gICAqIC0gaWFtOlB1dFJvbGVQb2xpY3lcbiAgICogLSBrbXM6Q3JlYXRlR3JhbnRcbiAgICogLSBrbXM6RGVzY3JpYmVLZXlcbiAgICogLSBsYWtlZm9ybWF0aW9uOkdldERhdGFMYWtlU2V0dGluZ3NcbiAgICogLSBsYWtlZm9ybWF0aW9uOlB1dERhdGFMYWtlU2V0dGluZ3NcbiAgICogLSBsYW1iZGE6QWRkUGVybWlzc2lvblxuICAgKiAtIGxhbWJkYTpDcmVhdGVFdmVudFNvdXJjZU1hcHBpbmdcbiAgICogLSBsYW1iZGE6Q3JlYXRlRnVuY3Rpb25cbiAgICogLSBvcmdhbml6YXRpb25zOkRlc2NyaWJlT3JnYW5pemF0aW9uXG4gICAqIC0gb3JnYW5pemF0aW9uczpMaXN0QWNjb3VudHNcbiAgICogLSBvcmdhbml6YXRpb25zOkxpc3REZWxlZ2F0ZWRTZXJ2aWNlc0ZvckFjY291bnRcbiAgICogLSBzMzpDcmVhdGVCdWNrZXRcbiAgICogLSBzMzpHZXRPYmplY3RcbiAgICogLSBzMzpHZXRPYmplY3RWZXJzaW9uXG4gICAqIC0gczM6TGlzdEJ1Y2tldFxuICAgKiAtIHMzOlB1dEJ1Y2tldFBvbGljeVxuICAgKiAtIHMzOlB1dEJ1Y2tldFB1YmxpY0FjY2Vzc0Jsb2NrXG4gICAqIC0gczM6UHV0QnVja2V0VmVyc2lvbmluZ1xuICAgKiAtIHNxczpDcmVhdGVRdWV1ZVxuICAgKiAtIHNxczpHZXRRdWV1ZUF0dHJpYnV0ZXNcbiAgICogLSBzcXM6U2V0UXVldWVBdHRyaWJ1dGVzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZURhdGFMYWtlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZURhdGFMYWtlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVEYXRhTGFrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBpbnN0YW50IG5vdGlmaWNhdGlvbnMgYWJvdXQgZXhjZXB0aW9ucy4gU3Vic2NyaWJlcyB0byB0aGUgU05TIHRvcGljcyBmb3IgZXhjZXB0aW9uIG5vdGlmaWNhdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVEYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVEYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlRGF0YUxha2VFeGNlcHRpb25TdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRvbWF0aWNhbGx5IGVuYWJsZSBBbWF6b24gU2VjdXJpdHkgTGFrZSBmb3IgbmV3IG1lbWJlciBhY2NvdW50cyBpbiB5b3VyIG9yZ2FuaXphdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZURhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVEYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZURhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHN1YnNjcmliZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOkNyZWF0ZVJvbGVcbiAgICogLSBpYW06RGVsZXRlUm9sZVBvbGljeVxuICAgKiAtIGlhbTpHZXRSb2xlXG4gICAqIC0gaWFtOlB1dFJvbGVQb2xpY3lcbiAgICogLSBsYWtlZm9ybWF0aW9uOkdyYW50UGVybWlzc2lvbnNcbiAgICogLSBsYWtlZm9ybWF0aW9uOkxpc3RQZXJtaXNzaW9uc1xuICAgKiAtIGxha2Vmb3JtYXRpb246UmVnaXN0ZXJSZXNvdXJjZVxuICAgKiAtIGxha2Vmb3JtYXRpb246UmV2b2tlUGVybWlzc2lvbnNcbiAgICogLSByYW06R2V0UmVzb3VyY2VTaGFyZUFzc29jaWF0aW9uc1xuICAgKiAtIHJhbTpHZXRSZXNvdXJjZVNoYXJlc1xuICAgKiAtIHJhbTpVcGRhdGVSZXNvdXJjZVNoYXJlXG4gICAqIC0gczM6UHV0T2JqZWN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVN1YnNjcmliZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU3Vic2NyaWJlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU3Vic2NyaWJlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHdlYmhvb2sgaW52b2NhdGlvbiB0byBub3RpZnkgYSBjbGllbnQgd2hlbiB0aGVyZSBpcyBuZXcgZGF0YSBpbiB0aGUgZGF0YSBsYWtlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZXZlbnRzOkNyZWF0ZUFwaURlc3RpbmF0aW9uXG4gICAqIC0gZXZlbnRzOkNyZWF0ZUNvbm5lY3Rpb25cbiAgICogLSBldmVudHM6RGVzY3JpYmVSdWxlXG4gICAqIC0gZXZlbnRzOkxpc3RBcGlEZXN0aW5hdGlvbnNcbiAgICogLSBldmVudHM6TGlzdENvbm5lY3Rpb25zXG4gICAqIC0gZXZlbnRzOlB1dFJ1bGVcbiAgICogLSBldmVudHM6UHV0VGFyZ2V0c1xuICAgKiAtIGlhbTpEZWxldGVSb2xlUG9saWN5XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06UGFzc1JvbGVcbiAgICogLSBzMzpHZXRCdWNrZXROb3RpZmljYXRpb25cbiAgICogLSBzMzpQdXRCdWNrZXROb3RpZmljYXRpb25cbiAgICogLSBzcXM6Q3JlYXRlUXVldWVcbiAgICogLSBzcXM6RGVsZXRlUXVldWVcbiAgICogLSBzcXM6R2V0UXVldWVBdHRyaWJ1dGVzXG4gICAqIC0gc3FzOkdldFF1ZXVlVXJsXG4gICAqIC0gc3FzOlNldFF1ZXVlQXR0cmlidXRlc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVTdWJzY3JpYmVyTm90aWZpY2F0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVN1YnNjcmliZXJOb3RpZmljYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVN1YnNjcmliZXJOb3RpZmljYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNhYmxlIGFueSBzb3VyY2UgdHlwZSBpbiBhbnkgcmVnaW9uIGZvciBhY2NvdW50cyB0aGF0IGFyZSBwYXJ0IG9mIGEgdHJ1c3RlZCBvcmdhbml6YXRpb24gb3Igc3RhbmRhbG9uZSBhY2NvdW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUF3c0xvZ1NvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVBd3NMb2dTb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUF3c0xvZ1NvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBhIGN1c3RvbSBzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBnbHVlOlN0b3BDcmF3bGVyU2NoZWR1bGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlQ3VzdG9tTG9nU291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUN1c3RvbUxvZ1NvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQ3VzdG9tTG9nU291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHNlY3VyaXR5IGRhdGEgbGFrZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIG9yZ2FuaXphdGlvbnM6RGVzY3JpYmVPcmdhbml6YXRpb25cbiAgICogLSBvcmdhbml6YXRpb25zOkxpc3REZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yc1xuICAgKiAtIG9yZ2FuaXphdGlvbnM6TGlzdERlbGVnYXRlZFNlcnZpY2VzRm9yQWNjb3VudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVEYXRhTGFrZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVEYXRhTGFrZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlRGF0YUxha2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1bnN1YnNjcmliZSBmcm9tIFNOUyB0b3BpY3MgZm9yIGV4Y2VwdGlvbiBub3RpZmljYXRpb25zLiBSZW1vdmVzIGV4Y2VwdGlvbiBub3RpZmljYXRpb25zIGZvciB0aGUgU05TIHRvcGljXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlRGF0YUxha2VFeGNlcHRpb25TdWJzY3JpcHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlRGF0YUxha2VFeGNlcHRpb25TdWJzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZURhdGFMYWtlRXhjZXB0aW9uU3Vic2NyaXB0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBhdXRvbWF0aWMgZW5hYmxlbWVudCBvZiBBbWF6b24gU2VjdXJpdHkgTGFrZSBhY2Nlc3MgZm9yIG5ldyBvcmdhbml6YXRpb24gYWNjb3VudHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVEYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlRGF0YUxha2VPcmdhbml6YXRpb25Db25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVEYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBzdWJzY3JpYmVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZXZlbnRzOkRlbGV0ZUFwaURlc3RpbmF0aW9uXG4gICAqIC0gZXZlbnRzOkRlbGV0ZUNvbm5lY3Rpb25cbiAgICogLSBldmVudHM6RGVsZXRlUnVsZVxuICAgKiAtIGV2ZW50czpEZXNjcmliZVJ1bGVcbiAgICogLSBldmVudHM6TGlzdEFwaURlc3RpbmF0aW9uc1xuICAgKiAtIGV2ZW50czpMaXN0VGFyZ2V0c0J5UnVsZVxuICAgKiAtIGV2ZW50czpSZW1vdmVUYXJnZXRzXG4gICAqIC0gaWFtOkRlbGV0ZVJvbGVcbiAgICogLSBpYW06RGVsZXRlUm9sZVBvbGljeVxuICAgKiAtIGlhbTpHZXRSb2xlXG4gICAqIC0gaWFtOkxpc3RSb2xlUG9saWNpZXNcbiAgICogLSBsYWtlZm9ybWF0aW9uOkxpc3RQZXJtaXNzaW9uc1xuICAgKiAtIGxha2Vmb3JtYXRpb246UmV2b2tlUGVybWlzc2lvbnNcbiAgICogLSBzcXM6RGVsZXRlUXVldWVcbiAgICogLSBzcXM6R2V0UXVldWVVcmxcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU3Vic2NyaWJlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTdWJzY3JpYmVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVTdWJzY3JpYmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIGEgd2ViaG9vayBpbnZvY2F0aW9uIHRvIG5vdGlmeSBhIGNsaWVudCB3aGVuIHRoZXJlIGlzIG5ldyBkYXRhIGluIHRoZSBkYXRhIGxha2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBldmVudHM6RGVsZXRlQXBpRGVzdGluYXRpb25cbiAgICogLSBldmVudHM6RGVsZXRlQ29ubmVjdGlvblxuICAgKiAtIGV2ZW50czpEZWxldGVSdWxlXG4gICAqIC0gZXZlbnRzOkRlc2NyaWJlUnVsZVxuICAgKiAtIGV2ZW50czpMaXN0QXBpRGVzdGluYXRpb25zXG4gICAqIC0gZXZlbnRzOkxpc3RUYXJnZXRzQnlSdWxlXG4gICAqIC0gZXZlbnRzOlJlbW92ZVRhcmdldHNcbiAgICogLSBpYW06RGVsZXRlUm9sZVxuICAgKiAtIGlhbTpEZWxldGVSb2xlUG9saWN5XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06TGlzdFJvbGVQb2xpY2llc1xuICAgKiAtIGxha2Vmb3JtYXRpb246UmV2b2tlUGVybWlzc2lvbnNcbiAgICogLSBzcXM6RGVsZXRlUXVldWVcbiAgICogLSBzcXM6R2V0UXVldWVVcmxcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU3Vic2NyaWJlck5vdGlmaWNhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTdWJzY3JpYmVyTm90aWZpY2F0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVTdWJzY3JpYmVyTm90aWZpY2F0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBEZWxlZ2F0ZWQgQWRtaW5pc3RyYXRvciBhY2NvdW50IGFuZCBkaXNhYmxlIEFtYXpvbiBTZWN1cml0eSBMYWtlIGFzIGEgc2VydmljZSBmb3IgdGhpcyBvcmdhbml6YXRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBvcmdhbml6YXRpb25zOkRlcmVnaXN0ZXJEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yXG4gICAqIC0gb3JnYW5pemF0aW9uczpEZXNjcmliZU9yZ2FuaXphdGlvblxuICAgKiAtIG9yZ2FuaXphdGlvbnM6TGlzdERlbGVnYXRlZFNlcnZpY2VzRm9yQWNjb3VudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXJlZ2lzdGVyRGF0YUxha2VEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlcmVnaXN0ZXJEYXRhTGFrZURlbGVnYXRlZEFkbWluaXN0cmF0b3IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlcmVnaXN0ZXJEYXRhTGFrZURlbGVnYXRlZEFkbWluaXN0cmF0b3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBxdWVyeSB0aGUgcHJvdG9jb2wgYW5kIGVuZHBvaW50IHRoYXQgd2VyZSBwcm92aWRlZCB3aGVuIHN1YnNjcmliaW5nIHRvIFNOUyB0b3BpY3MgZm9yIGV4Y2VwdGlvbiBub3RpZmljYXRpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXREYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXREYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0RGF0YUxha2VFeGNlcHRpb25TdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYW4gb3JnYW5pemF0aW9uJ3MgY29uZmlndXJhdGlvbiBzZXR0aW5nIGZvciBhdXRvbWF0aWNhbGx5IGVuYWJsaW5nIEFtYXpvbiBTZWN1cml0eSBMYWtlIGFjY2VzcyBmb3IgbmV3IG9yZ2FuaXphdGlvbiBhY2NvdW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gb3JnYW5pemF0aW9uczpEZXNjcmliZU9yZ2FuaXphdGlvblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXREYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0RGF0YUxha2VPcmdhbml6YXRpb25Db25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXREYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYSBzdGF0aWMgc25hcHNob3Qgb2YgdGhlIHNlY3VyaXR5IGRhdGEgbGFrZSBpbiB0aGUgY3VycmVudCByZWdpb24uIFRoZSBzbmFwc2hvdCBpbmNsdWRlcyBlbmFibGVkIGFjY291bnRzIGFuZCBsb2cgc291cmNlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0RGF0YUxha2VTb3VyY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldERhdGFMYWtlU291cmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0RGF0YUxha2VTb3VyY2VzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IHN1YnNjcmliZXIgdGhhdCBpcyBhbHJlYWR5IGNyZWF0ZWRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldFN1YnNjcmliZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0U3Vic2NyaWJlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U3Vic2NyaWJlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgbGlzdCBvZiBhbGwgbm9uLXJldHJ5YWJsZSBmYWlsdXJlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdERhdGFMYWtlRXhjZXB0aW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0RGF0YUxha2VFeGNlcHRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RGF0YUxha2VFeGNlcHRpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2VjdXJpdHkgZGF0YSBsYWtlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdERhdGFMYWtlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0RGF0YUxha2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RGF0YUxha2VzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmlldyB0aGUgZW5hYmxlZCBhY2NvdW50cy4gWW91IGNhbiB2aWV3IHRoZSBlbmFibGVkIHNvdXJjZXMgaW4gdGhlIGVuYWJsZWQgcmVnaW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdExvZ1NvdXJjZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdExvZ1NvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RMb2dTb3VyY2VzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhbGwgc3Vic2NyaWJlcnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RTdWJzY3JpYmVycy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U3Vic2NyaWJlcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RTdWJzY3JpYmVycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYWxsIHRhZ3MgZm9yIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFnc0ZvclJlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzaWduYXRlIGFuIGFjY291bnQgYXMgdGhlIEFtYXpvbiBTZWN1cml0eSBMYWtlIGFkbWluaXN0cmF0b3IgYWNjb3VudCBmb3IgdGhlIG9yZ2FuaXphdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVxuICAgKiAtIG9yZ2FuaXphdGlvbnM6RGVzY3JpYmVPcmdhbml6YXRpb25cbiAgICogLSBvcmdhbml6YXRpb25zOkVuYWJsZUFXU1NlcnZpY2VBY2Nlc3NcbiAgICogLSBvcmdhbml6YXRpb25zOkxpc3REZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yc1xuICAgKiAtIG9yZ2FuaXphdGlvbnM6TGlzdERlbGVnYXRlZFNlcnZpY2VzRm9yQWNjb3VudFxuICAgKiAtIG9yZ2FuaXphdGlvbnM6UmVnaXN0ZXJEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlZ2lzdGVyRGF0YUxha2VEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlZ2lzdGVyRGF0YUxha2VEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZWdpc3RlckRhdGFMYWtlRGVsZWdhdGVkQWRtaW5pc3RyYXRvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCB0YWdzIHRvIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1RhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRhZ3MgZnJvbSB0aGUgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VudGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVW50YWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVW50YWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhIHNlY3VyaXR5IGRhdGEgbGFrZVxuICA