iam-floyd
Version:
AWS IAM policy statement generator with fluent interface
625 lines • 58.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Kinesisvideo = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [kinesisvideo](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonkinesisvideostreams.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Kinesisvideo extends shared_1.PolicyStatement {
/**
* Statement provider for service [kinesisvideo](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonkinesisvideostreams.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 = 'kinesisvideo';
this.accessLevelList = {
Write: [
'ConnectAsMaster',
'ConnectAsViewer',
'CreateSignalingChannel',
'CreateStream',
'DeleteEdgeConfiguration',
'DeleteSignalingChannel',
'DeleteStream',
'JoinStorageSession',
'JoinStorageSessionAsViewer',
'PutMedia',
'SendAlexaOfferToMaster',
'StartEdgeConfigurationUpdate',
'UpdateDataRetention',
'UpdateImageGenerationConfiguration',
'UpdateMediaStorageConfiguration',
'UpdateNotificationConfiguration',
'UpdateSignalingChannel',
'UpdateStream'
],
Read: [
'DescribeEdgeConfiguration',
'DescribeImageGenerationConfiguration',
'DescribeMediaStorageConfiguration',
'DescribeNotificationConfiguration',
'GetClip',
'GetDASHStreamingSessionURL',
'GetDataEndpoint',
'GetHLSStreamingSessionURL',
'GetIceServerConfig',
'GetImages',
'GetMedia',
'GetMediaForFragmentList',
'GetSignalingChannelEndpoint',
'ListTagsForResource',
'ListTagsForStream'
],
List: [
'DescribeMappedResourceConfiguration',
'DescribeSignalingChannel',
'DescribeStream',
'ListEdgeAgentConfigurations',
'ListFragments',
'ListSignalingChannels',
'ListStreams'
],
Tagging: [
'TagResource',
'TagStream',
'UntagResource',
'UntagStream'
]
};
}
/**
* Grants permission to connect as a master to the signaling channel specified by the endpoint
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ConnectAsMaster.html
*/
toConnectAsMaster() {
return this.to('ConnectAsMaster');
}
/**
* Grants permission to connect as a viewer to the signaling channel specified by the endpoint
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ConnectAsViewer.html
*/
toConnectAsViewer() {
return this.to('ConnectAsViewer');
}
/**
* Grants permission to create a signaling channel
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_CreateSignalingChannel.html
*/
toCreateSignalingChannel() {
return this.to('CreateSignalingChannel');
}
/**
* Grants permission to create a Kinesis video stream
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_CreateStream.html
*/
toCreateStream() {
return this.to('CreateStream');
}
/**
* Grants permission to delete the edge configuration of your Kinesis Video Stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DeleteEdgeConfiguration.html
*/
toDeleteEdgeConfiguration() {
return this.to('DeleteEdgeConfiguration');
}
/**
* Grants permission to delete an existing signaling channel
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DeleteSignalingChannel.html
*/
toDeleteSignalingChannel() {
return this.to('DeleteSignalingChannel');
}
/**
* Grants permission to delete an existing Kinesis video stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DeleteStream.html
*/
toDeleteStream() {
return this.to('DeleteStream');
}
/**
* Grants permission to describe the edge configuration of your Kinesis Video Stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeEdgeConfiguration.html
*/
toDescribeEdgeConfiguration() {
return this.to('DescribeEdgeConfiguration');
}
/**
* Grants permission to describe the image generation configuration of your Kinesis video stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeImageGenerationConfiguration.html
*/
toDescribeImageGenerationConfiguration() {
return this.to('DescribeImageGenerationConfiguration');
}
/**
* Grants permission to describe the resource mapped to the Kinesis video stream
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeMappedResourceConfiguration.html
*/
toDescribeMappedResourceConfiguration() {
return this.to('DescribeMappedResourceConfiguration');
}
/**
* Grants permission to describe the media storage configuration of a signaling channel
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeMediaStorageConfiguration.html
*/
toDescribeMediaStorageConfiguration() {
return this.to('DescribeMediaStorageConfiguration');
}
/**
* Grants permission to describe the notification configuration of your Kinesis video stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeNotificationConfiguration.html
*/
toDescribeNotificationConfiguration() {
return this.to('DescribeNotificationConfiguration');
}
/**
* Grants permission to describe the specified signaling channel
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeSignalingChannel.html
*/
toDescribeSignalingChannel() {
return this.to('DescribeSignalingChannel');
}
/**
* Grants permission to describe the specified Kinesis video stream
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_DescribeStream.html
*/
toDescribeStream() {
return this.to('DescribeStream');
}
/**
* Grants permission to get a media clip from a video stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetClip.html
*/
toGetClip() {
return this.to('GetClip');
}
/**
* Grants permission to create a URL for MPEG-DASH video streaming
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetDASHStreamingSessionURL.html
*/
toGetDASHStreamingSessionURL() {
return this.to('GetDASHStreamingSessionURL');
}
/**
* Grants permission to get an endpoint for a specified stream for either reading or writing media data to Kinesis Video Streams
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_GetDataEndpoint.html
*/
toGetDataEndpoint() {
return this.to('GetDataEndpoint');
}
/**
* Grants permission to create a URL for HLS video streaming
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetHLSStreamingSessionURL.html
*/
toGetHLSStreamingSessionURL() {
return this.to('GetHLSStreamingSessionURL');
}
/**
* Grants permission to get the ICE server configuration
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_signaling_GetIceServerConfig.html
*/
toGetIceServerConfig() {
return this.to('GetIceServerConfig');
}
/**
* Grants permission to get generated images from your Kinesis video stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetImages.html
*/
toGetImages() {
return this.to('GetImages');
}
/**
* Grants permission to return media content of a Kinesis video stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html
*/
toGetMedia() {
return this.to('GetMedia');
}
/**
* Grants permission to read and return media data only from persisted storage
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetMediaForFragmentList.html
*/
toGetMediaForFragmentList() {
return this.to('GetMediaForFragmentList');
}
/**
* Grants permission to get endpoints for a specified combination of protocol and role for a signaling channel
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_GetSignalingChannelEndpoint.html
*/
toGetSignalingChannelEndpoint() {
return this.to('GetSignalingChannelEndpoint');
}
/**
* Grants permission to join a storage session for a channel
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_webrtc_JoinStorageSession.html
*/
toJoinStorageSession() {
return this.to('JoinStorageSession');
}
/**
* Grants permission to join a storage session for a channel as viewer
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_webrtc_JoinStorageSessionAsViewer.html
*/
toJoinStorageSessionAsViewer() {
return this.to('JoinStorageSessionAsViewer');
}
/**
* Grants permission to list an edge agent configurations
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ListEdgeAgentConfigurations.html
*/
toListEdgeAgentConfigurations() {
return this.to('ListEdgeAgentConfigurations');
}
/**
* Grants permission to list the fragments from archival storage based on the pagination token or selector type with range specified
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_ListFragments.html
*/
toListFragments() {
return this.to('ListFragments');
}
/**
* Grants permission to list your signaling channels
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ListSignalingChannels.html
*/
toListSignalingChannels() {
return this.to('ListSignalingChannels');
}
/**
* Grants permission to list your Kinesis video streams
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ListStreams.html
*/
toListStreams() {
return this.to('ListStreams');
}
/**
* Grants permission to fetch the tags associated with your resource
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to fetch the tags associated with Kinesis video stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_ListTagsForStream.html
*/
toListTagsForStream() {
return this.to('ListTagsForStream');
}
/**
* Grants permission to send media data to a Kinesis video stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html
*/
toPutMedia() {
return this.to('PutMedia');
}
/**
* Grants permission to send the Alexa SDP offer to the master
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_signaling_SendAlexaOfferToMaster.html
*/
toSendAlexaOfferToMaster() {
return this.to('SendAlexaOfferToMaster');
}
/**
* Grants permission to start edge configuration update of your Kinesis Video Stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_StartEdgeConfigurationUpdate.html
*/
toStartEdgeConfigurationUpdate() {
return this.to('StartEdgeConfigurationUpdate');
}
/**
* Grants permission to attach set of tags to your resource
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to attach set of tags to your Kinesis video streams
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_TagStream.html
*/
toTagStream() {
return this.to('TagStream');
}
/**
* Grants permission to remove one or more tags from your resource
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to remove one or more tags from your Kinesis video streams
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UntagStream.html
*/
toUntagStream() {
return this.to('UntagStream');
}
/**
* Grants permission to update the data retention period of your Kinesis video stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UpdateDataRetention.html
*/
toUpdateDataRetention() {
return this.to('UpdateDataRetention');
}
/**
* Grants permission to update the image generation configuration of your Kinesis video stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UpdateImageGenerationConfiguration.html
*/
toUpdateImageGenerationConfiguration() {
return this.to('UpdateImageGenerationConfiguration');
}
/**
* Grants permission to create or update an mapping between a signaling channel and stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UpdateMediaStorageConfiguration.html
*/
toUpdateMediaStorageConfiguration() {
return this.to('UpdateMediaStorageConfiguration');
}
/**
* Grants permission to update the notification configuration of your Kinesis video stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UpdateNotificationConfiguration.html
*/
toUpdateNotificationConfiguration() {
return this.to('UpdateNotificationConfiguration');
}
/**
* Grants permission to update an existing signaling channel
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UpdateSignalingChannel.html
*/
toUpdateSignalingChannel() {
return this.to('UpdateSignalingChannel');
}
/**
* Grants permission to update an existing Kinesis video stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_UpdateStream.html
*/
toUpdateStream() {
return this.to('UpdateStream');
}
/**
* Adds a resource of type stream to the statement
*
* https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/how-it-works.html
*
* @param streamName - Identifier for the streamName.
* @param creationTime - Identifier for the creationTime.
* @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()
*/
onStream(streamName, creationTime, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:kinesisvideo:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:stream/${streamName}/${creationTime}`);
}
/**
* Adds a resource of type channel to the statement
*
* https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-how-it-works.html
*
* @param channelName - Identifier for the channelName.
* @param creationTime - Identifier for the creationTime.
* @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()
*/
onChannel(channelName, creationTime, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:kinesisvideo:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:channel/${channelName}/${creationTime}`);
}
/**
* Filters requests based on the allowed set of values for each of the tags
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
*
* Applies to actions:
* - .toCreateSignalingChannel()
* - .toCreateStream()
* - .toTagResource()
* - .toTagStream()
*
* @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 actions based on tag-value assoicated with the stream
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
*
* Applies to resource types:
* - stream
* - channel
*
* @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 requests based on the presence of mandatory tag keys in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
*
* Applies to actions:
* - .toCreateSignalingChannel()
* - .toCreateStream()
* - .toTagResource()
* - .toTagStream()
* - .toUntagResource()
* - .toUntagStream()
*
* @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.Kinesisvideo = Kinesisvideo;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2luZXNpc3ZpZGVvc3RyZWFtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImtpbmVzaXN2aWRlb3N0cmVhbXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBRXpEOzs7O0dBSUc7QUFDSCxNQUFhLFlBQWEsU0FBUSx3QkFBZTtJQUcvQzs7OztPQUlHO0lBQ0gsWUFBWSxHQUFZO1FBQ3RCLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQVJOLGtCQUFhLEdBQUcsY0FBYyxDQUFDO1FBcWdCNUIsb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLGlCQUFpQjtnQkFDakIsaUJBQWlCO2dCQUNqQix3QkFBd0I7Z0JBQ3hCLGNBQWM7Z0JBQ2QseUJBQXlCO2dCQUN6Qix3QkFBd0I7Z0JBQ3hCLGNBQWM7Z0JBQ2Qsb0JBQW9CO2dCQUNwQiw0QkFBNEI7Z0JBQzVCLFVBQVU7Z0JBQ1Ysd0JBQXdCO2dCQUN4Qiw4QkFBOEI7Z0JBQzlCLHFCQUFxQjtnQkFDckIsb0NBQW9DO2dCQUNwQyxpQ0FBaUM7Z0JBQ2pDLGlDQUFpQztnQkFDakMsd0JBQXdCO2dCQUN4QixjQUFjO2FBQ2Y7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osMkJBQTJCO2dCQUMzQixzQ0FBc0M7Z0JBQ3RDLG1DQUFtQztnQkFDbkMsbUNBQW1DO2dCQUNuQyxTQUFTO2dCQUNULDRCQUE0QjtnQkFDNUIsaUJBQWlCO2dCQUNqQiwyQkFBMkI7Z0JBQzNCLG9CQUFvQjtnQkFDcEIsV0FBVztnQkFDWCxVQUFVO2dCQUNWLHlCQUF5QjtnQkFDekIsNkJBQTZCO2dCQUM3QixxQkFBcUI7Z0JBQ3JCLG1CQUFtQjthQUNwQjtZQUNELElBQUksRUFBRTtnQkFDSixxQ0FBcUM7Z0JBQ3JDLDBCQUEwQjtnQkFDMUIsZ0JBQWdCO2dCQUNoQiw2QkFBNkI7Z0JBQzdCLGVBQWU7Z0JBQ2YsdUJBQXVCO2dCQUN2QixhQUFhO2FBQ2Q7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsYUFB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Ozs7Ozs7OztPQVlHO0lBQ0ksZ0JBQWdCLENBQUMsTUFBYyxFQUFFLEtBQXdCLEVBQUUsUUFBNEI7UUFDNUYsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFvQixNQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2pGLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSSxZQUFZLENBQUMsS0FBd0IsRUFBRSxRQUE0QjtRQUN4RSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztDQUNGO0FBeHBCRCxvQ0F3cEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW2tpbmVzaXN2aWRlb10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9ua2luZXNpc3ZpZGVvc3RyZWFtcy5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEtpbmVzaXN2aWRlbyBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ2tpbmVzaXN2aWRlbyc7XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBba2luZXNpc3ZpZGVvXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hbWF6b25raW5lc2lzdmlkZW9zdHJlYW1zLmh0bWwpLlxuICAgKlxuICAgKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNpZD86IHN0cmluZykge1xuICAgIHN1cGVyKHNpZCk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY29ubmVjdCBhcyBhIG1hc3RlciB0byB0aGUgc2lnbmFsaW5nIGNoYW5uZWwgc3BlY2lmaWVkIGJ5IHRoZSBlbmRwb2ludFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfQ29ubmVjdEFzTWFzdGVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Nvbm5lY3RBc01hc3RlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ29ubmVjdEFzTWFzdGVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY29ubmVjdCBhcyBhIHZpZXdlciB0byB0aGUgc2lnbmFsaW5nIGNoYW5uZWwgc3BlY2lmaWVkIGJ5IHRoZSBlbmRwb2ludFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfQ29ubmVjdEFzVmlld2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Nvbm5lY3RBc1ZpZXdlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ29ubmVjdEFzVmlld2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgc2lnbmFsaW5nIGNoYW5uZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX0NyZWF0ZVNpZ25hbGluZ0NoYW5uZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU2lnbmFsaW5nQ2hhbm5lbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU2lnbmFsaW5nQ2hhbm5lbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIEtpbmVzaXMgdmlkZW8gc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9DcmVhdGVTdHJlYW0uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU3RyZWFtKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVTdHJlYW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIGVkZ2UgY29uZmlndXJhdGlvbiBvZiB5b3VyIEtpbmVzaXMgVmlkZW8gU3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9EZWxldGVFZGdlQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVFZGdlQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlRWRnZUNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYW4gZXhpc3Rpbmcgc2lnbmFsaW5nIGNoYW5uZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX0RlbGV0ZVNpZ25hbGluZ0NoYW5uZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU2lnbmFsaW5nQ2hhbm5lbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlU2lnbmFsaW5nQ2hhbm5lbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhbiBleGlzdGluZyBLaW5lc2lzIHZpZGVvIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfRGVsZXRlU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIGVkZ2UgY29uZmlndXJhdGlvbiBvZiB5b3VyIEtpbmVzaXMgVmlkZW8gU3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX0Rlc2NyaWJlRWRnZUNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVFZGdlQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVFZGdlQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBpbWFnZSBnZW5lcmF0aW9uIGNvbmZpZ3VyYXRpb24gb2YgeW91ciBLaW5lc2lzIHZpZGVvIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9EZXNjcmliZUltYWdlR2VuZXJhdGlvbkNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVJbWFnZUdlbmVyYXRpb25Db25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUltYWdlR2VuZXJhdGlvbkNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgcmVzb3VyY2UgbWFwcGVkIHRvIHRoZSBLaW5lc2lzIHZpZGVvIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9EZXNjcmliZU1hcHBlZFJlc291cmNlQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZU1hcHBlZFJlc291cmNlQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVNYXBwZWRSZXNvdXJjZUNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgbWVkaWEgc3RvcmFnZSBjb25maWd1cmF0aW9uIG9mIGEgc2lnbmFsaW5nIGNoYW5uZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfRGVzY3JpYmVNZWRpYVN0b3JhZ2VDb25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTWVkaWFTdG9yYWdlQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVNZWRpYVN0b3JhZ2VDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIG5vdGlmaWNhdGlvbiBjb25maWd1cmF0aW9uIG9mIHlvdXIgS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfRGVzY3JpYmVOb3RpZmljYXRpb25Db25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVOb3RpZmljYXRpb25Db25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHNwZWNpZmllZCBzaWduYWxpbmcgY2hhbm5lbFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9EZXNjcmliZVNpZ25hbGluZ0NoYW5uZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTaWduYWxpbmdDaGFubmVsKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVNpZ25hbGluZ0NoYW5uZWwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc3BlY2lmaWVkIEtpbmVzaXMgdmlkZW8gc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX0Rlc2NyaWJlU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU3RyZWFtKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVN0cmVhbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBhIG1lZGlhIGNsaXAgZnJvbSBhIHZpZGVvIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9yZWFkZXJfR2V0Q2xpcC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRDbGlwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRDbGlwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgVVJMIGZvciBNUEVHLURBU0ggdmlkZW8gc3RyZWFtaW5nXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX3JlYWRlcl9HZXREQVNIU3RyZWFtaW5nU2Vzc2lvblVSTC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXREQVNIU3RyZWFtaW5nU2Vzc2lvblVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0REFTSFN0cmVhbWluZ1Nlc3Npb25VUkwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYW4gZW5kcG9pbnQgZm9yIGEgc3BlY2lmaWVkIHN0cmVhbSBmb3IgZWl0aGVyIHJlYWRpbmcgb3Igd3JpdGluZyBtZWRpYSBkYXRhIHRvIEtpbmVzaXMgVmlkZW8gU3RyZWFtc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9HZXREYXRhRW5kcG9pbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0RGF0YUVuZHBvaW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXREYXRhRW5kcG9pbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBVUkwgZm9yIEhMUyB2aWRlbyBzdHJlYW1pbmdcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfcmVhZGVyX0dldEhMU1N0cmVhbWluZ1Nlc3Npb25VUkwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0SExTU3RyZWFtaW5nU2Vzc2lvblVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0SExTU3RyZWFtaW5nU2Vzc2lvblVSTCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCB0aGUgSUNFIHNlcnZlciBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX3NpZ25hbGluZ19HZXRJY2VTZXJ2ZXJDb25maWcuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0SWNlU2VydmVyQ29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRJY2VTZXJ2ZXJDb25maWcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgZ2VuZXJhdGVkIGltYWdlcyBmcm9tIHlvdXIgS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfcmVhZGVyX0dldEltYWdlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRJbWFnZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEltYWdlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBtZWRpYSBjb250ZW50IG9mIGEgS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfZGF0YXBsYW5lX0dldE1lZGlhLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldE1lZGlhKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRNZWRpYScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlYWQgYW5kIHJldHVybiBtZWRpYSBkYXRhIG9ubHkgZnJvbSBwZXJzaXN0ZWQgc3RvcmFnZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9yZWFkZXJfR2V0TWVkaWFGb3JGcmFnbWVudExpc3QuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0TWVkaWFGb3JGcmFnbWVudExpc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldE1lZGlhRm9yRnJhZ21lbnRMaXN0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGVuZHBvaW50cyBmb3IgYSBzcGVjaWZpZWQgY29tYmluYXRpb24gb2YgcHJvdG9jb2wgYW5kIHJvbGUgZm9yIGEgc2lnbmFsaW5nIGNoYW5uZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfR2V0U2lnbmFsaW5nQ2hhbm5lbEVuZHBvaW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFNpZ25hbGluZ0NoYW5uZWxFbmRwb2ludCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U2lnbmFsaW5nQ2hhbm5lbEVuZHBvaW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gam9pbiBhIHN0b3JhZ2Ugc2Vzc2lvbiBmb3IgYSBjaGFubmVsXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV93ZWJydGNfSm9pblN0b3JhZ2VTZXNzaW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0pvaW5TdG9yYWdlU2Vzc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnSm9pblN0b3JhZ2VTZXNzaW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gam9pbiBhIHN0b3JhZ2Ugc2Vzc2lvbiBmb3IgYSBjaGFubmVsIGFzIHZpZXdlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfd2VicnRjX0pvaW5TdG9yYWdlU2Vzc2lvbkFzVmlld2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0pvaW5TdG9yYWdlU2Vzc2lvbkFzVmlld2VyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdKb2luU3RvcmFnZVNlc3Npb25Bc1ZpZXdlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYW4gZWRnZSBhZ2VudCBjb25maWd1cmF0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9MaXN0RWRnZUFnZW50Q29uZmlndXJhdGlvbnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEVkZ2VBZ2VudENvbmZpZ3VyYXRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RWRnZUFnZW50Q29uZmlndXJhdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSBmcmFnbWVudHMgZnJvbSBhcmNoaXZhbCBzdG9yYWdlIGJhc2VkIG9uIHRoZSBwYWdpbmF0aW9uIHRva2VuIG9yIHNlbGVjdG9yIHR5cGUgd2l0aCByYW5nZSBzcGVjaWZpZWRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfcmVhZGVyX0xpc3RGcmFnbWVudHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEZyYWdtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEZyYWdtZW50cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgeW91ciBzaWduYWxpbmcgY2hhbm5lbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfTGlzdFNpZ25hbGluZ0NoYW5uZWxzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RTaWduYWxpbmdDaGFubmVscygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFNpZ25hbGluZ0NoYW5uZWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB5b3VyIEtpbmVzaXMgdmlkZW8gc3RyZWFtc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9MaXN0U3RyZWFtcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U3RyZWFtcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFN0cmVhbXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBmZXRjaCB0aGUgdGFncyBhc3NvY2lhdGVkIHdpdGggeW91ciByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBmZXRjaCB0aGUgdGFncyBhc3NvY2lhdGVkIHdpdGggS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfTGlzdFRhZ3NGb3JTdHJlYW0uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JTdHJlYW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc2VuZCBtZWRpYSBkYXRhIHRvIGEgS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX2RhdGFwbGFuZV9QdXRNZWRpYS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRNZWRpYSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0TWVkaWEnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzZW5kIHRoZSBBbGV4YSBTRFAgb2ZmZXIgdG8gdGhlIG1hc3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfc2lnbmFsaW5nX1NlbmRBbGV4YU9mZmVyVG9NYXN0ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU2VuZEFsZXhhT2ZmZXJUb01hc3RlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2VuZEFsZXhhT2ZmZXJUb01hc3RlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHN0YXJ0IGVkZ2UgY29uZmlndXJhdGlvbiB1cGRhdGUgb2YgeW91ciBLaW5lc2lzIFZpZGVvIFN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfU3RhcnRFZGdlQ29uZmlndXJhdGlvblVwZGF0ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TdGFydEVkZ2VDb25maWd1cmF0aW9uVXBkYXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdGFydEVkZ2VDb25maWd1cmF0aW9uVXBkYXRlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXR0YWNoIHNldCBvZiB0YWdzIHRvIHlvdXIgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfVGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1RhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXR0YWNoIHNldCBvZiB0YWdzIHRvIHlvdXIgS2luZXNpcyB2aWRlbyBzdHJlYW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX1RhZ1N0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdTdHJlYW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1RhZ1N0cmVhbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBvbmUgb3IgbW9yZSB0YWdzIGZyb20geW91ciByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgb25lIG9yIG1vcmUgdGFncyBmcm9tIHlvdXIgS2luZXNpcyB2aWRlbyBzdHJlYW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX1VudGFnU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnU3RyZWFtKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVbnRhZ1N0cmVhbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgZGF0YSByZXRlbnRpb24gcGVyaW9kIG9mIHlvdXIgS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX1VwZGF0ZURhdGFSZXRlbnRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlRGF0YVJldGVudGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlRGF0YVJldGVudGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgaW1hZ2UgZ2VuZXJhdGlvbiBjb25maWd1cmF0aW9uIG9mIHlvdXIgS2luZXNpcyB2aWRlbyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX1VwZGF0ZUltYWdlR2VuZXJhdGlvbkNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlSW1hZ2VHZW5lcmF0aW9uQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlSW1hZ2VHZW5lcmF0aW9uQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBvciB1cGRhdGUgYW4gbWFwcGluZyBiZXR3ZWVuIGEgc2lnbmFsaW5nIGNoYW5uZWwgYW5kIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfVXBkYXRlTWVkaWFTdG9yYWdlQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVNZWRpYVN0b3JhZ2VDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVNZWRpYVN0b3JhZ2VDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIHRoZSBub3RpZmljYXRpb24gY29uZmlndXJhdGlvbiBvZiB5b3VyIEtpbmVzaXMgdmlkZW8gc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXN2aWRlb3N0cmVhbXMvbGF0ZXN0L2RnL0FQSV9VcGRhdGVOb3RpZmljYXRpb25Db25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZU5vdGlmaWNhdGlvbkNvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZU5vdGlmaWNhdGlvbkNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYW4gZXhpc3Rpbmcgc2lnbmFsaW5nIGNoYW5uZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpc3ZpZGVvc3RyZWFtcy9sYXRlc3QvZGcvQVBJX1VwZGF0ZVNpZ25hbGluZ0NoYW5uZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlU2lnbmFsaW5nQ2hhbm5lbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlU2lnbmFsaW5nQ2hhbm5lbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhbiBleGlzdGluZyBLaW5lc2lzIHZpZGVvIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9BUElfVXBkYXRlU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlU3RyZWFtJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdDb25uZWN0QXNNYXN0ZXInLFxuICAgICAgJ0Nvbm5lY3RBc1ZpZXdlcicsXG4gICAgICAnQ3JlYXRlU2lnbmFsaW5nQ2hhbm5lbCcsXG4gICAgICAnQ3JlYXRlU3RyZWFtJyxcbiAgICAgICdEZWxldGVFZGdlQ29uZmlndXJhdGlvbicsXG4gICAgICAnRGVsZXRlU2lnbmFsaW5nQ2hhbm5lbCcsXG4gICAgICAnRGVsZXRlU3RyZWFtJyxcbiAgICAgICdKb2luU3RvcmFnZVNlc3Npb24nLFxuICAgICAgJ0pvaW5TdG9yYWdlU2Vzc2lvbkFzVmlld2VyJyxcbiAgICAgICdQdXRNZWRpYScsXG4gICAgICAnU2VuZEFsZXhhT2ZmZXJUb01hc3RlcicsXG4gICAgICAnU3RhcnRFZGdlQ29uZmlndXJhdGlvblVwZGF0ZScsXG4gICAgICAnVXBkYXRlRGF0YVJldGVudGlvbicsXG4gICAgICAnVXBkYXRlSW1hZ2VHZW5lcmF0aW9uQ29uZmlndXJhdGlvbicsXG4gICAgICAnVXBkYXRlTWVkaWFTdG9yYWdlQ29uZmlndXJhdGlvbicsXG4gICAgICAnVXBkYXRlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbicsXG4gICAgICAnVXBkYXRlU2lnbmFsaW5nQ2hhbm5lbCcsXG4gICAgICAnVXBkYXRlU3RyZWFtJ1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0Rlc2NyaWJlRWRnZUNvbmZpZ3VyYXRpb24nLFxuICAgICAgJ0Rlc2NyaWJlSW1hZ2VHZW5lcmF0aW9uQ29uZmlndXJhdGlvbicsXG4gICAgICAnRGVzY3JpYmVNZWRpYVN0b3JhZ2VDb25maWd1cmF0aW9uJyxcbiAgICAgICdEZXNjcmliZU5vdGlmaWNhdGlvbkNvbmZpZ3VyYXRpb24nLFxuICAgICAgJ0dldENsaXAnLFxuICAgICAgJ0dldERBU0hTdHJlYW1pbmdTZXNzaW9uVVJMJyxcbiAgICAgICdHZXREYXRhRW5kcG9pbnQnLFxuICAgICAgJ0dldEhMU1N0cmVhbWluZ1Nlc3Npb25VUkwnLFxuICAgICAgJ0dldEljZVNlcnZlckNvbmZpZycsXG4gICAgICAnR2V0SW1hZ2VzJyxcbiAgICAgICdHZXRNZWRpYScsXG4gICAgICAnR2V0TWVkaWFGb3JGcmFnbWVudExpc3QnLFxuICAgICAgJ0dldFNpZ25hbGluZ0NoYW5uZWxFbmRwb2ludCcsXG4gICAgICAnTGlzdFRhZ3NGb3JSZXNvdXJjZScsXG4gICAgICAnTGlzdFRhZ3NGb3JTdHJlYW0nXG4gICAgXSxcbiAgICBMaXN0OiBbXG4gICAgICAnRGVzY3JpYmVNYXBwZWRSZXNvdXJjZUNvbmZpZ3VyYXRpb24nLFxuICAgICAgJ0Rlc2NyaWJlU2lnbmFsaW5nQ2hhbm5lbCcsXG4gICAgICAnRGVzY3JpYmVTdHJlYW0nLFxuICAgICAgJ0xpc3RFZGdlQWdlbnRDb25maWd1cmF0aW9ucycsXG4gICAgICAnTGlzdEZyYWdtZW50cycsXG4gICAgICAnTGlzdFNpZ25hbGluZ0NoYW5uZWxzJyxcbiAgICAgICdMaXN0U3RyZWFtcydcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVGFnU3RyZWFtJyxcbiAgICAgICdVbnRhZ1Jlc291cmNlJyxcbiAgICAgICdVbnRhZ1N0cmVhbSdcbiAgICBdXG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHN0cmVhbSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zL2xhdGVzdC9kZy9ob3ctaXQtd29ya3MuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gc3RyZWFtTmFtZSAtIElkZW50aWZpZXIgZm9yIHRoZSBzdHJlYW1OYW1lLlxuICAgKiBAcGFyYW0gY3JlYXRpb25UaW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGNyZWF0aW9uVGltZS5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uU3RyZWFtKHN0cmVhbU5hbWU6IHN0cmluZywgY3JlYXRpb25UaW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06a2luZXNpc3ZpZGVvOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpzdHJlYW0vJHsgc3RyZWFtTmFtZSB9LyR7IGNyZWF0aW9uVGltZSB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgY2hhbm5lbCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzdmlkZW9zdHJlYW1zLXdlYnJ0Yy1kZy9sYXRlc3QvZGV2Z3VpZGUva3Zzd2VicnRjLWhvdy1pdC13b3Jrcy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBjaGFubmVsTmFtZSAtIElkZW50aWZpZXIgZm9yIHRoZSBjaGFubmVsTmFtZS5cbiAgICogQHBhcmFtIGNyZWF0aW9uVGltZSAtIElkZW50aWZpZXIgZm9yIHRoZSBjcmVhdGlvblRpbWUuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkNoYW5uZWwoY2hhbm5lbE5hbWU6IHN0cmluZywgY3JlYXRpb25UaW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06a2luZXNpc3ZpZGVvOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpjaGFubmVsLyR7IGNoYW5uZWxOYW1lIH0vJHsgY3JlYXRpb25UaW1lIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIHJlcXVlc3RzIGJhc2VkIG9uIHRoZSBhbGxvd2VkIHNldCBvZiB2YWx1ZXMgZm9yIGVhY2ggb2YgdGhlIHRhZ3NcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlcXVlc3R0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZVNpZ25hbGluZ0NoYW5uZWwoKVxuICAgKiAtIC50b0NyZWF0ZVN0cmVhbSgpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKiAtIC50b1RhZ1N0cmVhbSgpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjdGlvbnMgYmFzZWQgb24gdGFnLXZhbHVlIGFzc29pY2F0ZWQgd2l0aCB0aGUgc3RyZWFtXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXNvdXJjZXRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIHN0cmVhbVxuICAgKiAtIGNoYW5uZWxcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1Jlc291cmNlVGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlc291cmNlVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyByZXF1ZXN0cyBiYXNlZCBvbiB0aGUgcHJlc2VuY2Ugb2YgbWFuZGF0b3J5IHRhZyBrZXlzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy10YWdrZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVTaWduYWxpbmdDaGFubmVsKClcbiAgICogLSAudG9DcmVhdGVTdHJlYW0oKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICogLSAudG9UYWdTdHJlYW0oKVxuICAgKiAtIC50b1VudGFnUmVzb3VyY2UoKVxuICAgKiAtIC50b1VudGFnU3RyZWFtKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG59XG4iXX0=