ngx-agora
Version:
Angular wrapper for Agora RTC client (https://www.agora.io/en/)
820 lines • 89.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/data/models/agora-client.model.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* The Client object returned by the [createClient](https://docs.agora.io/en/Video/API%20Reference/web/globals.html#createclient)
* method provides access to much of the core AgoraRTC functionality.
*
* @see [Web Client](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html)
* @record
*/
export function AgoraClient() { }
if (false) {
/**
* Injects an Online Media Stream to a Live Broadcast
*
* If this method is called successfully, the server pulls the voice or video stream and
* injects it into a live channel. This is applicable to scenarios where all of the audience members
* in the channel can watch a live show and interact with each other.
*
*
* This method call triggers the following callbacks:
*
* - On the local client:
* - `Client.on("streamInjectedStatus")`, with the state of injecting the online stream.
* - `Client.on("stream-added")` and `Client.on("peer-online")` (uid: 666), if the online media stream is injected into the channel.
*
* - On the remote client:
* - `Client.on("stream-added")` and `Client.on("peer-online")` (uid: 666), if the online media stream is injected into the channel.
*
* \@remarks
* You can only inject one online media stream into the same channel at the same time.
* Ensure that you [enable the RTMP Converter service](https://docs.agora.io/en/Video/cdn_streaming_web#prerequisites)
* before using this function.
*
* \@param url URL address of the live streaming.
* ASCII characters only, and the string length must be greater than 0 and less than 256 bytes.
* Valid protocols are RTMP, HLS, and HTTP-FLV.
*
* - Supported FLV audio codec type: AAC.
* - Supported FLV video codec type: H.264 (AVC).
*
* \@param config Configuration of the inject stream, see
* [InjectStreamConfig](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.injectstreamconfig.html) for details.
*
* @see [Inject an Online Media Stream](https://docs.agora.io/en/Interactive%20Broadcast/inject_stream_web?platform=Web) for details.
* @type {?}
*/
AgoraClient.prototype.addInjectStreamUrl;
/**
* Configures the CDN Live Streaming
*
* @deprecated Agora recommends using the following methods instead:
* - [startLiveStreaming](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#startlivestreaming)
* - [setLiveTranscoding](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setlivetranscoding)
* - [stopLiveStreaming](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#stoplivestreaming)
* \@description
* This method configures the CDN live streaming before joining a channel.
* Call [configPublisher](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#configpublisher) before
* [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join).
* \@example
* client.configPublisher({
* width: 360,
* height: 640,
* framerate: 30,
* bitrate: 500,
* publishUrl: "rtmp://xxx/xxx/"
* });
* @type {?}
*/
AgoraClient.prototype.configPublisher;
/**
* Disables dual streams.
*
* \@example
* client.disableDualStream(() => {
* console.log("Disable dual stream success!")
* }, err => {
* console.log(err)
* })
* @type {?}
*/
AgoraClient.prototype.disableDualStream;
/**
* Enables the SDK to report the active remote users who are speaking and their volume regularly.
*
* If this method is enabled, the SDK will return the volumes every two seconds, regardless of whether there are active speakers.
*
* \@remark
* If you have multiple web pages running the Web SDK, this function might not work.
*
* \@example
* client.enableAudioVolumeIndicator(); // Triggers the "volume-indicator" callback event every two seconds.
* client.on("volume-indicator", evt => {
* evt.attr.forEach((volume, index) => {
* console.log(`#${index} UID ${volume.uid} Level ${volume.level}`);
* });
* });
* @type {?}
*/
AgoraClient.prototype.enableAudioVolumeIndicator;
/**
* Enables the dual-stream mode on the publisher side.
*
* Dual streams are a hybrid of a high-video stream and a low-video stream:
* - High-video stream: high bitrate, high resolution
* - Low-video stream: low bitrate, low resolution
*
* \@example
* client.enableDualStream(() => {
* console.log("Enable dual stream success!")
* }, err => {
* console,log(err)
* })
*
* \@remark
* This method does not apply to the following scenarios:
* - The stream is created by defining the audioSource and videoSource properties.
* - Audio-only mode (audio: true, video: false)
* - Safari browser on iOS
* - Screen-sharing scenario
* @type {?}
*/
AgoraClient.prototype.enableDualStream;
/**
* Enumerates the available video input devices, such as cameras.
*
* If this method succeeds, the SDK returns a list of video input devices in an array of MediaDeviceInfo objects.
* @type {?}
*/
AgoraClient.prototype.getCameras;
/**
* This method returns the state of the connection between the SDK and Agora's edge server.
*
* \@description
* The connection state:
* - DISCONNECTED: The SDK is disconnected from Agora's edge server.
* This is the initial state before
* [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join).
* The SDK also enters this state after the app calls
* [Client.leave](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#leave).
* - CONNECTING: The SDK is connecting to Agora's edge server. The SDK enters this state when
* calling [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join)
* or reconnecting to Agora's edge server automatically after the connection is lost.
* - CONNECTED: The SDK is connected to Agora's edge server and joins a channel. You can now publish or
* subscribe to a stream in the channel.
* - DISCONNECTING: The SDK is disconnecting from Agora's edge server. The SDK enters this state when calling
* [Client.leave](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#leave).
* @type {?}
*/
AgoraClient.prototype.getConnectionState;
/**
* Retrieves the Audio Statistics of the Local Stream
*
* This method retrieves the audio statistics of the published stream,
* including audio codec type, sampling rate, bitrate, and so on.
*
* \@description
* - Some of the statistics are calculated after the stream-published event, which may take at most 3 seconds.
* - This method supports the Chrome browser only.
* \@example
* client.getLocalAudioStats((localAudioStats) => {
* Object.keys(localAudioStats).forEach(uid => {
* console.log(`Audio CodecType from ${uid}: ${localAudioStats[uid].CodecType}`);
* console.log(`Audio MuteState from ${uid}: ${localAudioStats[uid].MuteState}`);
* console.log(`Audio RecordingLevel from ${uid}: ${localAudioStats[uid].RecordingLevel}`);
* console.log(`Audio SamplingRate from ${uid}: ${localAudioStats[uid].SamplingRate}`);
* console.log(`Audio SendBitrate from ${uid}: ${localAudioStats[uid].SendBitrate}`);
* console.log(`Audio SendLevel from ${uid}: ${localAudioStats[uid].SendLevel}`);
* })
* });
* @type {?}
*/
AgoraClient.prototype.getLocalAudioStats;
/**
* Retrieves the Video Statistics of the Local Stream
*
* This method retrieves the video statistics of the published stream, including video resolution, bitrate, frame rate, and so on.
*
* \@description
* Some of the statistics are calculated after the stream-published event, which may take at most 3 seconds.
* This method supports the Chrome browser only.
* @type {?}
*/
AgoraClient.prototype.getLocalVideoStats;
/**
* Gets the Statistics of the System Network
* @deprecated from v2.5.1, use getTransportStats instead.
*
* This method gets the statistics of the browser's local network.
* Currently only the network type information is provided, see NetworkType.
*
* \@description
* Chrome 61+ is required for this function, and the compatibility is not guaranteed. See Network Information API for details.
* @type {?}
*/
AgoraClient.prototype.getNetworkStats;
/**
* Enumerates Audio Output Devices
*
* This method enumerates the available audio output devices, such as speakers.
* If this method succeeds, the SDK returns a list of audio output devices in an array of
* [MediaDeviceInfo](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.mediadeviceinfo.html) objects.
* @type {?}
*/
AgoraClient.prototype.getPlayoutDevices;
/**
* Enumerates Audio Input Devices
*
* This method enumerates the available audio input devices, such as microphones.
* If this method succeeds, the SDK returns a list of audio input devices in an array of MediaDeviceInfo objects.
* @type {?}
*/
AgoraClient.prototype.getRecordingDevices;
/**
* Retrieves the Audio Statistics of the Remote Stream
* This method retrieves the audio statistics of the remote stream, including audio codec type, packet loss rate, bitrate, and so on.
*
* \@description
* The statistics are calculated after the `stream-subscribed` event, which may take at most 3 seconds.
* This method supports the Chrome browser only.
* @type {?}
*/
AgoraClient.prototype.getRemoteAudioStats;
/**
* Retrieves the Video Statistics of the Remote Stream
* This method retrieves the video statistics of the remote stream, including packet loss rate, video bitrate, frame rate, and so on.
*
* \@description
* The statistics are calculated after the `stream-subscribed` event, which may take at most 3 seconds.
* This method supports the Chrome browser only.
* @type {?}
*/
AgoraClient.prototype.getRemoteVideoStats;
/**
* Gets the Statistics of the Session
* This method gets the statistics of the session connection.
*
* \@description
* This method should be called after joining the channel, and it may take at most 3 seconds to retrieve the statistics.
* This method supports the Chrome browser only.
* @type {?}
*/
AgoraClient.prototype.getSessionStats;
/**
* Gets the Statistics of the System
*
* This method gets the statistics of the system.
*
* Currently only the battery level information is provided.
* @see [BatteryLevel](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.systemstats.html#batterylevel).
*
* \@description
* This feature is experimental.
* @see [Battery Status API](https://developer.mozilla.org/en-US/docs/Web/API/Battery_Status_API) for browser compatibility.
* @type {?}
*/
AgoraClient.prototype.getSystemStats;
/**
* Gets the Statistics of the Transmission
* This method gets the statistics of the transmission quality to Agora service.
*
* \@description
* Calculation of the statistics may take at most 3 seconds.
* This method supports the Chrome browser only.
* @type {?}
*/
AgoraClient.prototype.getTransportStats;
/**
* Initializes the Client object.
*
* \@param appId Pass in the App ID for your project.
* ASCII characters only, and the string length must be greater than 0 and less than 256 bytes.
* To get your App ID,
* @see [Get an App ID](https://docs.agora.io/en/Video/web_prepare?platform=Web#create-an-agora-account-and-get-an-app-id).
* \@param [onSuccess] The callback when the method succeeds.
* \@param [onFailure] The callback when the method fails.
*
* \@example
* client.init(appId, () => {
* console.log("client initialized");
* // Join a channel
* //……
* }, err => {
* console.log("client init failed ", err);
* // Error handling
* });
* @type {?}
*/
AgoraClient.prototype.init;
/**
* Joins an AgoraRTC Channel
* This method joins an AgoraRTC channel.
*
* \@description
* All users in the same channel should have the same type (number or string) of uid.
* - If you use a number as the user ID, it should be a 32-bit unsigned integer with a value ranging from 0 to (232-1).
* - If you use a string as the user ID, the maximum length is 255 characters.
*
* \@param tokenOrKey
* - Low security requirements: Pass null as the parameter value.
* - High security requirements: Pass the string of the Token or Channel Key as the parameter value. See Use Security Keys for details.
* \@param channel
* A string that provides a unique channel name for the Agora session. The length must be within 64 bytes. Supported character scopes:
* - 26 lowercase English letters a-z
* - 26 uppercase English letters A-Z
* - 10 numbers 0-9
* - Space
* - "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "\@", "[", "]", "^", "_", "{", "}", "|", "~", ","
* \@param uid The user ID, an integer or a string, ASCII characters only. Ensure this ID is unique.
* If you set the uid to null, the server assigns one and returns it in the onSuccess callback.
* \@param [onSuccess] The callback when the method succeeds. The server returns the uid which represents the identity of the user.
* \@param [onFailure] The callback when the method fails.
* \@example
* client.join(<token>, "1024", null, uid => {
* console.log("client" + uid + "joined channel");
* // Create a local stream
* //……
* }, err => {
* console.error("client join failed ", err);
* // Error handling
* });
*
* @type {?}
*/
AgoraClient.prototype.join;
/**
* Leaves an AgoraRTC Channel
*
* This method enables a user to leave a channel.
*
* \@param [onSuccess] The callback when the method succeeds.
* \@param [onFailure] The callback when the method fails.
* \@example
* client.leave(_ => {
* console.log("client leaves channel");
* //……
* }, err => {
* console.log("client leave failed ", err);
* //error handling
* });
* @type {?}
*/
AgoraClient.prototype.leave;
/**
* This method removes the events attached by the Client.on() method.
*
* \@example
* client.on("stream-published", function processStreamPublished(evt) {
* console.log("Stream Published");
* evt.stream.play("divId");
* client.off("stream-published", processStreamPublished);
* })
* @type {?}
*/
AgoraClient.prototype.off;
/**
* Occurs when an Agora.io event connected to the local client is received from the SDK.
*
* @see [On](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#on)
* for all variations of this core function.
* @type {?}
*/
AgoraClient.prototype.on;
/**
* Publishes a Local Stream
* This method publishes a local stream to the SD-RTN.
*
* \@description
* In a live broadcast, whoever calls this API is the host.
*
* \@param stream Stream object, which represents the local stream.
* \@param [onFailure] The callback when the method fails.
* \@example
* client.publish(stream, err => {
* console.log(err);
* //……
* })
* @type {?}
*/
AgoraClient.prototype.publish;
/**
* Removes the Injected Stream
*
* This method removes the HTTP/HTTPS URL address (added by addInjectStreamUrl) from the live broadcast.
*
* \@param url URL address of the live streaming. ASCII characters only, and the string
* length must be greater that 0 and less than 256 bytes.
* @type {?}
*/
AgoraClient.prototype.removeInjectStreamUrl;
/**
* This method renews your channel key.
*
* Once the Channel Key schema is enabled, the key expires after a certain period of time.
* When the onFailure callback reports the error DYNAMIC_KEY_TIMEOUT, the application should renew the
* Channel Key by calling this method. Not doing so will result in SDK disconnecting with the server.
* @type {?}
*/
AgoraClient.prototype.renewChannelKey;
/**
* This method renews your token.
*
* Once the Token schema is enabled, the token expires after a certain period of time.
* In case of the `onTokenPrivilegeWillExpire` or `onTokenPrivilegeDidExpire` callback events, the application
* should renew the Token by calling this method. Not doing so will result in SDK disconnecting with the server.
*
* \@param token Specifies the renewed Token.
* @type {?}
*/
AgoraClient.prototype.renewToken;
/**
* Sets the role of the user.
*
* This method is applicable only to the live mode.
* Sets the role of the user such as a host or an audience (default), before joining a channel.
* This method can be used to switch the user role after the user joins a channel.
*
* In live mode ([mode](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.clientconfig.html#mode) is set as live):
* - Before joining the channel, you can call this method to set the role.
* - After joining the channel, you can call this method to switch the role:
* When you call [publish](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#publish),
* the user role switches to host; when you call
* [unpublish](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#unpublish),
* the user role switches to audience.
* After calling [publish](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#publish),
* if you call this method and set the user role as audience,
* [unpublish](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#unpublish) is called automatically.
*
* In communication mode
* ([mode](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.clientconfig.html#mode) set as `rtc`),
* this method does not take effect. All users are host by default.
*
* \@param role User role in a live broadcast:
* - "audience": Audience, the default role. An audience can only receive streams.
* - "host": Host. A host can both send and receive streams.
*
* \@example
* client.setClientRole('host', _ => {
* console.log("setHost success");
* }, e => {
* console.log("setHost failed", e);
* })
* @type {?}
*/
AgoraClient.prototype.setClientRole;
/**
* This method sets the encryption mode.
*
* \@description
* Ensure that you call this API before
* [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join).
*
* \@param encryptionMode
* - aes-128-xts: Sets the encryption mode as AES128XTS.
* - aes-256-xts: Sets the encryption mode as AES256XTS.
* - aes-128-ecb: Sets the encryption mode as AES128ECB.
* @type {?}
*/
AgoraClient.prototype.setEncryptionMode;
/**
* This method enables the built-in encryption.
*
* \@description
* Ensure that you call this API before
* [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join).
*
* \@param password
* - The encryption password. ASCII characters only, and the string length must be greater than 0 and less than 256 bytes.
* @type {?}
*/
AgoraClient.prototype.setEncryptionSecret;
/**
* This method sets the video layout and audio for CDN live.
*
* \@description
* Call [setLiveTranscoding](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setlivetranscoding)
* after [createStream](https://docs.agora.io/en/Video/API%20Reference/web/globals.html#createstream).
* For details, see [Push Streams to the CDN](https://docs.agora.io/en/Video/push_stream_web).
* @type {?}
*/
AgoraClient.prototype.setLiveTranscoding;
/**
* Sets the Low-video Stream Parameter
*
* If you enabled the dual-stream mode by calling
* [Client.enableDualStream](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#enabledualstream),
* use this method to set the low-video stream profile.
* If you do not set the low-video stream profile, the SDK will assign default values based on your stream video profile.
*
* \@description
* - As different web browsers have different restrictions on the video profile, the parameters you set
* may fail to take effect. The Firefox browser has a fixed frame rate of 30 fps, therefore the frame
* rate settings do not work on the Firefox browser.
* - Due to limitations of some devices and browsers, the resolution you set may fail to take effect and
* get adjusted by the browser. In this case, billings will be calculated based on the actual resolution.
* - Call [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join) before using this method.
* - Screen sharing supports the high-video stream only.
*
* @see [setLowStreamParameter](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setlowstreamparameter)
* @type {?}
*/
AgoraClient.prototype.setLowStreamParameter;
/**
* Deploys the Nginx Server
*
* Use this method to deploy the Nginx server.
*
* \@description
* Ensure that you call this API before
* [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join).
* Proxy services by different service providers may result in slow performance if you are using the Firefox browser.
* Therefore, Agora recommends using the same service provider for the proxy services. If you use different service providers,
* Agora recommends not using the Firefox browser.
*
* \@param proxyServer Your Nginx server domain name. ASCII characters only, and the string length
* must be greater than 0 and less than 256 bytes.
* @type {?}
*/
AgoraClient.prototype.setProxyServer;
/**
* Sets the Remote Video-stream Type
* When a remote user sends dual streams, this method decides on which stream to receive on the subscriber side.
* If this method is not used, the subscriber receives the high-video stream.
*
* \@description
* As not all web browsers are compatible with dual streams, Agora does not recommend developers setting the
* resolution of the low-video stream.
*
* Some web browsers may not be fully compatible with dual streams:
* @see [Table](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setremotevideostreamtype)
*
* \@param stream The remote video stream object.
* \@param streamType Sets the remote video stream type. The following lists the video-stream types:
* - 0: High-bitrate, high-resolution video stream.
* - 1: Low-bitrate, low-resolution video stream.
*
* \@example
* switchStream = function (){
* if (highOrLow === 0) {
* highOrLow = 1
* console.log("Set to low");
* }
* else {
* highOrLow = 0
* console.log("Set to high");
* }
*
* client.setRemoteVideoStreamType(stream, highOrLow);
* }
* @type {?}
*/
AgoraClient.prototype.setRemoteVideoStreamType;
/**
* Use this method to set stream fallback option on the receiver.
*
* Under poor network conditions, the SDK can choose to subscribe to the low-video stream or only the audio stream.
*
* \@description
* This method can only be used when the publisher has enabled the dual-stream mode by
* [enableDualStream](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#enabledualstream).
*
* \@param stream The remote stream object.
* \@param fallbackType The fallback option:
* - 0: Disable the fallback.
* - 1: (Default) Automatically subscribe to the low-video stream under poor network.
* - 2: Under poor network, the SDK may subscribe to the low-video stream (of lower resolution and lower bitrate) first,
* but if the network still does not allow displaying the video, the SDK will receive audio only.
*
* \@example
* // The sender side, after publishing the high stream
* client.enableDualStream();
*
* // The receiver side, set the fallback option as 2
* client.setStreamFallbackOption(remoteStream, 2);
*
* @type {?}
*/
AgoraClient.prototype.setStreamFallbackOption;
/**
* Deploys the TURN Server.
*
* \@description
* Ensure that you call this API before
* [Client.join](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#join).
*
* @see [setTurnServer](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setturnserver)
* @type {?}
*/
AgoraClient.prototype.setTurnServer;
/**
* Starts relaying media streams across channels.
*
* After this method call, the SDK triggers the following callbacks:
*
* - Client.on(`"channel-media-relay-state"`), which reports the state and error code of the media stream relay.
* - If the media stream relay starts successfully, this callback returns `state` 2 and `code` 0.
* - If the media stream relay fails, this callback returns `state` 3. Refer to `code` for the error code and call this method again.
*
* - Client.on(`"channel-media-relay-event"`), which reports the events of the media stream relay.
* - If the media stream relay starts successfully, this callback returns `code` 4, reporting that the
* SDK starts relaying the media stream to the destination channel.
*
* \@remark
* - Contact sales-us@agora.io to enable this function.
* - We do not support string user IDs in this API.
* - Call this method only after joining a channel.
* - In a live-broadcast channel, only a host can call this method.
* - To call this method again after it succeeds, you must call stopChannelMediaRelay to quit the current relay.
*
* \@since 3.0.0
* @type {?}
*/
AgoraClient.prototype.startChannelMediaRelay;
/**
* This method starts a live stream.
*
* \@description
* Call [startLiveStreaming](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#startlivestreaming)
* after [createStream](https://docs.agora.io/en/Video/API%20Reference/web/globals.html#createstream).
*
* \@param url URL address for the live stream. ASCII characters only, and
* the string length must be greater than 0 and less than 256 bytes.
* \@param [enableTranscoding] Marks whether to enable live transcoding.
* If set as true, setLiveTranscoding must be called before this method.
*
* @see [Push Streams to the CDN](https://docs.agora.io/en/Video/push_stream_web).
* @type {?}
*/
AgoraClient.prototype.startLiveStreaming;
/**
* Enables Cloud Proxy.
*
* This method must be called before joining the channel or after leaving the channel.
*
* To use the cloud proxy service, some extra settings are needed, see
* [Use Cloud Proxy](https://docs.agora.io/en/Interactive%20Broadcast/cloud_proxy_web?platform=Web) for details.
* @type {?}
*/
AgoraClient.prototype.startProxyServer;
/**
* Stops the media stream relay. Once the relay stops, the user leaves all the destination channels.
*
* After this method call, the SDK triggers the `Client.on("channel-media-relay-state")` callback.
*
* - If the relay stops, the callback returns `state` 0.
* - If the relay fails to stop, the callback returns `state` 3 and `code` 2 or 8. The failure is usually due to poor network conditions.
* You can call [Client.leave](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#leave)
* to leave the channel and stop the relay.
*
* \@since 3.0.0
* \@example
* stopChannelMediaRelay: () => {
* client.stopChannelMediaRelay(e => {
* if(e) {
* utils.notification(`stopChannelMediaRelay failed: ${JSON.stringify(e)}`);
* } else {
* utils.notification(`stopChannelMediaRelay success`);
* }
* });
* }
*
* \@param callback The result of stopping the media stream relay.
* @type {?}
*/
AgoraClient.prototype.stopChannelMediaRelay;
/**
* This method stops and deletes the live streaming.
* When the live stream stops, the SDK triggers the `Client.on("liveStreamingStopped")` callback.
*
* \@param url URL address of the live streaming. ASCII characters only, and
* the string length must be greater than 0 and less than 256 bytes.
* @type {?}
*/
AgoraClient.prototype.stopLiveStreaming;
/**
* Disables Cloud Proxy.
*
* This method must be called before joining the channel or after leaving the channel.
*
* This method disables all proxy settings, including those set by
* [setProxyServer](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setproxyserver) and
* [setTurnServer](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#setturnserver).
* @type {?}
*/
AgoraClient.prototype.stopProxyServer;
/**
* This method enables a user to subscribe to a remote stream.
*
* After the user subscribes to a remote stream, the SDK triggers the `Client.on("stream-subscribed")` callback.
* If the remote stream contains an audio track, the SDK also triggers the `Client.on("first-audio-frame-decode")` callback;
* if the remote stream contains a video track, the SDK also triggers the `Client.on("first-video-frame-decode")` callback.
*
* \@example
* client.subscribe(stream, err => {
* console.error("stream subscribe failed", err);
* //……
* });
*
* Advanced
*
* This method can be called multiple times for a single remote stream,
* and enables you to switch between receiving/not receiving the video or audio data flexibly.
*
* \@example
* // Initially, subscribe to the stream and receive only the video data
* client.subscribe(stream, {video: true, audio: false});
*
* // After a while, switch to receiving only the audio data
* client.subscribe(stream, {video: false, audio: true});
*
* \@remarks
* - video and `audio` cannot be set as `false` at the same time. If you need to stop subscribing to the stream,
* call [Client.unsubscribe](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#unsubscribe) instead.
* - Safari does not support independent subscription. Set `options` as `null` for Safari,
* otherwise the `SAFARI_NOT_SUPPORTED_FOR_TRACK_SUBSCRIPTION` error occurs.
*
* \@param stream Stream object, which represents the remote stream.
* \@param [options] Sets whether to receive the video or audio data independently by the `video` and `audio` parameters.
* \@param [onFailure] The callback when the method fails. The following are common errors:
* - `"SAFARI_NOT_SUPPORTED_FOR_TRACK_SUBSCRIPTION"`: Safari does not support independent subscription.
* - `"INVALID_OPERATION"`: The user is not in the channel, possibly because the user has not
* joined the channel or the connection is interrupted.
* - `"SUBSCRIBE_STREAM_FAILED"`: The subscription fails, usually because the SDK has disconnected
* from the Agora server when subscribing to the stream.
* - `"PEERCONNECTION_FAILED"`: Fails to establish the media transport channel.
* @type {?}
*/
AgoraClient.prototype.subscribe;
/**
* Unpublishes the Local Stream.
*
* When the stream is unpublished, the `Client.on("stream-removed")` callback is triggered on the remote client.
*
* \@param stream Stream object, which represents the local stream.
*
* \@example
* client.unpublish(stream, err => {
* console.log(err);
* //……
* })
*
* \@remarks
* In a live broadcast, the user role of a host switches to audience after unpublishing, and
* the `Client.on("peer-leave")` callback is triggered on the remote client.
* @type {?}
*/
AgoraClient.prototype.unpublish;
/**
* Unsubscribes from a Remote Stream.
*
* \@param stream Stream object, which represents the remote stream.
*
* \@example
* client.unsubscribe(stream, err => {
* console.log(err);
* //……
* })
*
* @type {?}
*/
AgoraClient.prototype.unsubscribe;
/**
* Updates the channels for media stream relay.
*
* After the channel media relay starts, if you want to relay the media stream to more channels,
* or leave the current relay channel, you can call this method.
*
* After this method call, the SDK triggers the `Client.on("channel-media-relay-event")` callback.
* - If the update succeeds, the callback returns `code` 7.
* - If the update fails, the callback returns `code` 8, and the SDK also triggers the
* `Client.on("channel-media-relay-state")` callback with `state` 3. In this case, the media relay state is reset, and you need to call
* [startChannelMediaRelay](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#startchannelmediarelay)
* again to restart the relay.
*
* \@remarks
* - Call this method after
* [startChannelMediaRelay](https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.client.html#startchannelmediarelay).
* - You can add a maximum of four destination channels to a relay.
*
* \@example
* client.updateChannelMediaRelay(channelMediaConfig, e => {
* if (e) {
* utils.notification(`updateChannelMediaRelay failed: ${JSON.stringify(e)}`);
* } else {
* utils.notification(`updateChannelMediaRelay success`);
* }
* });
*
* \@since 3.0.0
* @type {?}
*/
AgoraClient.prototype.updateChannelMediaRelay;
/** @type {?|undefined} */
AgoraClient.prototype.aesMode;
/** @type {?|undefined} */
AgoraClient.prototype.aespassword;
/** @type {?|undefined} */
AgoraClient.prototype.gatewayClient;
/** @type {?|undefined} */
AgoraClient.prototype.highStream;
/** @type {?|undefined} */
AgoraClient.prototype.highStreamState;
/** @type {?|undefined} */
AgoraClient.prototype.isDualStream;
/** @type {?|undefined} */
AgoraClient.prototype.key;
/** @type {?|undefined} */
AgoraClient.prototype.lowStream;
/** @type {?|undefined} */
AgoraClient.prototype.lowStreamParameter;
/** @type {?|undefined} */
AgoraClient.prototype.lowStreamState;
/** @type {?|undefined} */
AgoraClient.prototype.proxyServer;
/** @type {?|undefined} */
AgoraClient.prototype.turnServer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdvcmEtY2xpZW50Lm1vZGVsLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWFnb3JhLyIsInNvdXJjZXMiOlsibGliL2RhdGEvbW9kZWxzL2Fnb3JhLWNsaWVudC5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUF1QkEsaUNBOHhCQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTN2QkMseUNBQXNFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBcUJ0RSxzQ0FNVTs7Ozs7Ozs7Ozs7O0lBV1Ysd0NBR1U7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWlCVixpREFBdUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBc0J2Qyx1Q0FHVTs7Ozs7OztJQU1WLGlDQUFvRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFtQnBFLHlDQUEwQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFzQjFDLHlDQUEyRTs7Ozs7Ozs7Ozs7SUFVM0UseUNBQTJFOzs7Ozs7Ozs7Ozs7SUFXM0Usc0NBQXlEOzs7Ozs7Ozs7SUFRekQsd0NBQTJFOzs7Ozs7OztJQU8zRSwwQ0FBNkU7Ozs7Ozs7Ozs7SUFTN0UsMENBQThFOzs7Ozs7Ozs7O0lBUzlFLDBDQUE4RTs7Ozs7Ozs7OztJQVM5RSxzQ0FBbUU7Ozs7Ozs7Ozs7Ozs7O0lBYW5FLHFDQUFpRTs7Ozs7Ozs7OztJQVNqRSx3Q0FBdUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFxQnZFLDJCQUlVOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFtQ1YsMkJBTVU7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWlCViw0QkFBNEU7Ozs7Ozs7Ozs7OztJQVc1RSwwQkFBb0U7Ozs7Ozs7O0lBT3BFLHlCQUErRDs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFnQi9ELDhCQUFzRTs7Ozs7Ozs7OztJQVN0RSw0Q0FBNkM7Ozs7Ozs7OztJQVE3QyxzQ0FJVTs7Ozs7Ozs7Ozs7SUFVVixpQ0FBb0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBa0NwQyxvQ0FHVTs7Ozs7Ozs7Ozs7Ozs7SUFhVix3Q0FFVTs7Ozs7Ozs7Ozs7O0lBV1YsMENBQWdEOzs7Ozs7Ozs7O0lBU2hELHlDQUFzRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBb0J0RCw0Q0FLVzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFnQlgscUNBQThDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFnQzlDLCtDQUFzRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUF5QnRFLDhDQUEyRTs7Ozs7Ozs7Ozs7SUFVM0Usb0NBQWdEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUF1QmhELDZDQUdVOzs7Ozs7Ozs7Ozs7Ozs7O0lBZVYseUNBQXVFOzs7Ozs7Ozs7O0lBU3ZFLHVDQUE2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUF5QjdCLDRDQUVVOzs7Ozs7Ozs7SUFRVix3Q0FBeUM7Ozs7Ozs7Ozs7O0lBVXpDLHNDQUE0Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTBDNUIsZ0NBSVU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFrQlYsZ0NBQXdFOzs7Ozs7Ozs7Ozs7OztJQWF4RSxrQ0FBMEU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUE4QjFFLDhDQUdVOztJQUdWLDhCQUFpQjs7SUFDakIsa0NBQXFCOztJQUNyQixvQ0FBbUI7O0lBQ25CLGlDQUFpQjs7SUFDakIsc0NBQXlCOztJQUN6QixtQ0FBdUI7O0lBQ3ZCLDBCQUFVOztJQUNWLGdDQUFnQjs7SUFDaEIseUNBQXlCOztJQUN6QixxQ0FBd0I7O0lBQ3hCLGtDQUFrQjs7SUFDbEIsaUNBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2xpZW50RXZlbnQgfSBmcm9tICcuLi9lbnVtcy9jbGllbnQtZXZlbnQuZW51bSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uU3RhdGUgfSBmcm9tICcuLi90eXBlcy9jb25uZWN0aW9uLXN0YXRlLnR5cGUnO1xuaW1wb3J0IHsgQ2hhbm5lbE1lZGlhRXJyb3IgfSBmcm9tICcuL2NoYW5uZWwtbWVkaWEtZXJyb3IubW9kZWwnO1xuaW1wb3J0IHsgQ2hhbm5lbE1lZGlhUmVsYXlDb25maWd1cmF0aW9uIH0gZnJvbSAnLi9jaGFubmVsLW1lZGlhLXJlbGF5LWNvbmZpZ3VyYXRpb24ubW9kZWwnO1xuaW1wb3J0IHsgSW5qZWN0U3RyZWFtQ29uZmlnIH0gZnJvbSAnLi9pbmplY3Qtc3RyZWFtLWNvbmZpZy5tb2RlbCc7XG5pbXBvcnQgeyBMaXZlVHJhbnNjb2RpbmcgfSBmcm9tICcuL2xpdmUtdHJhbnNjb2RpbmcubW9kZWwnO1xuaW1wb3J0IHsgTG9jYWxBdWRpb1N0YXRzTWFwIH0gZnJvbSAnLi9sb2NhbC1hdWRpby1zdGF0cy1tYXAubW9kZWwnO1xuaW1wb3J0IHsgTG9jYWxWaWRlb1N0YXRzTWFwIH0gZnJvbSAnLi9sb2NhbC12aWRlby1zdGF0cy1tYXAubW9kZWwnO1xuaW1wb3J0IHsgUmVtb3RlQXVkaW9TdGF0c01hcCB9IGZyb20gJy4vcmVtb3RlLWF1ZGlvLXN0YXRzLW1hcC5tb2RlbCc7XG5pbXBvcnQgeyBSZW1vdGVWaWRlb1N0YXRzTWFwIH0gZnJvbSAnLi9yZW1vdGUtdmlkZW8tc3RhdHMtbWFwLm1vZGVsJztcbmltcG9ydCB7IFNlc3Npb25TdGF0cyB9IGZyb20gJy4vc2Vzc2lvbi1zdGF0cy5tb2RlbCc7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL3N0cmVhbS5tb2RlbCc7XG5pbXBvcnQgeyBTdWJzY3JpYmVPcHRpb25zIH0gZnJvbSAnLi9zdWJzY3JpYmUtb3B0aW9ucy5tb2RlbCc7XG5pbXBvcnQgeyBTeXN0ZW1TdGF0cyB9IGZyb20gJy4vc3lzdGVtLXN0YXRzLm1vZGVsJztcbmltcG9ydCB7IFRyYW5zcG9ydFN0YXRzIH0gZnJvbSAnLi90cmFuc3BvcnQtc3RhdHMubW9kZWwnO1xuaW1wb3J0IHsgVHVyblNlcnZlciB9IGZyb20gJy4vdHVybi1zZXJ2ZXIubW9kZWwnO1xuXG4vKipcbiAqIFRoZSBDbGllbnQgb2JqZWN0IHJldHVybmVkIGJ5IHRoZSBbY3JlYXRlQ2xpZW50XShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9nbG9iYWxzLmh0bWwjY3JlYXRlY2xpZW50KVxuICogbWV0aG9kIHByb3ZpZGVzIGFjY2VzcyB0byBtdWNoIG9mIHRoZSBjb3JlIEFnb3JhUlRDIGZ1bmN0aW9uYWxpdHkuXG4gKlxuICogQHNlZSBbV2ViIENsaWVudF0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbClcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZ29yYUNsaWVudCB7XG4gIC8qKlxuICAgKiBJbmplY3RzIGFuIE9ubGluZSBNZWRpYSBTdHJlYW0gdG8gYSBMaXZlIEJyb2FkY2FzdFxuICAgKlxuICAgKiBJZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgc3VjY2Vzc2Z1bGx5LCB0aGUgc2VydmVyIHB1bGxzIHRoZSB2b2ljZSBvciB2aWRlbyBzdHJlYW0gYW5kXG4gICAqIGluamVjdHMgaXQgaW50byBhIGxpdmUgY2hhbm5lbC4gVGhpcyBpcyBhcHBsaWNhYmxlIHRvIHNjZW5hcmlvcyB3aGVyZSBhbGwgb2YgdGhlIGF1ZGllbmNlIG1lbWJlcnNcbiAgICogaW4gdGhlIGNoYW5uZWwgY2FuIHdhdGNoIGEgbGl2ZSBzaG93IGFuZCBpbnRlcmFjdCB3aXRoIGVhY2ggb3RoZXIuXG4gICAqXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNhbGwgdHJpZ2dlcnMgdGhlIGZvbGxvd2luZyBjYWxsYmFja3M6XG4gICAqXG4gICAqIC0gT24gdGhlIGxvY2FsIGNsaWVudDpcbiAgICogICAtIGBDbGllbnQub24oXCJzdHJlYW1JbmplY3RlZFN0YXR1c1wiKWAsIHdpdGggdGhlIHN0YXRlIG9mIGluamVjdGluZyB0aGUgb25saW5lIHN0cmVhbS5cbiAgICogICAtIGBDbGllbnQub24oXCJzdHJlYW0tYWRkZWRcIilgIGFuZCBgQ2xpZW50Lm9uKFwicGVlci1vbmxpbmVcIilgICh1aWQ6IDY2NiksIGlmIHRoZSBvbmxpbmUgbWVkaWEgc3RyZWFtIGlzIGluamVjdGVkIGludG8gdGhlIGNoYW5uZWwuXG4gICAqXG4gICAqIC0gT24gdGhlIHJlbW90ZSBjbGllbnQ6XG4gICAqICAgLSBgQ2xpZW50Lm9uKFwic3RyZWFtLWFkZGVkXCIpYCBhbmQgYENsaWVudC5vbihcInBlZXItb25saW5lXCIpYCAodWlkOiA2NjYpLCBpZiB0aGUgb25saW5lIG1lZGlhIHN0cmVhbSBpcyBpbmplY3RlZCBpbnRvIHRoZSBjaGFubmVsLlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBZb3UgY2FuIG9ubHkgaW5qZWN0IG9uZSBvbmxpbmUgbWVkaWEgc3RyZWFtIGludG8gdGhlIHNhbWUgY2hhbm5lbCBhdCB0aGUgc2FtZSB0aW1lLlxuICAgKiBFbnN1cmUgdGhhdCB5b3UgW2VuYWJsZSB0aGUgUlRNUCBDb252ZXJ0ZXIgc2VydmljZV0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL2Nkbl9zdHJlYW1pbmdfd2ViI3ByZXJlcXVpc2l0ZXMpXG4gICAqIGJlZm9yZSB1c2luZyB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gdXJsIFVSTCBhZGRyZXNzIG9mIHRoZSBsaXZlIHN0cmVhbWluZy5cbiAgICogQVNDSUkgY2hhcmFjdGVycyBvbmx5LCBhbmQgdGhlIHN0cmluZyBsZW5ndGggbXVzdCBiZSBncmVhdGVyIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDI1NiBieXRlcy5cbiAgICogVmFsaWQgcHJvdG9jb2xzIGFyZSBSVE1QLCBITFMsIGFuZCBIVFRQLUZMVi5cbiAgICpcbiAgICogLSBTdXBwb3J0ZWQgRkxWIGF1ZGlvIGNvZGVjIHR5cGU6IEFBQy5cbiAgICogLSBTdXBwb3J0ZWQgRkxWIHZpZGVvIGNvZGVjIHR5cGU6IEguMjY0IChBVkMpLlxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIENvbmZpZ3VyYXRpb24gb2YgdGhlIGluamVjdCBzdHJlYW0sIHNlZVxuICAgKiBbSW5qZWN0U3RyZWFtQ29uZmlnXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmluamVjdHN0cmVhbWNvbmZpZy5odG1sKSBmb3IgZGV0YWlscy5cbiAgICpcbiAgICogQHNlZSBbSW5qZWN0IGFuIE9ubGluZSBNZWRpYSBTdHJlYW1dKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9JbnRlcmFjdGl2ZSUyMEJyb2FkY2FzdC9pbmplY3Rfc3RyZWFtX3dlYj9wbGF0Zm9ybT1XZWIpIGZvciBkZXRhaWxzLlxuICAgKi9cbiAgYWRkSW5qZWN0U3RyZWFtVXJsOiAodXJsOiBzdHJpbmcsIGNvbmZpZzogSW5qZWN0U3RyZWFtQ29uZmlnKSA9PiB2b2lkO1xuICAvKipcbiAgICogQ29uZmlndXJlcyB0aGUgQ0ROIExpdmUgU3RyZWFtaW5nXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIEFnb3JhIHJlY29tbWVuZHMgdXNpbmcgdGhlIGZvbGxvd2luZyBtZXRob2RzIGluc3RlYWQ6XG4gICAqICAtIFtzdGFydExpdmVTdHJlYW1pbmddKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjc3RhcnRsaXZlc3RyZWFtaW5nKVxuICAgKiAgLSBbc2V0TGl2ZVRyYW5zY29kaW5nXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI3NldGxpdmV0cmFuc2NvZGluZylcbiAgICogIC0gW3N0b3BMaXZlU3RyZWFtaW5nXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI3N0b3BsaXZlc3RyZWFtaW5nKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogVGhpcyBtZXRob2QgY29uZmlndXJlcyB0aGUgQ0ROIGxpdmUgc3RyZWFtaW5nIGJlZm9yZSBqb2luaW5nIGEgY2hhbm5lbC5cbiAgICogQ2FsbCBbY29uZmlnUHVibGlzaGVyXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI2NvbmZpZ3B1Ymxpc2hlcikgYmVmb3JlXG4gICAqIFtDbGllbnQuam9pbl0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNqb2luKS5cbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50LmNvbmZpZ1B1Ymxpc2hlcih7XG4gICAqICB3aWR0aDogMzYwLFxuICAgKiAgaGVpZ2h0OiA2NDAsXG4gICAqICBmcmFtZXJhdGU6IDMwLFxuICAgKiAgYml0cmF0ZTogNTAwLFxuICAgKiAgcHVibGlzaFVybDogXCJydG1wOi8veHh4L3h4eC9cIlxuICAgKiB9KTtcbiAgICovXG4gIGNvbmZpZ1B1Ymxpc2hlcjogKFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgZnJhbWVyYXRlOiBudW1iZXIsXG4gICAgYml0cmF0ZTogbnVtYmVyLFxuICAgIHB1Ymxpc2hlclVybDogc3RyaW5nXG4gICkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIERpc2FibGVzIGR1YWwgc3RyZWFtcy5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50LmRpc2FibGVEdWFsU3RyZWFtKCgpID0+IHtcbiAgICogICBjb25zb2xlLmxvZyhcIkRpc2FibGUgZHVhbCBzdHJlYW0gc3VjY2VzcyFcIilcbiAgICogfSwgZXJyID0+IHtcbiAgICogICBjb25zb2xlLmxvZyhlcnIpXG4gICAqIH0pXG4gICAqL1xuICBkaXNhYmxlRHVhbFN0cmVhbTogKFxuICAgIG9uU3VjY2Vzcz86ICgpID0+IGFueSxcbiAgICBvbkZhaWx1cmU/OiAoZXJyb3I6IEVycm9yKSA9PiBhbnlcbiAgKSA9PiB2b2lkO1xuICAvKipcbiAgICogRW5hYmxlcyB0aGUgU0RLIHRvIHJlcG9ydCB0aGUgYWN0aXZlIHJlbW90ZSB1c2VycyB3aG8gYXJlIHNwZWFraW5nIGFuZCB0aGVpciB2b2x1bWUgcmVndWxhcmx5LlxuICAgKlxuICAgKiBJZiB0aGlzIG1ldGhvZCBpcyBlbmFibGVkLCB0aGUgU0RLIHdpbGwgcmV0dXJuIHRoZSB2b2x1bWVzIGV2ZXJ5IHR3byBzZWNvbmRzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlcmUgYXJlIGFjdGl2ZSBzcGVha2Vycy5cbiAgICpcbiAgICogQHJlbWFya1xuICAgKiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSB3ZWIgcGFnZXMgcnVubmluZyB0aGUgV2ViIFNESywgdGhpcyBmdW5jdGlvbiBtaWdodCBub3Qgd29yay5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50LmVuYWJsZUF1ZGlvVm9sdW1lSW5kaWNhdG9yKCk7IC8vIFRyaWdnZXJzIHRoZSBcInZvbHVtZS1pbmRpY2F0b3JcIiBjYWxsYmFjayBldmVudCBldmVyeSB0d28gc2Vjb25kcy5cbiAgICogY2xpZW50Lm9uKFwidm9sdW1lLWluZGljYXRvclwiLCBldnQgPT4ge1xuICAgKiAgIGV2dC5hdHRyLmZvckVhY2goKHZvbHVtZSwgaW5kZXgpID0+IHtcbiAgICogICAgIGNvbnNvbGUubG9nKGAjJHtpbmRleH0gVUlEICR7dm9sdW1lLnVpZH0gTGV2ZWwgJHt2b2x1bWUubGV2ZWx9YCk7XG4gICAqICAgfSk7XG4gICAqIH0pO1xuICAgKi9cbiAgZW5hYmxlQXVkaW9Wb2x1bWVJbmRpY2F0b3I6ICgpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBFbmFibGVzIHRoZSBkdWFsLXN0cmVhbSBtb2RlIG9uIHRoZSBwdWJsaXNoZXIgc2lkZS5cbiAgICpcbiAgICogRHVhbCBzdHJlYW1zIGFyZSBhIGh5YnJpZCBvZiBhIGhpZ2gtdmlkZW8gc3RyZWFtIGFuZCBhIGxvdy12aWRlbyBzdHJlYW06XG4gICAqIC0gSGlnaC12aWRlbyBzdHJlYW06IGhpZ2ggYml0cmF0ZSwgaGlnaCByZXNvbHV0aW9uXG4gICAqIC0gTG93LXZpZGVvIHN0cmVhbTogbG93IGJpdHJhdGUsIGxvdyByZXNvbHV0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNsaWVudC5lbmFibGVEdWFsU3RyZWFtKCgpID0+IHtcbiAgICogICBjb25zb2xlLmxvZyhcIkVuYWJsZSBkdWFsIHN0cmVhbSBzdWNjZXNzIVwiKVxuICAgKiB9LCBlcnIgPT4ge1xuICAgKiAgIGNvbnNvbGUsbG9nKGVycilcbiAgICogfSlcbiAgICpcbiAgICogQHJlbWFya1xuICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBhcHBseSB0byB0aGUgZm9sbG93aW5nIHNjZW5hcmlvczpcbiAgICogLSBUaGUgc3RyZWFtIGlzIGNyZWF0ZWQgYnkgZGVmaW5pbmcgdGhlIGF1ZGlvU291cmNlIGFuZCB2aWRlb1NvdXJjZSBwcm9wZXJ0aWVzLlxuICAgKiAtIEF1ZGlvLW9ubHkgbW9kZSAoYXVkaW86IHRydWUsIHZpZGVvOiBmYWxzZSlcbiAgICogLSBTYWZhcmkgYnJvd3NlciBvbiBpT1NcbiAgICogLSBTY3JlZW4tc2hhcmluZyBzY2VuYXJpb1xuICAgKi9cbiAgZW5hYmxlRHVhbFN0cmVhbTogKFxuICAgIG9uU3VjY2Vzcz86ICgpID0+IGFueSxcbiAgICBvbkZhaWx1cmU/OiAoZXJyb3I6IEVycm9yKSA9PiBhbnlcbiAgKSA9PiB2b2lkO1xuICAvKipcbiAgICogRW51bWVyYXRlcyB0aGUgYXZhaWxhYmxlIHZpZGVvIGlucHV0IGRldmljZXMsIHN1Y2ggYXMgY2FtZXJhcy5cbiAgICpcbiAgICogSWYgdGhpcyBtZXRob2Qgc3VjY2VlZHMsIHRoZSBTREsgcmV0dXJucyBhIGxpc3Qgb2YgdmlkZW8gaW5wdXQgZGV2aWNlcyBpbiBhbiBhcnJheSBvZiBNZWRpYURldmljZUluZm8gb2JqZWN0cy5cbiAgICovXG4gIGdldENhbWVyYXM6IChjYWxsYmFjazogKGRldmljZXM6IE1lZGlhRGV2aWNlSW5mb1tdKSA9PiBhbnkpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBzdGF0ZSBvZiB0aGUgY29ubmVjdGlvbiBiZXR3ZWVuIHRoZSBTREsgYW5kIEFnb3JhJ3MgZWRnZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUaGUgY29ubmVjdGlvbiBzdGF0ZTpcbiAgICogIC0gRElTQ09OTkVDVEVEOiBUaGUgU0RLIGlzIGRpc2Nvbm5lY3RlZCBmcm9tIEFnb3JhJ3MgZWRnZSBzZXJ2ZXIuXG4gICAqICAgIFRoaXMgaXMgdGhlIGluaXRpYWwgc3RhdGUgYmVmb3JlXG4gICAqICAgIFtDbGllbnQuam9pbl0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNqb2luKS5cbiAgICogICAgVGhlIFNESyBhbHNvIGVudGVycyB0aGlzIHN0YXRlIGFmdGVyIHRoZSBhcHAgY2FsbHNcbiAgICogICAgW0NsaWVudC5sZWF2ZV0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNsZWF2ZSkuXG4gICAqICAtIENPTk5FQ1RJTkc6IFRoZSBTREsgaXMgY29ubmVjdGluZyB0byBBZ29yYSdzIGVkZ2Ugc2VydmVyLiBUaGUgU0RLIGVudGVycyB0aGlzIHN0YXRlIHdoZW5cbiAgICogICAgY2FsbGluZyBbQ2xpZW50LmpvaW5dKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjam9pbilcbiAgICogICAgb3IgcmVjb25uZWN0aW5nIHRvIEFnb3JhJ3MgZWRnZSBzZXJ2ZXIgYXV0b21hdGljYWxseSBhZnRlciB0aGUgY29ubmVjdGlvbiBpcyBsb3N0LlxuICAgKiAgLSBDT05ORUNURUQ6IFRoZSBTREsgaXMgY29ubmVjdGVkIHRvIEFnb3JhJ3MgZWRnZSBzZXJ2ZXIgYW5kIGpvaW5zIGEgY2hhbm5lbC4gWW91IGNhbiBub3cgcHVibGlzaCBvclxuICAgKiAgICBzdWJzY3JpYmUgdG8gYSBzdHJlYW0gaW4gdGhlIGNoYW5uZWwuXG4gICAqICAtIERJU0NPTk5FQ1RJTkc6IFRoZSBTREsgaXMgZGlzY29ubmVjdGluZyBmcm9tIEFnb3JhJ3MgZWRnZSBzZXJ2ZXIuIFRoZSBTREsgZW50ZXJzIHRoaXMgc3RhdGUgd2hlbiBjYWxsaW5nXG4gICAqICAgIFtDbGllbnQubGVhdmVdKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjbGVhdmUpLlxuICAgKi9cbiAgZ2V0Q29ubmVjdGlvblN0YXRlOiAoKSA9PiBDb25uZWN0aW9uU3RhdGU7XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIEF1ZGlvIFN0YXRpc3RpY3Mgb2YgdGhlIExvY2FsIFN0cmVhbVxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIGF1ZGlvIHN0YXRpc3RpY3Mgb2YgdGhlIHB1Ymxpc2hlZCBzdHJlYW0sXG4gICAqIGluY2x1ZGluZyBhdWRpbyBjb2RlYyB0eXBlLCBzYW1wbGluZyByYXRlLCBiaXRyYXRlLCBhbmQgc28gb24uXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgLSBTb21lIG9mIHRoZSBzdGF0aXN0aWNzIGFyZSBjYWxjdWxhdGVkIGFmdGVyIHRoZSBzdHJlYW0tcHVibGlzaGVkIGV2ZW50LCB3aGljaCBtYXkgdGFrZSBhdCBtb3N0IDMgc2Vjb25kcy5cbiAgICogLSBUaGlzIG1ldGhvZCBzdXBwb3J0cyB0aGUgQ2hyb21lIGJyb3dzZXIgb25seS5cbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50LmdldExvY2FsQXVkaW9TdGF0cygobG9jYWxBdWRpb1N0YXRzKSA9PiB7XG4gICAqICBPYmplY3Qua2V5cyhsb2NhbEF1ZGlvU3RhdHMpLmZvckVhY2godWlkID0+IHtcbiAgICogICBjb25zb2xlLmxvZyhgQXVkaW8gQ29kZWNUeXBlIGZyb20gJHt1aWR9OiAke2xvY2FsQXVkaW9TdGF0c1t1aWRdLkNvZGVjVHlwZX1gKTtcbiAgICogICBjb25zb2xlLmxvZyhgQXVkaW8gTXV0ZVN0YXRlIGZyb20gJHt1aWR9OiAke2xvY2FsQXVkaW9TdGF0c1t1aWRdLk11dGVTdGF0ZX1gKTtcbiAgICogICBjb25zb2xlLmxvZyhgQXVkaW8gUmVjb3JkaW5nTGV2ZWwgZnJvbSAke3VpZH06ICR7bG9jYWxBdWRpb1N0YXRzW3VpZF0uUmVjb3JkaW5nTGV2ZWx9YCk7XG4gICAqICAgY29uc29sZS5sb2coYEF1ZGlvIFNhbXBsaW5nUmF0ZSBmcm9tICR7dWlkfTogJHtsb2NhbEF1ZGlvU3RhdHNbdWlkXS5TYW1wbGluZ1JhdGV9YCk7XG4gICAqICAgY29uc29sZS5sb2coYEF1ZGlvIFNlbmRCaXRyYXRlIGZyb20gJHt1aWR9OiAke2xvY2FsQXVkaW9TdGF0c1t1aWRdLlNlbmRCaXRyYXRlfWApO1xuICAgKiAgIGNvbnNvbGUubG9nKGBBdWRpbyBTZW5kTGV2ZWwgZnJvbSAke3VpZH06ICR7bG9jYWxBdWRpb1N0YXRzW3VpZF0uU2VuZExldmVsfWApO1xuICAgKiAgfSlcbiAgICogfSk7XG4gICAqL1xuICBnZXRMb2NhbEF1ZGlvU3RhdHM6IChjYWxsYmFjazogKHN0YXRzOiBMb2NhbEF1ZGlvU3RhdHNNYXApID0+IGFueSkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgVmlkZW8gU3RhdGlzdGljcyBvZiB0aGUgTG9jYWwgU3RyZWFtXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyB0aGUgdmlkZW8gc3RhdGlzdGljcyBvZiB0aGUgcHVibGlzaGVkIHN0cmVhbSwgaW5jbHVkaW5nIHZpZGVvIHJlc29sdXRpb24sIGJpdHJhdGUsIGZyYW1lIHJhdGUsIGFuZCBzbyBvbi5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFNvbWUgb2YgdGhlIHN0YXRpc3RpY3MgYXJlIGNhbGN1bGF0ZWQgYWZ0ZXIgdGhlIHN0cmVhbS1wdWJsaXNoZWQgZXZlbnQsIHdoaWNoIG1heSB0YWtlIGF0IG1vc3QgMyBzZWNvbmRzLlxuICAgKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyB0aGUgQ2hyb21lIGJyb3dzZXIgb25seS5cbiAgICovXG4gIGdldExvY2FsVmlkZW9TdGF0czogKGNhbGxiYWNrOiAoc3RhdHM6IExvY2FsVmlkZW9TdGF0c01hcCkgPT4gYW55KSA9PiB2b2lkO1xuICAvKipcbiAgICogR2V0cyB0aGUgU3RhdGlzdGljcyBvZiB0aGUgU3lzdGVtIE5ldHdvcmtcbiAgICogQGRlcHJlY2F0ZWQgZnJvbSB2Mi41LjEsIHVzZSBnZXRUcmFuc3BvcnRTdGF0cyBpbnN0ZWFkLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBzdGF0aXN0aWNzIG9mIHRoZSBicm93c2VyJ3MgbG9jYWwgbmV0d29yay5cbiAgICogQ3VycmVudGx5IG9ubHkgdGhlIG5ldHdvcmsgdHlwZSBpbmZvcm1hdGlvbiBpcyBwcm92aWRlZCwgc2VlIE5ldHdvcmtUeXBlLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogQ2hyb21lIDYxKyBpcyByZXF1aXJlZCBmb3IgdGhpcyBmdW5jdGlvbiwgYW5kIHRoZSBjb21wYXRpYmlsaXR5IGlzIG5vdCBndWFyYW50ZWVkLiBTZWUgTmV0d29yayBJbmZvcm1hdGlvbiBBUEkgZm9yIGRldGFpbHMuXG4gICAqL1xuICBnZXROZXR3b3JrU3RhdHM6IChjYWxsYmFjazogKHN0YXRzOiBhbnkpID0+IGFueSkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEVudW1lcmF0ZXMgQXVkaW8gT3V0cHV0IERldmljZXNcbiAgICpcbiAgICogVGhpcyBtZXRob2QgZW51bWVyYXRlcyB0aGUgYXZhaWxhYmxlIGF1ZGlvIG91dHB1dCBkZXZpY2VzLCBzdWNoIGFzIHNwZWFrZXJzLlxuICAgKiBJZiB0aGlzIG1ldGhvZCBzdWNjZWVkcywgdGhlIFNESyByZXR1cm5zIGEgbGlzdCBvZiBhdWRpbyBvdXRwdXQgZGV2aWNlcyBpbiBhbiBhcnJheSBvZlxuICAgKiBbTWVkaWFEZXZpY2VJbmZvXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLm1lZGlhZGV2aWNlaW5mby5odG1sKSBvYmplY3RzLlxuICAgKi9cbiAgZ2V0UGxheW91dERldmljZXM6IChjYWxsYmFjazogKGRldmljZXM6IE1lZGlhRGV2aWNlSW5mb1tdKSA9PiBhbnkpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBFbnVtZXJhdGVzIEF1ZGlvIElucHV0IERldmljZXNcbiAgICpcbiAgICogVGhpcyBtZXRob2QgZW51bWVyYXRlcyB0aGUgYXZhaWxhYmxlIGF1ZGlvIGlucHV0IGRldmljZXMsIHN1Y2ggYXMgbWljcm9waG9uZXMuXG4gICAqIElmIHRoaXMgbWV0aG9kIHN1Y2NlZWRzLCB0aGUgU0RLIHJldHVybnMgYSBsaXN0IG9mIGF1ZGlvIGlucHV0IGRldmljZXMgaW4gYW4gYXJyYXkgb2YgTWVkaWFEZXZpY2VJbmZvIG9iamVjdHMuXG4gICAqL1xuICBnZXRSZWNvcmRpbmdEZXZpY2VzOiAoY2FsbGJhY2s6IChkZXZpY2VzOiBNZWRpYURldmljZUluZm9bXSkgPT4gYW55KSA9PiB2b2lkO1xuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBBdWRpbyBTdGF0aXN0aWNzIG9mIHRoZSBSZW1vdGUgU3RyZWFtXG4gICAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyB0aGUgYXVkaW8gc3RhdGlzdGljcyBvZiB0aGUgcmVtb3RlIHN0cmVhbSwgaW5jbHVkaW5nIGF1ZGlvIGNvZGVjIHR5cGUsIHBhY2tldCBsb3NzIHJhdGUsIGJpdHJhdGUsIGFuZCBzbyBvbi5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFRoZSBzdGF0aXN0aWNzIGFyZSBjYWxjdWxhdGVkIGFmdGVyIHRoZSBgc3RyZWFtLXN1YnNjcmliZWRgIGV2ZW50LCB3aGljaCBtYXkgdGFrZSBhdCBtb3N0IDMgc2Vjb25kcy5cbiAgICogVGhpcyBtZXRob2Qgc3VwcG9ydHMgdGhlIENocm9tZSBicm93c2VyIG9ubHkuXG4gICAqL1xuICBnZXRSZW1vdGVBdWRpb1N0YXRzOiAoY2FsbGJhY2s6IChzdGF0czogUmVtb3RlQXVkaW9TdGF0c01hcCkgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgVmlkZW8gU3RhdGlzdGljcyBvZiB0aGUgUmVtb3RlIFN0cmVhbVxuICAgKiBUaGlzIG1ldGhvZCByZXRyaWV2ZXMgdGhlIHZpZGVvIHN0YXRpc3RpY3Mgb2YgdGhlIHJlbW90ZSBzdHJlYW0sIGluY2x1ZGluZyBwYWNrZXQgbG9zcyByYXRlLCB2aWRlbyBiaXRyYXRlLCBmcmFtZSByYXRlLCBhbmQgc28gb24uXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUaGUgc3RhdGlzdGljcyBhcmUgY2FsY3VsYXRlZCBhZnRlciB0aGUgYHN0cmVhbS1zdWJzY3JpYmVkYCBldmVudCwgd2hpY2ggbWF5IHRha2UgYXQgbW9zdCAzIHNlY29uZHMuXG4gICAqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIHRoZSBDaHJvbWUgYnJvd3NlciBvbmx5LlxuICAgKi9cbiAgZ2V0UmVtb3RlVmlkZW9TdGF0czogKGNhbGxiYWNrOiAoc3RhdHM6IFJlbW90ZVZpZGVvU3RhdHNNYXApID0+IHZvaWQpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBHZXRzIHRoZSBTdGF0aXN0aWNzIG9mIHRoZSBTZXNzaW9uXG4gICAqIFRoaXMgbWV0aG9kIGdldHMgdGhlIHN0YXRpc3RpY3Mgb2YgdGhlIHNlc3Npb24gY29ubmVjdGlvbi5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgam9pbmluZyB0aGUgY2hhbm5lbCwgYW5kIGl0IG1heSB0YWtlIGF0IG1vc3QgMyBzZWNvbmRzIHRvIHJldHJpZXZlIHRoZSBzdGF0aXN0aWNzLlxuICAgKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyB0aGUgQ2hyb21lIGJyb3dzZXIgb25seS5cbiAgICovXG4gIGdldFNlc3Npb25TdGF0czogKGNhbGxiYWNrOiAoc3RhdHM6IFNlc3Npb25TdGF0cykgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEdldHMgdGhlIFN0YXRpc3RpY3Mgb2YgdGhlIFN5c3RlbVxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBzdGF0aXN0aWNzIG9mIHRoZSBzeXN0ZW0uXG4gICAqXG4gICAqIEN1cnJlbnRseSBvbmx5IHRoZSBiYXR0ZXJ5IGxldmVsIGluZm9ybWF0aW9uIGlzIHByb3ZpZGVkLlxuICAgKiBAc2VlIFtCYXR0ZXJ5TGV2ZWxdKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuc3lzdGVtc3RhdHMuaHRtbCNiYXR0ZXJ5bGV2ZWwpLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogVGhpcyBmZWF0dXJlIGlzIGV4cGVyaW1lbnRhbC5cbiAgICogQHNlZSBbQmF0dGVyeSBTdGF0dXMgQVBJXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQmF0dGVyeV9TdGF0dXNfQVBJKSBmb3IgYnJvd3NlciBjb21wYXRpYmlsaXR5LlxuICAgKi9cbiAgZ2V0U3lzdGVtU3RhdHM6IChjYWxsYmFjazogKHN0YXRzOiBTeXN0ZW1TdGF0cykgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEdldHMgdGhlIFN0YXRpc3RpY3Mgb2YgdGhlIFRyYW5zbWlzc2lvblxuICAgKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBzdGF0aXN0aWNzIG9mIHRoZSB0cmFuc21pc3Npb24gcXVhbGl0eSB0byBBZ29yYSBzZXJ2aWNlLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogQ2FsY3VsYXRpb24gb2YgdGhlIHN0YXRpc3RpY3MgbWF5IHRha2UgYXQgbW9zdCAzIHNlY29uZHMuXG4gICAqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIHRoZSBDaHJvbWUgYnJvd3NlciBvbmx5LlxuICAgKi9cbiAgZ2V0VHJhbnNwb3J0U3RhdHM6IChjYWxsYmFjazogKHN0YXRzOiBUcmFuc3BvcnRTdGF0cykgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHRoZSBDbGllbnQgb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0gYXBwSWQgUGFzcyBpbiB0aGUgQXBwIElEIGZvciB5b3VyIHByb2plY3QuXG4gICAqIEFTQ0lJIGNoYXJhY3RlcnMgb25seSwgYW5kIHRoZSBzdHJpbmcgbGVuZ3RoIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAyNTYgYnl0ZXMuXG4gICAqIFRvIGdldCB5b3VyIEFwcCBJRCxcbiAgICogQHNlZSBbR2V0IGFuIEFwcCBJRF0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL3dlYl9wcmVwYXJlP3BsYXRmb3JtPVdlYiNjcmVhdGUtYW4tYWdvcmEtYWNjb3VudC1hbmQtZ2V0LWFuLWFwcC1pZCkuXG4gICAqIEBwYXJhbSBbb25TdWNjZXNzXSBUaGUgY2FsbGJhY2sgd2hlbiB0aGUgbWV0aG9kIHN1Y2NlZWRzLlxuICAgKiBAcGFyYW0gW29uRmFpbHVyZV0gVGhlIGNhbGxiYWNrIHdoZW4gdGhlIG1ldGhvZCBmYWlscy5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50LmluaXQoYXBwSWQsICgpID0+IHtcbiAgICogY29uc29sZS5sb2coXCJjbGllbnQgaW5pdGlhbGl6ZWRcIik7XG4gICAqIC8vIEpvaW4gYSBjaGFubmVsXG4gICAqIC8v4oCm4oCmXG4gICAqIH0sIGVyciA9PiB7XG4gICAqICAgICBjb25zb2xlLmxvZyhcImNsaWVudCBpbml0IGZhaWxlZCBcIiwgZXJyKTtcbiAgICogICAgIC8vIEVycm9yIGhhbmRsaW5nXG4gICAqIH0pO1xuICAgKi9cbiAgaW5pdDogKFxuICAgIGFwcElkOiBzdHJpbmcsXG4gICAgb25TdWNjZXNzPzogKCkgPT4gdm9pZCxcbiAgICBvbkZhaWx1cmU/OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkXG4gICkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEpvaW5zIGFuIEFnb3JhUlRDIENoYW5uZWxcbiAgICogVGhpcyBtZXRob2Qgam9pbnMgYW4gQWdvcmFSVEMgY2hhbm5lbC5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEFsbCB1c2VycyBpbiB0aGUgc2FtZSBjaGFubmVsIHNob3VsZCBoYXZlIHRoZSBzYW1lIHR5cGUgKG51bWJlciBvciBzdHJpbmcpIG9mIHVpZC5cbiAgICogIC0gSWYgeW91IHVzZSBhIG51bWJlciBhcyB0aGUgdXNlciBJRCwgaXQgc2hvdWxkIGJlIGEgMzItYml0IHVuc2lnbmVkIGludGVnZXIgd2l0aCBhIHZhbHVlIHJhbmdpbmcgZnJvbSAwIHRvICgyMzItMSkuXG4gICAqICAtIElmIHlvdSB1c2UgYSBzdHJpbmcgYXMgdGhlIHVzZXIgSUQsIHRoZSBtYXhpbXVtIGxlbmd0aCBpcyAyNTUgY2hhcmFjdGVycy5cbiAgICpcbiAgICogQHBhcmFtIHRva2VuT3JLZXlcbiAgICogLSBMb3cgc2VjdXJpdHkgcmVxdWlyZW1lbnRzOiBQYXNzIG51bGwgYXMgdGhlIHBhcmFtZXRlciB2YWx1ZS5cbiAgICogLSBIaWdoIHNlY3VyaXR5IHJlcXVpcmVtZW50czogUGFzcyB0aGUgc3RyaW5nIG9mIHRoZSBUb2tlbiBvciBDaGFubmVsIEtleSBhcyB0aGUgcGFyYW1ldGVyIHZhbHVlLiBTZWUgVXNlIFNlY3VyaXR5IEtleXMgZm9yIGRldGFpbHMuXG4gICAqIEBwYXJhbSBjaGFubmVsXG4gICAqIEEgc3RyaW5nIHRoYXQgcHJvdmlkZXMgYSB1bmlxdWUgY2hhbm5lbCBuYW1lIGZvciB0aGUgQWdvcmEgc2Vzc2lvbi4gVGhlIGxlbmd0aCBtdXN0IGJlIHdpdGhpbiA2NCBieXRlcy4gU3VwcG9ydGVkIGNoYXJhY3RlciBzY29wZXM6XG4gICAqIC0gMjYgbG93ZXJjYXNlIEVuZ2xpc2ggbGV0dGVycyBhLXpcbiAgICogLSAyNiB1cHBlcmNhc2UgRW5nbGlzaCBsZXR0ZXJzIEEtWlxuICAgKiAtIDEwIG51bWJlcnMgMC05XG4gICAqIC0gU3BhY2VcbiAgICogLSBcIiFcIiwgXCIjXCIsIFwiJFwiLCBcIiVcIiwgXCImXCIsIFwiKFwiLCBcIilcIiwgXCIrXCIsIFwiLVwiLCBcIjpcIiwgXCI7XCIsIFwiPFwiLCBcIj1cIiwgXCIuXCIsIFwiPlwiLCBcIj9cIiwgXCJAXCIsIFwiW1wiLCBcIl1cIiwgXCJeXCIsIFwiX1wiLCBcIntcIiwgXCJ9XCIsIFwifFwiLCBcIn5cIiwgXCIsXCJcbiAgICogQHBhcmFtIHVpZCBUaGUgdXNlciBJRCwgYW4gaW50ZWdlciBvciBhIHN0cmluZywgQVNDSUkgY2hhcmFjdGVycyBvbmx5LiBFbnN1cmUgdGhpcyBJRCBpcyB1bmlxdWUuXG4gICAqIElmIHlvdSBzZXQgdGhlIHVpZCB0byBudWxsLCB0aGUgc2VydmVyIGFzc2lnbnMgb25lIGFuZCByZXR1cm5zIGl0IGluIHRoZSBvblN1Y2Nlc3MgY2FsbGJhY2suXG4gICAqIEBwYXJhbSBbb25TdWNjZXNzXSBUaGUgY2FsbGJhY2sgd2hlbiB0aGUgbWV0aG9kIHN1Y2NlZWRzLiBUaGUgc2VydmVyIHJldHVybnMgdGhlIHVpZCB3aGljaCByZXByZXNlbnRzIHRoZSBpZGVudGl0eSBvZiB0aGUgdXNlci5cbiAgICogQHBhcmFtIFtvbkZhaWx1cmVdIFRoZSBjYWxsYmFjayB3aGVuIHRoZSBtZXRob2QgZmFpbHMuXG4gICAqIEBleGFtcGxlXG4gICAqIGNsaWVudC5qb2luKDx0b2tlbj4sIFwiMTAyNFwiLCBudWxsLCB1aWQgPT4ge1xuICAgKiAgICBjb25zb2xlLmxvZyhcImNsaWVudFwiICsgdWlkICsgXCJqb2luZWQgY2hhbm5lbFwiKTtcbiAgICogICAgLy8gQ3JlYXRlIGEgbG9jYWwgc3RyZWFtXG4gICAqICAgIC8v4oCm4oCmXG4gICAqIH0sIGVyciA9PiB7XG4gICAqICAgIGNvbnNvbGUuZXJyb3IoXCJjbGllbnQgam9pbiBmYWlsZWQgXCIsIGVycik7XG4gICAqICAgIC8vIEVycm9yIGhhbmRsaW5nXG4gICAqIH0pO1xuICAgKlxuICAgKi9cbiAgam9pbjogKFxuICAgIHRva2VuT3JLZXk6IHN0cmluZyB8IG51bGwsXG4gICAgY2hhbm5lbDogc3RyaW5nIHwgbnVsbCxcbiAgICB1aWQ6IG51bWJlciB8IHN0cmluZyB8IG51bGwsXG4gICAgb25TdWNjZXNzPzogKHVpZDogbnVtYmVyIHwgc3RyaW5nKSA9PiB2b2lkLFxuICAgIG9uRmFpbHVyZT86IChlcnJvcjogRXJyb3IpID0+IHZvaWRcbiAgKSA9PiB2b2lkO1xuICAvKipcbiAgICogTGVhdmVzIGFuIEFnb3JhUlRDIENoYW5uZWxcbiAgICpcbiAgICogVGhpcyBtZXRob2QgZW5hYmxlcyBhIHVzZXIgdG8gbGVhdmUgYSBjaGFubmVsLlxuICAgKlxuICAgKiBAcGFyYW0gW29uU3VjY2Vzc10gVGhlIGNhbGxiYWNrIHdoZW4gdGhlIG1ldGhvZCBzdWNjZWVkcy5cbiAgICogQHBhcmFtIFtvbkZhaWx1cmVdIFRoZSBjYWxsYmFjayB3aGVuIHRoZSBtZXRob2QgZmFpbHMuXG4gICAqIEBleGFtcGxlXG4gICAqIGNsaWVudC5sZWF2ZShfID0+IHtcbiAgICogICAgIGNvbnNvbGUubG9nKFwiY2xpZW50IGxlYXZlcyBjaGFubmVsXCIpO1xuICAgKiAgICAgLy/igKbigKZcbiAgICogfSwgZXJyID0+IHtcbiAgICogICAgIGNvbnNvbGUubG9nKFwiY2xpZW50IGxlYXZlIGZhaWxlZCBcIiwgZXJyKTtcbiAgICogICAgIC8vZXJyb3IgaGFuZGxpbmdcbiAgICogfSk7XG4gICAqL1xuICBsZWF2ZTogKG9uU3VjY2Vzcz86ICgpID0+IHZvaWQsIG9uRmFpbHVyZT86IChlcnJvcjogRXJyb3IpID0+IHZvaWQpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCByZW1vdmVzIHRoZSBldmVudHMgYXR0YWNoZWQgYnkgdGhlIENsaWVudC5vbigpIG1ldGhvZC5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50Lm9uKFwic3RyZWFtLXB1Ymxpc2hlZFwiLCBmdW5jdGlvbiBwcm9jZXNzU3RyZWFtUHVibGlzaGVkKGV2dCkge1xuICAgKiAgY29uc29sZS5sb2coXCJTdHJlYW0gUHVibGlzaGVkXCIpO1xuICAgKiAgZXZ0LnN0cmVhbS5wbGF5KFwiZGl2SWRcIik7XG4gICAqICBjbGllbnQub2ZmKFwic3RyZWFtLXB1Ymxpc2hlZFwiLCBwcm9jZXNzU3RyZWFtUHVibGlzaGVkKTtcbiAgICogfSlcbiAgICovXG4gIG9mZjogKGV2ZW50VHlwZTogQ2xpZW50RXZlbnQsIGNhbGxiYWNrOiAoZXZ0OiBhbnkpID0+IHZvaWQpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBPY2N1cnMgd2hlbiBhbiBBZ29yYS5pbyBldmVudCBjb25uZWN0ZWQgdG8gdGhlIGxvY2FsIGNsaWVudCBpcyByZWNlaXZlZCBmcm9tIHRoZSBTREsuXG4gICAqXG4gICAqIEBzZWUgW09uXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI29uKVxuICAgKiBmb3IgYWxsIHZhcmlhdGlvbnMgb2YgdGhpcyBjb3JlIGZ1bmN0aW9uLlxuICAgKi9cbiAgb246IChldmVudDogQ2xpZW50RXZlbnQsIGNhbGxiYWNrOiAoZXZ0OiBhbnkpID0+IHZvaWQpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBQdWJsaXNoZXMgYSBMb2NhbCBTdHJlYW1cbiAgICogVGhpcyBtZXRob2QgcHVibGlzaGVzIGEgbG9jYWwgc3RyZWFtIHRvIHRoZSBTRC1SVE4uXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBJbiBhIGxpdmUgYnJvYWRjYXN0LCB3aG9ldmVyIGNhbGxzIHRoaXMgQVBJIGlzIHRoZSBob3N0LlxuICAgKlxuICAgKiBAcGFyYW0gc3RyZWFtIFN0cmVhbSBvYmplY3QsIHdoaWNoIHJlcHJlc2VudHMgdGhlIGxvY2FsIHN0cmVhbS5cbiAgICogQHBhcmFtIFtvbkZhaWx1cmVdIFRoZSBjYWxsYmFjayB3aGVuIHRoZSBtZXRob2QgZmFpbHMuXG4gICAqIEBleGFtcGxlXG4gICAqIGNsaWVudC5wdWJsaXNoKHN0cmVhbSwgZXJyID0+IHtcbiAgICogICAgY29uc29sZS5sb2coZXJyKTtcbiAgICogICAgLy/igKbigKZcbiAgICogfSlcbiAgICovXG4gIHB1Ymxpc2g6IChzdHJlYW06IFN0cmVhbSwgb25GYWlsdXJlPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIEluamVjdGVkIFN0cmVhbVxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCByZW1vdmVzIHRoZSBIVFRQL0hUVFBTIFVSTCBhZGRyZXNzIChhZGRlZCBieSBhZGRJbmplY3RTdHJlYW1VcmwpIGZyb20gdGhlIGxpdmUgYnJvYWRjYXN0LlxuICAgKlxuICAgKiBAcGFyYW0gdXJsIFVSTCBhZGRyZXNzIG9mIHRoZSBsaXZlIHN0cmVhbWluZy4gQVNDSUkgY2hhcmFjdGVycyBvbmx5LCBhbmQgdGhlIHN0cmluZ1xuICAgKiBsZW5ndGggbXVzdCBiZSBncmVhdGVyIHRoYXQgMCBhbmQgbGVzcyB0aGFuIDI1NiBieXRlcy5cbiAgICovXG4gIHJlbW92ZUluamVjdFN0cmVhbVVybDogKHVybDogc3RyaW5nKSA9PiB2b2lkO1xuICAvKipcbiAgICogVGhpcyBtZXRob2QgcmVuZXdzIHlvdXIgY2hhbm5lbCBrZXkuXG4gICAqXG4gICAqIE9uY2UgdGhlIENoYW5uZWwgS2V5IHNjaGVtYSBpcyBlbmFibGVkLCB0aGUga2V5IGV4cGlyZXMgYWZ0ZXIgYSBjZXJ0YWluIHBlcmlvZCBvZiB0aW1lLlxuICAgKiBXaGVuIHRoZSBvbkZhaWx1cmUgY2FsbGJhY2sgcmVwb3J0cyB0aGUgZXJyb3IgRFlOQU1JQ19LRVlfVElNRU9VVCwgdGhlIGFwcGxpY2F0aW9uIHNob3VsZCByZW5ldyB0aGVcbiAgICogQ2hhbm5lbCBLZXkgYnkgY2FsbGluZyB0aGlzIG1ldGhvZC4gTm90IGRvaW5nIHNvIHdpbGwgcmVzdWx0IGluIFNESyBkaXNjb25uZWN0aW5nIHdpdGggdGhlIHNlcnZlci5cbiAgICovXG4gIHJlbmV3Q2hhbm5lbEtleTogKFxuICAgIGtleTogc3RyaW5nLFxuICAgIG9uU3VjY2Vzcz86ICgpID0+IHZvaWQsXG4gICAgb25GYWlsdXJlPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCByZW5ld3MgeW91ciB0b2tlbi5cbiAgICpcbiAgICogT25jZSB0aGUgVG9rZW4gc2NoZW1hIGlzIGVuYWJsZWQsIHRoZSB0b2tlbiBleHBpcmVzIGFmdGVyIGEgY2VydGFpbiBwZXJpb2Qgb2YgdGltZS5cbiAgICogSW4gY2FzZSBvZiB0aGUgYG9uVG9rZW5Qcml2aWxlZ2VXaWxsRXhwaXJlYCBvciBgb25Ub2tlblByaXZpbGVnZURpZEV4cGlyZWAgY2FsbGJhY2sgZXZlbnRzLCB0aGUgYXBwbGljYXRpb25cbiAgICogc2hvdWxkIHJlbmV3IHRoZSBUb2tlbiBieSBjYWxsaW5nIHRoaXMgbWV0aG9kLiBOb3QgZG9pbmcgc28gd2lsbCByZXN1bHQgaW4gU0RLIGRpc2Nvbm5lY3Rpbmcgd2l0aCB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW4gU3BlY2lmaWVzIHRoZSByZW5ld2VkIFRva2VuLlxuICAgKi9cbiAgcmVuZXdUb2tlbjogKHRva2VuOiBzdHJpbmcpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBTZXRzIHRoZSByb2xlIG9mIHRoZSB1c2VyLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBhcHBsaWNhYmxlIG9ubHkgdG8gdGhlIGxpdmUgbW9kZS5cbiAgICogU2V0cyB0aGUgcm9sZSBvZiB0aGUgdXNlciBzdWNoIGFzIGEgaG9zdCBvciBhbiBhdWRpZW5jZSAoZGVmYXVsdCksIGJlZm9yZSBqb2luaW5nIGEgY2hhbm5lbC5cbiAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gc3dpdGNoIHRoZSB1c2VyIHJvbGUgYWZ0ZXIgdGhlIHVzZXIgam9pbnMgYSBjaGFubmVsLlxuICAgKlxuICAgKiBJbiBsaXZlIG1vZGUgKFttb2RlXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudGNvbmZpZy5odG1sI21vZGUpIGlzIHNldCBhcyBsaXZlKTpcbiAgICogLSBCZWZvcmUgam9pbmluZyB0aGUgY2hhbm5lbCwgeW91IGNhbiBjYWxsIHRoaXMgbWV0aG9kIHRvIHNldCB0aGUgcm9sZS5cbiAgICogLSBBZnRlciBqb2luaW5nIHRoZSBjaGFubmVsLCB5b3UgY2FuIGNhbGwgdGhpcyBtZXRob2QgdG8gc3dpdGNoIHRoZSByb2xlOlxuICAgKiAgIFdoZW4geW91IGNhbGwgW3B1Ymxpc2hdKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjcHVibGlzaCksXG4gICAqICAgdGhlIHVzZXIgcm9sZSBzd2l0Y2hlcyB0byBob3N0OyB3aGVuIHlvdSBjYWxsXG4gICAqICAgW3VucHVibGlzaF0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCN1bnB1Ymxpc2gpLFxuICAgKiAgIHRoZSB1c2VyIHJvbGUgc3dpdGNoZXMgdG8gYXVkaWVuY2UuXG4gICAqICAgQWZ0ZXIgY2FsbGluZyBbcHVibGlzaF0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNwdWJsaXNoKSxcbiAgICogICBpZiB5b3UgY2FsbCB0aGlzIG1ldGhvZCBhbmQgc2V0IHRoZSB1c2VyIHJvbGUgYXMgYXVkaWVuY2UsXG4gICAqICAgW3VucHVibGlzaF0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCN1bnB1Ymxpc2gpIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5LlxuICAgKlxuICAgKiBJbiBjb21tdW5pY2F0aW9uIG1vZGVcbiAgICogKFttb2RlXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudGNvbmZpZy5odG1sI21vZGUpIHNldCBhcyBgcnRjYCksXG4gICAqIHRoaXMgbWV0aG9kIGRvZXMgbm90IHRha2UgZWZmZWN0LiBBbGwgdXNlcnMgYXJlIGhvc3QgYnkgZGVmYXVsdC5cbiAgICpcbiAgICogQHBhcmFtIHJvbGUgVXNlciByb2xlIGluIGEgbGl2ZSBicm9hZGNhc3Q6XG4gICAqIC0gXCJhdWRpZW5jZVwiOiBBdWRpZW5jZSwgdGhlIGRlZmF1bHQgcm9sZS4gQW4gYXVkaWVuY2UgY2FuIG9ubHkgcmVjZWl2ZSBzdHJlYW1zLlxuICAgKiAtIFwiaG9zdFwiOiBIb3N0LiBBIGhvc3QgY2FuIGJvdGggc2VuZCBhbmQgcmVjZWl2ZSBzdHJlYW1zLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjbGllbnQuc2V0Q2xpZW50Um9sZSgnaG9zdCcsIF8gPT4ge1xuICAgKiAgICBjb25zb2xlLmxvZyhcInNldEhvc3Qgc3VjY2Vzc1wiKTtcbiAgICogIH0sIGUgPT4ge1xuICAgKiAgICBjb25zb2xlLmxvZyhcInNldEhvc3QgZmFpbGVkXCIsIGUpO1xuICAgKiAgfSlcbiAgICovXG4gIHNldENsaWVudFJvbGU6IChcbiAgICByb2xlOiAnYXVkaWVuY2UnIHwgJ2hvc3QnLFxuICAgIGNhbGxiYWNrPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHRoZSBlbmNyeXB0aW9uIG1vZGUuXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBFbnN1cmUgdGhhdCB5b3UgY2FsbCB0aGlzIEFQSSBiZWZvcmVcbiAgICogW0NsaWVudC5qb2luXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI2pvaW4pLlxuICAgKlxuICAgKiBAcGFyYW0gZW5jcnlwdGlvbk1vZGVcbiAgICogLSBhZXMtMTI4LXh0czogU2V0cyB0aGUgZW5jcnlwdGlvbiBtb2RlIGFzIEFFUzEyOFhUUy5cbiAgICogLSBhZXMtMjU2LXh0czogU2V0cyB0aGUgZW5jcnlwdGlvbiBtb2RlIGFzIEFFUzI1NlhUUy5cbiAgICogLSBhZXMtMTI4LWVjYjogU2V0cyB0aGUgZW5jcnlwdGlvbiBtb2RlIGFzIEFFUzEyOEVDQi5cbiAgICovXG4gIHNldEVuY3J5cHRpb25Nb2RlOiAoXG4gICAgZW5jcnlwdGlvbk1vZGU6ICdhZXMtMTI4LXh0cycgfCAnYWVzLTI1Ni14dHMnIHwgJ2Flcy0xMjgtZWNiJ1xuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBlbmFibGVzIHRoZSBidWlsdC1pbiBlbmNyeXB0aW9uLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogRW5zdXJlIHRoYXQgeW91IGNhbGwgdGhpcyBBUEkgYmVmb3JlXG4gICAqIFtDbGllbnQuam9pbl0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNqb2luKS5cbiAgICpcbiAgICogQHBhcmFtIHBhc3N3b3JkXG4gICAqIC0gVGhlIGVuY3J5cHRpb24gcGFzc3dvcmQuIEFTQ0lJIGNoYXJhY3RlcnMgb25seSwgYW5kIHRoZSBzdHJpbmcgbGVuZ3RoIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAyNTYgYnl0ZXMuXG4gICAqL1xuICBzZXRFbmNyeXB0aW9uU2VjcmV0OiAocGFzc3dvcmQ6IHN0cmluZykgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHNldHMgdGhlIHZpZGVvIGxheW91dCBhbmQgYXVkaW8gZm9yIENETiBsaXZlLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogQ2FsbCBbc2V0TGl2ZVRyYW5zY29kaW5nXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI3NldGxpdmV0cmFuc2NvZGluZylcbiAgICogYWZ0ZXIgW2NyZWF0ZVN0cmVhbV0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvZ2xvYmFscy5odG1sI2NyZWF0ZXN0cmVhbSkuXG4gICAqIEZvciBkZXRhaWxzLCBzZWUgW1B1c2ggU3RyZWFtcyB0byB0aGUgQ0ROXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vcHVzaF9zdHJlYW1fd2ViKS5cbiAgICovXG4gIHNldExpdmVUcmFuc2NvZGluZzogKGNvZGluZzogTGl2ZVRyYW5zY29kaW5nKSA9PiB2b2lkO1xuICAvKipcbiAgICogU2V0cyB0aGUgTG93LXZpZGVvIFN0cmVhbSBQYXJhbWV0ZXJcbiAgICpcbiAgICogSWYgeW91IGVuYWJsZWQgdGhlIGR1YWwtc3RyZWFtIG1vZGUgYnkgY2FsbGluZ1xuICAgKiBbQ2xpZW50LmVuYWJsZUR1YWxTdHJlYW1dKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjZW5hYmxlZHVhbHN0cmVhbSksXG4gICAqIHVzZSB0aGlzIG1ldGhvZCB0byBzZXQgdGhlIGxvdy12aWRlbyBzdHJlYW0gcHJvZmlsZS5cbiAgICogSWYgeW91IGRvIG5vdCBzZXQgdGhlIGxvdy12aWRlbyBzdHJlYW0gcHJvZmlsZSwgdGhlIFNESyB3aWxsIGFzc2lnbiBkZWZhdWx0IHZhbHVlcyBiYXNlZCBvbiB5b3VyIHN0cmVhbSB2aWRlbyBwcm9maWxlLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogLSBBcyBkaWZmZXJlbnQgd2ViIGJyb3dzZXJzIGhhdmUgZGlmZmVyZW50IHJlc3RyaWN0aW9ucyBvbiB0aGUgdmlkZW8gcHJvZmlsZSwgdGhlIHBhcmFtZXRlcnMgeW91IHNldFxuICAgKiAgIG1heSBmYWlsIHRvIHRha2UgZWZmZWN0LiBUaGUgRmlyZWZveCBicm93c2VyIGhhcyBhIGZpeGVkIGZyYW1lIHJhdGUgb2YgMzAgZnBzLCB0aGVyZWZvcmUgdGhlIGZyYW1lXG4gICAqICAgcmF0ZSBzZXR0aW5ncyBkbyBub3Qgd29yayBvbiB0aGUgRmlyZWZveCBicm93c2VyLlxuICAgKiAtIER1ZSB0byBsaW1pdGF0aW9ucyBvZiBzb21lIGRldmljZXMgYW5kIGJyb3dzZXJzLCB0aGUgcmVzb2x1dGlvbiB5b3Ugc2V0IG1heSBmYWlsIHRvIHRha2UgZWZmZWN0IGFuZFxuICAgKiAgIGdldCBhZGp1c3RlZCBieSB0aGUgYnJvd3Nlci4gSW4gdGhpcyBjYXNlLCBiaWxsaW5ncyB3aWxsIGJlIGNhbGN1bGF0ZWQgYmFzZWQgb24gdGhlIGFjdHVhbCByZXNvbHV0aW9uLlxuICAgKiAtIENhbGwgW0NsaWVudC5qb2luXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI2pvaW4pIGJlZm9yZSB1c2luZyB0aGlzIG1ldGhvZC5cbiAgICogLSBTY3JlZW4gc2hhcmluZyBzdXBwb3J0cyB0aGUgaGlnaC12aWRlbyBzdHJlYW0gb25seS5cbiAgICpcbiAgICogQHNlZSBbc2V0TG93U3RyZWFtUGFyYW1ldGVyXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI3NldGxvd3N0cmVhbXBhcmFtZXRlcilcbiAgICovXG4gIHNldExvd1N0cmVhbVBhcmFtZXRlcjogKHBhcmFtOiB7XG4gICAgYml0cmF0ZT86IG51bWJlcjtcbiAgICBmcmFtZXJhdGU/OiBudW1iZXI7XG4gICAgaGVpZ2h0PzogbnVtYmVyO1xuICAgIHdpZHRoPzogbnVtYmVyO1xuICB9KSA9PiB2b2lkO1xuICAvKipcbiAgICogRGVwbG95cyB0aGUgTmdpbnggU2VydmVyXG4gICAqXG4gICAqIFVzZSB0aGlzIG1ldGhvZCB0byBkZXBsb3kgdGhlIE5naW54IHNlcnZlci5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEVuc3VyZSB0aGF0IHlvdSBjYWxsIHRoaXMgQVBJIGJlZm9yZVxuICAgKiBbQ2xpZW50LmpvaW5dKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjam9pbikuXG4gICAqIFByb3h5IHNlcnZpY2VzIGJ5IGRpZmZlcmVudCBzZXJ2aWNlIHByb3ZpZGVycyBtYXkgcmVzdWx0IGluIHNsb3cgcGVyZm9ybWFuY2UgaWYgeW91IGFyZSB1c2luZyB0aGUgRmlyZWZveCBicm93c2VyLlxuICAgKiBUaGVyZWZvcmUsIEFnb3JhIHJlY29tbWVuZHMgdXNpbmcgdGhlIHNhbWUgc2VydmljZSBwcm92aWRlciBmb3IgdGhlIHByb3h5IHNlcnZpY2VzLiBJZiB5b3UgdXNlIGRpZmZlcmVudCBzZXJ2aWNlIHByb3ZpZGVycyxcbiAgICogQWdvcmEgcmVjb21tZW5kcyBub3QgdXNpbmcgdGhlIEZpcmVmb3ggYnJvd3Nlci5cbiAgICpcbiAgICogQHBhcmFtIHByb3h5U2VydmVyIFlvdXIgTmdpbnggc2VydmVyIGRvbWFpbiBuYW1lLiBBU0NJSSBjaGFyYWN0ZXJzIG9ubHksIGFuZCB0aGUgc3RyaW5nIGxlbmd0aFxuICAgKiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIGFuZCBsZXNzIHRoYW4gMjU2IGJ5dGVzLlxuICAgKi9cbiAgc2V0UHJveHlTZXJ2ZXI6IChwcm94eVNlcnZlcjogc3RyaW5nKSA9PiB2b2lkO1xuICAvKipcbiAgICogU2V0cyB0aGUgUmVtb3RlIFZpZGVvLXN0cmVhbSBUeXBlXG4gICAqIFdoZW4gYSByZW1vdGUgdXNlciBzZW5kcyBkdWFsIHN0cmVhbXMsIHRoaXMgbWV0aG9kIGRlY2lkZXMgb24gd2hpY2ggc3RyZWFtIHRvIHJlY2VpdmUgb24gdGhlIHN1YnNjcmliZXIgc2lkZS5cbiAgICogSWYgdGhpcyBtZXRob2QgaXMgbm90IHVzZWQsIHRoZSBzdWJzY3JpYmVyIHJlY2VpdmVzIHRoZSBoaWdoLXZpZGVvIHN0cmVhbS5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEFzIG5vdCBhbGwgd2ViIGJyb3dzZXJzIGFyZSBjb21wYXRpYmxlIHdpdGggZHVhbCBzdHJlYW1zLCBBZ29yYSBkb2VzIG5vdCByZWNvbW1lbmQgZGV2ZWxvcGVycyBzZXR0aW5nIHRoZVxuICAgKiByZXNvbHV0aW9uIG9mIHRoZSBsb3ctdmlkZW8gc3RyZWFtLlxuICAgKlxuICAgKiBTb21lIHdlYiBicm93c2VycyBtYXkgbm90IGJlIGZ1bGx5IGNvbXBhdGlibGUgd2l0aCBkdWFsIHN0cmVhbXM6XG4gICAqIEBzZWUgW1RhYmxlXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI3NldHJlbW90ZXZpZGVvc3RyZWFtdHlwZSlcbiAgICpcbiAgICogQHBhcmFtIHN0cmVhbSBUaGUgcmVtb3RlIHZpZGVvIHN0cmVhbSBvYmplY3QuXG4gICAqIEBwYXJhbSBzdHJlYW1UeXBlIFNldHMgdGhlIHJlbW90ZSB2aWRlbyBzdHJlYW0gdHlwZS4gVGhlIGZvbGxvd2luZyBsaXN0cyB0aGUgdmlkZW8tc3RyZWFtIHR5cGVzOlxuICAgKiAtIDA6IEhpZ2gtYml0cmF0ZSwgaGlnaC1yZXNvbHV0aW9uIHZpZGVvIHN0cmVhbS5cbiAgICogLSAxOiBMb3ctYml0cmF0ZSwgbG93LXJlc29sdXRpb24gdmlkZW8gc3RyZWFtLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBzd2l0Y2hTdHJlYW0gPSBmdW5jdGlvbiAoKXtcbiAgICogICBpZiAoaGlnaE9yTG93ID09PSAwKSB7XG4gICAqICAgICBoaWdoT3JMb3cgPSAxXG4gICAqICAgICBjb25zb2xlLmxvZyhcIlNldCB0byBsb3dcIik7XG4gICAqICAgfVxuICAgKiAgIGVsc2Uge1xuICAgKiAgICAgaGlnaE9yTG93ID0gMFxuICAgKiAgICAgY29uc29sZS5sb2coXCJTZXQgdG8gaGlnaFwiKTtcbiAgICogICB9XG4gICAqXG4gICAqICAgY2xpZW50LnNldFJlbW90ZVZpZGVvU3RyZWFtVHlwZShzdHJlYW0sIGhpZ2hPckxvdyk7XG4gICAqIH1cbiAgICovXG4gIHNldFJlbW90ZVZpZGVvU3RyZWFtVHlwZTogKHN0cmVhbTogU3RyZWFtLCBzdHJlYW1UeXBlOiAwIHwgMSkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFVzZSB0aGlzIG1ldGhvZCB0byBzZXQgc3RyZWFtIGZhbGxiYWNrIG9wdGlvbiBvbiB0aGUgcmVjZWl2ZXIuXG4gICAqXG4gICAqIFVuZGVyIHBvb3IgbmV0d29yayBjb25kaXRpb25zLCB0aGUgU0RLIGNhbiBjaG9vc2UgdG8gc3Vic2NyaWJlIHRvIHRoZSBsb3ctdmlkZW8gc3RyZWFtIG9yIG9ubHkgdGhlIGF1ZGlvIHN0cmVhbS5cbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFRoaXMgbWV0aG9kIGNhbiBvbmx5IGJlIHVzZWQgd2hlbiB0aGUgcHVibGlzaGVyIGhhcyBlbmFibGVkIHRoZSBkdWFsLXN0cmVhbSBtb2RlIGJ5XG4gICAqIFtlbmFibGVEdWFsU3RyZWFtXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI2VuYWJsZWR1YWxzdHJlYW0pLlxuICAgKlxuICAgKiBAcGFyYW0gc3RyZWFtIFRoZSByZW1vdGUgc3RyZWFtIG9iamVjdC5cbiAgICogQHBhcmFtIGZhbGxiYWNrVHlwZSBUaGUgZmFsbGJhY2sgb3B0aW9uOlxuICAgKiAtIDA6IERpc2FibGUgdGhlIGZhbGxiYWNrLlxuICAgKiAtIDE6IChEZWZhdWx0KSBBdXRvbWF0aWNhbGx5IHN1YnNjcmliZSB0byB0aGUgbG93LXZpZGVvIHN0cmVhbSB1bmRlciBwb29yIG5ldHdvcmsuXG4gICAqIC0gMjogVW5kZXIgcG9vciBuZXR3b3JrLCB0aGUgU0RLIG1heSBzdWJzY3JpYmUgdG8gdGhlIGxvdy12aWRlbyBzdHJlYW0gKG9mIGxvd2VyIHJlc29sdXRpb24gYW5kIGxvd2VyIGJpdHJhdGUpIGZpcnN0LFxuICAgKiBidXQgaWYgdGhlIG5ldHdvcmsgc3RpbGwgZG9lcyBub3QgYWxsb3cgZGlzcGxheWluZyB0aGUgdmlkZW8sIHRoZSBTREsgd2lsbCByZWNlaXZlIGF1ZGlvIG9ubHkuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFRoZSBzZW5kZXIgc2lkZSwgYWZ0ZXIgcHVibGlzaGluZyB0aGUgaGlnaCBzdHJlYW1cbiAgICogIGNsaWVudC5lbmFibGVEdWFsU3RyZWFtKCk7XG4gICAqXG4gICAqICAvLyBUaGUgcmVjZWl2ZXIgc2lkZSwgc2V0IHRoZSBmYWxsYmFjayBvcHRpb24gYXMgMlxuICAgKiAgY2xpZW50LnNldFN0cmVhbUZhbGxiYWNrT3B0aW9uKHJlbW90ZVN0cmVhbSwgMik7XG4gICAqXG4gICAqL1xuICBzZXRTdHJlYW1GYWxsYmFja09wdGlvbjogKHN0cmVhbTogU3RyZWFtLCBmYWxsYmFja1R5cGU6IDAgfCAxIHwgMikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIERlcGxveXMgdGhlIFRVUk4gU2VydmVyLlxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogRW5zdXJlIHRoYXQgeW91IGNhbGwgdGhpcyBBUEkgYmVmb3JlXG4gICAqIFtDbGllbnQuam9pbl0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNqb2luKS5cbiAgICpcbiAgICogQHNlZSBbc2V0VHVyblNlcnZlcl0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNzZXR0dXJuc2VydmVyKVxuICAgKi9cbiAgc2V0VHVyblNlcnZlcjogKHR1cm5TZXJ2ZXI6IFR1cm5TZXJ2ZXIpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBTdGFydHMgcmVsYXlpbmcgbWVkaWEgc3RyZWFtcyBhY3Jvc3MgY2hhbm5lbHMuXG4gICAqXG4gICAqIEFmdGVyIHRoaXMgbWV0aG9kIGNhbGwsIHRoZSBTREsgdHJpZ2dlcnMgdGhlIGZvbGxvd2luZyBjYWxsYmFja3M6XG4gICAqXG4gICAqIC0gQ2xpZW50Lm9uKGBcImNoYW5uZWwtbWVkaWEtcmVsYXktc3RhdGVcImApLCB3aGljaCByZXBvcnRzIHRoZSBzdGF0ZSBhbmQgZXJyb3IgY29kZSBvZiB0aGUgbWVkaWEgc3RyZWFtIHJlbGF5LlxuICAgKiAgLSBJZiB0aGUgbWVkaWEgc3RyZWFtIHJlbGF5IHN0YXJ0cyBzdWNjZXNzZnVsbHksIHRoaXMgY2FsbGJhY2sgcmV0dXJucyBgc3RhdGVgIDIgYW5kIGBjb2RlYCAwLlxuICAgKiAgLSBJZiB0aGUgbWVkaWEgc3RyZWFtIHJlbGF5IGZhaWxzLCB0aGlzIGNhbGxiYWNrIHJldHVybnMgYHN0YXRlYCAzLiBSZWZlciB0byBgY29kZWAgZm9yIHRoZSBlcnJvciBjb2RlIGFuZCBjYWxsIHRoaXMgbWV0aG9kIGFnYWluLlxuICAgKlxuICAgKiAtIENsaWVudC5vbihgXCJjaGFubmVsLW1lZGlhLXJlbGF5LWV2ZW50XCJgKSwgd2hpY2ggcmVwb3J0cyB0aGUgZXZlbnRzIG9mIHRoZSBtZWRpYSBzdHJlYW0gcmVsYXkuXG4gICAqICAtIElmIHRoZSBtZWRpYSBzdHJlYW0gcmVsYXkgc3RhcnRzIHN1Y2Nlc3NmdWxseSwgdGhpcyBjYWxsYmFjayByZXR1cm5zIGBjb2RlYCA0LCByZXBvcnRpbmcgdGhhdCB0aGVcbiAgICogICAgU0RLIHN0YXJ0cyByZWxheWluZyB0aGUgbWVkaWEgc3RyZWFtIHRvIHRoZSBkZXN0aW5hdGlvbiBjaGFubmVsLlxuICAgKlxuICAgKiBAcmVtYXJrXG4gICAqIC0gQ29udGFjdCBzYWxlcy11c++8oGFnb3JhLmlvIHRvIGVuYWJsZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIFdlIGRvIG5vdCBzdXBwb3J0IHN0cmluZyB1c2VyIElEcyBpbiB0aGlzIEFQSS5cbiAgICogLSBDYWxsIHRoaXMgbWV0aG9kIG9ubHkgYWZ0ZXIgam9pbmluZyBhIGNoYW5uZWwuXG4gICAqIC0gSW4gYSBsaXZlLWJyb2FkY2FzdCBjaGFubmVsLCBvbmx5IGEgaG9zdCBjYW4gY2FsbCB0aGlzIG1ldGhvZC5cbiAgICogLSBUbyBjYWxsIHRoaXMgbWV0aG9kIGFnYWluIGFmdGVyIGl0IHN1Y2NlZWRzLCB5b3UgbXVzdCBjYWxsIHN0b3BDaGFubmVsTWVkaWFSZWxheSB0byBxdWl0IHRoZSBjdXJyZW50IHJlbGF5LlxuICAgKlxuICAgKiBAc2luY2UgMy4wLjBcbiAgICovXG4gIHN0YXJ0Q2hhbm5lbE1lZGlhUmVsYXk6IChcbiAgICBjb25maWc6IENoYW5uZWxNZWRpYVJlbGF5Q29uZmlndXJhdGlvbixcbiAgICBjYWxsYmFjazogKGVycm9yPzogQ2hhbm5lbE1lZGlhRXJyb3IpID0+IHZvaWRcbiAgKSA9PiB2b2lkO1xuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc3RhcnRzIGEgbGl2ZSBzdHJlYW0uXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBDYWxsIFtzdGFydExpdmVTdHJlYW1pbmddKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjc3RhcnRsaXZlc3RyZWFtaW5nKVxuICAgKiBhZnRlciBbY3JlYXRlU3RyZWFtXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9nbG9iYWxzLmh0bWwjY3JlYXRlc3RyZWFtKS5cbiAgICpcbiAgICogQHBhcmFtIHVybCBVUkwgYWRkcmVzcyBmb3IgdGhlIGxpdmUgc3RyZWFtLiBBU0NJSSBjaGFyYWN0ZXJzIG9ubHksIGFuZFxuICAgKiB0aGUgc3RyaW5nIGxlbmd0aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIGFuZCBsZXNzIHRoYW4gMjU2IGJ5dGVzLlxuICAgKiBAcGFyYW0gW2VuYWJsZVRyYW5zY29kaW5nXSBNYXJrcyB3aGV0aGVyIHRvIGVuYWJsZSBsaXZlIHRyYW5zY29kaW5nLlxuICAgKiBJZiBzZXQgYXMgdHJ1ZSwgc2V0TGl2ZVRyYW5zY29kaW5nIG11c3QgYmUgY2FsbGVkIGJlZm9yZSB0aGlzIG1ldGhvZC5cbiAgICpcbiAgICogQHNlZSBbUHVzaCBTdHJlYW1zIHRvIHRoZSBDRE5dKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9wdXNoX3N0cmVhbV93ZWIpLlxuICAgKi9cbiAgc3RhcnRMaXZlU3RyZWFtaW5nOiAodXJsOiBzdHJpbmcsIGVuYWJsZVRyYW5zY29kaW5nPzogYm9vbGVhbikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIEVuYWJsZXMgQ2xvdWQgUHJveHkuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBqb2luaW5nIHRoZSBjaGFubmVsIG9yIGFmdGVyIGxlYXZpbmcgdGhlIGNoYW5uZWwuXG4gICAqXG4gICAqIFRvIHVzZSB0aGUgY2xvdWQgcHJveHkgc2VydmljZSwgc29tZSBleHRyYSBzZXR0aW5ncyBhcmUgbmVlZGVkLCBzZWVcbiAgICogW1VzZSBDbG91ZCBQcm94eV0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL0ludGVyYWN0aXZlJTIwQnJvYWRjYXN0L2Nsb3VkX3Byb3h5X3dlYj9wbGF0Zm9ybT1XZWIpIGZvciBkZXRhaWxzLlxuICAgKi9cbiAgc3RhcnRQcm94eVNlcnZlcjogKCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFN0b3BzIHRoZSBtZWRpYSBzdHJlYW0gcmVsYXkuIE9uY2UgdGhlIHJlbGF5IHN0b3BzLCB0aGUgdXNlciBsZWF2ZXMgYWxsIHRoZSBkZXN0aW5hdGlvbiBjaGFubmVscy5cbiAgICpcbiAgICogQWZ0ZXIgdGhpcyBtZXRob2QgY2FsbCwgdGhlIFNESyB0cmlnZ2VycyB0aGUgYENsaWVudC5vbihcImNoYW5uZWwtbWVkaWEtcmVsYXktc3RhdGVcIilgIGNhbGxiYWNrLlxuICAgKlxuICAgKiAtIElmIHRoZSByZWxheSBzdG9wcywgdGhlIGNhbGxiYWNrIHJldHVybnMgYHN0YXRlYCAwLlxuICAgKiAtIElmIHRoZSByZWxheSBmYWlscyB0byBzdG9wLCB0aGUgY2FsbGJhY2sgcmV0dXJucyBgc3RhdGVgIDMgYW5kIGBjb2RlYCAyIG9yIDguIFRoZSBmYWlsdXJlIGlzIHVzdWFsbHkgZHVlIHRvIHBvb3IgbmV0d29yayBjb25kaXRpb25zLlxuICAgKiAgIFlvdSBjYW4gY2FsbCBbQ2xpZW50LmxlYXZlXShodHRwczovL2RvY3MuYWdvcmEuaW8vZW4vVmlkZW8vQVBJJTIwUmVmZXJlbmNlL3dlYi9pbnRlcmZhY2VzL2Fnb3JhcnRjLmNsaWVudC5odG1sI2xlYXZlKVxuICAgKiAgIHRvIGxlYXZlIHRoZSBjaGFubmVsIGFuZCBzdG9wIHRoZSByZWxheS5cbiAgICpcbiAgICogQHNpbmNlIDMuMC4wXG4gICAqIEBleGFtcGxlXG4gICAqIHN0b3BDaGFubmVsTWVkaWFSZWxheTogKCkgPT4ge1xuICAgKiAgY2xpZW50LnN0b3BDaGFubmVsTWVkaWFSZWxheShlID0+IHtcbiAgICogICAgaWYoZSkge1xuICAgKiAgICAgIHV0aWxzLm5vdGlmaWNhdGlvbihgc3RvcENoYW5uZWxNZWRpYVJlbGF5IGZhaWxlZDogJHtKU09OLnN0cmluZ2lmeShlKX1gKTtcbiAgICogICAgfSBlbHNlIHtcbiAgICogICAgICB1dGlscy5ub3RpZmljYXRpb24oYHN0b3BDaGFubmVsTWVkaWFSZWxheSBzdWNjZXNzYCk7XG4gICAqICAgIH1cbiAgICogIH0pO1xuICAgKiB9XG4gICAqXG4gICAqIEBwYXJhbSBjYWxsYmFjayBUaGUgcmVzdWx0IG9mIHN0b3BwaW5nIHRoZSBtZWRpYSBzdHJlYW0gcmVsYXkuXG4gICAqL1xuICBzdG9wQ2hhbm5lbE1lZGlhUmVsYXk6IChcbiAgICBjYWxsYmFjazogKGVycm9yPzogQ2hhbm5lbE1lZGlhRXJyb3IpID0+IHZvaWRcbiAgKSA9PiB2b2lkO1xuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc3RvcHMgYW5kIGRlbGV0ZXMgdGhlIGxpdmUgc3RyZWFtaW5nLlxuICAgKiBXaGVuIHRoZSBsaXZlIHN0cmVhbSBzdG9wcywgdGhlIFNESyB0cmlnZ2VycyB0aGUgYENsaWVudC5vbihcImxpdmVTdHJlYW1pbmdTdG9wcGVkXCIpYCBjYWxsYmFjay5cbiAgICpcbiAgICogQHBhcmFtIHVybCBVUkwgYWRkcmVzcyBvZiB0aGUgbGl2ZSBzdHJlYW1pbmcuIEFTQ0lJIGNoYXJhY3RlcnMgb25seSwgYW5kXG4gICAqIHRoZSBzdHJpbmcgbGVuZ3RoIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAyNTYgYnl0ZXMuXG4gICAqL1xuICBzdG9wTGl2ZVN0cmVhbWluZzogKHVybDogc3RyaW5nKSA9PiB2b2lkO1xuICAvKipcbiAgICogRGlzYWJsZXMgQ2xvdWQgUHJveHkuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBqb2luaW5nIHRoZSBjaGFubmVsIG9yIGFmdGVyIGxlYXZpbmcgdGhlIGNoYW5uZWwuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGRpc2FibGVzIGFsbCBwcm94eSBzZXR0aW5ncywgaW5jbHVkaW5nIHRob3NlIHNldCBieVxuICAgKiBbc2V0UHJveHlTZXJ2ZXJdKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjc2V0cHJveHlzZXJ2ZXIpIGFuZFxuICAgKiBbc2V0VHVyblNlcnZlcl0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNzZXR0dXJuc2VydmVyKS5cbiAgICovXG4gIHN0b3BQcm94eVNlcnZlcjogKCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGVuYWJsZXMgYSB1c2VyIHRvIHN1YnNjcmliZSB0byBhIHJlbW90ZSBzdHJlYW0uXG4gICAqXG4gICAqIEFmdGVyIHRoZSB1c2VyIHN1YnNjcmliZXMgdG8gYSByZW1vdGUgc3RyZWFtLCB0aGUgU0RLIHRyaWdnZXJzIHRoZSBgQ2xpZW50Lm9uKFwic3RyZWFtLXN1YnNjcmliZWRcIilgIGNhbGxiYWNrLlxuICAgKiBJZiB0aGUgcmVtb3RlIHN0cmVhbSBjb250YWlucyBhbiBhdWRpbyB0cmFjaywgdGhlIFNESyBhbHNvIHRyaWdnZXJzIHRoZSBgQ2xpZW50Lm9uKFwiZmlyc3QtYXVkaW8tZnJhbWUtZGVjb2RlXCIpYCBjYWxsYmFjaztcbiAgICogaWYgdGhlIHJlbW90ZSBzdHJlYW0gY29udGFpbnMgYSB2aWRlbyB0cmFjaywgdGhlIFNESyBhbHNvIHRyaWdnZXJzIHRoZSBgQ2xpZW50Lm9uKFwiZmlyc3QtdmlkZW8tZnJhbWUtZGVjb2RlXCIpYCBjYWxsYmFjay5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2xpZW50LnN1YnNjcmliZShzdHJlYW0sIGVyciA9PiB7XG4gICAqICAgIGNvbnNvbGUuZXJyb3IoXCJzdHJlYW0gc3Vic2NyaWJlIGZhaWxlZFwiLCBlcnIpO1xuICAgKiAgICAvL+KApuKAplxuICAgKiB9KTtcbiAgICpcbiAgICogQWR2YW5jZWRcbiAgICpcbiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBmb3IgYSBzaW5nbGUgcmVtb3RlIHN0cmVhbSxcbiAgICogYW5kIGVuYWJsZXMgeW91IHRvIHN3aXRjaCBiZXR3ZWVuIHJlY2VpdmluZy9ub3QgcmVjZWl2aW5nIHRoZSB2aWRlbyBvciBhdWRpbyBkYXRhIGZsZXhpYmx5LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBJbml0aWFsbHksIHN1YnNjcmliZSB0byB0aGUgc3RyZWFtIGFuZCByZWNlaXZlIG9ubHkgdGhlIHZpZGVvIGRhdGFcbiAgICogY2xpZW50LnN1YnNjcmliZShzdHJlYW0sIHt2aWRlbzogdHJ1ZSwgYXVkaW86IGZhbHNlfSk7XG4gICAqXG4gICAqIC8vIEFmdGVyIGEgd2hpbGUsIHN3aXRjaCB0byByZWNlaXZpbmcgb25seSB0aGUgYXVkaW8gZGF0YVxuICAgKiBjbGllbnQuc3Vic2NyaWJlKHN0cmVhbSwge3ZpZGVvOiBmYWxzZSwgYXVkaW86IHRydWV9KTtcbiAgICpcbiAgICogQHJlbWFya3NcbiAgICogLSB2aWRlbyBhbmQgYGF1ZGlvYCBjYW5ub3QgYmUgc2V0IGFzIGBmYWxzZWAgYXQgdGhlIHNhbWUgdGltZS4gSWYgeW91IG5lZWQgdG8gc3RvcCBzdWJzY3JpYmluZyB0byB0aGUgc3RyZWFtLFxuICAgKiBjYWxsIFtDbGllbnQudW5zdWJzY3JpYmVdKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjdW5zdWJzY3JpYmUpIGluc3RlYWQuXG4gICAqIC0gU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgaW5kZXBlbmRlbnQgc3Vic2NyaXB0aW9uLiBTZXQgYG9wdGlvbnNgIGFzIGBudWxsYCBmb3IgU2FmYXJpLFxuICAgKiBvdGhlcndpc2UgdGhlIGBTQUZBUklfTk9UX1NVUFBPUlRFRF9GT1JfVFJBQ0tfU1VCU0NSSVBUSU9OYCBlcnJvciBvY2N1cnMuXG4gICAqXG4gICAqIEBwYXJhbSBzdHJlYW0gU3RyZWFtIG9iamVjdCwgd2hpY2ggcmVwcmVzZW50cyB0aGUgcmVtb3RlIHN0cmVhbS5cbiAgICogQHBhcmFtIFtvcHRpb25zXSBTZXRzIHdoZXRoZXIgdG8gcmVjZWl2ZSB0aGUgdmlkZW8gb3IgYXVkaW8gZGF0YSBpbmRlcGVuZGVudGx5IGJ5IHRoZSBgdmlkZW9gIGFuZCBgYXVkaW9gIHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSBbb25GYWlsdXJlXSBUaGUgY2FsbGJhY2sgd2hlbiB0aGUgbWV0aG9kIGZhaWxzLiBUaGUgZm9sbG93aW5nIGFyZSBjb21tb24gZXJyb3JzOlxuICAgKiAtIGBcIlNBRkFSSV9OT1RfU1VQUE9SVEVEX0ZPUl9UUkFDS19TVUJTQ1JJUFRJT05cImA6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGluZGVwZW5kZW50IHN1YnNjcmlwdGlvbi5cbiAgICogLSBgXCJJTlZBTElEX09QRVJBVElPTlwiYDogVGhlIHVzZXIgaXMgbm90IGluIHRoZSBjaGFubmVsLCBwb3NzaWJseSBiZWNhdXNlIHRoZSB1c2VyIGhhcyBub3RcbiAgICogICAgam9pbmVkIHRoZSBjaGFubmVsIG9yIHRoZSBjb25uZWN0aW9uIGlzIGludGVycnVwdGVkLlxuICAgKiAtIGBcIlNVQlNDUklCRV9TVFJFQU1fRkFJTEVEXCJgOiBUaGUgc3Vic2NyaXB0aW9uIGZhaWxzLCB1c3VhbGx5IGJlY2F1c2UgdGhlIFNESyBoYXMgZGlzY29ubmVjdGVkXG4gICAqICAgIGZyb20gdGhlIEFnb3JhIHNlcnZlciB3aGVuIHN1YnNjcmliaW5nIHRvIHRoZSBzdHJlYW0uXG4gICAqIC0gYFwiUEVFUkNPTk5FQ1RJT05fRkFJTEVEXCJgOiBGYWlscyB0byBlc3RhYmxpc2ggdGhlIG1lZGlhIHRyYW5zcG9ydCBjaGFubmVsLlxuICAgKi9cbiAgc3Vic2NyaWJlOiAoXG4gICAgc3RyZWFtOiBTdHJlYW0sXG4gICAgb3B0aW9ucz86IFN1YnNjcmliZU9wdGlvbnMsXG4gICAgb25GYWlsdXJlPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZFxuICApID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBVbnB1Ymxpc2hlcyB0aGUgTG9jYWwgU3RyZWFtLlxuICAgKlxuICAgKiBXaGVuIHRoZSBzdHJlYW0gaXMgdW5wdWJsaXNoZWQsIHRoZSBgQ2xpZW50Lm9uKFwic3RyZWFtLXJlbW92ZWRcIilgIGNhbGxiYWNrIGlzIHRyaWdnZXJlZCBvbiB0aGUgcmVtb3RlIGNsaWVudC5cbiAgICpcbiAgICogQHBhcmFtIHN0cmVhbSBTdHJlYW0gb2JqZWN0LCB3aGljaCByZXByZXNlbnRzIHRoZSBsb2NhbCBzdHJlYW0uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNsaWVudC51bnB1Ymxpc2goc3RyZWFtLCBlcnIgPT4ge1xuICAgKiAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgKiAgICAvL+KApuKAplxuICAgKiB9KVxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBJbiBhIGxpdmUgYnJvYWRjYXN0LCB0aGUgdXNlciByb2xlIG9mIGEgaG9zdCBzd2l0Y2hlcyB0byBhdWRpZW5jZSBhZnRlciB1bnB1Ymxpc2hpbmcsIGFuZFxuICAgKiB0aGUgYENsaWVudC5vbihcInBlZXItbGVhdmVcIilgIGNhbGxiYWNrIGlzIHRyaWdnZXJlZCBvbiB0aGUgcmVtb3RlIGNsaWVudC5cbiAgICovXG4gIHVucHVibGlzaDogKHN0cmVhbTogU3RyZWFtLCBvbkZhaWx1cmU/OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkKSA9PiB2b2lkO1xuICAvKipcbiAgICogVW5zdWJzY3JpYmVzIGZyb20gYSBSZW1vdGUgU3RyZWFtLlxuICAgKlxuICAgKiBAcGFyYW0gc3RyZWFtIFN0cmVhbSBvYmplY3QsIHdoaWNoIHJlcHJlc2VudHMgdGhlIHJlbW90ZSBzdHJlYW0uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNsaWVudC51bnN1YnNjcmliZShzdHJlYW0sIGVyciA9PiB7XG4gICAqICAgY29uc29sZS5sb2coZXJyKTtcbiAgICogICAvL+KApuKAplxuICAgKiB9KVxuICAgKlxuICAgKi9cbiAgdW5zdWJzY3JpYmU6IChzdHJlYW06IFN0cmVhbSwgb25GYWlsdXJlPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGNoYW5uZWxzIGZvciBtZWRpYSBzdHJlYW0gcmVsYXkuXG4gICAqXG4gICAqIEFmdGVyIHRoZSBjaGFubmVsIG1lZGlhIHJlbGF5IHN0YXJ0cywgaWYgeW91IHdhbnQgdG8gcmVsYXkgdGhlIG1lZGlhIHN0cmVhbSB0byBtb3JlIGNoYW5uZWxzLFxuICAgKiBvciBsZWF2ZSB0aGUgY3VycmVudCByZWxheSBjaGFubmVsLCB5b3UgY2FuIGNhbGwgdGhpcyBtZXRob2QuXG4gICAqXG4gICAqIEFmdGVyIHRoaXMgbWV0aG9kIGNhbGwsIHRoZSBTREsgdHJpZ2dlcnMgdGhlIGBDbGllbnQub24oXCJjaGFubmVsLW1lZGlhLXJlbGF5LWV2ZW50XCIpYCBjYWxsYmFjay5cbiAgICogLSBJZiB0aGUgdXBkYXRlIHN1Y2NlZWRzLCB0aGUgY2FsbGJhY2sgcmV0dXJucyBgY29kZWAgNy5cbiAgICogLSBJZiB0aGUgdXBkYXRlIGZhaWxzLCB0aGUgY2FsbGJhY2sgcmV0dXJucyBgY29kZWAgOCwgYW5kIHRoZSBTREsgYWxzbyB0cmlnZ2VycyB0aGVcbiAgICogYENsaWVudC5vbihcImNoYW5uZWwtbWVkaWEtcmVsYXktc3RhdGVcIilgIGNhbGxiYWNrIHdpdGggYHN0YXRlYCAzLiBJbiB0aGlzIGNhc2UsIHRoZSBtZWRpYSByZWxheSBzdGF0ZSBpcyByZXNldCwgYW5kIHlvdSBuZWVkIHRvIGNhbGxcbiAgICogW3N0YXJ0Q2hhbm5lbE1lZGlhUmVsYXldKGh0dHBzOi8vZG9jcy5hZ29yYS5pby9lbi9WaWRlby9BUEklMjBSZWZlcmVuY2Uvd2ViL2ludGVyZmFjZXMvYWdvcmFydGMuY2xpZW50Lmh0bWwjc3RhcnRjaGFubmVsbWVkaWFyZWxheSlcbiAgICogYWdhaW4gdG8gcmVzdGFydCB0aGUgcmVsYXkuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIC0gQ2FsbCB0aGlzIG1ldGhvZCBhZnRlclxuICAgKiBbc3RhcnRDaGFubmVsTWVkaWFSZWxheV0oaHR0cHM6Ly9kb2NzLmFnb3JhLmlvL2VuL1ZpZGVvL0FQSSUyMFJlZmVyZW5jZS93ZWIvaW50ZXJmYWNlcy9hZ29yYXJ0Yy5jbGllbnQuaHRtbCNzdGFydGNoYW5uZWxtZWRpYXJlbGF5KS5cbiAgICogLSBZb3UgY2FuIGFkZCBhIG1heGltdW0gb2YgZm91ciBkZXN0aW5hdGlvbiBjaGFubmVscyB0byBhIHJlbGF5LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjbGllbnQudXBkYXRlQ2hhbm5lbE1lZGlhUmVsYXkoY2hhbm5lbE1lZGlhQ29uZmlnLCBlID0+IHtcbiAgICogICBpZiAoZSkge1xuICAgKiAgICAgdXRpbHMubm90aWZpY2F0aW9uKGB1cGRhdGVDaGFubmVsTWVkaWFSZWxheSBmYWlsZWQ6ICR7SlNPTi5zdHJpbmdpZnkoZSl9YCk7XG4gICAqICAgfSBlbHNlIHtcbiAgICogICAgIHV0aWxzLm5vdGlmaWNhdGlvbihgdXBkYXRlQ2hhbm5lbE1lZGlhUmVsYXkgc3VjY2Vzc2ApO1xuICAgKiAgIH1cbiAgICogfSk7XG4gICAqXG4gICAqIEBzaW5jZSAzLjAuMFxuICAgKi9cbiAgdXBkYXRlQ2hhbm5lbE1lZGlhUmVsYXk6IChcbiAgICBjb25maWc6IENoYW5uZWxNZWRpYVJlbGF5Q29uZmlndXJhdGlvbixcbiAgICBjYWxsYmFjazogKGVycm9yPzogQ2hhbm5lbE1lZGlhRXJyb3IpID0+IHZvaWRcbiAgKSA9PiB2b2lkO1xuXG4gIC8qIExlZ2FjeSBwcm9wZXJ0aWVzIGZyb20gYW5ndWxhci1hZ29yYS1ydGMgKi9cbiAgYWVzTW9kZT86IHN0cmluZztcbiAgYWVzcGFzc3dvcmQ/OiBzdHJpbmc7XG4gIGdhdGV3YXlDbGllbnQ/OiB7fTtcbiAgaGlnaFN0cmVhbT86IGFueTtcbiAgaGlnaFN0cmVhbVN0YXRlPzogbnVtYmVyO1xuICBpc0R1YWxTdHJlYW0/OiBib29sZWFuO1xuICBrZXk/OiBhbnk7XG4gIGxvd1N0cmVhbT86IGFueTtcbiAgbG93U3RyZWFtUGFyYW1ldGVyPzogYW55O1xuICBsb3dTdHJlYW1TdGF0ZT86IG51bWJlcjtcbiAgcHJveHlTZXJ2ZXI/OiBhbnk7XG4gIHR1cm5TZXJ2ZXI/OiBhbnk7XG59XG4iXX0=