UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

656 lines 56.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NeptuneGraph = void 0; const shared_1 = require("../../shared"); /** * Statement provider for service [neptune-graph](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonneptuneanalytics.html). * * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement */ class NeptuneGraph extends shared_1.PolicyStatement { /** * Grants permission to cancel an ongoing import task * * Access Level: Write * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_CancelImportTask.html */ toCancelImportTask() { return this.to('CancelImportTask'); } /** * Grants permission to cancel a query * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_CancelQuery.html */ toCancelQuery() { return this.to('CancelQuery'); } /** * Grants permission to create a new graph * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * - .ifPublicConnectivity() * * Dependent actions: * - iam:CreateServiceLinkedRole * - kms:CreateGrant * - kms:Decrypt * - kms:DescribeKey * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_CreateGraph.html */ toCreateGraph() { return this.to('CreateGraph'); } /** * Grants permission to create a new snapshot from an existing graph * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsResourceTag() * - .ifAwsTagKeys() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_CreateGraphSnapshot.html */ toCreateGraphSnapshot() { return this.to('CreateGraphSnapshot'); } /** * Grants permission to create a new graph while importing data into the new graph * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * - .ifPublicConnectivity() * * Dependent actions: * - iam:CreateServiceLinkedRole * - iam:PassRole * - kms:CreateGrant * - kms:Decrypt * - kms:DescribeKey * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_CreateGraphUsingImportTask.html */ toCreateGraphUsingImportTask() { return this.to('CreateGraphUsingImportTask'); } /** * Grants permission to create a new private graph endpoint to access the graph from within a vpc * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsResourceTag() * - .ifAwsTagKeys() * * Dependent actions: * - ec2:CreateVpcEndpoint * - ec2:DescribeAvailabilityZones * - ec2:DescribeSecurityGroups * - ec2:DescribeSubnets * - ec2:DescribeVpcAttribute * - ec2:DescribeVpcEndpoints * - ec2:DescribeVpcs * - ec2:ModifyVpcEndpoint * - route53:AssociateVPCWithHostedZone * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_CreatePrivateGraphEndpoint.html */ toCreatePrivateGraphEndpoint() { return this.to('CreatePrivateGraphEndpoint'); } /** * Grants permission to delete data via query APIs on the graph * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ExecuteQuery.html */ toDeleteDataViaQuery() { return this.to('DeleteDataViaQuery'); } /** * Grants permission to delete a graph * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_DeleteGraph.html */ toDeleteGraph() { return this.to('DeleteGraph'); } /** * Grants permission to delete a snapshot * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_DeleteGraphSnapshot.html */ toDeleteGraphSnapshot() { return this.to('DeleteGraphSnapshot'); } /** * Grants permission to delete a private graph endpoint of a graph * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * Dependent actions: * - ec2:DeleteVpcEndpoints * - ec2:DescribeAvailabilityZones * - ec2:DescribeSecurityGroups * - ec2:DescribeSubnets * - ec2:DescribeVpcAttribute * - ec2:DescribeVpcEndpoints * - ec2:DescribeVpcs * - ec2:ModifyVpcEndpoint * - route53:DisassociateVPCFromHostedZone * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_DeletePrivateGraphEndpoint.html */ toDeletePrivateGraphEndpoint() { return this.to('DeletePrivateGraphEndpoint'); } /** * Grants permission to get the engine status of the graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/#GetEngineStatus */ toGetEngineStatus() { return this.to('GetEngineStatus'); } /** * Grants permission to get details about a graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_GetGraph.html */ toGetGraph() { return this.to('GetGraph'); } /** * Grants permission to get details about a snapshot * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_GetGraphSnapshot.html */ toGetGraphSnapshot() { return this.to('GetGraphSnapshot'); } /** * Grants permission to get the summary for the data in the graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_GetGraphSummary.html */ toGetGraphSummary() { return this.to('GetGraphSummary'); } /** * Grants permission to get details about an import task * * Access Level: Read * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_GetImportTask.html */ toGetImportTask() { return this.to('GetImportTask'); } /** * Grants permission to get details about a private graph endpoint of a graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_GetPrivateGraphEndpoint.html */ toGetPrivateGraphEndpoint() { return this.to('GetPrivateGraphEndpoint'); } /** * Grants permission to check the status of a given query * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_GetQuery.html */ toGetQueryStatus() { return this.to('GetQueryStatus'); } /** * Grants permission to get the statistics for the data in the graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/#GetStatisticsStatus */ toGetStatisticsStatus() { return this.to('GetStatisticsStatus'); } /** * Grants permission to list the snapshots in your account * * Access Level: Read * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ListGraphSnapshots.html */ toListGraphSnapshots() { return this.to('ListGraphSnapshots'); } /** * Grants permission to list the graphs in your account * * Access Level: Read * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ListGraphs.html */ toListGraphs() { return this.to('ListGraphs'); } /** * Grants permission to list the import tasks in your account * * Access Level: Read * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ListImportTasks.html */ toListImportTasks() { return this.to('ListImportTasks'); } /** * Grants permission to list the private graph endpoints for a given graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ListPrivateGraphEndpoints.html */ toListPrivateGraphEndpoints() { return this.to('ListPrivateGraphEndpoints'); } /** * Grants permission to check the status of all active queries * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ListQueries.html */ toListQueries() { return this.to('ListQueries'); } /** * Grants permission to lists tag for a Neptune Analytics resource * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ListTagsForResource.html */ toListTagsForResource() { return this.to('ListTagsForResource'); } /** * Grants permission to read data via query APIs on the graph * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ExecuteQuery.html */ toReadDataViaQuery() { return this.to('ReadDataViaQuery'); } /** * Grants permission to reset a graph which deletes all data within the graph * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ResetGraph.html */ toResetGraph() { return this.to('ResetGraph'); } /** * Grants permission to create a new graph from an existing snapshot * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsResourceTag() * - .ifAwsTagKeys() * - .ifPublicConnectivity() * * Dependent actions: * - kms:CreateGrant * - kms:Decrypt * - kms:DescribeKey * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_RestoreGraphFromSnapshot.html */ toRestoreGraphFromSnapshot() { return this.to('RestoreGraphFromSnapshot'); } /** * Grants permission to import data into an existing graph * * Access Level: Write * * Dependent actions: * - iam:PassRole * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_StartImportTask.html */ toStartImportTask() { return this.to('StartImportTask'); } /** * Grants permission to tag a Neptune Analytics resource * * Access Level: Tagging * * Possible conditions: * - .ifAwsTagKeys() * - .ifAwsRequestTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_TagResource.html */ toTagResource() { return this.to('TagResource'); } /** * Grants permission to untag a Neptune Analytics resource * * Access Level: Tagging * * Possible conditions: * - .ifAwsTagKeys() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_UntagResource.html */ toUntagResource() { return this.to('UntagResource'); } /** * Grants permission to modify a graph * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifPublicConnectivity() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_UpdateGraph.html */ toUpdateGraph() { return this.to('UpdateGraph'); } /** * Grants permission to write data via query APIs on the graph * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/neptune-analytics/latest/apiref/API_ExecuteQuery.html */ toWriteDataViaQuery() { return this.to('WriteDataViaQuery'); } /** * Adds a resource of type graph to the statement * * https://docs.aws.amazon.com/neptune-analytics/latest/userguide/iam-resources.html#graph * * @param resourceId - Identifier for the resourceId. * @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() */ onGraph(resourceId, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:neptune-graph:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:graph/${resourceId}`); } /** * Adds a resource of type graph-snapshot to the statement * * https://docs.aws.amazon.com/neptune-analytics/latest/userguide/iam-resources.html#graph-snapshot * * @param resourceId - Identifier for the resourceId. * @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() */ onGraphSnapshot(resourceId, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:neptune-graph:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:graph-snapshot/${resourceId}`); } /** * Adds a resource of type import-task to the statement * * https://docs.aws.amazon.com/neptune-analytics/latest/userguide/iam-resources.html#import-task * * @param resourceId - Identifier for the resourceId. * @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. */ onImportTask(resourceId, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:neptune-graph:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:import-task/${resourceId}`); } /** * Filters access by a tag's key and value in a request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag * * Applies to actions: * - .toCreateGraph() * - .toCreateGraphSnapshot() * - .toCreateGraphUsingImportTask() * - .toCreatePrivateGraphEndpoint() * - .toRestoreGraphFromSnapshot() * - .toTagResource() * * @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 the presence of tag key-value pairs in the request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag * * Applies to actions: * - .toCancelQuery() * - .toCreateGraphSnapshot() * - .toCreatePrivateGraphEndpoint() * - .toDeleteDataViaQuery() * - .toDeleteGraph() * - .toDeleteGraphSnapshot() * - .toDeletePrivateGraphEndpoint() * - .toGetEngineStatus() * - .toGetGraph() * - .toGetGraphSnapshot() * - .toGetGraphSummary() * - .toGetPrivateGraphEndpoint() * - .toGetQueryStatus() * - .toGetStatisticsStatus() * - .toListPrivateGraphEndpoints() * - .toListQueries() * - .toListTagsForResource() * - .toReadDataViaQuery() * - .toResetGraph() * - .toRestoreGraphFromSnapshot() * - .toUpdateGraph() * - .toWriteDataViaQuery() * * Applies to resource types: * - graph * - graph-snapshot * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsResourceTag(tagKey, value, operator) { return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by the tag keys in a request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys * * Applies to actions: * - .toCreateGraph() * - .toCreateGraphSnapshot() * - .toCreateGraphUsingImportTask() * - .toCreatePrivateGraphEndpoint() * - .toRestoreGraphFromSnapshot() * - .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'); } /** * Filters access by the value of the public connectivity parameter provided in the request or its default value, if unspecified. All access to graphs is IAM authenticated * * https://docs.aws.amazon.com/neptune-analytics/latest/userguide/iam-condition-keys.html#publicconnectivity * * Applies to actions: * - .toCreateGraph() * - .toCreateGraphUsingImportTask() * - .toRestoreGraphFromSnapshot() * - .toUpdateGraph() * * @param value `true` or `false`. **Default:** `true` */ ifPublicConnectivity(value) { return this.if(`PublicConnectivity`, (typeof value !== 'undefined' ? value : true), 'Bool'); } /** * Statement provider for service [neptune-graph](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonneptuneanalytics.html). * */ constructor(props) { super(props); this.servicePrefix = 'neptune-graph'; this.accessLevelList = { Write: [ 'CancelImportTask', 'CancelQuery', 'CreateGraph', 'CreateGraphSnapshot', 'CreateGraphUsingImportTask', 'CreatePrivateGraphEndpoint', 'DeleteDataViaQuery', 'DeleteGraph', 'DeleteGraphSnapshot', 'DeletePrivateGraphEndpoint', 'ResetGraph', 'RestoreGraphFromSnapshot', 'StartImportTask', 'UpdateGraph', 'WriteDataViaQuery' ], Read: [ 'GetEngineStatus', 'GetGraph', 'GetGraphSnapshot', 'GetGraphSummary', 'GetImportTask', 'GetPrivateGraphEndpoint', 'GetQueryStatus', 'GetStatisticsStatus', 'ListGraphSnapshots', 'ListGraphs', 'ListImportTasks', 'ListPrivateGraphEndpoints', 'ListQueries', 'ListTagsForResource', 'ReadDataViaQuery' ], Tagging: [ 'TagResource', 'UntagResource' ] }; } } exports.NeptuneGraph = NeptuneGraph; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVwdHVuZWFuYWx5dGljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5lcHR1bmVhbmFseXRpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBR3pEOzs7O0dBSUc7QUFDSCxNQUFhLFlBQWEsU0FBUSx3QkFBZTtJQUcvQzs7Ozs7O09BTUc7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FpQkc7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxxQkFBcUI7UUFDMUIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FrQkc7SUFDSSw0QkFBNEI7UUFDakMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDRCQUE0QixDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bc0JHO0lBQ0ksNEJBQTRCO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLENB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QXdlN0Isb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLGtCQUFrQjtnQkFDbEIsYUFBYTtnQkFDYixhQUFhO2dCQUNiLHFCQUFxQjtnQkFDckIsNEJBQTRCO2dCQUM1Qiw0QkFBNEI7Z0JBQzVCLG9CQUFvQjtnQkFDcEIsYUFBYTtnQkFDYixxQkFBcUI7Z0JBQ3JCLDRCQUE0QjtnQkFDNUIsWUFBWTtnQkFDWiwwQkFBMEI7Z0JBQzFCLGlCQUFpQjtnQkFDakIsYUFBYTtnQkFDYixtQkFBbUI7YUFDcEI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osaUJBQWlCO2dCQUNqQixVQUFVO2dCQUNWLGtCQUFrQjtnQkFDbEIsaUJBQWlCO2dCQUNqQixlQUFlO2dCQUNmLHlCQUF5QjtnQkFDekIsZ0JBQWdCO2dCQUNoQixxQkFBcUI7Z0JBQ3JCLG9CQUFvQjtnQkFDcEIsWUFBWTtnQkFDWixpQkFBaUI7Z0JBQ2pCLDJCQUEyQjtnQkFDM0IsYUFBYTtnQkFDYixxQkFBcUI7Z0JBQ3JCLGtCQUFrQjthQUNuQjtZQUNELE9BQU8sRUFBRTtnQkFDUCxhQUFhO2dCQUNiLGVBQWU7YUFDaEI7U0FDRixDQUFDO0lBNEpGLENBQUM7Q0FDRjtBQTdxQkQsb0NBNnFCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBhd3NfaWFtIGFzIGlhbSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbbmVwdHVuZS1ncmFwaF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9ubmVwdHVuZWFuYWx5dGljcy5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE5lcHR1bmVHcmFwaCBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ25lcHR1bmUtZ3JhcGgnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjYW5jZWwgYW4gb25nb2luZyBpbXBvcnQgdGFza1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9DYW5jZWxJbXBvcnRUYXNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NhbmNlbEltcG9ydFRhc2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NhbmNlbEltcG9ydFRhc2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjYW5jZWwgYSBxdWVyeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfQ2FuY2VsUXVlcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ2FuY2VsUXVlcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NhbmNlbFF1ZXJ5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3IGdyYXBoXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZQdWJsaWNDb25uZWN0aXZpdHkoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBpYW06Q3JlYXRlU2VydmljZUxpbmtlZFJvbGVcbiAgICogLSBrbXM6Q3JlYXRlR3JhbnRcbiAgICogLSBrbXM6RGVjcnlwdFxuICAgKiAtIGttczpEZXNjcmliZUtleVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfQ3JlYXRlR3JhcGguaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlR3JhcGgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUdyYXBoJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3IHNuYXBzaG90IGZyb20gYW4gZXhpc3RpbmcgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0NyZWF0ZUdyYXBoU25hcHNob3QuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlR3JhcGhTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlR3JhcGhTbmFwc2hvdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIG5ldyBncmFwaCB3aGlsZSBpbXBvcnRpbmcgZGF0YSBpbnRvIHRoZSBuZXcgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZlB1YmxpY0Nvbm5lY3Rpdml0eSgpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVxuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKiAtIGttczpDcmVhdGVHcmFudFxuICAgKiAtIGttczpEZWNyeXB0XG4gICAqIC0ga21zOkRlc2NyaWJlS2V5XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9DcmVhdGVHcmFwaFVzaW5nSW1wb3J0VGFzay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVHcmFwaFVzaW5nSW1wb3J0VGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlR3JhcGhVc2luZ0ltcG9ydFRhc2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcgcHJpdmF0ZSBncmFwaCBlbmRwb2ludCB0byBhY2Nlc3MgdGhlIGdyYXBoIGZyb20gd2l0aGluIGEgdnBjXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGVjMjpDcmVhdGVWcGNFbmRwb2ludFxuICAgKiAtIGVjMjpEZXNjcmliZUF2YWlsYWJpbGl0eVpvbmVzXG4gICAqIC0gZWMyOkRlc2NyaWJlU2VjdXJpdHlHcm91cHNcbiAgICogLSBlYzI6RGVzY3JpYmVTdWJuZXRzXG4gICAqIC0gZWMyOkRlc2NyaWJlVnBjQXR0cmlidXRlXG4gICAqIC0gZWMyOkRlc2NyaWJlVnBjRW5kcG9pbnRzXG4gICAqIC0gZWMyOkRlc2NyaWJlVnBjc1xuICAgKiAtIGVjMjpNb2RpZnlWcGNFbmRwb2ludFxuICAgKiAtIHJvdXRlNTM6QXNzb2NpYXRlVlBDV2l0aEhvc3RlZFpvbmVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0NyZWF0ZVByaXZhdGVHcmFwaEVuZHBvaW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVByaXZhdGVHcmFwaEVuZHBvaW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQcml2YXRlR3JhcGhFbmRwb2ludCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBkYXRhIHZpYSBxdWVyeSBBUElzIG9uIHRoZSBncmFwaFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfRXhlY3V0ZVF1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZURhdGFWaWFRdWVyeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlRGF0YVZpYVF1ZXJ5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0RlbGV0ZUdyYXBoLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUdyYXBoKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVHcmFwaCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHNuYXBzaG90XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9EZWxldGVHcmFwaFNuYXBzaG90Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUdyYXBoU25hcHNob3QoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUdyYXBoU25hcHNob3QnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBwcml2YXRlIGdyYXBoIGVuZHBvaW50IG9mIGEgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZWMyOkRlbGV0ZVZwY0VuZHBvaW50c1xuICAgKiAtIGVjMjpEZXNjcmliZUF2YWlsYWJpbGl0eVpvbmVzXG4gICAqIC0gZWMyOkRlc2NyaWJlU2VjdXJpdHlHcm91cHNcbiAgICogLSBlYzI6RGVzY3JpYmVTdWJuZXRzXG4gICAqIC0gZWMyOkRlc2NyaWJlVnBjQXR0cmlidXRlXG4gICAqIC0gZWMyOkRlc2NyaWJlVnBjRW5kcG9pbnRzXG4gICAqIC0gZWMyOkRlc2NyaWJlVnBjc1xuICAgKiAtIGVjMjpNb2RpZnlWcGNFbmRwb2ludFxuICAgKiAtIHJvdXRlNTM6RGlzYXNzb2NpYXRlVlBDRnJvbUhvc3RlZFpvbmVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0RlbGV0ZVByaXZhdGVHcmFwaEVuZHBvaW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVByaXZhdGVHcmFwaEVuZHBvaW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVQcml2YXRlR3JhcGhFbmRwb2ludCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgZW5naW5lIHN0YXR1cyBvZiB0aGUgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi8jR2V0RW5naW5lU3RhdHVzXG4gICAqL1xuICBwdWJsaWMgdG9HZXRFbmdpbmVTdGF0dXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEVuZ2luZVN0YXR1cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBkZXRhaWxzIGFib3V0IGEgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfR2V0R3JhcGguaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0R3JhcGgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEdyYXBoJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGRldGFpbHMgYWJvdXQgYSBzbmFwc2hvdFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9HZXRHcmFwaFNuYXBzaG90Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEdyYXBoU25hcHNob3QoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEdyYXBoU25hcHNob3QnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgdGhlIHN1bW1hcnkgZm9yIHRoZSBkYXRhIGluIHRoZSBncmFwaFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9HZXRHcmFwaFN1bW1hcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0R3JhcGhTdW1tYXJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRHcmFwaFN1bW1hcnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgZGV0YWlscyBhYm91dCBhbiBpbXBvcnQgdGFza1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0dldEltcG9ydFRhc2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0SW1wb3J0VGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0SW1wb3J0VGFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBkZXRhaWxzIGFib3V0IGEgcHJpdmF0ZSBncmFwaCBlbmRwb2ludCBvZiBhIGdyYXBoXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0dldFByaXZhdGVHcmFwaEVuZHBvaW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFByaXZhdGVHcmFwaEVuZHBvaW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRQcml2YXRlR3JhcGhFbmRwb2ludCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNoZWNrIHRoZSBzdGF0dXMgb2YgYSBnaXZlbiBxdWVyeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9HZXRRdWVyeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRRdWVyeVN0YXR1cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0UXVlcnlTdGF0dXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgdGhlIHN0YXRpc3RpY3MgZm9yIHRoZSBkYXRhIGluIHRoZSBncmFwaFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmLyNHZXRTdGF0aXN0aWNzU3RhdHVzXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTdGF0aXN0aWNzU3RhdHVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTdGF0aXN0aWNzU3RhdHVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgc25hcHNob3RzIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0xpc3RHcmFwaFNuYXBzaG90cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0R3JhcGhTbmFwc2hvdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RHcmFwaFNuYXBzaG90cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIGdyYXBocyBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9MaXN0R3JhcGhzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RHcmFwaHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RHcmFwaHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSBpbXBvcnQgdGFza3MgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfTGlzdEltcG9ydFRhc2tzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RJbXBvcnRUYXNrcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEltcG9ydFRhc2tzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgcHJpdmF0ZSBncmFwaCBlbmRwb2ludHMgZm9yIGEgZ2l2ZW4gZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfTGlzdFByaXZhdGVHcmFwaEVuZHBvaW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UHJpdmF0ZUdyYXBoRW5kcG9pbnRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0UHJpdmF0ZUdyYXBoRW5kcG9pbnRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY2hlY2sgdGhlIHN0YXR1cyBvZiBhbGwgYWN0aXZlIHF1ZXJpZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfTGlzdFF1ZXJpZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFF1ZXJpZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RRdWVyaWVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdHMgdGFnIGZvciBhIE5lcHR1bmUgQW5hbHl0aWNzIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0xpc3RUYWdzRm9yUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ3NGb3JSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlYWQgZGF0YSB2aWEgcXVlcnkgQVBJcyBvbiB0aGUgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfRXhlY3V0ZVF1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlYWREYXRhVmlhUXVlcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlYWREYXRhVmlhUXVlcnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXNldCBhIGdyYXBoIHdoaWNoIGRlbGV0ZXMgYWxsIGRhdGEgd2l0aGluIHRoZSBncmFwaFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfUmVzZXRHcmFwaC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZXNldEdyYXBoKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZXNldEdyYXBoJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3IGdyYXBoIGZyb20gYW4gZXhpc3Rpbmcgc25hcHNob3RcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZQdWJsaWNDb25uZWN0aXZpdHkoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBrbXM6Q3JlYXRlR3JhbnRcbiAgICogLSBrbXM6RGVjcnlwdFxuICAgKiAtIGttczpEZXNjcmliZUtleVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfUmVzdG9yZUdyYXBoRnJvbVNuYXBzaG90Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1Jlc3RvcmVHcmFwaEZyb21TbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVzdG9yZUdyYXBoRnJvbVNuYXBzaG90Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW1wb3J0IGRhdGEgaW50byBhbiBleGlzdGluZyBncmFwaFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfU3RhcnRJbXBvcnRUYXNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0YXJ0SW1wb3J0VGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU3RhcnRJbXBvcnRUYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFnIGEgTmVwdHVuZSBBbmFseXRpY3MgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9uZXB0dW5lLWFuYWx5dGljcy9sYXRlc3QvYXBpcmVmL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1bnRhZyBhIE5lcHR1bmUgQW5hbHl0aWNzIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfVW50YWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VbnRhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVbnRhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW9kaWZ5IGEgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZQdWJsaWNDb25uZWN0aXZpdHkoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L2FwaXJlZi9BUElfVXBkYXRlR3JhcGguaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlR3JhcGgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUdyYXBoJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gd3JpdGUgZGF0YSB2aWEgcXVlcnkgQVBJcyBvbiB0aGUgZ3JhcGhcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC9hcGlyZWYvQVBJX0V4ZWN1dGVRdWVyeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Xcml0ZURhdGFWaWFRdWVyeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnV3JpdGVEYXRhVmlhUXVlcnknKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0NhbmNlbEltcG9ydFRhc2snLFxuICAgICAgJ0NhbmNlbFF1ZXJ5JyxcbiAgICAgICdDcmVhdGVHcmFwaCcsXG4gICAgICAnQ3JlYXRlR3JhcGhTbmFwc2hvdCcsXG4gICAgICAnQ3JlYXRlR3JhcGhVc2luZ0ltcG9ydFRhc2snLFxuICAgICAgJ0NyZWF0ZVByaXZhdGVHcmFwaEVuZHBvaW50JyxcbiAgICAgICdEZWxldGVEYXRhVmlhUXVlcnknLFxuICAgICAgJ0RlbGV0ZUdyYXBoJyxcbiAgICAgICdEZWxldGVHcmFwaFNuYXBzaG90JyxcbiAgICAgICdEZWxldGVQcml2YXRlR3JhcGhFbmRwb2ludCcsXG4gICAgICAnUmVzZXRHcmFwaCcsXG4gICAgICAnUmVzdG9yZUdyYXBoRnJvbVNuYXBzaG90JyxcbiAgICAgICdTdGFydEltcG9ydFRhc2snLFxuICAgICAgJ1VwZGF0ZUdyYXBoJyxcbiAgICAgICdXcml0ZURhdGFWaWFRdWVyeSdcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdHZXRFbmdpbmVTdGF0dXMnLFxuICAgICAgJ0dldEdyYXBoJyxcbiAgICAgICdHZXRHcmFwaFNuYXBzaG90JyxcbiAgICAgICdHZXRHcmFwaFN1bW1hcnknLFxuICAgICAgJ0dldEltcG9ydFRhc2snLFxuICAgICAgJ0dldFByaXZhdGVHcmFwaEVuZHBvaW50JyxcbiAgICAgICdHZXRRdWVyeVN0YXR1cycsXG4gICAgICAnR2V0U3RhdGlzdGljc1N0YXR1cycsXG4gICAgICAnTGlzdEdyYXBoU25hcHNob3RzJyxcbiAgICAgICdMaXN0R3JhcGhzJyxcbiAgICAgICdMaXN0SW1wb3J0VGFza3MnLFxuICAgICAgJ0xpc3RQcml2YXRlR3JhcGhFbmRwb2ludHMnLFxuICAgICAgJ0xpc3RRdWVyaWVzJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICdSZWFkRGF0YVZpYVF1ZXJ5J1xuICAgIF0sXG4gICAgVGFnZ2luZzogW1xuICAgICAgJ1RhZ1Jlc291cmNlJyxcbiAgICAgICdVbnRhZ1Jlc291cmNlJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgZ3JhcGggdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbmVwdHVuZS1hbmFseXRpY3MvbGF0ZXN0L3VzZXJndWlkZS9pYW0tcmVzb3VyY2VzLmh0bWwjZ3JhcGhcbiAgICpcbiAgICogQHBhcmFtIHJlc291cmNlSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgcmVzb3VyY2VJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uR3JhcGgocmVzb3VyY2VJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9Om5lcHR1bmUtZ3JhcGg6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OmdyYXBoLyR7IHJlc291cmNlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGdyYXBoLXNuYXBzaG90IHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC91c2VyZ3VpZGUvaWFtLXJlc291cmNlcy5odG1sI2dyYXBoLXNuYXBzaG90XG4gICAqXG4gICAqIEBwYXJhbSByZXNvdXJjZUlkIC0gSWRlbnRpZmllciBmb3IgdGhlIHJlc291cmNlSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkdyYXBoU25hcHNob3QocmVzb3VyY2VJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9Om5lcHR1bmUtZ3JhcGg6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OmdyYXBoLXNuYXBzaG90LyR7IHJlc291cmNlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGltcG9ydC10YXNrIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL25lcHR1bmUtYW5hbHl0aWNzL2xhdGVzdC91c2VyZ3VpZGUvaWFtLXJlc291cmNlcy5odG1sI2ltcG9ydC10YXNrXG4gICAqXG4gICAqIEBwYXJhbSByZXNvdXJjZUlkIC0gSWRlbnRpZmllciBmb3IgdGhlIHJlc291cmNlSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW