UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

693 lines 61.7 kB
"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 { /** * 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() * - .ifAwsResourceTag() * - .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: * - .toCreateDataLake() * - .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'); } /** * Statement provider for service [securitylake](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsecuritylake.html). * */ constructor(props) { super(props); 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' ] }; } } exports.Securitylake = Securitylake; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHlsYWtlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2VjdXJpdHlsYWtlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0ksb0JBQW9CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F1Qkc7SUFDSSx1QkFBdUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXlDRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0kscUNBQXFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSx5Q0FBeUM7UUFDOUMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHlDQUF5QyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BeUJHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXlCRztJQUNJLDhCQUE4QjtRQUNuQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsOEJBQThCLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksb0JBQW9CO1FBQ3pC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LGVBQWU7Z0JBQ2YsZ0JBQWdCO2dCQUNoQixpQkFBaUI7Z0JBQ2pCLHFCQUFxQjthQUN0QjtZQUNELE9BQU8sRUFBRTtnQkFDUCxhQUFhO2dCQUNiLGVBQWU7YUFDaEI7U0FDRixDQUFDO0lBd0dGLENBQUM7Q0FDRjtBQS9zQkQsb0NBK3NCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBhd3NfaWFtIGFzIGlhbSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbc2VjdXJpdHlsYWtlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hbWF6b25zZWN1cml0eWxha2UuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTZWN1cml0eWxha2UgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdzZWN1cml0eWxha2UnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBlbmFibGUgYW55IHNvdXJjZSB0eXBlIGluIGFueSByZWdpb24gZm9yIGFjY291bnRzIHRoYXQgYXJlIGVpdGhlciBwYXJ0IG9mIGEgdHJ1c3RlZCBvcmdhbml6YXRpb24gb3Igc3RhbmRhbG9uZSBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZ2x1ZTpDcmVhdGVEYXRhYmFzZVxuICAgKiAtIGdsdWU6Q3JlYXRlVGFibGVcbiAgICogLSBnbHVlOkdldERhdGFiYXNlXG4gICAqIC0gZ2x1ZTpHZXRUYWJsZVxuICAgKiAtIGlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVxuICAgKiAtIGttczpDcmVhdGVHcmFudFxuICAgKiAtIGttczpEZXNjcmliZUtleVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVBd3NMb2dTb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQXdzTG9nU291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVBd3NMb2dTb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgYSBjdXN0b20gc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZ2x1ZTpDcmVhdGVDcmF3bGVyXG4gICAqIC0gZ2x1ZTpDcmVhdGVEYXRhYmFzZVxuICAgKiAtIGdsdWU6Q3JlYXRlVGFibGVcbiAgICogLSBnbHVlOlN0YXJ0Q3Jhd2xlclNjaGVkdWxlXG4gICAqIC0gaWFtOkRlbGV0ZVJvbGVQb2xpY3lcbiAgICogLSBpYW06R2V0Um9sZVxuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKiAtIGlhbTpQdXRSb2xlUG9saWN5XG4gICAqIC0ga21zOkNyZWF0ZUdyYW50XG4gICAqIC0ga21zOkRlc2NyaWJlS2V5XG4gICAqIC0ga21zOkdlbmVyYXRlRGF0YUtleVxuICAgKiAtIGxha2Vmb3JtYXRpb246R3JhbnRQZXJtaXNzaW9uc1xuICAgKiAtIGxha2Vmb3JtYXRpb246UmVnaXN0ZXJSZXNvdXJjZVxuICAgKiAtIHMzOkxpc3RCdWNrZXRcbiAgICogLSBzMzpQdXRPYmplY3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlQ3VzdG9tTG9nU291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUN1c3RvbUxvZ1NvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQ3VzdG9tTG9nU291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3IHNlY3VyaXR5IGRhdGEgbGFrZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBldmVudHM6UHV0UnVsZVxuICAgKiAtIGV2ZW50czpQdXRUYXJnZXRzXG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0gaWFtOkRlbGV0ZVJvbGVQb2xpY3lcbiAgICogLSBpYW06R2V0Um9sZVxuICAgKiAtIGlhbTpMaXN0QXR0YWNoZWRSb2xlUG9saWNpZXNcbiAgICogLSBpYW06UGFzc1JvbGVcbiAgICogLSBpYW06UHV0Um9sZVBvbGljeVxuICAgKiAtIGttczpDcmVhdGVHcmFudFxuICAgKiAtIGttczpEZXNjcmliZUtleVxuICAgKiAtIGxha2Vmb3JtYXRpb246R2V0RGF0YUxha2VTZXR0aW5nc1xuICAgKiAtIGxha2Vmb3JtYXRpb246UHV0RGF0YUxha2VTZXR0aW5nc1xuICAgKiAtIGxhbWJkYTpBZGRQZXJtaXNzaW9uXG4gICAqIC0gbGFtYmRhOkNyZWF0ZUV2ZW50U291cmNlTWFwcGluZ1xuICAgKiAtIGxhbWJkYTpDcmVhdGVGdW5jdGlvblxuICAgKiAtIG9yZ2FuaXphdGlvbnM6RGVzY3JpYmVPcmdhbml6YXRpb25cbiAgICogLSBvcmdhbml6YXRpb25zOkxpc3RBY2NvdW50c1xuICAgKiAtIG9yZ2FuaXphdGlvbnM6TGlzdERlbGVnYXRlZFNlcnZpY2VzRm9yQWNjb3VudFxuICAgKiAtIHMzOkNyZWF0ZUJ1Y2tldFxuICAgKiAtIHMzOkdldE9iamVjdFxuICAgKiAtIHMzOkdldE9iamVjdFZlcnNpb25cbiAgICogLSBzMzpMaXN0QnVja2V0XG4gICAqIC0gczM6UHV0QnVja2V0UG9saWN5XG4gICAqIC0gczM6UHV0QnVja2V0UHVibGljQWNjZXNzQmxvY2tcbiAgICogLSBzMzpQdXRCdWNrZXRWZXJzaW9uaW5nXG4gICAqIC0gc3FzOkNyZWF0ZVF1ZXVlXG4gICAqIC0gc3FzOkdldFF1ZXVlQXR0cmlidXRlc1xuICAgKiAtIHNxczpTZXRRdWV1ZUF0dHJpYnV0ZXNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlRGF0YUxha2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlRGF0YUxha2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZURhdGFMYWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluc3RhbnQgbm90aWZpY2F0aW9ucyBhYm91dCBleGNlcHRpb25zLiBTdWJzY3JpYmVzIHRvIHRoZSBTTlMgdG9waWNzIGZvciBleGNlcHRpb24gbm90aWZpY2F0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZURhdGFMYWtlRXhjZXB0aW9uU3Vic2NyaXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZURhdGFMYWtlRXhjZXB0aW9uU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVEYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGF1dG9tYXRpY2FsbHkgZW5hYmxlIEFtYXpvbiBTZWN1cml0eSBMYWtlIGZvciBuZXcgbWVtYmVyIGFjY291bnRzIGluIHlvdXIgb3JnYW5pemF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlRGF0YUxha2VPcmdhbml6YXRpb25Db25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZURhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlRGF0YUxha2VPcmdhbml6YXRpb25Db25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgc3Vic2NyaWJlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBpYW06Q3JlYXRlUm9sZVxuICAgKiAtIGlhbTpEZWxldGVSb2xlUG9saWN5XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06UHV0Um9sZVBvbGljeVxuICAgKiAtIGxha2Vmb3JtYXRpb246R3JhbnRQZXJtaXNzaW9uc1xuICAgKiAtIGxha2Vmb3JtYXRpb246TGlzdFBlcm1pc3Npb25zXG4gICAqIC0gbGFrZWZvcm1hdGlvbjpSZWdpc3RlclJlc291cmNlXG4gICAqIC0gbGFrZWZvcm1hdGlvbjpSZXZva2VQZXJtaXNzaW9uc1xuICAgKiAtIHJhbTpHZXRSZXNvdXJjZVNoYXJlQXNzb2NpYXRpb25zXG4gICAqIC0gcmFtOkdldFJlc291cmNlU2hhcmVzXG4gICAqIC0gcmFtOlVwZGF0ZVJlc291cmNlU2hhcmVcbiAgICogLSBzMzpQdXRPYmplY3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlU3Vic2NyaWJlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVTdWJzY3JpYmVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVTdWJzY3JpYmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgd2ViaG9vayBpbnZvY2F0aW9uIHRvIG5vdGlmeSBhIGNsaWVudCB3aGVuIHRoZXJlIGlzIG5ldyBkYXRhIGluIHRoZSBkYXRhIGxha2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBldmVudHM6Q3JlYXRlQXBpRGVzdGluYXRpb25cbiAgICogLSBldmVudHM6Q3JlYXRlQ29ubmVjdGlvblxuICAgKiAtIGV2ZW50czpEZXNjcmliZVJ1bGVcbiAgICogLSBldmVudHM6TGlzdEFwaURlc3RpbmF0aW9uc1xuICAgKiAtIGV2ZW50czpMaXN0Q29ubmVjdGlvbnNcbiAgICogLSBldmVudHM6UHV0UnVsZVxuICAgKiAtIGV2ZW50czpQdXRUYXJnZXRzXG4gICAqIC0gaWFtOkRlbGV0ZVJvbGVQb2xpY3lcbiAgICogLSBpYW06R2V0Um9sZVxuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKiAtIHMzOkdldEJ1Y2tldE5vdGlmaWNhdGlvblxuICAgKiAtIHMzOlB1dEJ1Y2tldE5vdGlmaWNhdGlvblxuICAgKiAtIHNxczpDcmVhdGVRdWV1ZVxuICAgKiAtIHNxczpEZWxldGVRdWV1ZVxuICAgKiAtIHNxczpHZXRRdWV1ZUF0dHJpYnV0ZXNcbiAgICogLSBzcXM6R2V0UXVldWVVcmxcbiAgICogLSBzcXM6U2V0UXVldWVBdHRyaWJ1dGVzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVN1YnNjcmliZXJOb3RpZmljYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU3Vic2NyaWJlck5vdGlmaWNhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU3Vic2NyaWJlck5vdGlmaWNhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRpc2FibGUgYW55IHNvdXJjZSB0eXBlIGluIGFueSByZWdpb24gZm9yIGFjY291bnRzIHRoYXQgYXJlIHBhcnQgb2YgYSB0cnVzdGVkIG9yZ2FuaXphdGlvbiBvciBzdGFuZGFsb25lIGFjY291bnRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlQXdzTG9nU291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUF3c0xvZ1NvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQXdzTG9nU291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIGEgY3VzdG9tIHNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGdsdWU6U3RvcENyYXdsZXJTY2hlZHVsZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVDdXN0b21Mb2dTb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlQ3VzdG9tTG9nU291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVDdXN0b21Mb2dTb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgc2VjdXJpdHkgZGF0YSBsYWtlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gb3JnYW5pemF0aW9uczpEZXNjcmliZU9yZ2FuaXphdGlvblxuICAgKiAtIG9yZ2FuaXphdGlvbnM6TGlzdERlbGVnYXRlZEFkbWluaXN0cmF0b3JzXG4gICAqIC0gb3JnYW5pemF0aW9uczpMaXN0RGVsZWdhdGVkU2VydmljZXNGb3JBY2NvdW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZURhdGFMYWtlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZURhdGFMYWtlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVEYXRhTGFrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVuc3Vic2NyaWJlIGZyb20gU05TIHRvcGljcyBmb3IgZXhjZXB0aW9uIG5vdGlmaWNhdGlvbnMuIFJlbW92ZXMgZXhjZXB0aW9uIG5vdGlmaWNhdGlvbnMgZm9yIHRoZSBTTlMgdG9waWNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVEYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVEYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlRGF0YUxha2VFeGNlcHRpb25TdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIGF1dG9tYXRpYyBlbmFibGVtZW50IG9mIEFtYXpvbiBTZWN1cml0eSBMYWtlIGFjY2VzcyBmb3IgbmV3IG9yZ2FuaXphdGlvbiBhY2NvdW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZURhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVEYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZURhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIHN1YnNjcmliZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBldmVudHM6RGVsZXRlQXBpRGVzdGluYXRpb25cbiAgICogLSBldmVudHM6RGVsZXRlQ29ubmVjdGlvblxuICAgKiAtIGV2ZW50czpEZWxldGVSdWxlXG4gICAqIC0gZXZlbnRzOkRlc2NyaWJlUnVsZVxuICAgKiAtIGV2ZW50czpMaXN0QXBpRGVzdGluYXRpb25zXG4gICAqIC0gZXZlbnRzOkxpc3RUYXJnZXRzQnlSdWxlXG4gICAqIC0gZXZlbnRzOlJlbW92ZVRhcmdldHNcbiAgICogLSBpYW06RGVsZXRlUm9sZVxuICAgKiAtIGlhbTpEZWxldGVSb2xlUG9saWN5XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06TGlzdFJvbGVQb2xpY2llc1xuICAgKiAtIGxha2Vmb3JtYXRpb246TGlzdFBlcm1pc3Npb25zXG4gICAqIC0gbGFrZWZvcm1hdGlvbjpSZXZva2VQZXJtaXNzaW9uc1xuICAgKiAtIHNxczpEZWxldGVRdWV1ZVxuICAgKiAtIHNxczpHZXRRdWV1ZVVybFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVTdWJzY3JpYmVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVN1YnNjcmliZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVN1YnNjcmliZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgYSB3ZWJob29rIGludm9jYXRpb24gdG8gbm90aWZ5IGEgY2xpZW50IHdoZW4gdGhlcmUgaXMgbmV3IGRhdGEgaW4gdGhlIGRhdGEgbGFrZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGV2ZW50czpEZWxldGVBcGlEZXN0aW5hdGlvblxuICAgKiAtIGV2ZW50czpEZWxldGVDb25uZWN0aW9uXG4gICAqIC0gZXZlbnRzOkRlbGV0ZVJ1bGVcbiAgICogLSBldmVudHM6RGVzY3JpYmVSdWxlXG4gICAqIC0gZXZlbnRzOkxpc3RBcGlEZXN0aW5hdGlvbnNcbiAgICogLSBldmVudHM6TGlzdFRhcmdldHNCeVJ1bGVcbiAgICogLSBldmVudHM6UmVtb3ZlVGFyZ2V0c1xuICAgKiAtIGlhbTpEZWxldGVSb2xlXG4gICAqIC0gaWFtOkRlbGV0ZVJvbGVQb2xpY3lcbiAgICogLSBpYW06R2V0Um9sZVxuICAgKiAtIGlhbTpMaXN0Um9sZVBvbGljaWVzXG4gICAqIC0gbGFrZWZvcm1hdGlvbjpSZXZva2VQZXJtaXNzaW9uc1xuICAgKiAtIHNxczpEZWxldGVRdWV1ZVxuICAgKiAtIHNxczpHZXRRdWV1ZVVybFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVTdWJzY3JpYmVyTm90aWZpY2F0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVN1YnNjcmliZXJOb3RpZmljYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVN1YnNjcmliZXJOb3RpZmljYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIERlbGVnYXRlZCBBZG1pbmlzdHJhdG9yIGFjY291bnQgYW5kIGRpc2FibGUgQW1hem9uIFNlY3VyaXR5IExha2UgYXMgYSBzZXJ2aWNlIGZvciB0aGlzIG9yZ2FuaXphdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIG9yZ2FuaXphdGlvbnM6RGVyZWdpc3RlckRlbGVnYXRlZEFkbWluaXN0cmF0b3JcbiAgICogLSBvcmdhbml6YXRpb25zOkRlc2NyaWJlT3JnYW5pemF0aW9uXG4gICAqIC0gb3JnYW5pemF0aW9uczpMaXN0RGVsZWdhdGVkU2VydmljZXNGb3JBY2NvdW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlcmVnaXN0ZXJEYXRhTGFrZURlbGVnYXRlZEFkbWluaXN0cmF0b3IuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVyZWdpc3RlckRhdGFMYWtlRGVsZWdhdGVkQWRtaW5pc3RyYXRvcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVyZWdpc3RlckRhdGFMYWtlRGVsZWdhdGVkQWRtaW5pc3RyYXRvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHF1ZXJ5IHRoZSBwcm90b2NvbCBhbmQgZW5kcG9pbnQgdGhhdCB3ZXJlIHByb3ZpZGVkIHdoZW4gc3Vic2NyaWJpbmcgdG8gU05TIHRvcGljcyBmb3IgZXhjZXB0aW9uIG5vdGlmaWNhdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldERhdGFMYWtlRXhjZXB0aW9uU3Vic2NyaXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldERhdGFMYWtlRXhjZXB0aW9uU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXREYXRhTGFrZUV4Y2VwdGlvblN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBhbiBvcmdhbml6YXRpb24ncyBjb25maWd1cmF0aW9uIHNldHRpbmcgZm9yIGF1dG9tYXRpY2FsbHkgZW5hYmxpbmcgQW1hem9uIFNlY3VyaXR5IExha2UgYWNjZXNzIGZvciBuZXcgb3JnYW5pemF0aW9uIGFjY291bnRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBvcmdhbml6YXRpb25zOkRlc2NyaWJlT3JnYW5pemF0aW9uXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZWN1cml0eS1sYWtlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldERhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXREYXRhTGFrZU9yZ2FuaXphdGlvbkNvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldERhdGFMYWtlT3JnYW5pemF0aW9uQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBhIHN0YXRpYyBzbmFwc2hvdCBvZiB0aGUgc2VjdXJpdHkgZGF0YSBsYWtlIGluIHRoZSBjdXJyZW50IHJlZ2lvbi4gVGhlIHNuYXBzaG90IGluY2x1ZGVzIGVuYWJsZWQgYWNjb3VudHMgYW5kIGxvZyBzb3VyY2VzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXREYXRhTGFrZVNvdXJjZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0RGF0YUxha2VTb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXREYXRhTGFrZVNvdXJjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgaW5mb3JtYXRpb24gYWJvdXQgc3Vic2NyaWJlciB0aGF0IGlzIGFscmVhZHkgY3JlYXRlZFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0U3Vic2NyaWJlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTdWJzY3JpYmVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTdWJzY3JpYmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHRoZSBsaXN0IG9mIGFsbCBub24tcmV0cnlhYmxlIGZhaWx1cmVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0RGF0YUxha2VFeGNlcHRpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3REYXRhTGFrZUV4Y2VwdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3REYXRhTGFrZUV4Y2VwdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IHRoZSBzZWN1cml0eSBkYXRhIGxha2VzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0RGF0YUxha2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3REYXRhTGFrZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3REYXRhTGFrZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB2aWV3IHRoZSBlbmFibGVkIGFjY291bnRzLiBZb3UgY2FuIHZpZXcgdGhlIGVuYWJsZWQgc291cmNlcyBpbiB0aGUgZW5hYmxlZCByZWdpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0TG9nU291cmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0TG9nU291cmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdExvZ1NvdXJjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBzdWJzY3JpYmVyc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFN1YnNjcmliZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RTdWJzY3JpYmVycygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFN1YnNjcmliZXJzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhbGwgdGFncyBmb3IgdGhlIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNpZ25hdGUgYW4gYWNjb3VudCBhcyB0aGUgQW1hem9uIFNlY3VyaXR5IExha2UgYWRtaW5pc3RyYXRvciBhY2NvdW50IGZvciB0aGUgb3JnYW5pemF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0gb3JnYW5pemF0aW9uczpEZXNjcmliZU9yZ2FuaXphdGlvblxuICAgKiAtIG9yZ2FuaXphdGlvbnM6RW5hYmxlQVdTU2VydmljZUFjY2Vzc1xuICAgKiAtIG9yZ2FuaXphdGlvbnM6TGlzdERlbGVnYXRlZEFkbWluaXN0cmF0b3JzXG4gICAqIC0gb3JnYW5pemF0aW9uczpMaXN0RGVsZWdhdGVkU2VydmljZXNGb3JBY2NvdW50XG4gICAqIC0gb3JnYW5pemF0aW9uczpSZWdpc3RlckRlbGVnYXRlZEFkbWluaXN0cmF0b3JcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVnaXN0ZXJEYXRhTGFrZURlbGVnYXRlZEFkbWluaXN0cmF0b3IuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVnaXN0ZXJEYXRhTGFrZURlbGVnYXRlZEFkbWluaXN0cmF0b3IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlZ2lzdGVyRGF0YUxha2VEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHRhZ3MgdG8gdGhlIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGFncyBmcm9tIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVW50YWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VbnRhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVbnRhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGEgc2VjdXJpdHkgZGF0YSBsYWtlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZXZlbnRzOlB1dFJ1bGVcbiAgICogLSBldmVudHM6UHV0VGFyZ2V0c1xuICAgKiAtIGlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVxuICAgKiAtIGlhbTpEZWxldGVSb2xlUG9saWN5XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06TGlzdEF0dGFjaGVkUm9sZVBvbGljaWVzXG4gICAqIC0gaWFtOlB1dFJvbGVQb2xpY3lcbiAgICogLSBrbXM6Q3JlYXRlR3JhbnRcbiAgICogLSBrbXM6RGVzY3JpYmVLZXlcbiAgICogLSBsYWtlZm9yb