import * as __WEBPACK_EXTERNAL_MODULE__epicgames_ps_lib_pixelstreamingfrontend_ue5_3_512f3c9b__ from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3";
import * as __WEBPACK_EXTERNAL_MODULE_jss__ from "jss";
import * as __WEBPACK_EXTERNAL_MODULE_jss_plugin_camel_case_de113355__ from "jss-plugin-camel-case";
import * as __WEBPACK_EXTERNAL_MODULE_jss_plugin_global_ef86f421__ from "jss-plugin-global";
/******/ var __webpack_modules__ = ({
/***/ "./src/Application/Application.ts":
/*!****************************************!*\
!*** ./src/Application/Application.ts ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Application": () => (/* binding */ Application)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Overlay/ConnectOverlay */ "./src/Overlay/ConnectOverlay.ts");
/* harmony import */ var _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Overlay/DisconnectOverlay */ "./src/Overlay/DisconnectOverlay.ts");
/* harmony import */ var _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Overlay/PlayOverlay */ "./src/Overlay/PlayOverlay.ts");
/* harmony import */ var _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Overlay/InfoOverlay */ "./src/Overlay/InfoOverlay.ts");
/* harmony import */ var _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Overlay/ErrorOverlay */ "./src/Overlay/ErrorOverlay.ts");
/* harmony import */ var _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Overlay/AFKOverlay */ "./src/Overlay/AFKOverlay.ts");
/* harmony import */ var _UI_Controls__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../UI/Controls */ "./src/UI/Controls.ts");
/* harmony import */ var _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../UI/LabelledButton */ "./src/UI/LabelledButton.ts");
/* harmony import */ var _UI_SettingsPanel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../UI/SettingsPanel */ "./src/UI/SettingsPanel.ts");
/* harmony import */ var _UI_StatsPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../UI/StatsPanel */ "./src/UI/StatsPanel.ts");
/* harmony import */ var _UI_VideoQpIndicator__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../UI/VideoQpIndicator */ "./src/UI/VideoQpIndicator.ts");
/* harmony import */ var _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Config/ConfigUI */ "./src/Config/ConfigUI.ts");
/* harmony import */ var _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../UI/UIConfigurationTypes */ "./src/UI/UIConfigurationTypes.ts");
/* harmony import */ var _UI_FullscreenIcon__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../UI/FullscreenIcon */ "./src/UI/FullscreenIcon.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* An Application is a combination of UI elements to display and manage a WebRTC Pixel Streaming
* connection. It includes features for controlling a stream with mouse and keyboard,
* managing connection endpoints, as well as displaying stats and other information about it.
*/
class Application {
/**
* @param options - Initialization options
*/
constructor(options) {
this._options = options;
this.stream = options.stream;
this.onColorModeChanged = options.onColorModeChanged;
this.configUI = new _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.ConfigUI(this.stream.config);
this.createOverlays();
if ((0,_UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.isPanelEnabled)(options.statsPanelConfig)) {
// Add stats panel
this.statsPanel = new _UI_StatsPanel__WEBPACK_IMPORTED_MODULE_3__.StatsPanel();
this.uiFeaturesElement.appendChild(this.statsPanel.rootElement);
}
if ((0,_UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.isPanelEnabled)(options.settingsPanelConfig)) {
// Add settings panel
this.settingsPanel = new _UI_SettingsPanel__WEBPACK_IMPORTED_MODULE_4__.SettingsPanel();
this.uiFeaturesElement.appendChild(this.settingsPanel.rootElement);
this.configureSettings();
}
if (!options.videoQpIndicatorConfig || !options.videoQpIndicatorConfig.disableIndicator) {
// Add the video stream QP indicator
this.videoQpIndicator = new _UI_VideoQpIndicator__WEBPACK_IMPORTED_MODULE_5__.VideoQpIndicator();
this.uiFeaturesElement.appendChild(this.videoQpIndicator.rootElement);
}
this.createButtons();
this.registerCallbacks();
this.showConnectOrAutoConnectOverlays();
this.setColorMode(this.configUI.isCustomFlagEnabled(_Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.LightMode));
}
createOverlays() {
// build all of the overlays
this.disconnectOverlay = new _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__.DisconnectOverlay(this.stream.videoElementParent);
this.connectOverlay = new _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_7__.ConnectOverlay(this.stream.videoElementParent);
this.playOverlay = new _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_8__.PlayOverlay(this.stream.videoElementParent);
this.infoOverlay = new _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_9__.InfoOverlay(this.stream.videoElementParent);
this.errorOverlay = new _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_10__.ErrorOverlay(this.stream.videoElementParent);
this.afkOverlay = new _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_11__.AFKOverlay(this.stream.videoElementParent);
this.disconnectOverlay.onAction(() => this.stream.reconnect());
// Build the webRtc connect overlay Event Listener and show the connect overlay
this.connectOverlay.onAction(() => this.stream.connect());
// set up the play overlays action
this.playOverlay.onAction(() => this.stream.play());
}
/**
* Set up button click functions and button functionality
*/
createButtons() {
const controlsUIConfig = {
statsButtonType: !!this._options.statsPanelConfig
? this._options.statsPanelConfig.visibilityButtonConfig
: undefined,
settingsButtonType: !!this._options.settingsPanelConfig
? this._options.settingsPanelConfig.visibilityButtonConfig
: undefined,
fullscreenButtonType: this._options.fullScreenControlsConfig,
xrIconType: this._options.xrControlsConfig
};
// Setup controls
const controls = new _UI_Controls__WEBPACK_IMPORTED_MODULE_12__.Controls(controlsUIConfig);
this.uiFeaturesElement.appendChild(controls.rootElement);
// When we fullscreen we want this element to be the root
const fullScreenButton =
// Depending on if we're creating an internal button, or using an external one
(!!this._options.fullScreenControlsConfig
&& this._options.fullScreenControlsConfig.creationMode === _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.UIElementCreationMode.UseCustomElement)
// Either create a fullscreen class based on the external button
? new _UI_FullscreenIcon__WEBPACK_IMPORTED_MODULE_13__.FullScreenIconExternal(this._options.fullScreenControlsConfig.customElement)
// Or use the one created by the Controls initializer earlier
: controls.fullscreenIcon;
if (fullScreenButton) {
fullScreenButton.fullscreenElement = /iPad|iPhone|iPod/.test(navigator.userAgent) ? this.stream.videoElementParent.getElementsByTagName("video")[0] : this.rootElement;
}
// Add settings button to controls
const settingsButton = !!controls.settingsIcon ? controls.settingsIcon.rootElement :
this._options.settingsPanelConfig.visibilityButtonConfig.customElement;
if (!!settingsButton)
settingsButton.onclick = () => this.settingsClicked();
if (!!this.settingsPanel)
this.settingsPanel.settingsCloseButton.onclick = () => this.settingsClicked();
// Add WebXR button to controls
const xrButton = !!controls.xrIcon ? controls.xrIcon.rootElement :
this._options.xrControlsConfig.creationMode === _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.UIElementCreationMode.UseCustomElement ?
this._options.xrControlsConfig.customElement : undefined;
if (!!xrButton)
xrButton.onclick = () => this.stream.toggleXR();
// setup the stats/info button
const statsButton = !!controls.statsIcon ? controls.statsIcon.rootElement :
this._options.statsPanelConfig.visibilityButtonConfig.customElement;
if (!!statsButton)
statsButton.onclick = () => this.statsClicked();
if (!!this.statsPanel) {
this.statsPanel.statsCloseButton.onclick = () => this.statsClicked();
}
// Add command buttons (if we have somewhere to add them to)
if (!!this.settingsPanel) {
// Add button for toggle fps
const showFPSButton = new _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__.LabelledButton('Show FPS', 'Toggle');
showFPSButton.addOnClickListener(() => {
this.stream.requestShowFps();
});
// Add button for restart stream
const restartStreamButton = new _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__.LabelledButton('Restart Stream', 'Restart');
restartStreamButton.addOnClickListener(() => {
this.stream.reconnect();
});
// Add button for request keyframe
const requestKeyframeButton = new _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__.LabelledButton('Request keyframe', 'Request');
requestKeyframeButton.addOnClickListener(() => {
this.stream.requestIframe();
});
const commandsSectionElem = this.configUI.buildSectionWithHeading(this.settingsPanel.settingsContentElement, 'Commands');
commandsSectionElem.appendChild(showFPSButton.rootElement);
commandsSectionElem.appendChild(requestKeyframeButton.rootElement);
commandsSectionElem.appendChild(restartStreamButton.rootElement);
}
}
/**
* Configure the settings with on change listeners and any additional per experience settings.
*/
configureSettings() {
// This builds all the settings sections and flags under this `settingsContent` element.
this.configUI.populateSettingsElement(this.settingsPanel.settingsContentElement);
this.configUI.addCustomFlagOnSettingChangedListener(_Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.LightMode, (isLightMode) => {
this.configUI.setCustomFlagLabel(_Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.LightMode, `Color Scheme: ${isLightMode ? 'Light' : 'Dark'} Mode`);
this.setColorMode(isLightMode);
});
}
registerCallbacks() {
this.stream.addEventListener('afkWarningActivate', ({ data: { countDown, dismissAfk } }) => this.showAfkOverlay(countDown, dismissAfk));
this.stream.addEventListener('afkWarningUpdate', ({ data: { countDown } }) => this.afkOverlay.updateCountdown(countDown));
this.stream.addEventListener('afkWarningDeactivate', () => this.afkOverlay.hide());
this.stream.addEventListener('afkTimedOut', () => this.afkOverlay.hide());
this.stream.addEventListener('videoEncoderAvgQP', ({ data: { avgQP } }) => this.onVideoEncoderAvgQP(avgQP));
this.stream.addEventListener('webRtcSdp', () => this.onWebRtcSdp());
this.stream.addEventListener('webRtcAutoConnect', () => this.onWebRtcAutoConnect());
this.stream.addEventListener('webRtcConnecting', () => this.onWebRtcConnecting());
this.stream.addEventListener('webRtcConnected', () => this.onWebRtcConnected());
this.stream.addEventListener('webRtcFailed', () => this.onWebRtcFailed());
this.stream.addEventListener('webRtcDisconnected', ({ data: { eventString, allowClickToReconnect } }) => this.onDisconnect(eventString, allowClickToReconnect));
this.stream.addEventListener('videoInitialized', () => this.onVideoInitialized());
this.stream.addEventListener('streamLoading', () => this.onStreamLoading());
this.stream.addEventListener('playStreamError', ({ data: { message } }) => this.onPlayStreamError(message));
this.stream.addEventListener('playStream', () => this.onPlayStream());
this.stream.addEventListener('playStreamRejected', ({ data: { reason } }) => this.onPlayStreamRejected(reason));
this.stream.addEventListener('loadFreezeFrame', ({ data: { shouldShowPlayOverlay } }) => this.onLoadFreezeFrame(shouldShowPlayOverlay));
this.stream.addEventListener('statsReceived', ({ data: { aggregatedStats } }) => this.onStatsReceived(aggregatedStats));
this.stream.addEventListener('latencyTestResult', ({ data: { latencyTimings } }) => this.onLatencyTestResults(latencyTimings));
this.stream.addEventListener('dataChannelLatencyTestResult', ({ data: { result } }) => this.onDataChannelLatencyTestResults(result));
this.stream.addEventListener('streamerListMessage', ({ data: { messageStreamerList, autoSelectedStreamerId, wantedStreamerId } }) => this.handleStreamerListMessage(messageStreamerList, autoSelectedStreamerId, wantedStreamerId));
this.stream.addEventListener('settingsChanged', (event) => this.configUI.onSettingsChanged(event));
this.stream.addEventListener('playerCount', ({ data: { count } }) => this.onPlayerCount(count));
}
/**
* Gets the rootElement of the application, video stream and all UI are children of this element.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('div');
this._rootElement.id = 'playerUI';
this._rootElement.classList.add('noselect');
this._rootElement.appendChild(this.stream.videoElementParent);
this._rootElement.appendChild(this.uiFeaturesElement);
}
return this._rootElement;
}
/**
* Gets the element that contains all the UI features, like the stats and settings panels.
*/
get uiFeaturesElement() {
if (!this._uiFeatureElement) {
this._uiFeatureElement = document.createElement('div');
this._uiFeatureElement.id = 'uiFeatures';
}
return this._uiFeatureElement;
}
/**
* Shows the disconnect overlay
* @param updateText - the text that will be displayed in the overlay
*/
showDisconnectOverlay(updateText) {
this.hideCurrentOverlay();
this.updateDisconnectOverlay(updateText);
this.disconnectOverlay.show();
this.currentOverlay = this.disconnectOverlay;
}
/**
* Update the disconnect overlays span text
* @param updateText - the new countdown number
*/
updateDisconnectOverlay(updateText) {
this.disconnectOverlay.update(updateText);
}
/**
* Activates the disconnect overlays action
*/
onDisconnectionAction() {
this.disconnectOverlay.activate();
}
/**
* Hides the current overlay
*/
hideCurrentOverlay() {
if (this.currentOverlay != null) {
this.currentOverlay.hide();
this.currentOverlay = null;
}
}
/**
* Shows the connect overlay
*/
showConnectOverlay() {
this.hideCurrentOverlay();
this.connectOverlay.show();
this.currentOverlay = this.connectOverlay;
}
/**
* Shows the play overlay
*/
showPlayOverlay() {
this.hideCurrentOverlay();
this.playOverlay.show();
this.currentOverlay = this.playOverlay;
}
/**
* Shows the text overlay
* @param text - the text that will be shown in the overlay
*/
showTextOverlay(text) {
this.hideCurrentOverlay();
this.infoOverlay.update(text);
this.infoOverlay.show();
this.currentOverlay = this.infoOverlay;
}
/**
* Shows the error overlay
* @param text - the text that will be shown in the overlay
*/
showErrorOverlay(text) {
this.hideCurrentOverlay();
this.errorOverlay.update(text);
this.errorOverlay.show();
this.currentOverlay = this.errorOverlay;
}
/**
* Shows or hides the settings panel if clicked
*/
settingsClicked() {
var _a;
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.hide();
this.settingsPanel.toggleVisibility();
}
/**
* Shows or hides the stats panel if clicked
*/
statsClicked() {
var _a;
(_a = this.settingsPanel) === null || _a === void 0 ? void 0 : _a.hide();
this.statsPanel.toggleVisibility();
}
/**
* Activates the connect overlays action
*/
onConnectAction() {
this.connectOverlay.activate();
}
/**
* Activates the play overlays action
*/
onPlayAction() {
this.playOverlay.activate();
}
/**
* Shows the afk overlay
* @param countDown - the countdown number for the afk countdown
*/
showAfkOverlay(countDown, dismissAfk) {
this.hideCurrentOverlay();
this.afkOverlay.updateCountdown(countDown);
this.afkOverlay.onAction(() => dismissAfk());
this.afkOverlay.show();
this.currentOverlay = this.afkOverlay;
}
/**
* Show the Connect Overlay or auto connect
*/
showConnectOrAutoConnectOverlays() {
// set up if the auto play will be used or regular click to start
if (!this.stream.config.isFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoConnect)) {
this.showConnectOverlay();
}
}
/**
* Show the webRtcAutoConnect Overlay and connect
*/
onWebRtcAutoConnect() {
this.showTextOverlay('Auto Connecting Now');
}
/**
* Set up functionality to happen when receiving a webRTC answer
*/
onWebRtcSdp() {
this.showTextOverlay('WebRTC Connection Negotiated');
}
/**
* Shows a text overlay to alert the user the stream is currently loading
*/
onStreamLoading() {
// build the spinner span
const spinnerSpan = document.createElement('span');
spinnerSpan.className = 'visually-hidden';
spinnerSpan.innerHTML = 'Loading...';
// build the spinner div
const spinnerDiv = document.createElement('div');
spinnerDiv.id = 'loading-spinner';
spinnerDiv.className = 'spinner-border ms-2';
spinnerDiv.setAttribute('role', 'status');
// append the spinner to the element
spinnerDiv.appendChild(spinnerSpan);
this.showTextOverlay('Loading Stream ' + spinnerDiv.outerHTML);
}
/**
* Event fired when the video is disconnected - displays the error overlay and resets the buttons stream tools upon disconnect
* @param eventString - the event text that will be shown in the overlay
* @param allowClickToReconnect - true if we want to allow the user to click to reconnect. Otherwise it's just a message.
*/
onDisconnect(eventString, allowClickToReconnect) {
var _a;
const overlayMessage = 'Disconnected' + (eventString ? `: ${eventString}` : '');
if (allowClickToReconnect) {
this.showDisconnectOverlay(`${overlayMessage} Click To Restart.`);
}
else {
this.showErrorOverlay(overlayMessage);
}
// disable starting a latency checks
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.onDisconnect();
}
/**
* Handles when Web Rtc is connecting
*/
onWebRtcConnecting() {
this.showTextOverlay('Starting connection to server, please wait');
}
/**
* Handles when Web Rtc has connected
*/
onWebRtcConnected() {
this.showTextOverlay('WebRTC connected, waiting for video');
}
/**
* Handles when Web Rtc fails to connect
*/
onWebRtcFailed() {
this.showErrorOverlay('Unable to setup video');
}
onLoadFreezeFrame(shouldShowPlayOverlay) {
if (shouldShowPlayOverlay === true) {
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), 'showing play overlay');
this.showPlayOverlay();
}
}
onPlayStream() {
this.hideCurrentOverlay();
}
onPlayStreamError(message) {
this.showErrorOverlay(message);
}
onPlayStreamRejected(onRejectedReason) {
this.showPlayOverlay();
}
onVideoInitialized() {
var _a;
if (!this.stream.config.isFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoPlayVideo)) {
this.showPlayOverlay();
}
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.onVideoInitialized(this.stream);
}
/**
* Set up functionality to happen when calculating the average video encoder qp
* @param QP - the quality number of the stream
*/
onVideoEncoderAvgQP(QP) {
// Update internal QP indicator if one is present
if (!!this.videoQpIndicator) {
this.videoQpIndicator.updateQpTooltip(QP);
}
}
onInitialSettings(settings) {
var _a;
if (settings.PixelStreamingSettings) {
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.configure(settings.PixelStreamingSettings);
}
}
onStatsReceived(aggregatedStats) {
var _a;
// Grab all stats we can off the aggregated stats
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.handleStats(aggregatedStats);
}
onLatencyTestResults(latencyTimings) {
var _a;
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.latencyTest.handleTestResult(latencyTimings);
}
onDataChannelLatencyTestResults(result) {
var _a;
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.dataChannelLatencyTest.handleTestResult(result);
}
onPlayerCount(playerCount) {
var _a;
(_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.handlePlayerCount(playerCount);
}
handleStreamerListMessage(messageStreamingList, autoSelectedStreamerId, wantedStreamerId) {
const waitForStreamer = this.stream.config.isFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.WaitForStreamer);
const isReconnecting = this.stream.isReconnecting();
let message = null;
let allowRestart = true;
if (!autoSelectedStreamerId) {
if (waitForStreamer && wantedStreamerId) {
if (isReconnecting) {
message = `Waiting for ${wantedStreamerId} to become available.`;
allowRestart = false;
}
else {
message = `Gave up waiting for ${wantedStreamerId} to become available. Click to try again`;
if (messageStreamingList.ids.length > 0) {
message += ` or select a streamer from the settings menu.`;
}
allowRestart = true;
}
}
else if (messageStreamingList.ids.length == 0) {
if (isReconnecting) {
message = `Waiting for a streamer to become available.`;
allowRestart = false;
}
else {
message = `No streamers available. Click to try again.`;
allowRestart = true;
}
}
else {
message = `Multiple streamers available. Select one from the settings menu.`;
allowRestart = false;
}
if (allowRestart) {
this.showDisconnectOverlay(message);
}
else {
this.showTextOverlay(message);
}
}
}
/**
* Set light/dark color mode
* @param isLightMode - should we use a light or dark color scheme
*/
setColorMode(isLightMode) {
if (this.onColorModeChanged) {
this.onColorModeChanged(isLightMode);
}
}
}
/***/ }),
/***/ "./src/Config/ConfigUI.ts":
/*!********************************!*\
!*** ./src/Config/ConfigUI.ts ***!
\********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "ConfigUI": () => (/* binding */ ConfigUI),
/* harmony export */ "LightMode": () => (/* binding */ LightMode)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _SettingUIFlag__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SettingUIFlag */ "./src/Config/SettingUIFlag.ts");
/* harmony import */ var _SettingUINumber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SettingUINumber */ "./src/Config/SettingUINumber.ts");
/* harmony import */ var _SettingUIText__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./SettingUIText */ "./src/Config/SettingUIText.ts");
/* harmony import */ var _SettingUIOption__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./SettingUIOption */ "./src/Config/SettingUIOption.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
const LightMode = 'LightMode';
class ConfigUI {
// ------------ Settings -----------------
constructor(config) {
this.customFlags = new Map();
/* A map of flags that can be toggled - options that can be set in the application - e.g. Use Mic? */
this.flagsUi = new Map();
/* A map of numerical settings - options that can be in the application - e.g. MinBitrate */
this.numericParametersUi = new Map();
/* A map of text settings - e.g. signalling server url */
this.textParametersUi = new Map();
/* A map of enum based settings - e.g. preferred codec */
this.optionParametersUi = new Map();
this.createCustomUISettings(config.useUrlParams);
this.registerSettingsUIComponents(config);
}
/**
* Create custom UI settings that are not provided by the Pixel Streaming library.
*/
createCustomUISettings(useUrlParams) {
this.customFlags.set(LightMode, new _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.SettingFlag(LightMode, 'Color Scheme: Dark Mode', 'Page styling will be either light or dark', false /*if want to use system pref: (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches)*/, useUrlParams, (isLightMode, setting) => {
setting.label = `Color Scheme: ${isLightMode ? 'Light' : 'Dark'} Mode`;
}));
}
/**
* Creates UI wrapper components for each setting element in config.
* @param config
*/
registerSettingsUIComponents(config) {
for (const setting of config.getFlags()) {
this.flagsUi.set(setting.id, new _SettingUIFlag__WEBPACK_IMPORTED_MODULE_1__.SettingUIFlag(setting));
}
for (const setting of Array.from(this.customFlags.values())) {
this.flagsUi.set(setting.id, new _SettingUIFlag__WEBPACK_IMPORTED_MODULE_1__.SettingUIFlag(setting));
}
for (const setting of config.getTextSettings()) {
this.textParametersUi.set(setting.id, new _SettingUIText__WEBPACK_IMPORTED_MODULE_2__.SettingUIText(setting));
}
for (const setting of config.getNumericSettings()) {
this.numericParametersUi.set(setting.id, new _SettingUINumber__WEBPACK_IMPORTED_MODULE_3__.SettingUINumber(setting));
}
for (const setting of config.getOptionSettings()) {
this.optionParametersUi.set(setting.id, new _SettingUIOption__WEBPACK_IMPORTED_MODULE_4__.SettingUIOption(setting));
}
}
/**
* Make DOM elements for a settings section with a heading.
* @param settingsElem The parent container for our DOM elements.
* @param sectionHeading The heading element to go into the section.
* @returns The constructed DOM element for the section.
*/
buildSectionWithHeading(settingsElem, sectionHeading) {
// make section element
const sectionElem = document.createElement('section');
sectionElem.classList.add('settingsContainer');
// make section heading
const psSettingsHeader = document.createElement('div');
psSettingsHeader.classList.add('settingsHeader');
psSettingsHeader.classList.add('settings-text');
psSettingsHeader.textContent = sectionHeading;
// add section and heading to parent settings element
sectionElem.appendChild(psSettingsHeader);
settingsElem.appendChild(sectionElem);
return sectionElem;
}
/**
* Setup flags with their default values and add them to the `Config.flags` map.
* @param settingsElem - The element that contains all the individual settings sections, flags, and so on.
*/
populateSettingsElement(settingsElem) {
/* Setup all Pixel Streaming specific settings */
const psSettingsSection = this.buildSectionWithHeading(settingsElem, 'Pixel Streaming');
// make settings show up in DOM
this.addSettingText(psSettingsSection, this.textParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.TextParameters.SignallingServerUrl));
this.addSettingOption(psSettingsSection, this.optionParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.OptionParameters.StreamerId));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoConnect));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoPlayVideo));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.BrowserSendOffer));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.UseMic));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.StartVideoMuted));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.IsQualityController));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.ForceMonoAudio));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.ForceTURN));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.SuppressBrowserKeys));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AFKDetection));
this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.WaitForStreamer));
this.addSettingNumeric(psSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.AFKTimeoutSecs));
this.addSettingNumeric(psSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.MaxReconnectAttempts));
this.addSettingNumeric(psSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.StreamerAutoJoinInterval));
/* Setup all view/ui related settings under this section */
const viewSettingsSection = this.buildSectionWithHeading(settingsElem, 'UI');
this.addSettingFlag(viewSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.MatchViewportResolution));
this.addSettingFlag(viewSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.HoveringMouseMode));
this.addSettingFlag(viewSettingsSection, this.flagsUi.get(LightMode));
/* Setup all encoder related settings under this section */
const inputSettingsSection = this.buildSectionWithHeading(settingsElem, 'Input');
this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.KeyboardInput));
this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.MouseInput));
this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.TouchInput));
this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.GamepadInput));
this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.XRControllerInput));
/* Setup all encoder related settings under this section */
const encoderSettingsSection = this.buildSectionWithHeading(settingsElem, 'Encoder');
this.addSettingNumeric(encoderSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.MinQP));
this.addSettingNumeric(encoderSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.MaxQP));
const preferredCodecOption = this.optionParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.OptionParameters.PreferredCodec);
this.addSettingOption(encoderSettingsSection, this.optionParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.OptionParameters.PreferredCodec));
if (preferredCodecOption &&
[...preferredCodecOption.selector.options]
.map((o) => o.value)
.includes('Only available on Chrome')) {
preferredCodecOption.disable();
}
/* Setup all webrtc related settings under this section */
const webrtcSettingsSection = this.buildSectionWithHeading(settingsElem, 'WebRTC');
this.addSettingNumeric(webrtcSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.WebRTCFPS));
this.addSettingNumeric(webrtcSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.WebRTCMinBitrate));
this.addSettingNumeric(webrtcSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.WebRTCMaxBitrate));
}
/**
* Add a SettingText element to a particular settings section in the DOM and registers that text in the text settings map.
* @param settingsSection The settings section HTML element.
* @param settingText The textual settings object.
*/
addSettingText(settingsSection, settingText) {
if (settingText) {
settingsSection.appendChild(settingText.rootElement);
this.textParametersUi.set(settingText.setting.id, settingText);
}
}
/**
* Add a SettingFlag element to a particular settings section in the DOM and registers that flag in the Config.flag map.
* @param settingsSection The settings section HTML element.
* @param settingFlag The settings flag object.
*/
addSettingFlag(settingsSection, settingFlag) {
if (settingFlag) {
settingsSection.appendChild(settingFlag.rootElement);
this.flagsUi.set(settingFlag.setting.id, settingFlag);
}
}
/**
* Add a numeric setting element to a particular settings section in the DOM and registers that flag in the Config.numericParameters map.
* @param settingsSection The settings section HTML element.
* @param settingFlag The settings flag object.
*/
addSettingNumeric(settingsSection, setting) {
if (setting) {
settingsSection.appendChild(setting.rootElement);
this.numericParametersUi.set(setting.setting.id, setting);
}
}
/**
* Add an enum based settings element to a particular settings section in the DOM and registers that flag in the Config.enumParameters map.
* @param settingsSection The settings section HTML element.
* @param settingFlag The settings flag object.
*/
addSettingOption(settingsSection, setting) {
if (setting) {
settingsSection.appendChild(setting.rootElement);
this.optionParametersUi.set(setting.setting.id, setting);
}
}
onSettingsChanged({ data: { id, target, type } }) {
if (type === 'flag') {
const _id = id;
const _target = target;
const setting = this.flagsUi.get(_id);
if (setting) {
if (setting.flag !== _target.flag) {
setting.flag = _target.flag;
}
if (setting.label !== _target.label) {
setting.label = _target.label;
}
}
}
else if (type === 'number') {
const _id = id;
const _target = target;
const setting = this.numericParametersUi.get(_id);
if (setting) {
if (setting.number !== _target.number) {
setting.number = _target.number;
}
if (setting.label !== _target.label) {
setting.label = _target.label;
}
}
}
else if (type === 'text') {
const _id = id;
const _target = target;
const setting = this.textParametersUi.get(_id);
if (setting) {
if (setting.text !== _target.text) {
setting.text = _target.text;
}
if (setting.label !== _target.label) {
setting.label = _target.label;
}
}
}
else if (type === 'option') {
const _id = id;
const _target = target;
const setting = this.optionParametersUi.get(_id);
if (setting) {
const uiOptions = setting.options;
const targetOptions = _target.options;
if (uiOptions.length !== targetOptions.length ||
!uiOptions.every((value) => targetOptions.includes(value))) {
setting.options = _target.options;
}
if (setting.selected !== _target.selected) {
setting.selected = _target.selected;
}
if (setting.label !== _target.label) {
setting.label = _target.label;
}
}
}
}
/**
* Add a callback to fire when the flag is toggled.
* @param id The id of the flag.
* @param onChangeListener The callback to fire when the value changes.
*/
addCustomFlagOnSettingChangedListener(id, onChangeListener) {
if (this.customFlags.has(id)) {
this.customFlags.get(id).onChange = onChangeListener;
}
}
/**
* Set the label for the flag.
* @param id The id of the flag.
* @param label The new label to use for the flag.
*/
setCustomFlagLabel(id, label) {
if (!this.customFlags.has(id)) {
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Warning(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), `Cannot set label for flag called ${id} - it does not exist in the Config.flags map.`);
}
else {
this.customFlags.get(id).label = label;
this.flagsUi.get(id).label = label;
}
}
/**
* Get the value of the configuration flag which has the given id.
* @param id The unique id for the flag.
* @returns True if the flag is enabled.
*/
isCustomFlagEnabled(id) {
return this.customFlags.get(id).flag;
}
}
/***/ }),
/***/ "./src/Config/SettingUIBase.ts":
/*!*************************************!*\
!*** ./src/Config/SettingUIBase.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingUIBase": () => (/* binding */ SettingUIBase)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Base class for a setting that has a text label, an arbitrary setting value it stores, an a HTML element that represents this setting.
*/
class SettingUIBase {
constructor(setting) {
this._setting = setting;
}
/**
* @returns The setting component.
*/
get setting() {
return this._setting;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('div');
}
return this._rootElement;
}
}
/***/ }),
/***/ "./src/Config/SettingUIFlag.ts":
/*!*************************************!*\
!*** ./src/Config/SettingUIFlag.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingUIFlag": () => (/* binding */ SettingUIFlag)
/* harmony export */ });
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
class SettingUIFlag extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__.SettingUIBase {
constructor(setting) {
super(setting);
this.label = setting.label;
this.flag = setting.flag;
}
/**
* @returns The setting component.
*/
get setting() {
return this._setting;
}
get settingsTextElem() {
if (!this._settingsTextElem) {
this._settingsTextElem = document.createElement('div');
this._settingsTextElem.innerText = this.setting._label;
this._settingsTextElem.title = this.setting.description;
}
return this._settingsTextElem;
}
get checkbox() {
if (!this._checkbox) {
this._checkbox = document.createElement('input');
this._checkbox.type = 'checkbox';
}
return this._checkbox;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
// create root div with "setting" css class
this._rootElement = document.createElement('div');
this._rootElement.id = this.setting.id;
this._rootElement.classList.add('setting');
// create div element to contain our setting's text
this._rootElement.appendChild(this.settingsTextElem);
// create label element to wrap out input type
const wrapperLabel = document.createElement('label');
wrapperLabel.classList.add('tgl-switch');
this._rootElement.appendChild(wrapperLabel);
// create input type=checkbox
this.checkbox.title = this.setting.description;
this.checkbox.classList.add('tgl');
this.checkbox.classList.add('tgl-flat');
const slider = document.createElement('div');
slider.classList.add('tgl-slider');
wrapperLabel.appendChild(this.checkbox);
wrapperLabel.appendChild(slider);
// setup on change from checkbox
this.checkbox.addEventListener('change', () => {
if (this.setting.flag !== this.checkbox.checked) {
this.setting.flag = this.checkbox.checked;
this.setting.updateURLParams();
}
});
}
return this._rootElement;
}
/**
* Update the setting's stored value.
* @param inValue The new value for the setting.
*/
set flag(inValue) {
this.checkbox.checked = inValue;
}
/**
* Get value
*/
get flag() {
return this.checkbox.checked;
}
/**
* Set the label text for the setting.
* @param label setting label.
*/
set label(inLabel) {
this.settingsTextElem.innerText = inLabel;
}
/**
* Get label
*/
get label() {
return this.settingsTextElem.innerText;
}
}
/***/ }),
/***/ "./src/Config/SettingUINumber.ts":
/*!***************************************!*\
!*** ./src/Config/SettingUINumber.ts ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingUINumber": () => (/* binding */ SettingUINumber)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* A number spinner with a text label beside it.
*/
class SettingUINumber extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_1__.SettingUIBase {
constructor(setting) {
super(setting);
this.label = this.setting.label;
this.number = this.setting.number;
}
/**
* @returns The setting component.
*/
get setting() {
return this._setting;
}
get settingsTextElem() {
if (!this._settingsTextElem) {
this._settingsTextElem = document.createElement('label');
this._settingsTextElem.innerText = this.setting.label;
this._settingsTextElem.title = this.setting.description;
}
return this._settingsTextElem;
}
/**
* Get the HTMLInputElement for the button.
*/
get spinner() {
if (!this._spinner) {
this._spinner = document.createElement('input');
this._spinner.type = 'number';
this._spinner.min = this.setting.min.toString();
this._spinner.max = this.setting.max.toString();
this._spinner.value = this.setting.number.toString();
this._spinner.title = this.setting.description;
this._spinner.classList.add('form-control');
}
return this._spinner;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
// create root div with "setting" css class
this._rootElement = document.createElement('div');
this._rootElement.classList.add('setting');
this._rootElement.classList.add('form-group');
// create div element to contain our setting's text
this._rootElement.appendChild(this.settingsTextElem);
// create label element to wrap out input type
this._rootElement.appendChild(this.spinner);
// setup onchange
this.spinner.onchange = (event) => {
const inputElem = event.target;
const parsedValue = Number.parseInt(inputElem.value);
if (Number.isNaN(parsedValue)) {
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Warning(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), `Could not parse value change into a valid number - value was ${inputElem.value}, resetting value to ${this.setting.min}`);
if (this.setting.number !== this.setting.min) {
this.setting.number = this.setting.min;
}
}
else {
if (this.setting.number !== parsedValue) {
this.setting.number = parsedValue;
this.setting.updateURLParams();
}
}
};
}
return this._rootElement;
}
/**
* Set the number in the spinner (will be clamped within range).
*/
set number(newNumber) {
this.spinner.value = this.setting.clamp(newNumber).toString();
}
/**
* Get value
*/
get number() {
return +this.spinner.value;
}
/**
* Set the label text for the setting.
* @param label setting label.
*/
set label(inLabel) {
this.settingsTextElem.innerText = inLabel;
}
/**
* Get label
*/
get label() {
return this.settingsTextElem.innerText;
}
}
/***/ }),
/***/ "./src/Config/SettingUIOption.ts":
/*!***************************************!*\
!*** ./src/Config/SettingUIOption.ts ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingUIOption": () => (/* binding */ SettingUIOption)
/* harmony export */ });
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
class SettingUIOption extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__.SettingUIBase {
constructor(setting) {
super(setting);
this.label = this.setting.label;
this.options = this.setting.options;
this.selected = this.setting.selected;
}
/**
* @returns The setting component.
*/
get setting() {
return this._setting;
}
get selector() {
if (!this._selector) {
this._selector = document.createElement('select');
this._selector.classList.add('form-control');
this._selector.classList.add('settings-option');
}
return this._selector;
}
get settingsTextElem() {
if (!this._settingsTextElem) {
this._settingsTextElem = document.createElement('div');
this._settingsTextElem.innerText = this.setting.label;
this._settingsTextElem.title = this.setting.description;
}
return this._settingsTextElem;
}
/**
* Set the label text for the setting.
* @param label setting label.
*/
set label(inLabel) {
this.settingsTextElem.innerText = inLabel;
}
/**
* Get label
*/
get label() {
return this.settingsTextElem.innerText;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
// create root div with "setting" css class
this._rootElement = document.createElement('div');
this._rootElement.id = this.setting.id;
this._rootElement.classList.add('setting');
this._rootElement.classList.add('form-group');
// create div element to contain our setting's text
this._rootElement.appendChild(this.settingsTextElem);
// create label element to wrap out input type
const wrapperLabel = document.createElement('label');
this._rootElement.appendChild(wrapperLabel);
// create select element
this.selector.title = this.setting.description;
wrapperLabel.appendChild(this.selector);
// setup on change from selector
this.selector.onchange = () => {
if (this.setting.selected !== this.selector.value) {
this.setting.selected = this.selector.value;
this.setting.updateURLParams();
}
};
}
return this._rootElement;
}
set options(values) {
for (let i = this.selector.options.length - 1; i >= 0; i--) {
this.selector.remove(i);
}
values.forEach((value) => {
const opt = document.createElement('option');
opt.value = value;
opt.innerHTML = value;
this.selector.appendChild(opt);
});
}
get options() {
return [...this.selector.options].map((o) => o.value);
}
set selected(value) {
// A user may not specify the full possible value so we instead use the closest match.
// eg ?xxx=H264 would select 'H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f'
const filteredList = this.options.filter((option) => option.indexOf(value) !== -1);
if (filteredList.length) {
this.selector.value = filteredList[0];
}
}
get selected() {
return this.selector.value;
}
disable() {
this.selector.disabled = true;
}
enable() {
this.selector.disabled = false;
}
}
/***/ }),
/***/ "./src/Config/SettingUIText.ts":
/*!*************************************!*\
!*** ./src/Config/SettingUIText.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingUIText": () => (/* binding */ SettingUIText)
/* harmony export */ });
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
class SettingUIText extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__.SettingUIBase {
constructor(setting) {
super(setting);
this.label = this.setting.label;
this.text = this.setting.text;
}
/**
* @returns The setting component.
*/
get setting() {
return this._setting;
}
get settingsTextElem() {
if (!this._settingsTextElem) {
this._settingsTextElem = document.createElement('div');
this._settingsTextElem.innerText = this.setting.label;
this._settingsTextElem.title = this.setting.description;
}
return this._settingsTextElem;
}
get textbox() {
if (!this._textbox) {
this._textbox = document.createElement('input');
this._textbox.classList.add('form-control');
this._textbox.type = 'textbox';
}
return this._textbox;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
// create root div with "setting" css class
this._rootElement = document.createElement('div');
this._rootElement.id = this.setting.id;
this._rootElement.classList.add('setting');
// create div element to contain our setting's text
this._rootElement.appendChild(this.settingsTextElem);
// create label element to wrap out input type
const wrapperLabel = document.createElement('label');
this._rootElement.appendChild(wrapperLabel);
// create input type=checkbox
this.textbox.title = this.setting.description;
wrapperLabel.appendChild(this.textbox);
// setup on change from checkbox
this.textbox.addEventListener('input', () => {
if (this.setting.text !== this.textbox.value) {
this.setting.text = this.textbox.value;
this.setting.updateURLParams();
}
});
}
return this._rootElement;
}
/**
* Update the setting's stored value.
* @param inValue The new value for the setting.
*/
set text(inValue) {
this.textbox.value = inValue;
}
/**
* Get value
*/
get text() {
return this.textbox.value;
}
/**
* Set the label text for the setting.
* @param label setting label.
*/
set label(inLabel) {
this.settingsTextElem.innerText = inLabel;
}
/**
* Get label
*/
get label() {
return this.settingsTextElem.innerText;
}
}
/***/ }),
/***/ "./src/Overlay/AFKOverlay.ts":
/*!***********************************!*\
!*** ./src/Overlay/AFKOverlay.ts ***!
\***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "AFKOverlay": () => (/* binding */ AFKOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Show an overlay for when the session is unattended, it begins a countdown timer, which when elapsed will disconnect the stream.
*/
class AFKOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
/**
* @returns The created root element of this overlay.
*/
static createRootElement() {
const afkOverlayHtml = document.createElement('div');
afkOverlayHtml.id = 'afkOverlay';
afkOverlayHtml.className = 'clickableState';
return afkOverlayHtml;
}
/**
* @returns The created content element of this overlay, which contain some text for an afk count down.
*/
static createContentElement() {
const afkOverlayHtmlInner = document.createElement('div');
afkOverlayHtmlInner.id = 'afkOverlayInner';
afkOverlayHtmlInner.innerHTML =
'
No activity detected
Disconnecting in seconds
Click to continue
';
return afkOverlayHtmlInner;
}
/**
* Construct an Afk overlay
* @param parentElement the element this overlay will be inserted into
*/
constructor(rootDiv) {
super(rootDiv, AFKOverlay.createRootElement(), AFKOverlay.createContentElement());
this.rootElement.addEventListener('click', () => {
this.activate();
});
}
/**
* Update the count down spans number for the overlay
* @param countdown the count down number to be inserted into the span for updating
*/
updateCountdown(countdown) {
this.textElement.innerHTML = `No activity detected
Disconnecting in ${countdown} seconds
Click to continue
`;
}
}
/***/ }),
/***/ "./src/Overlay/ActionOverlay.ts":
/*!**************************************!*\
!*** ./src/Overlay/ActionOverlay.ts ***!
\**************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "ActionOverlay": () => (/* binding */ ActionOverlay)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _BaseOverlay__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BaseOverlay */ "./src/Overlay/BaseOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Class for the base action overlay structure
*/
class ActionOverlay extends _BaseOverlay__WEBPACK_IMPORTED_MODULE_1__.OverlayBase {
/**
* Construct an action overlay
* @param rootDiv the root element this overlay will be inserted into
* @param rootElement the root element that is the overlay
* @param contentElement an element that contains text for the action overlay
*/
constructor(rootDiv, rootElement, contentElement) {
super(rootDiv, rootElement, contentElement);
this.onActionCallback = () => {
/* do nothing */ _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Info(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), 'Did you forget to set the onAction callback in your overlay?');
};
}
/**
* Update the text overlays inner text
* @param text the update text to be inserted into the overlay
*/
update(text) {
if (text != null || text != undefined) {
this.textElement.innerHTML = text;
}
}
/**
* Set a method as an event emitter callback
* @param callBack the method that is to be called when the event is emitted
*/
onAction(callBack) {
this.onActionCallback = callBack;
}
/**
* Activate an event that is attached to the event emitter
*/
activate() {
this.onActionCallback();
}
}
/***/ }),
/***/ "./src/Overlay/BaseOverlay.ts":
/*!************************************!*\
!*** ./src/Overlay/BaseOverlay.ts ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "OverlayBase": () => (/* binding */ OverlayBase)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Class for the base overlay structure
*/
class OverlayBase {
/**
* Construct an overlay
* @param rootDiv the root element this overlay will be inserted into
* @param rootElement the root element that is the overlay
*/
constructor(rootDiv, rootElement, textElement) {
this.rootDiv = rootDiv;
this.rootElement = rootElement;
this.textElement = textElement;
this.rootElement.appendChild(this.textElement);
this.hide();
this.rootDiv.appendChild(this.rootElement);
}
/**
* Show the overlay
*/
show() {
this.rootElement.classList.remove('hiddenState');
}
/**
* Hide the overlay
*/
hide() {
this.rootElement.classList.add('hiddenState');
}
}
/***/ }),
/***/ "./src/Overlay/ConnectOverlay.ts":
/*!***************************************!*\
!*** ./src/Overlay/ConnectOverlay.ts ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "ConnectOverlay": () => (/* binding */ ConnectOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Overlay shown during connection, has a button that can be clicked to initiate a connection.
*/
class ConnectOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
/**
* @returns The created root element of this overlay.
*/
static createRootElement() {
const connectElem = document.createElement('div');
connectElem.id = 'connectOverlay';
connectElem.className = 'clickableState';
return connectElem;
}
/**
* @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
*/
static createContentElement() {
const connectContentElem = document.createElement('div');
connectContentElem.id = 'connectButton';
connectContentElem.innerHTML = 'Click to start';
return connectContentElem;
}
/**
* Construct a connect overlay with a connection button.
* @param parentElem the parent element this overlay will be inserted into.
*/
constructor(parentElem) {
super(parentElem, ConnectOverlay.createRootElement(), ConnectOverlay.createContentElement());
// add the new event listener
this.rootElement.addEventListener('click', () => {
this.activate();
});
}
}
/***/ }),
/***/ "./src/Overlay/DisconnectOverlay.ts":
/*!******************************************!*\
!*** ./src/Overlay/DisconnectOverlay.ts ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DisconnectOverlay": () => (/* binding */ DisconnectOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Overlay shown during disconnection, has a reconnection element that can be clicked to reconnect.
*/
class DisconnectOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
/**
* @returns The created root element of this overlay.
*/
static createRootElement() {
const disconnectOverlayHtml = document.createElement('div');
disconnectOverlayHtml.id = 'disconnectOverlay';
disconnectOverlayHtml.className = 'clickableState';
return disconnectOverlayHtml;
}
/**
* @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
*/
static createContentElement() {
// build the inner html container
const disconnectOverlayHtmlContainer = document.createElement('div');
disconnectOverlayHtmlContainer.id = 'disconnectButton';
disconnectOverlayHtmlContainer.innerHTML = 'Click To Restart';
return disconnectOverlayHtmlContainer;
}
/**
* Construct a disconnect overlay with a retry connection icon.
* @param parentElem the parent element this overlay will be inserted into.
*/
constructor(parentElem) {
super(parentElem, DisconnectOverlay.createRootElement(), DisconnectOverlay.createContentElement());
// add the new event listener
this.rootElement.addEventListener('click', () => {
this.activate();
});
}
}
/***/ }),
/***/ "./src/Overlay/ErrorOverlay.ts":
/*!*************************************!*\
!*** ./src/Overlay/ErrorOverlay.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "ErrorOverlay": () => (/* binding */ ErrorOverlay)
/* harmony export */ });
/* harmony import */ var _TextOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./TextOverlay */ "./src/Overlay/TextOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Generic overlay used to show textual error info to the user.
*/
class ErrorOverlay extends _TextOverlay__WEBPACK_IMPORTED_MODULE_0__.TextOverlay {
/**
* @returns The created root element of this overlay.
*/
static createRootElement() {
const errorOverlayHtml = document.createElement('div');
errorOverlayHtml.id = 'errorOverlay';
errorOverlayHtml.className = 'textDisplayState';
return errorOverlayHtml;
}
/**
* @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
*/
static createContentElement() {
const errorOverlayHtmlInner = document.createElement('div');
errorOverlayHtmlInner.id = 'errorOverlayInner';
return errorOverlayHtmlInner;
}
/**
* Construct a connect overlay with a connection button.
* @param parentElem the parent element this overlay will be inserted into.
*/
constructor(parentElem) {
super(parentElem, ErrorOverlay.createRootElement(), ErrorOverlay.createContentElement());
}
}
/***/ }),
/***/ "./src/Overlay/InfoOverlay.ts":
/*!************************************!*\
!*** ./src/Overlay/InfoOverlay.ts ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "InfoOverlay": () => (/* binding */ InfoOverlay)
/* harmony export */ });
/* harmony import */ var _TextOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./TextOverlay */ "./src/Overlay/TextOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Generic overlay used to show textual info to the user.
*/
class InfoOverlay extends _TextOverlay__WEBPACK_IMPORTED_MODULE_0__.TextOverlay {
/**
* @returns The created root element of this overlay.
*/
static createRootElement() {
const infoOverlayHtml = document.createElement('div');
infoOverlayHtml.id = 'infoOverlay';
infoOverlayHtml.className = 'textDisplayState';
return infoOverlayHtml;
}
/**
* @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
*/
static createContentElement() {
const infoOverlayHtmlInner = document.createElement('div');
infoOverlayHtmlInner.id = 'messageOverlayInner';
return infoOverlayHtmlInner;
}
/**
* Construct a connect overlay with a connection button.
* @param parentElem the parent element this overlay will be inserted into.
*/
constructor(parentElem) {
super(parentElem, InfoOverlay.createRootElement(), InfoOverlay.createContentElement());
}
}
/***/ }),
/***/ "./src/Overlay/PlayOverlay.ts":
/*!************************************!*\
!*** ./src/Overlay/PlayOverlay.ts ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "PlayOverlay": () => (/* binding */ PlayOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Overlay shown when stream is ready to play.
*/
class PlayOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
/**
* @returns The created root element of this overlay.
*/
static createRootElement() {
const playElem = document.createElement('div');
playElem.id = 'playOverlay';
playElem.className = 'clickableState';
return playElem;
}
/**
* @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
*/
static createContentElement() {
// todo: change this to an svg
const playOverlayHtmlInner = document.createElement('img');
playOverlayHtmlInner.id = 'playButton';
playOverlayHtmlInner.src =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPEAAAD5CAYAAAD2mNNkAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAASgklEQVR4Xu2dC7BdVX2HqUCCIRASCPjAFIQREBRBBSRYbFOt8lIrFUWRFqXWsT5wbItUqFWs0KqIMPKoYEWpRS06KDjS1BeVFkVQbCw+wCfiAwGhCKWP9PuZtU24uTe59zz22Y/vm/nGkXtz7jlrr9+sdfZea/03Wb169QtxGW62iYi0D8L7NbwYj8EdcdPyIxFpA4T2P/F/8Ua8CI/GhPnXyq+ISJMhrAlxxX9hRuYL8Sh8SPk1EWkqBHXdEFfcg6vw3fhs3Kb8uog0DQI6XYgr8rOvYsJ8OM4v/0xEmkIJ6ob4P8zIfANegCvQMIs0BQK5sRBXJMy/wIzM5+ByXFBeRkQmBUGcbYjX5S5MmM/AA3CL8nIiUjcEcJAQV9yBX8a/wSeiz5hF6obgDRPikGfMCfOX8DTcu7y0iNQBoRs2xBX/g3diwvwm3Kn8CREZJ4RtVCGuqMKcu9kn4xJ09ZfIuCBgow5xyJ3sTLNzAywrwF6J26NhFhk1BGscIV6XhPluvA6Pxx3KnxaRUUCoxh3iioQ5z5n/BY/FJeUtiMgwEKa6QlyRMN+Hn8Hn4ZblrYjIIBCiukMc8p25Ws6ZMD+zvB0RmSsEaBIhnkrew5V4EHrCiMhcKAFqCv+Nl+J+uBC9my2yMQhKk0Jcke/M78Gsy06YH1TerohMhYA0McQVP8Nz8UDcCl2bLTIVgtHkEFd8D8/E/XFrdGQWqSAQbQhxyKOpm/B03Ac9MkgkEIa2hLgiN78S5lPx0bgIvQEm/YUAtC3EFQnzzfgnuDc6zZZ+Qsdva4jX5Sv4atwXHZmlX9DhuxDikC2Qn8dXYUbmReUjinQbOntXQlyRTRafwldgwrxV+agi3YRO3rUQV/wcV+LL8DHoyZzSTejcXQ1xRc7/uhyzl3kv3Lx8dJFuQKfueohDnjFnZP4o/j7m0ZQH4Es3oDP3IcQV2f6YMF+COZjgUeiZ2dJu6MR9CvG63ILvx4zMCfO80iQi7YLO29cQV3wb34spsr4rumBE2gWdtu8hDln99S1MXeYX4M6leUSaDx3WEK8lRdYT5lR/zPlfnswpzYeOaojXJ4cSfB3Pw+fgtug0W5oJndMQT0/uZGeaXZVyfTZuV5pNpDnQMQ3xxsk0O9Ufz8ZDcdvSfCKThw5piGdP2ioF496JT0c3WcjkKR1T5kYWjCTM78DfQheMyOSgAxriwch35lR/vAbPwOXozS+pHzqeIR6Oal12wvx2fBy6yULqgw5niEdDwpyR+VpMkfXsmHIpp4wfOpohHj234RfwFNwDnWbL+KCDGeLxkJH5p3g1vg53K00uMlroXIZ4vGTBSMJ8FeZkzmWl6UVGA53KENfD/ZiyNCmynvO/FpdLIDIcdCZDXC8ZmfOd+d/wJejZXzIcdCJDXD95xpwjdnP+V74zH4Wu/pLBoPMY4smSMN+FKbJ+BBpmmRt0GkPcDBLmu/FjeAi6lFNmB53FEDeHTLPzaCoj80dwBfqMWTYMncQQN5esAPsw7lcul8j60EEMcfPJDbD3YU7l3KxcOpE10CkMcTvIVDvfmc/E3XELtPqjGOKWkhVgp+GemDD7vbnP0AEMcXtJkfU34GNxAToy9xEuvCFuP6vwJMyOqYXl0kpf4KIb4m5QncyZTRapZGGY+wIX2xB3i3vxOswmi13QaXbX4QIb4m6SY3a/iMdh7mYb5q7ChTXE3aXaaLESq7rMW5ZLL12Bi2qI+8E9eDkmzLuhYe4KXExD3B8yMt+Ol+KL0CLrXYCLaIj7R8J8K16CR6PLOdsMF88Q95fsmPoRXozPxdzNdvVX2+CiGWLJza+EOXWZj8Sd0APw2wIXyxBLqPYy34LnY8K8DA1z0+EiGWKZSgJ9I74LU2R9R3Sa3VS4OIZYZqJaynkWpsj6w0u3kSbBhTHEsjHuwxswpVwPw6Wl+0gT4IIYYpkNmWKnr1yPqf54KG5VupFMknJhRGZLwpzVX6n++DZ8GrpjapJwAQyxDELCnB1TqWTx1/gUdGSeBDS8IZZBSZBjzv76PP4VHoSGuU5ocEMsoyBhTsG4VH98Ix6A80s3k3FCQxtiGSVZMPIT/CwmzPuhz5jHCQ1siGUcZClnwvxpPAX3LF1ORg2Na4hlXGSKnQUjCfNn8PX4CNy0dD8ZBTSoIZZxkzBXI/Pn8ATMumzDPApoSEMsdZEw5zvzDzHT7JdjwuzZX8NAAxpimQSZZifMn8Tj8aGlS8pcofEMsUyKjMw5lTOnjHwcc2TQktI1ZbbQaIZYJk3CnE0WGZmvwOeh+5hnC41liKUpVCNzwvwJPBy9+bUxaCRDLE0jYb4fU/0x0+yD8cGly8pUaBxDLE0kQa7CfCfmML8D0SN2p0KjGGJpOglztWgkh/k9CT1it4LGMMTSFhLmLBrJ3exzcJ/SjfsNDWGIpY0k0D/AM/GRpTv3ExrAEEubqVaAnY5LsX93s/nQhli6QLUF8nWYI3bnYT+Wc/JBDbF0heqO9jfwlfhInI/dDjMf0BBLF0mYr8NsskiNqS2wm2Hmgxli6TJ5zpwjg/4Qd8buLRrhQxli6QM5ZjdHBh2H+c7cnUUjfBhDLH0hU+y7cCU+H7OXeV6JQnvhQxhi6RsJc0bmy/BZ+MsbYCUS7YM3b4ilryTM2QL5QUzBuHxnbt80mzdtiEVWr74NL8KUck2R9faMzLxZQyyyhozMWcp5If4uJszNP5yAN2mIRR5IVn/djOfhEdjsw/x4c4ZYZHryjPkmPBsPwYeV2DQL3pghFpmZTLFzZFDCnLrMz8DtsTkbLXgzhlhk4yTM2cu8CrNjKiNzwjz5OlO8CUMsMjcS5qzLfgumyPr2JU6TgTdgiEUGoyqynrrMv42TOTObP2yIRQYn0+ws5bwaU8r1N3HrEq964A8aYpHhSZjvwBSMS5gPwnrWZfOHDLHI6Mgz5hyxm4Jxf4kH4HjDzB8wxCKjJ2HONPuf8c9xHxzPXmZe2BCLjIdMsWMqWfwTnoiPwdGOzLygIRYZPwlzVWPqtbgXjmbBCC9kiEXqI8+Ys8nicnwN7laiODi8iCEWqZeMylmXnTCnYFxO5tyxRHLu8I8NschkSJizLvv7mJH5pbgY57Zjin9giEUmSzUyfw9TZP1Y3LZEdOPwy4ZYpBkkzKn++B38KB6F25Wozgy/ZIhFmkXCnLO/vosfwpwysqhEdn34oSEWaSYJ8y8w0+wP4GG4/oIR/qMhFmk2VZgzzU6Ys2Nq7T5m/o8hFmkHCXO2PybMF+O++CBDLNIuEuSsy8535lvxZEMs0j6qWszZJbXUEIu0i1vwrZhqFZv5nVikPWTqfA5mF9QDD+fjPxhikeaR777xdrwAn1Aiuz780BCLNIvsdMqBAqkNtRw3XBeKXzDEIpMno27Cezdeik/GBSWmG4ZfNMQikyPhzXrpVGXM6R8rcG7lVfkHhlikfhLe7FzKo6KV+Hu45m7zXOEfGmKReske4oT3k3gMblniOBi8gCEWqYeMvD/GK/F43KHEcDh4IUMsMl5yw+pHmLOoX4aDH8UzHbygIRYZD/nem5H3KjwBd8LRV1HkRQ2xyGjJ3eacNZ1iayfhr+P46hnz4oZYZDRk2pzwph7TX+CuOP76xfwRQywyHNlVVIX3VHx8iVc98AcNscjgZJFGypq+GffHwZ71DgN/1BCLzJ2f47/iWzBlTId71jsM/HFDLDI7crf5HrwG34YHY70FxaeDN2GIRTZMwpvjcK7Fd+BTcfLhreDNGGKRmcnIez2+Ew/FhTi3MivjhjdkiEXWJ0fEfhXPwmfi4hKZ5sGbM8Qia8n65lX4LkzlhYeVqDQX3qQhFlnzrPc/8FzMtsBl2Kxp80zwRg2x9J0cxn4epoBZlkjW/6x3GHjDhlj6SJZI5gTJ9+DzMeHdvMSiXfDGDbH0iWpbYMqgJLy7YLtG3qnwAQyx9IVsC7wEX4C74/h2FtUJH8QQS9fJUTg5QfI43APnle7fDfhAhli6So5//Ri+GBPeya1vHid8MEMsXSMH0X0CX4J74cLS3bsJH9AQS1fITavs6f1VeLEdz3qHgQ9piKXtZHNC1jfnELpfTpux++Gt4MMaYmkrmTZ/GV+LCW+3p80zwQc3xNI2skTyBswhdHtic7YFTgIawBBLm7gRT8HH4dbYn2nzTNAIhljaQCrkvwkT3tywGv8pkm2BxjDE0lRyokbOsjoDUyE/N6wM71RoFEMsTSPhvRPfjY/GBei0eSZoHEMsTeJ2/ADug+3cVVQ3NJQhliaQkfcf8SnoqDsXaDBDLJMij4ruxcvwaejIOwg0nCGWusnyyIT3CjwM+7lIY1TQgIZY6iA3qzLyZmdRSn0eic09QbJN0JCGWMZJwpuR9w78Er4Qu7klcFLQoIZYxkXq9OZuc2oWZXNCv5dHjgsa1hDLqKnCm2qB2Zzw0NLdZBzQwIZYRkWmzT/DhPdE3KV0MxknNLQhlmHJ996ENwXHsjkhq6xcHlkXNLYhlkFJeHPDKhvyszkh4W338a9thEY3xDJX8qgoGxMS3tTpfSzOL11K6obGN8QyWxLeLI/MtDmlPvdHp82ThotgiGU2ZOStwrsCXSLZFLgYhlg2xF2Yc6zOxqejCzWaBhfFEMt0pMj2VzB1eg/BJaXLSNPg4hhiqcjd5izUSIX8lPp8Fi4tXUWaChfJEEtIhfwU2b4QU2R7O3RfbxvgQhnifpOD17+JCW9KfS5F7zi3CS6YIe4nOXj9W/h3eAw+vHQJaRtcPEPcL/Ks92a8CI/FXdFpc5vhAhri/vB9/Hv8A3wUukSyC3AhDXH3+Sn+Ax6PqZDvEskuwQU1xN2kOgonJ0im1Gc2J2xRLrt0CS6sIe4W1c6ij2NG3lROmFcut3QRLrAh7g4J75X4R7g3Gt4+wIU2xO0n0+ZP4aswBcdc39wnuOCGuL3kWe/n8DW4Ly4ql1X6BBfeELeTL+AJ+ATcBn3W21e4+Ia4PeSO89fwT/GJuAhdItl36ASGuPlkZ9G38fWYo3Ay8hpeWQOdwRA3lxwBexO+GVPq07Insj50DEPcTLK++e2Yc6wWo995ZXroHIa4WdyKOQpnOWbavGm5VCLTQycxxM0gp0iej0/G3LAyvDI76CyGeHJUx+G8Hw9Ewytzh05jiCdDDqK7HA/Aheh3XhkMOo8hrpe096fxd9D9vDI8pVPJ+LkXP4vPQafMMjroUIZ4fOQ7b9Y3X4U5x8oi2zJ66FiGePRkeWROkfwiHoee3Szjgw5miEdDRt14D+bw9ZfjDqWZRcYHHc0QD091FE6OgP0z9OB1qQ86myEenKxtTngz8r4BHXmlfuh4hnjuJLwp9Zlqgafh7qU5ReqHDmiIZ0+mzVkeeQO+FR9fmlFkctARDfHsSJ3ef8dqZ5GH0EkzoDMa4pnJ3ea0T07TOAezvnlBaTqRZlA6qTyQhDdrm1fhBXgwGl5pJnROQ7yW6jlvwvtefAZuXppKpJmUTitrp80p9Zn1zQ8uTSTSbOisfQ9xps2pkJ/wPhe3K00j0g7otH0N8f34dXwfHo0W2ZZ2QuftY4izPDKnabwIH4Ee/yrthQ7clxBnldUP8BJ8MSa87uuV9kNH7nqIc4ZVwvshfCkuQ8Mr3YEO3dUQZ4nkD/HDmFKfe5SPLNIt6NxdDHHC+xF8BabsiSOvdBc6eJdCfBtehglvimz7rFe6Dx29CyHOQo0r8NWYOr0W2Zb+QIdva4izRDLPeldi6vSm1OfC8rFE+gMdv40hznu+GlMhfz/cEj0OR/oJnb9NIc57vQZPxCehI69ICUbTydnN1+LJmPAuKW9fRAhEk0OcZ73XYw6hOwg9v1lkKgSjqSHO5oRT8TdwKbq+WWQ6CEeTQpw7zlmocTqmTm/Ob7bomMiGICRNCHGmzT/BszClPjPyuspKZDYQlkmH+Mf4t7gct0enzSJzgdBMKsQJ70X4VHTkFRkUwlN3iFM54YN4KG6LHkQnMgyEqK4Q51nvpZjwZuQ1vCKjgDDVEeIr8XBMeL3bLDJKCNW4QpyR9zo8ArdBb1iJjAPCNeoQJ7ypFngszkc3JoiME0I2qhDnWW8Kjv0xujFBpC4I3DAhzgqrHESXUp/Z0/uQ8rIiUhcEb5AQJ7z34TfwJNy5vJyI1A0BnG2IE9yYsiffwTfizuh3XpFJQghnE+J83014v4upkL8r+qhIpAkQxg2FOOHNzzNtPhf3REdekSZRQjqVTJtzguSNeD4eWH5dRJoGAZ0a4rvxm3ghrkCnzSJNhpBWIc7/plpgwpudRZ7dLNIGCOvtJbwX42G4uPxIRNoAoU2d3iNxUflPItIaNtnk/wEGBoMdpECGHAAAAABJRU5ErkJggg==';
playOverlayHtmlInner.alt = 'Start Streaming';
return playOverlayHtmlInner;
}
/**
* Construct a connect overlay with a connection button.
* @param parentElem the parent element this overlay will be inserted into.
*/
constructor(parentElem) {
super(parentElem, PlayOverlay.createRootElement(), PlayOverlay.createContentElement());
// add the new event listener
this.rootElement.addEventListener('click', () => {
this.activate();
});
}
}
/***/ }),
/***/ "./src/Overlay/TextOverlay.ts":
/*!************************************!*\
!*** ./src/Overlay/TextOverlay.ts ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "TextOverlay": () => (/* binding */ TextOverlay)
/* harmony export */ });
/* harmony import */ var _BaseOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseOverlay */ "./src/Overlay/BaseOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Class for the text overlay base
*/
class TextOverlay extends _BaseOverlay__WEBPACK_IMPORTED_MODULE_0__.OverlayBase {
/**
* Construct a text overlay
* @param rootDiv the root element this overlay will be inserted into
* @param rootElement the root element that is the overlay
* @param textElement an element that contains text for the action overlay
*/
constructor(rootDiv, rootElement, textElement) {
super(rootDiv, rootElement, textElement);
}
/**
* Update the text overlays inner text
* @param text the update text to be inserted into the overlay
*/
update(text) {
if (text != null || text != undefined) {
this.textElement.innerHTML = text;
}
}
}
/***/ }),
/***/ "./src/Styles/PixelStreamingApplicationStyles.ts":
/*!*******************************************************!*\
!*** ./src/Styles/PixelStreamingApplicationStyles.ts ***!
\*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "PixelStreamingApplicationStyle": () => (/* binding */ PixelStreamingApplicationStyle)
/* harmony export */ });
/* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jss */ "jss");
/* harmony import */ var jss_plugin_global__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss-plugin-global */ "jss-plugin-global");
/* harmony import */ var jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! jss-plugin-camel-case */ "jss-plugin-camel-case");
/* Copyright Epic Games, Inc. All Rights Reserved. */
class PixelStreamingApplicationStyle {
constructor(options) {
this.defaultLightModePalette = {
'--color0': '#e2e0dd80',
'--color1': '#FFFFFF',
'--color2': '#000000',
'--color3': '#0585fe',
'--color4': '#35b350',
'--color5': '#ffab00',
'--color6': '#e1e2dd',
'--color7': '#c3c4bf'
};
this.defaultDarkModePalette = {
'--color0': '#1D1F2280',
'--color1': '#000000',
'--color2': '#FFFFFF',
'--color3': '#0585fe',
'--color4': '#35b350',
'--color5': '#ffab00',
'--color6': '#1e1d22',
'--color7': '#3c3b40'
};
this.defaultStyles = {
':root': {
'--color0': '#1D1F2280',
'--color1': '#000000',
'--color2': '#FFFFFF',
'--color3': '#0585fe',
'--color4': '#35b350',
'--color5': '#ffab00',
'--color6': '#1e1d22',
'--color7': '#3c3b40',
'--color8': '#41008c',
'--color9': '#3e0070',
'--color10': '#2e0052',
'--color11': 'rgba(65,0,139,1)'
},
'.noselect': {
userSelect: 'none'
},
'#playerUI': {
width: '100%',
height: '100%',
position: 'relative'
},
'#videoElementParent': {
width: '100%',
height: '100%',
position: 'absolute',
backgroundColor: 'var(--color1)'
},
'#uiFeatures': {
width: '100%',
height: '100%',
zIndex: '30',
position: 'relative',
color: 'var(--color2)',
pointerEvents: 'none',
overflow: 'hidden'
},
'.UiTool .tooltiptext': {
visibility: 'hidden',
width: 'auto',
color: 'var(--color2)',
textAlign: 'center',
borderRadius: '15px',
padding: '0px 10px',
fontFamily: "'Montserrat', sans-serif",
fontSize: '0.75rem',
letterSpacing: '0.75px',
position: 'absolute',
top: '0',
transform: 'translateY(25%)',
left: '125%',
zIndex: '20'
},
'.UiTool:hover .tooltiptext': {
visibility: 'visible',
backgroundColor: 'var(--color7)'
},
'#connection .tooltiptext': {
top: '125%',
transform: 'translateX(-25%)',
left: '0',
zIndex: '20',
padding: '5px 10px'
},
'#connection': {
position: 'absolute',
bottom: '8%',
left: '5%',
fontFamily: "'Michroma', sans-serif",
height: '3rem',
width: '3rem',
pointerEvents: 'all'
},
'#settings-panel .tooltiptext': {
display: 'block',
top: '125%',
transform: 'translateX(-50%)',
left: '0',
zIndex: '20',
padding: '5px 10px',
border: '3px solid var(--color3)',
width: 'max-content',
fallbacks: [
{
width: 'max-content'
},
{
border: '3px solid var(--color3)'
},
{
padding: '5px 10px'
},
{
zIndex: '20'
},
{
left: '0'
},
{
transform: 'translateX(-50%)'
},
{
top: '125%'
},
{
display: 'block'
}
]
},
'#controls': {
position: 'absolute',
top: '3%',
left: '2%',
fontFamily: "'Michroma', sans-serif",
pointerEvents: 'all',
display: 'block'
},
'#controls>*': {
marginBottom: '0.5rem',
borderRadius: '50%',
display: 'block',
height: '2rem',
lineHeight: '1.75rem',
padding: '0.5rem'
},
'#controls #additionalinfo': {
textAlign: 'center',
fontFamily: "'Montserrat', sans-serif"
},
'#fullscreen-btn': {
padding: '0.6rem !important'
},
'#minimizeIcon': {
display: 'none'
},
'#settingsBtn, #statsBtn': {
cursor: 'pointer'
},
'#uiFeatures button': {
backgroundColor: 'var(--color7)',
border: '1px solid var(--color7)',
color: 'var(--color2)',
position: 'relative',
width: '3rem',
height: '3rem',
padding: '0.5rem',
textAlign: 'center'
},
'#uiFeatures button:hover': {
backgroundColor: 'var(--color3)',
border: '3px solid var(--color3)',
transition: '0.25s ease',
paddingLeft: '0.55rem',
paddingTop: '0.55rem'
},
'#uiFeatures button:active': {
border: '3px solid var(--color3)',
backgroundColor: 'var(--color7)',
paddingLeft: '0.55rem',
paddingTop: '0.55rem'
},
'.btn-flat': {
backgroundColor: 'transparent',
color: 'var(--color2)',
fontFamily: "'Montserrat'",
fontWeight: 'bold',
border: '3px solid var(--color3)',
borderRadius: '1rem',
fontSize: '0.75rem',
paddingLeft: '0.5rem',
paddingRight: '0.5rem',
cursor: 'pointer',
textAlign: 'center'
},
'.btn-flat:hover': {
backgroundColor: 'var(--color3)',
transition: 'ease 0.3s'
},
'.btn-flat:disabled': {
background: 'var(--color7)',
borderColor: 'var(--color3)',
color: 'var(--color3)',
cursor: 'default'
},
'.btn-flat:active': {
backgroundColor: 'transparent'
},
'.btn-flat:focus': {
outline: 'none'
},
'#uiFeatures img': {
width: '100%',
height: '100%'
},
'.panel-wrap': {
position: 'absolute',
top: '0',
bottom: '0',
right: '0',
height: '100%',
minWidth: '20vw',
maxWidth: '90vw',
transform: 'translateX(100%)',
transition: '.3s ease-out',
pointerEvents: 'all',
backdropFilter: 'blur(10px)',
'-webkit-backdrop-filter': 'blur(10px)',
overflowY: 'auto',
overflowX: 'hidden',
backgroundColor: 'var(--color0)'
},
'.panel-wrap-visible': {
transform: 'translateX(0%)'
},
'.panel': {
overflowY: 'auto',
padding: '1em'
},
'#settingsHeading, #statsHeading': {
display: 'inline-block',
fontSize: '2em',
marginBlockStart: '0.67em',
marginBlockEnd: '0.67em',
marginInlineStart: '0px',
marginInlineEnd: '0px',
position: 'relative',
padding: '0 0 0 2rem'
},
'#settingsClose, #statsClose': {
margin: '0.5rem',
paddingTop: '0.5rem',
paddingBottom: '0.5rem',
paddingRight: '0.5rem',
fontSize: '2em',
float: 'right'
},
'#settingsClose:after, #statsClose:after': {
paddingLeft: '0.5rem',
display: 'inline-block',
content: '"\\00d7"'
},
'#settingsClose:hover, #statsClose:hover': {
color: 'var(--color3)',
transition: 'ease 0.3s'
},
'#settingsContent, #statsContent': {
marginLeft: '2rem',
marginRight: '2rem'
},
'.setting': {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
padding: '0.15rem 10px 0.15rem 10px'
},
'.settings-text': {
color: 'var(--color2)',
verticalAlign: 'middle',
fontWeight: 'normal'
},
'.settings-option': {
width: '100%',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
},
'#connectOverlay, #playOverlay, #infoOverlay, #errorOverlay, #afkOverlay, #disconnectOverlay': {
zIndex: '30',
position: 'absolute',
color: 'var(--color2)',
fontSize: '1.8em',
width: '100%',
height: '100%',
backgroundColor: 'var(--color1)',
alignItems: 'center',
justifyContent: 'center',
textTransform: 'uppercase'
},
'.clickableState': {
alignItems: 'center',
justifyContent: 'center',
display: 'flex',
cursor: 'pointer'
},
'.textDisplayState': {
display: 'flex'
},
'.hiddenState': {
display: 'none'
},
'#playButton, #connectButton': {
display: 'inline-block',
height: 'auto',
zIndex: '30'
},
'img#playButton': {
maxWidth: '241px',
width: '10%'
},
'#uiInteraction': {
position: 'fixed'
},
'#UIInteractionButtonBoundary': {
padding: '2px'
},
'#UIInteractionButton': {
cursor: 'pointer'
},
'#hiddenInput': {
position: 'absolute',
left: '-10%',
width: '0px',
opacity: '0'
},
'#editTextButton': {
position: 'absolute',
height: '40px',
width: '40px'
},
'.btn-overlay': {
verticalAlign: 'middle',
display: 'inline-block'
},
'.tgl-switch': {
verticalAlign: 'middle',
display: 'inline-block'
},
'.tgl-switch .tgl': {
display: 'none'
},
'.tgl, .tgl:after, .tgl:before, .tgl *, .tgl *:after, .tgl *:before, .tgl+.tgl-slider': {
'-webkit-box-sizing': 'border-box',
boxSizing: 'border-box'
},
'.tgl::-moz-selection, .tgl:after::-moz-selection, .tgl:before::-moz-selection, .tgl *::-moz-selection, .tgl *:after::-moz-selection, .tgl *:before::-moz-selection, .tgl+.tgl-slider::-moz-selection': {
background: 'none'
},
'.tgl::selection, .tgl:after::selection, .tgl:before::selection, .tgl *::selection, .tgl *:after::selection, .tgl *:before::selection, .tgl+.tgl-slider::selection': {
background: 'none'
},
'.tgl-slider': {},
'.tgl+.tgl-slider': {
outline: '0',
display: 'block',
width: '40px',
height: '18px',
position: 'relative',
cursor: 'pointer',
userSelect: 'none'
},
'.tgl+.tgl-slider:after, .tgl+.tgl-slider:before': {
position: 'relative',
display: 'block',
content: '""',
width: '50%',
height: '100%'
},
'.tgl+.tgl-slider:after': {
left: '0'
},
'.tgl+.tgl-slider:before': {
display: 'none'
},
'.tgl-flat+.tgl-slider': {
padding: '2px',
'-webkit-transition': 'all .2s ease',
transition: 'all .2s ease',
background: 'var(--color6)',
border: '3px solid var(--color7)',
borderRadius: '2em'
},
'.tgl-flat+.tgl-slider:after': {
'-webkit-transition': 'all .2s ease',
transition: 'all .2s ease',
background: 'var(--color7)',
content: '""',
borderRadius: '1em'
},
'.tgl-flat:checked+.tgl-slider': {
border: '3px solid var(--color3)'
},
'.tgl-flat:checked+.tgl-slider:after': {
left: '50%',
background: 'var(--color3)'
},
'.btn-apply': {
display: 'block !important',
marginLeft: 'auto',
marginRight: 'auto',
width: '40%'
},
'.form-control': {
backgroundColor: 'var(--color7)',
border: '2px solid var(--color7)',
borderRadius: '4px',
color: 'var(--color2)',
textAlign: 'right',
fontFamily: 'inherit'
},
'.form-control:hover': {
borderColor: 'var(--color7)'
},
'.form-group': {
paddingTop: '4px',
display: 'grid',
gridTemplateColumns: '80% 20%',
rowGap: '4px',
paddingRight: '10px',
paddingLeft: '10px'
},
'.form-group label': {
verticalAlign: 'middle',
fontWeight: 'normal'
},
'.settingsContainer': {
display: 'flex',
flexDirection: 'column',
borderBottom: '1px solid var(--color7)',
paddingTop: '10px',
paddingBottom: '10px'
},
'.settingsContainer> :first-child': {
marginTop: '4px',
marginBottom: '4px',
fontWeight: 'bold',
justifyContent: 'space-between',
display: 'flex',
flexDirection: 'row',
alignItems: 'baseline'
},
'.collapse': {
paddingLeft: '5%'
},
'#streamTools': {
borderBottomRightRadius: '5px',
borderBottomLeftRadius: '5px',
userSelect: 'none',
position: 'absolute',
top: '0',
right: '2%',
zIndex: '100',
border: '4px solid var(--colour8)',
borderTopWidth: '0px'
},
'.settingsHeader': {
fontStyle: 'italic'
},
'#streamToolsHeader': {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
borderBottom: '1px solid var(--colour8)',
backgroundColor: 'var(--color7)'
},
'.streamTools': {
backgroundColor: 'var(--color2)',
fontFamily: 'var(--buttonFont)',
fontWeight: 'lighter',
color: 'var(--color7)'
},
'.streamTools-shown>#streamToolsSettings, .streamTools-shown>#streamToolsStats': {
display: 'block'
},
'#streamToolsToggle': {
width: '100%'
},
'#qualityStatus': {
fontSize: '37px',
paddingRight: '4px'
},
'.svgIcon': {
fill: 'var(--color2)'
}
};
const { customStyles, lightModePalette, darkModePalette, jssInsertionPoint } = options !== null && options !== void 0 ? options : {};
// One time setup with default plugins and settings.
const jssOptions = {
// JSS has many interesting plugins we may wish to turn on
//plugins: [functions(), template(), global(), extend(), nested(), compose(), camelCase(), defaultUnit(options.defaultUnit), expand(), vendorPrefixer(), propsSort()]
plugins: [(0,jss_plugin_global__WEBPACK_IMPORTED_MODULE_1__["default"])(), (0,jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_2__["default"])()],
insertionPoint: jssInsertionPoint
};
jss__WEBPACK_IMPORTED_MODULE_0__["default"].setup(jssOptions);
this.customStyles = customStyles;
this.lightModePalette =
lightModePalette !== null && lightModePalette !== void 0 ? lightModePalette : this.defaultLightModePalette;
this.darkModePalette = darkModePalette !== null && darkModePalette !== void 0 ? darkModePalette : this.defaultDarkModePalette;
}
applyStyleSheet() {
// Todo: refactor codebase to use jss at a component level, classes can be grabbed like so:
//const {pixelStreamingClasses} = jss.createStyleSheet(styles).attach();
// attach generated style sheet to page
jss__WEBPACK_IMPORTED_MODULE_0__["default"].createStyleSheet({
'@global': Object.assign(Object.assign({}, this.defaultStyles), this.customStyles)
}).attach();
}
applyPalette(palette) {
const rootElement = document.querySelector(':root');
rootElement.style.setProperty('--color0', palette['--color0']);
rootElement.style.setProperty('--color1', palette['--color1']);
rootElement.style.setProperty('--color2', palette['--color2']);
rootElement.style.setProperty('--color3', palette['--color3']);
rootElement.style.setProperty('--color4', palette['--color4']);
rootElement.style.setProperty('--color5', palette['--color5']);
rootElement.style.setProperty('--color6', palette['--color6']);
rootElement.style.setProperty('--color7', palette['--color7']);
}
/**
* Update the players color variables
* @param isLightMode - should we use a light or dark color scheme
*/
setColorMode(isLightMode) {
if (isLightMode) {
this.applyPalette(this.lightModePalette);
}
else {
this.applyPalette(this.darkModePalette);
}
}
}
/***/ }),
/***/ "./src/UI/Controls.ts":
/*!****************************!*\
!*** ./src/UI/Controls.ts ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Controls": () => (/* binding */ Controls)
/* harmony export */ });
/* harmony import */ var _FullscreenIcon__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./FullscreenIcon */ "./src/UI/FullscreenIcon.ts");
/* harmony import */ var _SettingsIcon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SettingsIcon */ "./src/UI/SettingsIcon.ts");
/* harmony import */ var _StatsIcon__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./StatsIcon */ "./src/UI/StatsIcon.ts");
/* harmony import */ var _XRIcon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./XRIcon */ "./src/UI/XRIcon.ts");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../UI/UIConfigurationTypes */ "./src/UI/UIConfigurationTypes.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
// If there isn't a type provided, default behaviour is to create the element.
function shouldCreateButton(type) {
return (type == undefined) ? true : (type.creationMode === _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_1__.UIElementCreationMode.CreateDefaultElement);
}
/**
* Element containing various controls like stats, settings, fullscreen.
*/
class Controls {
/**
* Construct the controls
*/
constructor(config) {
if (!config || shouldCreateButton(config.statsButtonType)) {
this.statsIcon = new _StatsIcon__WEBPACK_IMPORTED_MODULE_2__.StatsIcon();
}
if (!config || shouldCreateButton(config.settingsButtonType)) {
this.settingsIcon = new _SettingsIcon__WEBPACK_IMPORTED_MODULE_3__.SettingsIcon();
}
if (!config || shouldCreateButton(config.fullscreenButtonType)) {
this.fullscreenIcon = new _FullscreenIcon__WEBPACK_IMPORTED_MODULE_4__.FullScreenIcon();
}
if (!config || shouldCreateButton(config.xrIconType)) {
this.xrIcon = new _XRIcon__WEBPACK_IMPORTED_MODULE_5__.XRIcon();
}
}
/**
* Get the element containing the controls.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('div');
this._rootElement.id = 'controls';
if (!!this.fullscreenIcon) {
this._rootElement.appendChild(this.fullscreenIcon.rootElement);
}
if (!!this.settingsIcon) {
this._rootElement.appendChild(this.settingsIcon.rootElement);
}
if (!!this.statsIcon) {
this._rootElement.appendChild(this.statsIcon.rootElement);
}
if (!!this.xrIcon) {
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.WebXRController.isSessionSupported('immersive-vr').then((supported) => {
if (supported) {
this._rootElement.appendChild(this.xrIcon.rootElement);
}
});
}
;
}
return this._rootElement;
}
}
/***/ }),
/***/ "./src/UI/DataChannelLatencyTest.ts":
/*!******************************************!*\
!*** ./src/UI/DataChannelLatencyTest.ts ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DataChannelLatencyTest": () => (/* binding */ DataChannelLatencyTest)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* DataChannel Latency test UI elements and results handling.
*/
class DataChannelLatencyTest {
/**
* Get the button containing the stats icon.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('section');
this._rootElement.classList.add('settingsContainer');
// make heading
const heading = document.createElement('div');
heading.id = 'dataChannelLatencyTestHeader';
heading.classList.add('settings-text');
heading.classList.add('settingsHeader');
this._rootElement.appendChild(heading);
const headingText = document.createElement('div');
headingText.innerHTML = 'Data Channel Latency Test';
heading.appendChild(headingText);
heading.appendChild(this.latencyTestButton);
// make test results element
const resultsParentElem = document.createElement('div');
resultsParentElem.id = 'dataChannelLatencyTestContainer';
resultsParentElem.classList.add('d-none');
this._rootElement.appendChild(resultsParentElem);
resultsParentElem.appendChild(this.latencyTestResultsElement);
}
return this._rootElement;
}
get latencyTestResultsElement() {
if (!this._latencyTestResultsElement) {
this._latencyTestResultsElement = document.createElement('div');
this._latencyTestResultsElement.id = 'dataChannelLatencyStatsResults';
this._latencyTestResultsElement.classList.add('StatsResult');
}
return this._latencyTestResultsElement;
}
get latencyTestButton() {
if (!this._latencyTestButton) {
this._latencyTestButton = document.createElement('input');
this._latencyTestButton.type = 'button';
this._latencyTestButton.value = 'Run Test';
this._latencyTestButton.id = 'btn-start-data-channel-latency-test';
this._latencyTestButton.classList.add('streamTools-button');
this._latencyTestButton.classList.add('btn-flat');
}
return this._latencyTestButton;
}
/**
* Populate the UI based on the latency test's results.
* @param result The latency test results.
*/
handleTestResult(result) {
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), result.toString(), 6);
/**
* Check we have results, NaN would mean that UE version we talk to doesn't support our test
*/
if (isNaN(result.dataChannelRtt)) {
this.latencyTestResultsElement.innerHTML = 'Not supported
';
return;
}
let latencyStatsInnerHTML = '';
latencyStatsInnerHTML +=
'Data channel RTT (ms): ' +
result.dataChannelRtt +
'
';
/**
* Separate path time discovery works only when UE and Player clocks have been synchronized.
*/
if (result.playerToStreamerTime >= 0 && result.streamerToPlayerTime >= 0) {
latencyStatsInnerHTML +=
'Player to Streamer path (ms): ' + result.playerToStreamerTime + '
';
latencyStatsInnerHTML +=
'Streamer to Player path (ms): ' +
result.streamerToPlayerTime +
'
';
}
this.latencyTestResultsElement.innerHTML = latencyStatsInnerHTML;
//setup button to download the detailed results
let downloadButton = document.createElement('input');
downloadButton.type = 'button';
downloadButton.value = 'Download';
downloadButton.classList.add('streamTools-button');
downloadButton.classList.add('btn-flat');
downloadButton.onclick = () => {
let file = new Blob([result.exportLatencyAsCSV()], { type: 'text/plain' });
let a = document.createElement("a"), url = URL.createObjectURL(file);
a.href = url;
a.download = "data_channel_latency_test_results.csv";
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
};
this.latencyTestResultsElement.appendChild(downloadButton);
}
handleTestStart() {
this.latencyTestResultsElement.innerHTML =
'Test in progress
';
}
}
/***/ }),
/***/ "./src/UI/FullscreenIcon.ts":
/*!**********************************!*\
!*** ./src/UI/FullscreenIcon.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "FullScreenIcon": () => (/* binding */ FullScreenIcon),
/* harmony export */ "FullScreenIconBase": () => (/* binding */ FullScreenIconBase),
/* harmony export */ "FullScreenIconExternal": () => (/* binding */ FullScreenIconExternal)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Base class for an element (i.e. button) that, when clicked, will toggle fullscreen of a given element.
* Can be initialized with any HTMLElement, if it is set as rootElement in the constructor.
*/
class FullScreenIconBase {
get rootElement() {
return this._rootElement;
}
set rootElement(element) {
element.onclick = () => this.toggleFullscreen();
this._rootElement = element;
}
constructor() {
this.isFullscreen = false;
// set up the full screen events
document.addEventListener('webkitfullscreenchange', () => this.onFullscreenChange(), false);
document.addEventListener('mozfullscreenchange', () => this.onFullscreenChange(), false);
document.addEventListener('fullscreenchange', () => this.onFullscreenChange(), false);
document.addEventListener('MSFullscreenChange', () => this.onFullscreenChange(), false);
}
/**
* Makes the document or fullscreenElement fullscreen.
*/
toggleFullscreen() {
// if already full screen; exit
// else go fullscreen
if (document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement) {
if (document.exitFullscreen) {
document.exitFullscreen();
}
else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
}
else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
else {
const element = this.fullscreenElement;
if (!element) {
return;
}
if (element.requestFullscreen) {
element.requestFullscreen();
}
else if (element.mozRequestFullscreen) {
element.mozRequestFullscreen();
}
else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
}
else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
else if (element.webkitEnterFullscreen) {
element.webkitEnterFullscreen(); //for iphone this code worked
}
}
this.onFullscreenChange();
}
/**
* Handles the fullscreen button on change
*/
onFullscreenChange() {
this.isFullscreen =
document.webkitIsFullScreen ||
document.mozFullScreen ||
(document.msFullscreenElement &&
document.msFullscreenElement !== null) ||
(document.fullscreenElement && document.fullscreenElement !== null);
}
}
/**
* An implementation of FullScreenIconBase that uses an externally
* provided HTMLElement for toggling full screen.
*/
class FullScreenIconExternal extends FullScreenIconBase {
constructor(externalButton) {
super();
this.rootElement = externalButton;
}
}
/**
* The default fullscreen icon that contains a button and svgs for each state.
*/
class FullScreenIcon extends FullScreenIconBase {
constructor() {
super();
const createdButton = document.createElement('button');
createdButton.type = 'button';
createdButton.classList.add('UiTool');
createdButton.id = 'fullscreen-btn';
createdButton.appendChild(this.maximizeIcon);
createdButton.appendChild(this.minimizeIcon);
createdButton.appendChild(this.tooltipText);
this.rootElement = createdButton;
}
get tooltipText() {
if (!this._tooltipText) {
this._tooltipText = document.createElement('span');
this._tooltipText.classList.add('tooltiptext');
this._tooltipText.innerHTML = 'Fullscreen';
}
return this._tooltipText;
}
get maximizeIcon() {
if (!this._maximizeIcon) {
this._maximizeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._maximizeIcon.setAttributeNS(null, 'id', 'maximizeIcon');
this._maximizeIcon.setAttributeNS(null, 'x', '0px');
this._maximizeIcon.setAttributeNS(null, 'y', '0px');
this._maximizeIcon.setAttributeNS(null, 'viewBox', '0 0 384.97 384.97');
// create svg group for the paths
const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
svgGroup.classList.add('svgIcon');
this._maximizeIcon.appendChild(svgGroup);
// create paths for the icon itself, one for each corner
const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path1.setAttributeNS(null, 'd', 'M384.97,12.03c0-6.713-5.317-12.03-12.03-12.03H264.847c-6.833,0-11.922,5.39-11.934,12.223c0,6.821,5.101,11.838,11.934,11.838h96.062l-0.193,96.519c0,6.833,5.197,12.03,12.03,12.03c6.833-0.012,12.03-5.197,12.03-12.03l0.193-108.369c0-0.036-0.012-0.06-0.012-0.084C384.958,12.09,384.97,12.066,384.97,12.03z');
const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path2.setAttributeNS(null, 'd', 'M120.496,0H12.403c-0.036,0-0.06,0.012-0.096,0.012C12.283,0.012,12.247,0,12.223,0C5.51,0,0.192,5.317,0.192,12.03L0,120.399c0,6.833,5.39,11.934,12.223,11.934c6.821,0,11.838-5.101,11.838-11.934l0.192-96.339h96.242c6.833,0,12.03-5.197,12.03-12.03C132.514,5.197,127.317,0,120.496,0z');
const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path3.setAttributeNS(null, 'd', 'M120.123,360.909H24.061v-96.242c0-6.833-5.197-12.03-12.03-12.03S0,257.833,0,264.667v108.092c0,0.036,0.012,0.06,0.012,0.084c0,0.036-0.012,0.06-0.012,0.096c0,6.713,5.317,12.03,12.03,12.03h108.092c6.833,0,11.922-5.39,11.934-12.223C132.057,365.926,126.956,360.909,120.123,360.909z');
const path4 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path4.setAttributeNS(null, 'd', 'M372.747,252.913c-6.833,0-11.85,5.101-11.838,11.934v96.062h-96.242c-6.833,0-12.03,5.197-12.03,12.03s5.197,12.03,12.03,12.03h108.092c0.036,0,0.06-0.012,0.084-0.012c0.036-0.012,0.06,0.012,0.096,0.012c6.713,0,12.03-5.317,12.03-12.03V264.847C384.97,258.014,379.58,252.913,372.747,252.913z');
svgGroup.appendChild(path1);
svgGroup.appendChild(path2);
svgGroup.appendChild(path3);
svgGroup.appendChild(path4);
}
return this._maximizeIcon;
}
get minimizeIcon() {
if (!this._minimizeIcon) {
this._minimizeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._minimizeIcon.setAttributeNS(null, 'id', 'minimizeIcon');
this._minimizeIcon.setAttributeNS(null, 'x', '0px');
this._minimizeIcon.setAttributeNS(null, 'y', '0px');
this._minimizeIcon.setAttributeNS(null, 'viewBox', '0 0 385.331 385.331');
// create svg group for the paths
const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
svgGroup.classList.add('svgIcon');
this._minimizeIcon.appendChild(svgGroup);
// create paths for the icon itself, one for each corner
const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path1.setAttributeNS(null, 'd', 'M264.943,156.665h108.273c6.833,0,11.934-5.39,11.934-12.211c0-6.833-5.101-11.85-11.934-11.838h-96.242V36.181c0-6.833-5.197-12.03-12.03-12.03s-12.03,5.197-12.03,12.03v108.273c0,0.036,0.012,0.06,0.012,0.084c0,0.036-0.012,0.06-0.012,0.096C252.913,151.347,258.23,156.677,264.943,156.665z');
const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path2.setAttributeNS(null, 'd', 'M120.291,24.247c-6.821,0-11.838,5.113-11.838,11.934v96.242H12.03c-6.833,0-12.03,5.197-12.03,12.03c0,6.833,5.197,12.03,12.03,12.03h108.273c0.036,0,0.06-0.012,0.084-0.012c0.036,0,0.06,0.012,0.096,0.012c6.713,0,12.03-5.317,12.03-12.03V36.181C132.514,29.36,127.124,24.259,120.291,24.247z');
const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path3.setAttributeNS(null, 'd', 'M120.387,228.666H12.115c-6.833,0.012-11.934,5.39-11.934,12.223c0,6.833,5.101,11.85,11.934,11.838h96.242v96.423c0,6.833,5.197,12.03,12.03,12.03c6.833,0,12.03-5.197,12.03-12.03V240.877c0-0.036-0.012-0.06-0.012-0.084c0-0.036,0.012-0.06,0.012-0.096C132.418,233.983,127.1,228.666,120.387,228.666z');
const path4 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path4.setAttributeNS(null, 'd', 'M373.3,228.666H265.028c-0.036,0-0.06,0.012-0.084,0.012c-0.036,0-0.06-0.012-0.096-0.012c-6.713,0-12.03,5.317-12.03,12.03v108.273c0,6.833,5.39,11.922,12.223,11.934c6.821,0.012,11.838-5.101,11.838-11.922v-96.242H373.3c6.833,0,12.03-5.197,12.03-12.03S380.134,228.678,373.3,228.666z');
svgGroup.appendChild(path1);
svgGroup.appendChild(path2);
svgGroup.appendChild(path3);
svgGroup.appendChild(path4);
}
return this._minimizeIcon;
}
onFullscreenChange() {
super.onFullscreenChange();
const minimize = this.minimizeIcon;
const maximize = this.maximizeIcon;
if (this.isFullscreen) {
minimize.style.display = 'inline';
//ios disappearing svg fix
minimize.style.transform = 'translate(0, 0)';
maximize.style.display = 'none';
}
else {
minimize.style.display = 'none';
maximize.style.display = 'inline';
//ios disappearing svg fix
maximize.style.transform = 'translate(0, 0)';
}
}
}
/***/ }),
/***/ "./src/UI/LabelledButton.ts":
/*!**********************************!*\
!*** ./src/UI/LabelledButton.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "LabelledButton": () => (/* binding */ LabelledButton)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* A button with a text label beside it.
*/
class LabelledButton {
constructor(label, buttonText) {
this._label = label;
this._buttonText = buttonText;
}
/**
* Add a click listener to the button element.
*/
addOnClickListener(onClickFunc) {
this.button.addEventListener('click', onClickFunc);
}
/**
* Get the HTMLInputElement for the button.
*/
get button() {
if (!this._button) {
this._button = document.createElement('input');
this._button.type = 'button';
this._button.value = this._buttonText;
this._button.classList.add('overlay-button');
this._button.classList.add('btn-flat');
}
return this._button;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
// create root div with "setting" css class
this._rootElement = document.createElement('div');
this._rootElement.classList.add('setting');
// create div element to contain our setting's text
const settingsTextElem = document.createElement('div');
settingsTextElem.innerText = this._label;
this._rootElement.appendChild(settingsTextElem);
// create label element to wrap out input type
const wrapperLabel = document.createElement('label');
wrapperLabel.classList.add('btn-overlay');
this._rootElement.appendChild(wrapperLabel);
wrapperLabel.appendChild(this.button);
}
return this._rootElement;
}
}
/***/ }),
/***/ "./src/UI/LatencyTest.ts":
/*!*******************************!*\
!*** ./src/UI/LatencyTest.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "LatencyTest": () => (/* binding */ LatencyTest)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Latency test UI elements and results handling.
*/
class LatencyTest {
/**
* Get the the button containing the stats icon.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('section');
this._rootElement.classList.add('settingsContainer');
// make heading
const heading = document.createElement('div');
heading.id = 'latencyTestHeader';
heading.classList.add('settings-text');
heading.classList.add('settingsHeader');
this._rootElement.appendChild(heading);
const headingText = document.createElement('div');
headingText.innerHTML = 'Latency Test';
heading.appendChild(headingText);
heading.appendChild(this.latencyTestButton);
// make test results element
const resultsParentElem = document.createElement('div');
resultsParentElem.id = 'latencyTestContainer';
resultsParentElem.classList.add('d-none');
this._rootElement.appendChild(resultsParentElem);
resultsParentElem.appendChild(this.latencyTestResultsElement);
}
return this._rootElement;
}
get latencyTestResultsElement() {
if (!this._latencyTestResultsElement) {
this._latencyTestResultsElement = document.createElement('div');
this._latencyTestResultsElement.id = 'latencyStatsResults';
this._latencyTestResultsElement.classList.add('StatsResult');
}
return this._latencyTestResultsElement;
}
get latencyTestButton() {
if (!this._latencyTestButton) {
this._latencyTestButton = document.createElement('input');
this._latencyTestButton.type = 'button';
this._latencyTestButton.value = 'Run Test';
this._latencyTestButton.id = 'btn-start-latency-test';
this._latencyTestButton.classList.add('streamTools-button');
this._latencyTestButton.classList.add('btn-flat');
}
return this._latencyTestButton;
}
/**
* Populate the UI based on the latency test's results.
* @param latencyTimings The latency test results.
*/
handleTestResult(latencyTimings) {
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), latencyTimings.toString(), 6);
let latencyStatsInnerHTML = '';
latencyStatsInnerHTML +=
'Net latency RTT (ms): ' +
latencyTimings.networkLatency +
'
';
latencyStatsInnerHTML +=
'UE Encode (ms): ' + latencyTimings.EncodeMs + '
';
latencyStatsInnerHTML +=
'UE Capture (ms): ' +
latencyTimings.CaptureToSendMs +
'
';
latencyStatsInnerHTML +=
'Browser send latency (ms): ' +
latencyTimings.browserSendLatency +
'
';
latencyStatsInnerHTML +=
latencyTimings.frameDisplayDeltaTimeMs &&
latencyTimings.browserReceiptTimeMs
? 'Browser receive latency (ms): ' +
latencyTimings.frameDisplayDeltaTimeMs +
'
'
: '';
latencyStatsInnerHTML +=
'Total latency (excluding browser) (ms): ' +
latencyTimings.latencyExcludingDecode +
'
';
latencyStatsInnerHTML += latencyTimings.endToEndLatency
? 'Total latency (ms): ' +
latencyTimings.endToEndLatency +
'
'
: '';
this.latencyTestResultsElement.innerHTML = latencyStatsInnerHTML;
}
}
/***/ }),
/***/ "./src/UI/SettingsIcon.ts":
/*!********************************!*\
!*** ./src/UI/SettingsIcon.ts ***!
\********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingsIcon": () => (/* binding */ SettingsIcon)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Settings icon that can be clicked.
*/
class SettingsIcon {
/**
* Get the the button containing the settings icon.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('button');
this._rootElement.type = 'button';
this._rootElement.classList.add('UiTool');
this._rootElement.id = 'settingsBtn';
this._rootElement.appendChild(this.settingsIcon);
this._rootElement.appendChild(this.tooltipText);
}
return this._rootElement;
}
get tooltipText() {
if (!this._tooltipText) {
this._tooltipText = document.createElement('span');
this._tooltipText.classList.add('tooltiptext');
this._tooltipText.innerHTML = 'Settings';
}
return this._tooltipText;
}
get settingsIcon() {
if (!this._settingsIcon) {
this._settingsIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._settingsIcon.setAttributeNS(null, 'id', 'settingsIcon');
this._settingsIcon.setAttributeNS(null, 'x', '0px');
this._settingsIcon.setAttributeNS(null, 'y', '0px');
this._settingsIcon.setAttributeNS(null, 'viewBox', '0 0 478.703 478.703');
// create svg group for the paths
const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
svgGroup.classList.add('svgIcon');
this._settingsIcon.appendChild(svgGroup);
// create paths for the icon itself, the inner and out path of a cog
const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path1.setAttributeNS(null, 'd', 'M454.2,189.101l-33.6-5.7c-3.5-11.3-8-22.2-13.5-32.6l19.8-27.7c8.4-11.8,7.1-27.9-3.2-38.1l-29.8-29.8\
c-5.6-5.6-13-8.7-20.9-8.7c-6.2,0-12.1,1.9-17.1,5.5l-27.8,19.8c-10.8-5.7-22.1-10.4-33.8-13.9l-5.6-33.2\
c-2.4-14.3-14.7-24.7-29.2-24.7h-42.1c-14.5,0-26.8,10.4-29.2,24.7l-5.8,34c-11.2,3.5-22.1,8.1-32.5,13.7l-27.5-19.8\
c-5-3.6-11-5.5-17.2-5.5c-7.9,0-15.4,3.1-20.9,8.7l-29.9,29.8c-10.2,10.2-11.6,26.3-3.2,38.1l20,28.1\
c-5.5,10.5-9.9,21.4-13.3,32.7l-33.2,5.6c-14.3,2.4-24.7,14.7-24.7,29.2v42.1c0,14.5,10.4,26.8,24.7,29.2l34,5.8\
c3.5,11.2,8.1,22.1,13.7,32.5l-19.7,27.4c-8.4,11.8-7.1,27.9,3.2,38.1l29.8,29.8c5.6,5.6,13,8.7,20.9,8.7c6.2,0,12.1-1.9,17.1-5.5\
l28.1-20c10.1,5.3,20.7,9.6,31.6,13l5.6,33.6c2.4,14.3,14.7,24.7,29.2,24.7h42.2c14.5,0,26.8-10.4,29.2-24.7l5.7-33.6\
c11.3-3.5,22.2-8,32.6-13.5l27.7,19.8c5,3.6,11,5.5,17.2,5.5l0,0c7.9,0,15.3-3.1,20.9-8.7l29.8-29.8c10.2-10.2,11.6-26.3,3.2-38.1\
l-19.8-27.8c5.5-10.5,10.1-21.4,13.5-32.6l33.6-5.6c14.3-2.4,24.7-14.7,24.7-29.2v-42.1\
C478.9,203.801,468.5,191.501,454.2,189.101z M451.9,260.401c0,1.3-0.9,2.4-2.2,2.6l-42,7c-5.3,0.9-9.5,4.8-10.8,9.9\
c-3.8,14.7-9.6,28.8-17.4,41.9c-2.7,4.6-2.5,10.3,0.6,14.7l24.7,34.8c0.7,1,0.6,2.5-0.3,3.4l-29.8,29.8c-0.7,0.7-1.4,0.8-1.9,0.8\
c-0.6,0-1.1-0.2-1.5-0.5l-34.7-24.7c-4.3-3.1-10.1-3.3-14.7-0.6c-13.1,7.8-27.2,13.6-41.9,17.4c-5.2,1.3-9.1,5.6-9.9,10.8l-7.1,42\
c-0.2,1.3-1.3,2.2-2.6,2.2h-42.1c-1.3,0-2.4-0.9-2.6-2.2l-7-42c-0.9-5.3-4.8-9.5-9.9-10.8c-14.3-3.7-28.1-9.4-41-16.8\
c-2.1-1.2-4.5-1.8-6.8-1.8c-2.7,0-5.5,0.8-7.8,2.5l-35,24.9c-0.5,0.3-1,0.5-1.5,0.5c-0.4,0-1.2-0.1-1.9-0.8l-29.8-29.8\
c-0.9-0.9-1-2.3-0.3-3.4l24.6-34.5c3.1-4.4,3.3-10.2,0.6-14.8c-7.8-13-13.8-27.1-17.6-41.8c-1.4-5.1-5.6-9-10.8-9.9l-42.3-7.2\
c-1.3-0.2-2.2-1.3-2.2-2.6v-42.1c0-1.3,0.9-2.4,2.2-2.6l41.7-7c5.3-0.9,9.6-4.8,10.9-10c3.7-14.7,9.4-28.9,17.1-42\
c2.7-4.6,2.4-10.3-0.7-14.6l-24.9-35c-0.7-1-0.6-2.5,0.3-3.4l29.8-29.8c0.7-0.7,1.4-0.8,1.9-0.8c0.6,0,1.1,0.2,1.5,0.5l34.5,24.6\
c4.4,3.1,10.2,3.3,14.8,0.6c13-7.8,27.1-13.8,41.8-17.6c5.1-1.4,9-5.6,9.9-10.8l7.2-42.3c0.2-1.3,1.3-2.2,2.6-2.2h42.1\
c1.3,0,2.4,0.9,2.6,2.2l7,41.7c0.9,5.3,4.8,9.6,10,10.9c15.1,3.8,29.5,9.7,42.9,17.6c4.6,2.7,10.3,2.5,14.7-0.6l34.5-24.8\
c0.5-0.3,1-0.5,1.5-0.5c0.4,0,1.2,0.1,1.9,0.8l29.8,29.8c0.9,0.9,1,2.3,0.3,3.4l-24.7,34.7c-3.1,4.3-3.3,10.1-0.6,14.7\
c7.8,13.1,13.6,27.2,17.4,41.9c1.3,5.2,5.6,9.1,10.8,9.9l42,7.1c1.3,0.2,2.2,1.3,2.2,2.6v42.1H451.9z');
const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path2.setAttributeNS(null, 'd', 'M239.4,136.001c-57,0-103.3,46.3-103.3,103.3s46.3,103.3,103.3,103.3s103.3-46.3,103.3-103.3S296.4,136.001,239.4,136.001z M239.4,315.601c-42.1,0-76.3-34.2-76.3-76.3s34.2-76.3,76.3-76.3s76.3,34.2,76.3,76.3S281.5,315.601,239.4,315.601z');
svgGroup.appendChild(path1);
svgGroup.appendChild(path2);
}
return this._settingsIcon;
}
}
/***/ }),
/***/ "./src/UI/SettingsPanel.ts":
/*!*********************************!*\
!*** ./src/UI/SettingsPanel.ts ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "SettingsPanel": () => (/* binding */ SettingsPanel)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* A UI component containing all the settings for the application.
*/
class SettingsPanel {
constructor() {
this._rootElement = null;
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('div');
this._rootElement.id = 'settings-panel';
this._rootElement.classList.add('panel-wrap');
const panelElem = document.createElement('div');
panelElem.classList.add('panel');
this._rootElement.appendChild(panelElem);
const settingsHeading = document.createElement('div');
settingsHeading.id = 'settingsHeading';
settingsHeading.textContent = 'Settings';
panelElem.appendChild(settingsHeading);
panelElem.appendChild(this.settingsCloseButton);
panelElem.appendChild(this.settingsContentElement);
}
return this._rootElement;
}
get settingsContentElement() {
if (!this._settingsContentElement) {
this._settingsContentElement = document.createElement('div');
this._settingsContentElement.id = 'settingsContent';
}
return this._settingsContentElement;
}
get settingsCloseButton() {
if (!this._settingsCloseButton) {
this._settingsCloseButton = document.createElement('div');
this._settingsCloseButton.id = 'settingsClose';
}
return this._settingsCloseButton;
}
/**
* Show settings panel.
*/
show() {
if (!this.rootElement.classList.contains('panel-wrap-visible')) {
this.rootElement.classList.add('panel-wrap-visible');
}
}
/**
* Toggle the visibility of the settings panel.
*/
toggleVisibility() {
this.rootElement.classList.toggle('panel-wrap-visible');
}
/**
* Hide settings panel.
*/
hide() {
if (this.rootElement.classList.contains('panel-wrap-visible')) {
this.rootElement.classList.remove('panel-wrap-visible');
}
}
}
/***/ }),
/***/ "./src/UI/StatsIcon.ts":
/*!*****************************!*\
!*** ./src/UI/StatsIcon.ts ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "StatsIcon": () => (/* binding */ StatsIcon)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* Stats icon that can be clicked.
*/
class StatsIcon {
/**
* Get the the button containing the stats icon.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('button');
this._rootElement.type = 'button';
this._rootElement.classList.add('UiTool');
this._rootElement.id = 'statsBtn';
this._rootElement.appendChild(this.statsIcon);
this._rootElement.appendChild(this.tooltipText);
}
return this._rootElement;
}
get tooltipText() {
if (!this._tooltipText) {
this._tooltipText = document.createElement('span');
this._tooltipText.classList.add('tooltiptext');
this._tooltipText.innerHTML = 'Information';
}
return this._tooltipText;
}
get statsIcon() {
if (!this._statsIcon) {
this._statsIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._statsIcon.setAttributeNS(null, 'id', 'statsIcon');
this._statsIcon.setAttributeNS(null, 'x', '0px');
this._statsIcon.setAttributeNS(null, 'y', '0px');
this._statsIcon.setAttributeNS(null, 'viewBox', '0 0 330 330');
// create svg group for the paths
const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
svgGroup.classList.add('svgIcon');
this._statsIcon.appendChild(svgGroup);
// create paths for the icon itself, the inner and out path of a cog
const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path1.setAttributeNS(null, 'd', 'M165,0.008C74.019,0.008,0,74.024,0,164.999c0,90.977,74.019,164.992,165,164.992s165-74.015,165-164.992C330,74.024,255.981,0.008,165,0.008z M165,299.992c-74.439,0-135-60.557-135-134.992S90.561,30.008,165,30.008s135,60.557,135,134.991C300,239.436,239.439,299.992,165,299.992z');
const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path2.setAttributeNS(null, 'd', 'M165,130.008c-8.284,0-15,6.716-15,15v99.983c0,8.284,6.716,15,15,15s15-6.716,15-15v-99.983C180,136.725,173.284,130.008,165,130.008z');
const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path3.setAttributeNS(null, 'd', 'M165,70.011c-3.95,0-7.811,1.6-10.61,4.39c-2.79,2.79-4.39,6.66-4.39,10.61s1.6,7.81,4.39,10.61c2.79,2.79,6.66,4.39,10.61,4.39s7.81-1.6,10.609-4.39c2.79-2.8,4.391-6.66,4.391-10.61s-1.601-7.82-4.391-10.61C172.81,71.61,168.95,70.011,165,70.011z');
svgGroup.appendChild(path1);
svgGroup.appendChild(path2);
svgGroup.appendChild(path3);
}
return this._statsIcon;
}
}
/***/ }),
/***/ "./src/UI/StatsPanel.ts":
/*!******************************!*\
!*** ./src/UI/StatsPanel.ts ***!
\******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Stat": () => (/* binding */ Stat),
/* harmony export */ "StatsPanel": () => (/* binding */ StatsPanel)
/* harmony export */ });
/* harmony import */ var _LatencyTest__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./LatencyTest */ "./src/UI/LatencyTest.ts");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _Util_MathUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Util/MathUtils */ "./src/Util/MathUtils.ts");
/* harmony import */ var _DataChannelLatencyTest__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./DataChannelLatencyTest */ "./src/UI/DataChannelLatencyTest.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* A stat structure, an id, the stat string, and the element where it is rendered.
*/
class Stat {
}
/**
* A UI component containing all the stats for the application.
*/
class StatsPanel {
constructor() {
/* A map stats we are storing/rendering */
this.statsMap = new Map();
this.latencyTest = new _LatencyTest__WEBPACK_IMPORTED_MODULE_1__.LatencyTest();
this.dataChannelLatencyTest = new _DataChannelLatencyTest__WEBPACK_IMPORTED_MODULE_2__.DataChannelLatencyTest();
}
/**
* @returns Return or creates a HTML element that represents this setting in the DOM.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('div');
this._rootElement.id = 'stats-panel';
this._rootElement.classList.add('panel-wrap');
const panelElem = document.createElement('div');
panelElem.classList.add('panel');
this._rootElement.appendChild(panelElem);
const statsHeading = document.createElement('div');
statsHeading.id = 'statsHeading';
statsHeading.textContent = 'Information';
panelElem.appendChild(statsHeading);
panelElem.appendChild(this.statsCloseButton);
panelElem.appendChild(this.statsContentElement);
}
return this._rootElement;
}
get statsContentElement() {
if (!this._statsContentElement) {
this._statsContentElement = document.createElement('div');
this._statsContentElement.id = 'statsContent';
const streamToolStats = document.createElement('div');
streamToolStats.id = 'streamToolsStats';
streamToolStats.classList.add('container');
const controlStats = document.createElement('div');
controlStats.id = 'ControlStats';
controlStats.classList.add('row');
const statistics = document.createElement('section');
statistics.id = 'statistics';
statistics.classList.add('settingsContainer');
const statisticsHeader = document.createElement('div');
statisticsHeader.id = 'statisticsHeader';
statisticsHeader.classList.add('settings-text');
statisticsHeader.classList.add('settingsHeader');
const sessionStats = document.createElement('div');
sessionStats.innerHTML = 'Session Stats';
this._statsContentElement.appendChild(streamToolStats);
streamToolStats.appendChild(controlStats);
controlStats.appendChild(statistics);
statistics.appendChild(statisticsHeader);
statisticsHeader.appendChild(sessionStats);
statistics.appendChild(this.statisticsContainer);
controlStats.appendChild(this.latencyTest.rootElement);
controlStats.appendChild(this.dataChannelLatencyTest.rootElement);
}
return this._statsContentElement;
}
get statisticsContainer() {
if (!this._statisticsContainer) {
this._statisticsContainer = document.createElement('div');
this._statisticsContainer.id = 'statisticsContainer';
this._statisticsContainer.classList.add('d-none');
this._statisticsContainer.appendChild(this.statsResult);
}
return this._statisticsContainer;
}
get statsResult() {
if (!this._statsResult) {
this._statsResult = document.createElement('div');
this._statsResult.id = 'statisticsResult';
this._statsResult.classList.add('StatsResult');
}
return this._statsResult;
}
get statsCloseButton() {
if (!this._statsCloseButton) {
this._statsCloseButton = document.createElement('div');
this._statsCloseButton.id = 'statsClose';
}
return this._statsCloseButton;
}
onDisconnect() {
this.latencyTest.latencyTestButton.onclick = () => {
// do nothing
};
this.dataChannelLatencyTest.latencyTestButton.onclick = () => {
//do nothing
};
}
onVideoInitialized(stream) {
// starting a latency check
this.latencyTest.latencyTestButton.onclick = () => {
stream.requestLatencyTest();
};
this.dataChannelLatencyTest.latencyTestButton.onclick = () => {
let started = stream.requestDataChannelLatencyTest({
duration: 1000,
rps: 10,
requestSize: 200,
responseSize: 200
});
if (started) {
this.dataChannelLatencyTest.handleTestStart();
}
};
}
configure(settings) {
if (settings.DisableLatencyTest) {
this.latencyTest.latencyTestButton.disabled = true;
this.latencyTest.latencyTestButton.title =
'Disabled by -PixelStreamingDisableLatencyTester=true';
this.dataChannelLatencyTest.latencyTestButton.disabled = true;
this.dataChannelLatencyTest.latencyTestButton.title =
'Disabled by -PixelStreamingDisableLatencyTester=true';
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Info(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), '-PixelStreamingDisableLatencyTester=true, requesting latency report from the the browser to UE is disabled.');
}
}
/**
* Show stats panel.
*/
show() {
if (!this.rootElement.classList.contains('panel-wrap-visible')) {
this.rootElement.classList.add('panel-wrap-visible');
}
}
/**
* Toggle the visibility of the stats panel.
*/
toggleVisibility() {
this.rootElement.classList.toggle('panel-wrap-visible');
}
/**
* Hide the stats panel.
*/
hide() {
if (this.rootElement.classList.contains('panel-wrap-visible')) {
this.rootElement.classList.remove('panel-wrap-visible');
}
}
handlePlayerCount(playerCount) {
this.addOrUpdateStat('PlayerCountStat', 'Players', playerCount.toString());
}
/**
* Handle stats coming in from browser/UE
* @param stats the stats structure
*/
handleStats(stats) {
var _a, _b, _c, _d, _e;
// format numbering based on the browser language
const numberFormat = new Intl.NumberFormat(window.navigator.language, {
maximumFractionDigits: 0
});
// Inbound data
const inboundData = _Util_MathUtils__WEBPACK_IMPORTED_MODULE_3__.MathUtils.formatBytes(stats.inboundVideoStats.bytesReceived, 2);
this.addOrUpdateStat('InboundDataStat', 'Received', inboundData);
// Packets lost
const packetsLostStat = Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'packetsLost')
? numberFormat.format(stats.inboundVideoStats.packetsLost)
: 'Chrome only';
this.addOrUpdateStat('PacketsLostStat', 'Packets Lost', packetsLostStat);
// Bitrate
if (stats.inboundVideoStats.bitrate) {
this.addOrUpdateStat('VideoBitrateStat', 'Video Bitrate (kbps)', stats.inboundVideoStats.bitrate.toString());
}
if (stats.inboundAudioStats.bitrate) {
this.addOrUpdateStat('AudioBitrateStat', 'Audio Bitrate (kbps)', stats.inboundAudioStats.bitrate.toString());
}
// Video resolution
const resStat = Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'frameWidth') &&
stats.inboundVideoStats.frameWidth &&
Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'frameHeight') &&
stats.inboundVideoStats.frameHeight
? stats.inboundVideoStats.frameWidth +
'x' +
stats.inboundVideoStats.frameHeight
: 'Chrome only';
this.addOrUpdateStat('VideoResStat', 'Video resolution', resStat);
// Frames decoded
const framesDecoded = Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'framesDecoded')
? numberFormat.format(stats.inboundVideoStats.framesDecoded)
: 'Chrome only';
this.addOrUpdateStat('FramesDecodedStat', 'Frames Decoded', framesDecoded);
// Framerate
if (stats.inboundVideoStats.framesPerSecond) {
this.addOrUpdateStat('FramerateStat', 'Framerate', stats.inboundVideoStats.framesPerSecond.toString());
}
// Frames dropped
this.addOrUpdateStat('FramesDroppedStat', 'Frames dropped', (_a = stats.inboundVideoStats.framesDropped) === null || _a === void 0 ? void 0 : _a.toString());
if (stats.inboundVideoStats.codecId) {
this.addOrUpdateStat('VideoCodecStat', 'Video codec',
// Split the codec to remove the Fmtp line
(_c = (_b = stats.codecs
.get(stats.inboundVideoStats.codecId)) === null || _b === void 0 ? void 0 : _b.split(' ')[0]) !== null && _c !== void 0 ? _c : '');
}
if (stats.inboundAudioStats.codecId) {
this.addOrUpdateStat('AudioCodecStat', 'Audio codec',
// Split the codec to remove the Fmtp line
(_e = (_d = stats.codecs
.get(stats.inboundAudioStats.codecId)) === null || _d === void 0 ? void 0 : _d.split(' ')[0]) !== null && _e !== void 0 ? _e : '');
}
// RTT
const netRTT = Object.prototype.hasOwnProperty.call(stats.candidatePair, 'currentRoundTripTime') && stats.isNumber(stats.candidatePair.currentRoundTripTime)
? numberFormat.format(stats.candidatePair.currentRoundTripTime * 1000)
: "Can't calculate";
this.addOrUpdateStat('RTTStat', 'Net RTT (ms)', netRTT);
this.addOrUpdateStat('DurationStat', 'Duration', stats.sessionStats.runTime);
this.addOrUpdateStat('ControlsInputStat', 'Controls stream input', stats.sessionStats.controlsStreamInput);
// QP
this.addOrUpdateStat('QPStat', 'Video quantization parameter', stats.sessionStats.videoEncoderAvgQP.toString());
// todo:
//statsText += `Browser receive to composite (ms): ${stats.inboundVideoStats.receiveToCompositeMs}
`;
_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), `--------- Stats ---------\n ${stats}\n------------------------`, 6);
}
/**
* Adds a new stat to the stats results in the DOM or updates an exiting stat.
* @param id The id of the stat to add/update.
* @param stat The contents of the stat.
*/
addOrUpdateStat(id, statLabel, stat) {
const statHTML = `${statLabel}: ${stat}`;
if (!this.statsMap.has(id)) {
// create the stat
const newStat = new Stat();
newStat.id = id;
newStat.stat = stat;
newStat.title = statLabel;
newStat.element = document.createElement('div');
newStat.element.innerHTML = statHTML;
// add the stat to the dom
this.statsResult.appendChild(newStat.element);
this.statsMap.set(id, newStat);
}
// update the existing stat
else {
const value = this.statsMap.get(id);
if (value !== undefined) {
value.element.innerHTML = statHTML;
}
}
}
}
/***/ }),
/***/ "./src/UI/UIConfigurationTypes.ts":
/*!****************************************!*\
!*** ./src/UI/UIConfigurationTypes.ts ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "UIElementCreationMode": () => (/* binding */ UIElementCreationMode),
/* harmony export */ "isPanelEnabled": () => (/* binding */ isPanelEnabled)
/* harmony export */ });
/** Whether a stream UI element is internally made, externally provided, or disabled. */
var UIElementCreationMode;
(function (UIElementCreationMode) {
UIElementCreationMode[UIElementCreationMode["CreateDefaultElement"] = 0] = "CreateDefaultElement";
UIElementCreationMode[UIElementCreationMode["UseCustomElement"] = 1] = "UseCustomElement";
UIElementCreationMode[UIElementCreationMode["Disable"] = 2] = "Disable";
})(UIElementCreationMode || (UIElementCreationMode = {}));
function isPanelEnabled(config) {
return !config || (!!config && config.isEnabled);
}
/***/ }),
/***/ "./src/UI/VideoQpIndicator.ts":
/*!************************************!*\
!*** ./src/UI/VideoQpIndicator.ts ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "VideoQpIndicator": () => (/* binding */ VideoQpIndicator)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* A UI element showing the QP (quantization parameter) of the video stream at the last encoded frame (well, last transmitted QP really).
* A blockier encoding will have a higher QP and this will make the indicator turn more red.
* A non-blocky stream will have a lower QP and this will make the indicator turn more green.
* The QP indicator is represented visually using a WiFi icon.
*/
class VideoQpIndicator {
constructor() {
this.videoEncoderAvgQP = -1;
// non html elements
this.statsText = '';
this.color = '';
// qp colors
this.orangeQP = 26;
this.redQP = 35;
}
/**
* Get the root element of the QP indicator.
*/
get rootElement() {
if (!this._rootElement) {
// make the root element that contains the svg for the connection
this._rootElement = document.createElement('div');
this._rootElement.id = 'connection';
this._rootElement.classList.add('UiTool');
// add svg icon for the connection strength
this._rootElement.appendChild(this.qualityStatus);
// add the text underneath the connection
this._rootElement.appendChild(this.qualityText);
// set colors to not connected initially
this.updateQpTooltip(-1);
}
return this._rootElement;
}
/**
* Get the text that displays under the icon.
*/
get qualityText() {
if (!this._qualityText) {
this._qualityText = document.createElement('span');
this._qualityText.id = 'qualityText';
this._qualityText.classList.add('tooltiptext');
}
return this._qualityText;
}
/**
* Get the icon.
*/
get qualityStatus() {
if (!this._qualityStatus) {
this._qualityStatus = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._qualityStatus.setAttributeNS(null, 'id', 'connectionStrength');
this._qualityStatus.setAttributeNS(null, 'x', '0px');
this._qualityStatus.setAttributeNS(null, 'y', '0px');
this._qualityStatus.setAttributeNS(null, 'viewBox', '0 0 494.45 494.45');
// build wifi icon
this.qualityStatus.appendChild(this.dot);
this.qualityStatus.appendChild(this.middle);
this.qualityStatus.appendChild(this.outer);
this.qualityStatus.appendChild(this.inner);
}
return this._qualityStatus;
}
/**
* Get the dot at the bottom of the wifi icon.
*/
get dot() {
if (!this._dot) {
this._dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
this._dot.setAttributeNS(null, 'id', 'dot');
this._dot.setAttributeNS(null, 'cx', '247.125');
this._dot.setAttributeNS(null, 'cy', '398.925');
this._dot.setAttributeNS(null, 'r', '35.3');
}
return this._dot;
}
/**
* Get the outer arc of the wifi icon.
*/
get outer() {
if (!this._outer) {
this._outer = document.createElementNS('http://www.w3.org/2000/svg', 'path');
this._outer.setAttributeNS(null, 'id', 'outer');
this._outer.setAttributeNS(null, 'd', 'M467.925,204.625c-6.8,0-13.5-2.6-18.7-7.8c-111.5-111.4-292.7-111.4-404.1,0c-10.3,10.3-27.1,10.3-37.4,0s-10.3-27.1,0-37.4c64-64,149-99.2,239.5-99.2s175.5,35.2,239.5,99.2c10.3,10.3,10.3,27.1,0,37.4C481.425,202.025,474.625,204.625,467.925,204.625z');
}
return this._outer;
}
/**
* Get the middle arc of the wifi icon.
*/
get middle() {
if (!this._middle) {
this._middle = document.createElementNS('http://www.w3.org/2000/svg', 'path');
this._middle.setAttributeNS(null, 'id', 'middle');
this._middle.setAttributeNS(null, 'd', 'M395.225,277.325c-6.8,0-13.5-2.6-18.7-7.8c-71.4-71.3-187.4-71.3-258.8,0c-10.3,10.3-27.1,10.3-37.4,0s-10.3-27.1,0-37.4c92-92,241.6-92,333.6,0c10.3,10.3,10.3,27.1,0,37.4C408.725,274.725,401.925,277.325,395.225,277.325z');
}
return this._middle;
}
/**
* Get the inner arc of the wifi icon.
*/
get inner() {
if (!this._inner) {
this._inner = document.createElementNS('http://www.w3.org/2000/svg', 'path');
this._inner.setAttributeNS(null, 'id', 'inner');
this._inner.setAttributeNS(null, 'd', 'M323.625,348.825c-6.8,0-13.5-2.6-18.7-7.8c-15.4-15.4-36-23.9-57.8-23.9s-42.4,8.5-57.8,23.9c-10.3,10.3-27.1,10.3-37.4,0c-10.3-10.3-10.3-27.1,0-37.4c25.4-25.4,59.2-39.4,95.2-39.4s69.8,14,95.2,39.5c10.3,10.3,10.3,27.1,0,37.4C337.225,346.225,330.425,348.825,323.625,348.825z');
}
return this._inner;
}
/**
* Used to set the speed of the status light.
* @param speed - Set the speed of the blink, higher numbers make the status light blink faster.
*/
blinkVideoQualityStatus(speed) {
let iteration = speed;
let opacity = 1;
const tickID = setInterval(() => {
opacity -= 0.1;
this.qualityText.style.opacity = String(Math.abs((opacity - 0.5) * 2));
if (opacity <= 0.1) {
if (--iteration == 0) {
clearInterval(tickID);
}
else {
opacity = 1;
}
}
}, 100 / speed);
}
/**
* updates the QP tooltip by converting the Video Encoder QP to a color light
* @param QP - The video encoder QP number needed to find the average
*/
updateQpTooltip(QP) {
this.videoEncoderAvgQP = QP;
if (QP > this.redQP) {
this.color = 'red';
this.blinkVideoQualityStatus(2);
this.statsText = `Poor encoding quality
`;
this.outer.setAttributeNS(null, 'fill', '#3c3b40');
this.middle.setAttributeNS(null, 'fill', '#3c3b40');
this.inner.setAttributeNS(null, 'fill', this.color);
this.dot.setAttributeNS(null, 'fill', this.color);
}
else if (QP > this.orangeQP) {
this.color = 'orange';
this.blinkVideoQualityStatus(1);
this.statsText = `Blocky encoding quality
`;
this.outer.setAttributeNS(null, 'fill', '#3c3b40');
this.middle.setAttributeNS(null, 'fill', this.color);
this.inner.setAttributeNS(null, 'fill', this.color);
this.dot.setAttributeNS(null, 'fill', this.color);
}
else if (QP <= 0) {
this.color = '#b0b0b0';
this.outer.setAttributeNS(null, 'fill', '#3c3b40');
this.middle.setAttributeNS(null, 'fill', '#3c3b40');
this.inner.setAttributeNS(null, 'fill', '#3c3b40');
this.dot.setAttributeNS(null, 'fill', '#3c3b40');
this.statsText = `Not connected
`;
}
else {
this.color = 'lime';
this.qualityStatus.style.opacity = '1';
this.statsText = `Clear encoding quality
`;
this.outer.setAttributeNS(null, 'fill', this.color);
this.middle.setAttributeNS(null, 'fill', this.color);
this.inner.setAttributeNS(null, 'fill', this.color);
this.dot.setAttributeNS(null, 'fill', this.color);
}
this.qualityText.innerHTML = this.statsText;
}
}
/***/ }),
/***/ "./src/UI/XRIcon.ts":
/*!**************************!*\
!*** ./src/UI/XRIcon.ts ***!
\**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "XRIcon": () => (/* binding */ XRIcon)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
* XR icon that can be clicked.
*/
class XRIcon {
/**
* Get the the button containing the XR icon.
*/
get rootElement() {
if (!this._rootElement) {
this._rootElement = document.createElement('button');
this._rootElement.type = 'button';
this._rootElement.classList.add('UiTool');
this._rootElement.id = 'xrBtn';
this._rootElement.appendChild(this.xrIcon);
this._rootElement.appendChild(this.tooltipText);
}
return this._rootElement;
}
get tooltipText() {
if (!this._tooltipText) {
this._tooltipText = document.createElement('span');
this._tooltipText.classList.add('tooltiptext');
this._tooltipText.innerHTML = 'XR';
}
return this._tooltipText;
}
get xrIcon() {
if (!this._xrIcon) {
this._xrIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._xrIcon.setAttributeNS(null, 'id', 'xrIcon');
this._xrIcon.setAttributeNS(null, 'x', '0px');
this._xrIcon.setAttributeNS(null, 'y', '0px');
this._xrIcon.setAttributeNS(null, 'viewBox', '0 0 100 100');
// create svg group for the paths
const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
svgGroup.classList.add('svgIcon');
this._xrIcon.appendChild(svgGroup);
// create paths for the icon itself, the path of the xr headset
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttributeNS(null, 'd', 'M29 41c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 14c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5zm42-14c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 14c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5zm12-31H17c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h14.5c3.5 0 6.8-1.5 9-4.1l3.5-4c1.5-1.7 3.7-2.7 6-2.7s4.5 1 6 2.7l3.5 4c2.3 2.6 5.6 4.1 9 4.1H83c6.6 0 12-5.4 12-12V36c0-6.6-5.4-12-12-12zm8 40c0 4.4-3.6 8-8 8H68.5c-2.3 0-4.5-1-6-2.7l-3.5-4c-2.3-2.6-5.6-4.1-9-4.1-3.5 0-6.8 1.5-9 4.1l-3.5 4C36 71 33.8 72 31.5 72H17c-4.4 0-8-3.6-8-8V36c0-4.4 3.6-8 8-8h66c4.4 0 8 3.6 8 8v28z');
svgGroup.appendChild(path);
}
return this._xrIcon;
}
}
/***/ }),
/***/ "./src/Util/MathUtils.ts":
/*!*******************************!*\
!*** ./src/Util/MathUtils.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "MathUtils": () => (/* binding */ MathUtils)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
class MathUtils {
/**
* formats Bytes coming in for video stats
* @param bytes number to convert
* @param decimals number of decimal places
*/
static formatBytes(bytes, decimals) {
if (bytes === 0) {
return '0';
}
const factor = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = [
'Bytes',
'KiB',
'MiB',
'GiB',
'TiB',
'PiB',
'EiB',
'ZiB',
'YiB'
];
const i = Math.floor(Math.log(bytes) / Math.log(factor));
return (parseFloat((bytes / Math.pow(factor, i)).toFixed(dm)) +
' ' +
sizes[i]);
}
}
/***/ }),
/***/ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3":
/*!*****************************************************************!*\
!*** external "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3" ***!
\*****************************************************************/
/***/ ((module) => {
var x = y => { var x = {}; __webpack_require__.d(x, y); return x; }
var y = x => () => x
module.exports = __WEBPACK_EXTERNAL_MODULE__epicgames_ps_lib_pixelstreamingfrontend_ue5_3_512f3c9b__;
/***/ }),
/***/ "jss":
/*!**********************!*\
!*** external "jss" ***!
\**********************/
/***/ ((module) => {
var x = y => { var x = {}; __webpack_require__.d(x, y); return x; }
var y = x => () => x
module.exports = __WEBPACK_EXTERNAL_MODULE_jss__;
/***/ }),
/***/ "jss-plugin-camel-case":
/*!****************************************!*\
!*** external "jss-plugin-camel-case" ***!
\****************************************/
/***/ ((module) => {
var x = y => { var x = {}; __webpack_require__.d(x, y); return x; }
var y = x => () => x
module.exports = __WEBPACK_EXTERNAL_MODULE_jss_plugin_camel_case_de113355__;
/***/ }),
/***/ "jss-plugin-global":
/*!************************************!*\
!*** external "jss-plugin-global" ***!
\************************************/
/***/ ((module) => {
var x = y => { var x = {}; __webpack_require__.d(x, y); return x; }
var y = x => () => x
module.exports = __WEBPACK_EXTERNAL_MODULE_jss_plugin_global_ef86f421__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/*!******************************************!*\
!*** ./src/pixelstreamingfrontend-ui.ts ***!
\******************************************/
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "AFKOverlay": () => (/* reexport safe */ _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_2__.AFKOverlay),
/* harmony export */ "ActionOverlay": () => (/* reexport safe */ _Overlay_ActionOverlay__WEBPACK_IMPORTED_MODULE_3__.ActionOverlay),
/* harmony export */ "Application": () => (/* reexport safe */ _Application_Application__WEBPACK_IMPORTED_MODULE_0__.Application),
/* harmony export */ "ConfigUI": () => (/* reexport safe */ _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_11__.ConfigUI),
/* harmony export */ "ConnectOverlay": () => (/* reexport safe */ _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_5__.ConnectOverlay),
/* harmony export */ "DisconnectOverlay": () => (/* reexport safe */ _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__.DisconnectOverlay),
/* harmony export */ "ErrorOverlay": () => (/* reexport safe */ _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_7__.ErrorOverlay),
/* harmony export */ "InfoOverlay": () => (/* reexport safe */ _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_8__.InfoOverlay),
/* harmony export */ "OverlayBase": () => (/* reexport safe */ _Overlay_BaseOverlay__WEBPACK_IMPORTED_MODULE_4__.OverlayBase),
/* harmony export */ "PixelStreamingApplicationStyle": () => (/* reexport safe */ _Styles_PixelStreamingApplicationStyles__WEBPACK_IMPORTED_MODULE_1__.PixelStreamingApplicationStyle),
/* harmony export */ "PlayOverlay": () => (/* reexport safe */ _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_9__.PlayOverlay),
/* harmony export */ "SettingUIBase": () => (/* reexport safe */ _Config_SettingUIBase__WEBPACK_IMPORTED_MODULE_12__.SettingUIBase),
/* harmony export */ "SettingUIFlag": () => (/* reexport safe */ _Config_SettingUIFlag__WEBPACK_IMPORTED_MODULE_13__.SettingUIFlag),
/* harmony export */ "SettingUINumber": () => (/* reexport safe */ _Config_SettingUINumber__WEBPACK_IMPORTED_MODULE_14__.SettingUINumber),
/* harmony export */ "SettingUIOption": () => (/* reexport safe */ _Config_SettingUIOption__WEBPACK_IMPORTED_MODULE_15__.SettingUIOption),
/* harmony export */ "SettingUIText": () => (/* reexport safe */ _Config_SettingUIText__WEBPACK_IMPORTED_MODULE_16__.SettingUIText),
/* harmony export */ "TextOverlay": () => (/* reexport safe */ _Overlay_TextOverlay__WEBPACK_IMPORTED_MODULE_10__.TextOverlay),
/* harmony export */ "UIElementCreationMode": () => (/* reexport safe */ _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_17__.UIElementCreationMode)
/* harmony export */ });
/* harmony import */ var _Application_Application__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Application/Application */ "./src/Application/Application.ts");
/* harmony import */ var _Styles_PixelStreamingApplicationStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Styles/PixelStreamingApplicationStyles */ "./src/Styles/PixelStreamingApplicationStyles.ts");
/* harmony import */ var _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Overlay/AFKOverlay */ "./src/Overlay/AFKOverlay.ts");
/* harmony import */ var _Overlay_ActionOverlay__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Overlay/ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
/* harmony import */ var _Overlay_BaseOverlay__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Overlay/BaseOverlay */ "./src/Overlay/BaseOverlay.ts");
/* harmony import */ var _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Overlay/ConnectOverlay */ "./src/Overlay/ConnectOverlay.ts");
/* harmony import */ var _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Overlay/DisconnectOverlay */ "./src/Overlay/DisconnectOverlay.ts");
/* harmony import */ var _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Overlay/ErrorOverlay */ "./src/Overlay/ErrorOverlay.ts");
/* harmony import */ var _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Overlay/InfoOverlay */ "./src/Overlay/InfoOverlay.ts");
/* harmony import */ var _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Overlay/PlayOverlay */ "./src/Overlay/PlayOverlay.ts");
/* harmony import */ var _Overlay_TextOverlay__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Overlay/TextOverlay */ "./src/Overlay/TextOverlay.ts");
/* harmony import */ var _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Config/ConfigUI */ "./src/Config/ConfigUI.ts");
/* harmony import */ var _Config_SettingUIBase__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Config/SettingUIBase */ "./src/Config/SettingUIBase.ts");
/* harmony import */ var _Config_SettingUIFlag__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Config/SettingUIFlag */ "./src/Config/SettingUIFlag.ts");
/* harmony import */ var _Config_SettingUINumber__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Config/SettingUINumber */ "./src/Config/SettingUINumber.ts");
/* harmony import */ var _Config_SettingUIOption__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Config/SettingUIOption */ "./src/Config/SettingUIOption.ts");
/* harmony import */ var _Config_SettingUIText__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Config/SettingUIText */ "./src/Config/SettingUIText.ts");
/* harmony import */ var _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./UI/UIConfigurationTypes */ "./src/UI/UIConfigurationTypes.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
})();
var __webpack_exports__AFKOverlay = __webpack_exports__.AFKOverlay;
var __webpack_exports__ActionOverlay = __webpack_exports__.ActionOverlay;
var __webpack_exports__Application = __webpack_exports__.Application;
var __webpack_exports__ConfigUI = __webpack_exports__.ConfigUI;
var __webpack_exports__ConnectOverlay = __webpack_exports__.ConnectOverlay;
var __webpack_exports__DisconnectOverlay = __webpack_exports__.DisconnectOverlay;
var __webpack_exports__ErrorOverlay = __webpack_exports__.ErrorOverlay;
var __webpack_exports__InfoOverlay = __webpack_exports__.InfoOverlay;
var __webpack_exports__OverlayBase = __webpack_exports__.OverlayBase;
var __webpack_exports__PixelStreamingApplicationStyle = __webpack_exports__.PixelStreamingApplicationStyle;
var __webpack_exports__PlayOverlay = __webpack_exports__.PlayOverlay;
var __webpack_exports__SettingUIBase = __webpack_exports__.SettingUIBase;
var __webpack_exports__SettingUIFlag = __webpack_exports__.SettingUIFlag;
var __webpack_exports__SettingUINumber = __webpack_exports__.SettingUINumber;
var __webpack_exports__SettingUIOption = __webpack_exports__.SettingUIOption;
var __webpack_exports__SettingUIText = __webpack_exports__.SettingUIText;
var __webpack_exports__TextOverlay = __webpack_exports__.TextOverlay;
var __webpack_exports__UIElementCreationMode = __webpack_exports__.UIElementCreationMode;
export { __webpack_exports__AFKOverlay as AFKOverlay, __webpack_exports__ActionOverlay as ActionOverlay, __webpack_exports__Application as Application, __webpack_exports__ConfigUI as ConfigUI, __webpack_exports__ConnectOverlay as ConnectOverlay, __webpack_exports__DisconnectOverlay as DisconnectOverlay, __webpack_exports__ErrorOverlay as ErrorOverlay, __webpack_exports__InfoOverlay as InfoOverlay, __webpack_exports__OverlayBase as OverlayBase, __webpack_exports__PixelStreamingApplicationStyle as PixelStreamingApplicationStyle, __webpack_exports__PlayOverlay as PlayOverlay, __webpack_exports__SettingUIBase as SettingUIBase, __webpack_exports__SettingUIFlag as SettingUIFlag, __webpack_exports__SettingUINumber as SettingUINumber, __webpack_exports__SettingUIOption as SettingUIOption, __webpack_exports__SettingUIText as SettingUIText, __webpack_exports__TextOverlay as TextOverlay, __webpack_exports__UIElementCreationMode as UIElementCreationMode };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNOQSxrREFBa0Q7QUFFeUM7QUFFRDtBQUV4QztBQUNNO0FBQ0o7QUFDTTtBQUNNO0FBQ1Y7QUFDRjtBQUNBO0FBQ0E7QUFDUDtBQUNVO0FBQ0E7QUFDSTtBQUNBO0FBQ0o7QUFDK0MiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL0FwcGxpY2F0aW9uL0FwcGxpY2F0aW9uLnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvQ29uZmlnL0NvbmZpZ1VJLnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvQ29uZmlnL1NldHRpbmdVSUJhc2UudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9Db25maWcvU2V0dGluZ1VJRmxhZy50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL0NvbmZpZy9TZXR0aW5nVUlOdW1iZXIudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9Db25maWcvU2V0dGluZ1VJT3B0aW9uLnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvQ29uZmlnL1NldHRpbmdVSVRleHQudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9PdmVybGF5L0FGS092ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9PdmVybGF5L0FjdGlvbk92ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9PdmVybGF5L0Jhc2VPdmVybGF5LnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvT3ZlcmxheS9Db25uZWN0T3ZlcmxheS50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL092ZXJsYXkvRGlzY29ubmVjdE92ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9PdmVybGF5L0Vycm9yT3ZlcmxheS50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL092ZXJsYXkvSW5mb092ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9PdmVybGF5L1BsYXlPdmVybGF5LnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvT3ZlcmxheS9UZXh0T3ZlcmxheS50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL1N0eWxlcy9QaXhlbFN0cmVhbWluZ0FwcGxpY2F0aW9uU3R5bGVzLnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvVUkvQ29udHJvbHMudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9VSS9EYXRhQ2hhbm5lbExhdGVuY3lUZXN0LnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvVUkvRnVsbHNjcmVlbkljb24udHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9VSS9MYWJlbGxlZEJ1dHRvbi50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL1VJL0xhdGVuY3lUZXN0LnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvVUkvU2V0dGluZ3NJY29uLnRzIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvLi9zcmMvVUkvU2V0dGluZ3NQYW5lbC50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL1VJL1N0YXRzSWNvbi50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL1VJL1N0YXRzUGFuZWwudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9VSS9VSUNvbmZpZ3VyYXRpb25UeXBlcy50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL1VJL1ZpZGVvUXBJbmRpY2F0b3IudHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9VSS9YUkljb24udHMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy8uL3NyYy9VdGlsL01hdGhVdGlscy50cyIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zL2V4dGVybmFsIG1vZHVsZSBcIkBlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjNcIiIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zL2V4dGVybmFsIG1vZHVsZSBcImpzc1wiIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvZXh0ZXJuYWwgbW9kdWxlIFwianNzLXBsdWdpbi1jYW1lbC1jYXNlXCIiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy9leHRlcm5hbCBtb2R1bGUgXCJqc3MtcGx1Z2luLWdsb2JhbFwiIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS11ZTUuMy93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWktdWU1LjMvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9AZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLXVlNS4zLy4vc3JjL3BpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHtcbiAgICBQaXhlbFN0cmVhbWluZyxcbiAgICBGbGFncyxcbiAgICBMb2dnZXIsXG4gICAgQWdncmVnYXRlZFN0YXRzLFxuICAgIExhdGVuY3lUZXN0UmVzdWx0cyxcbiAgICBJbml0aWFsU2V0dGluZ3MsXG4gICAgTWVzc2FnZVN0cmVhbWVyTGlzdFxufSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IE92ZXJsYXlCYXNlIH0gZnJvbSAnLi4vT3ZlcmxheS9CYXNlT3ZlcmxheSc7XG5pbXBvcnQgeyBBY3Rpb25PdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9BY3Rpb25PdmVybGF5JztcbmltcG9ydCB7IFRleHRPdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9UZXh0T3ZlcmxheSc7XG5pbXBvcnQgeyBDb25uZWN0T3ZlcmxheSB9IGZyb20gJy4uL092ZXJsYXkvQ29ubmVjdE92ZXJsYXknO1xuaW1wb3J0IHsgRGlzY29ubmVjdE92ZXJsYXkgfSBmcm9tICcuLi9PdmVybGF5L0Rpc2Nvbm5lY3RPdmVybGF5JztcbmltcG9ydCB7IFBsYXlPdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9QbGF5T3ZlcmxheSc7XG5pbXBvcnQgeyBJbmZvT3ZlcmxheSB9IGZyb20gJy4uL092ZXJsYXkvSW5mb092ZXJsYXknO1xuaW1wb3J0IHsgRXJyb3JPdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9FcnJvck92ZXJsYXknO1xuaW1wb3J0IHsgQUZLT3ZlcmxheSB9IGZyb20gJy4uL092ZXJsYXkvQUZLT3ZlcmxheSc7XG5pbXBvcnQgeyBDb250cm9scywgQ29udHJvbHNVSUNvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9VSS9Db250cm9scyc7XG5pbXBvcnQgeyBMYWJlbGxlZEJ1dHRvbiB9IGZyb20gJy4uL1VJL0xhYmVsbGVkQnV0dG9uJztcbmltcG9ydCB7IFNldHRpbmdzUGFuZWwgfSBmcm9tICcuLi9VSS9TZXR0aW5nc1BhbmVsJztcbmltcG9ydCB7IFN0YXRzUGFuZWwgfSBmcm9tICcuLi9VSS9TdGF0c1BhbmVsJztcbmltcG9ydCB7IFZpZGVvUXBJbmRpY2F0b3IgfSBmcm9tICcuLi9VSS9WaWRlb1FwSW5kaWNhdG9yJztcbmltcG9ydCB7IENvbmZpZ1VJLCBMaWdodE1vZGUgfSBmcm9tICcuLi9Db25maWcvQ29uZmlnVUknO1xuaW1wb3J0IHsgXG4gICAgVUlFbGVtZW50Q3JlYXRpb25Nb2RlLCBcbiAgICBQYW5lbENvbmZpZ3VyYXRpb24sIFxuICAgIGlzUGFuZWxFbmFibGVkLFxuICAgIFVJRWxlbWVudENvbmZpZ1xufSBmcm9tICcuLi9VSS9VSUNvbmZpZ3VyYXRpb25UeXBlcydcbmltcG9ydCB7IEZ1bGxTY3JlZW5JY29uQmFzZSwgRnVsbFNjcmVlbkljb25FeHRlcm5hbCB9IGZyb20gJy4uL1VJL0Z1bGxzY3JlZW5JY29uJztcbmltcG9ydCB7XG4gICAgRGF0YUNoYW5uZWxMYXRlbmN5VGVzdFJlc3VsdFxufSBmcm9tIFwiQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMy90eXBlcy9EYXRhQ2hhbm5lbC9EYXRhQ2hhbm5lbExhdGVuY3lUZXN0UmVzdWx0c1wiO1xuXG5cbi8qKiBcbiAqIENvbmZpZ3VyYXRpb24gb2YgdGhlIGludGVybmFsIHZpZGVvIFFQIGluZGljYXRvciBlbGVtZW50LlxuICogQnkgZGVmYXVsdCwgb25lIHdpbGwgYmUgbWFkZSwgYnV0IGlmIG5lZWRlZCB0aGlzIGNhbiBiZSBkaXNhYmxlZC5cbiAqIFxuICogTm90ZTogRm9yIGN1c3RvbSBVSSBlbGVtZW50cyB0byByZWFjdCB0byB0aGUgUVAgYmVpbmcgY2hhbmdlZCwgdXNlIGEgUGl4ZWxTdHJlYW1pbmcgXG4gKiBvYmplY3QncyBhZGRFdmVudExpc3RlbmVyKCd2aWRlb0VuY29kZXJBdmdRUCcsIC4uLikgb3IgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi4pLlxuICovXG5leHBvcnQgdHlwZSBWaWRlb1FQSW5kaWNhdG9yQ29uZmlnID0ge1xuICAgIGRpc2FibGVJbmRpY2F0b3I/OiBib29sZWFuXG59XG5cbi8qKlxuICogVUkgT3B0aW9ucyBjYW4gYmUgcHJvdmlkZWQgd2hlbiBjcmVhdGluZyBhbiBBcHBsaWNhdGlvbiwgdG8gY29uZmlndXJlIGl0J3MgaW50ZXJuYWxcbiAqIGFuZCBleHRlcm5hbCBiZWhhdmlvdXIsIGVuYWJsZS9kaXNhYmxlIGZlYXR1cmVzLCBhbmQgY29ubmVjdCB0byBleHRlcm5hbCBVSS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVSU9wdGlvbnMge1xuICAgIHN0cmVhbTogUGl4ZWxTdHJlYW1pbmc7XG4gICAgb25Db2xvck1vZGVDaGFuZ2VkPzogKGlzTGlnaHRNb2RlOiBib29sZWFuKSA9PiB2b2lkO1xuICAgIC8qKiBCeSBkZWZhdWx0LCBhIHNldHRpbmdzIHBhbmVsIGFuZCBhc3NvY2lhdGUgdmlzaWJpbGl0eSB0b2dnbGUgYnV0dG9uIHdpbGwgYmUgbWFkZS5cbiAgICAgICogSWYgbmVlZGVkLCB0aGlzIGJlaGF2aW91ciBjYW4gYmUgY29uZmlndXJlZC4gKi9cbiAgICBzZXR0aW5nc1BhbmVsQ29uZmlnPzogUGFuZWxDb25maWd1cmF0aW9uO1xuICAgIC8qKiBCeSBkZWZhdWx0LCBhIHN0YXRzIHBhbmVsIGFuZCBhc3NvY2lhdGUgdmlzaWJpbGl0eSB0b2dnbGUgYnV0dG9uIHdpbGwgYmUgbWFkZS5cbiAgICAgICogSWYgbmVlZGVkLCB0aGlzIGJlaGF2aW91ciBjYW4gYmUgY29uZmlndXJlZC4gKi9cbiAgICBzdGF0c1BhbmVsQ29uZmlnPzogUGFuZWxDb25maWd1cmF0aW9uO1xuICAgIC8qKiBJZiBuZWVkZWQsIHRoZSBmdWxsIHNjcmVlbiBidXR0b24gY2FuIGJlIGV4dGVybmFsIG9yIGRpc2FibGVkLiAqL1xuICAgIGZ1bGxTY3JlZW5Db250cm9sc0NvbmZpZz8gOiBVSUVsZW1lbnRDb25maWcsXG4gICAgLyoqIElmIG5lZWRlZCwgWFIgYnV0dG9uIGNhbiBiZSBleHRlcm5hbCBvciBkaXNhYmxlZC4gKi9cbiAgICB4ckNvbnRyb2xzQ29uZmlnPyA6IFVJRWxlbWVudENvbmZpZyxcbiAgICAvKiogQ29uZmlndXJhdGlvbiBvZiB0aGUgdmlkZW8gUVAgaW5kaWNhdG9yLiAqL1xuICAgIHZpZGVvUXBJbmRpY2F0b3JDb25maWc/IDogVmlkZW9RUEluZGljYXRvckNvbmZpZ1xufVxuXG4vKipcbiAqIEFuIEFwcGxpY2F0aW9uIGlzIGEgY29tYmluYXRpb24gb2YgVUkgZWxlbWVudHMgdG8gZGlzcGxheSBhbmQgbWFuYWdlIGEgV2ViUlRDIFBpeGVsIFN0cmVhbWluZ1xuICogY29ubmVjdGlvbi4gSXQgaW5jbHVkZXMgZmVhdHVyZXMgZm9yIGNvbnRyb2xsaW5nIGEgc3RyZWFtIHdpdGggbW91c2UgYW5kIGtleWJvYXJkLCBcbiAqIG1hbmFnaW5nIGNvbm5lY3Rpb24gZW5kcG9pbnRzLCBhcyB3ZWxsIGFzIGRpc3BsYXlpbmcgc3RhdHMgYW5kIG90aGVyIGluZm9ybWF0aW9uIGFib3V0IGl0LlxuICovXG5leHBvcnQgY2xhc3MgQXBwbGljYXRpb24ge1xuICAgIHN0cmVhbTogUGl4ZWxTdHJlYW1pbmc7XG5cbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF91aUZlYXR1cmVFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8vIHNldCB0aGUgb3ZlcmxheSBwbGFjZWhvbGRlcnNcbiAgICBjdXJyZW50T3ZlcmxheTogT3ZlcmxheUJhc2UgfCBudWxsO1xuICAgIGRpc2Nvbm5lY3RPdmVybGF5OiBBY3Rpb25PdmVybGF5O1xuICAgIGNvbm5lY3RPdmVybGF5OiBBY3Rpb25PdmVybGF5O1xuICAgIHBsYXlPdmVybGF5OiBBY3Rpb25PdmVybGF5O1xuICAgIGluZm9PdmVybGF5OiBUZXh0T3ZlcmxheTtcbiAgICBlcnJvck92ZXJsYXk6IFRleHRPdmVybGF5O1xuICAgIGFma092ZXJsYXk6IEFGS092ZXJsYXk7XG5cbiAgICBjb250cm9sczogQ29udHJvbHM7XG5cbiAgICBzZXR0aW5nc1BhbmVsOiBTZXR0aW5nc1BhbmVsO1xuICAgIHN0YXRzUGFuZWw6IFN0YXRzUGFuZWw7XG4gICAgdmlkZW9RcEluZGljYXRvcjogVmlkZW9RcEluZGljYXRvcjtcblxuICAgIGNvbmZpZ1VJOiBDb25maWdVSTtcblxuICAgIG9uQ29sb3JNb2RlQ2hhbmdlZDogVUlPcHRpb25zW1wib25Db2xvck1vZGVDaGFuZ2VkXCJdO1xuXG4gICAgcHJvdGVjdGVkIF9vcHRpb25zIDogVUlPcHRpb25zO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBJbml0aWFsaXphdGlvbiBvcHRpb25zXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogVUlPcHRpb25zKSB7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICBcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBvcHRpb25zLnN0cmVhbTtcbiAgICAgICAgdGhpcy5vbkNvbG9yTW9kZUNoYW5nZWQgPSBvcHRpb25zLm9uQ29sb3JNb2RlQ2hhbmdlZDtcbiAgICAgICAgdGhpcy5jb25maWdVSSA9IG5ldyBDb25maWdVSSh0aGlzLnN0cmVhbS5jb25maWcpO1xuXG4gICAgICAgIHRoaXMuY3JlYXRlT3ZlcmxheXMoKTtcblxuICAgICAgICBpZiAoaXNQYW5lbEVuYWJsZWQob3B0aW9ucy5zdGF0c1BhbmVsQ29uZmlnKSkge1xuICAgICAgICAgICAgLy8gQWRkIHN0YXRzIHBhbmVsXG4gICAgICAgICAgICB0aGlzLnN0YXRzUGFuZWwgPSBuZXcgU3RhdHNQYW5lbCgpO1xuICAgICAgICAgICAgdGhpcy51aUZlYXR1cmVzRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnN0YXRzUGFuZWwucm9vdEVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBpZiAoaXNQYW5lbEVuYWJsZWQob3B0aW9ucy5zZXR0aW5nc1BhbmVsQ29uZmlnKSkge1xuICAgICAgICAgICAgLy8gQWRkIHNldHRpbmdzIHBhbmVsXG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzUGFuZWwgPSBuZXcgU2V0dGluZ3NQYW5lbCgpO1xuICAgICAgICAgICAgdGhpcy51aUZlYXR1cmVzRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNldHRpbmdzUGFuZWwucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5jb25maWd1cmVTZXR0aW5ncygpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBpZiAoIW9wdGlvbnMudmlkZW9RcEluZGljYXRvckNvbmZpZyB8fCAhb3B0aW9ucy52aWRlb1FwSW5kaWNhdG9yQ29uZmlnLmRpc2FibGVJbmRpY2F0b3IpIHtcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgdmlkZW8gc3RyZWFtIFFQIGluZGljYXRvclxuICAgICAgICAgICAgdGhpcy52aWRlb1FwSW5kaWNhdG9yID0gbmV3IFZpZGVvUXBJbmRpY2F0b3IoKTtcbiAgICAgICAgICAgIHRoaXMudWlGZWF0dXJlc0VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1FwSW5kaWNhdG9yLnJvb3RFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3JlYXRlQnV0dG9ucygpO1xuXG4gICAgICAgIHRoaXMucmVnaXN0ZXJDYWxsYmFja3MoKTtcblxuICAgICAgICB0aGlzLnNob3dDb25uZWN0T3JBdXRvQ29ubmVjdE92ZXJsYXlzKCk7XG5cbiAgICAgICAgdGhpcy5zZXRDb2xvck1vZGUodGhpcy5jb25maWdVSS5pc0N1c3RvbUZsYWdFbmFibGVkKExpZ2h0TW9kZSkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVPdmVybGF5cygpOiB2b2lkIHtcbiAgICAgICAgLy8gYnVpbGQgYWxsIG9mIHRoZSBvdmVybGF5c1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RPdmVybGF5ID0gbmV3IERpc2Nvbm5lY3RPdmVybGF5KFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9FbGVtZW50UGFyZW50XG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuY29ubmVjdE92ZXJsYXkgPSBuZXcgQ29ubmVjdE92ZXJsYXkoXG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0VsZW1lbnRQYXJlbnRcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5wbGF5T3ZlcmxheSA9IG5ldyBQbGF5T3ZlcmxheShcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRWxlbWVudFBhcmVudFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmluZm9PdmVybGF5ID0gbmV3IEluZm9PdmVybGF5KFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9FbGVtZW50UGFyZW50XG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuZXJyb3JPdmVybGF5ID0gbmV3IEVycm9yT3ZlcmxheShcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRWxlbWVudFBhcmVudFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFma092ZXJsYXkgPSBuZXcgQUZLT3ZlcmxheShcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRWxlbWVudFBhcmVudFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuZGlzY29ubmVjdE92ZXJsYXkub25BY3Rpb24oKCkgPT4gdGhpcy5zdHJlYW0ucmVjb25uZWN0KCkpO1xuXG4gICAgICAgIC8vIEJ1aWxkIHRoZSB3ZWJSdGMgY29ubmVjdCBvdmVybGF5IEV2ZW50IExpc3RlbmVyIGFuZCBzaG93IHRoZSBjb25uZWN0IG92ZXJsYXlcbiAgICAgICAgdGhpcy5jb25uZWN0T3ZlcmxheS5vbkFjdGlvbigoKSA9PiB0aGlzLnN0cmVhbS5jb25uZWN0KCkpO1xuXG4gICAgICAgIC8vIHNldCB1cCB0aGUgcGxheSBvdmVybGF5cyBhY3Rpb25cbiAgICAgICAgdGhpcy5wbGF5T3ZlcmxheS5vbkFjdGlvbigoKSA9PiB0aGlzLnN0cmVhbS5wbGF5KCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB1cCBidXR0b24gY2xpY2sgZnVuY3Rpb25zIGFuZCBidXR0b24gZnVuY3Rpb25hbGl0eVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVCdXR0b25zKCkge1xuICAgICAgICBjb25zdCBjb250cm9sc1VJQ29uZmlnIDogQ29udHJvbHNVSUNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAgICAgICBzdGF0c0J1dHRvblR5cGUgOiAhIXRoaXMuX29wdGlvbnMuc3RhdHNQYW5lbENvbmZpZ1xuICAgICAgICAgICAgICAgID8gdGhpcy5fb3B0aW9ucy5zdGF0c1BhbmVsQ29uZmlnLnZpc2liaWxpdHlCdXR0b25Db25maWdcbiAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHNldHRpbmdzQnV0dG9uVHlwZTogISF0aGlzLl9vcHRpb25zLnNldHRpbmdzUGFuZWxDb25maWdcbiAgICAgICAgICAgICAgICA/IHRoaXMuX29wdGlvbnMuc2V0dGluZ3NQYW5lbENvbmZpZy52aXNpYmlsaXR5QnV0dG9uQ29uZmlnXG4gICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBmdWxsc2NyZWVuQnV0dG9uVHlwZTogdGhpcy5fb3B0aW9ucy5mdWxsU2NyZWVuQ29udHJvbHNDb25maWcsXG4gICAgICAgICAgICB4ckljb25UeXBlOiB0aGlzLl9vcHRpb25zLnhyQ29udHJvbHNDb25maWdcbiAgICAgICAgfVxuICAgICAgICAvLyBTZXR1cCBjb250cm9sc1xuICAgICAgICBjb25zdCBjb250cm9scyA9IG5ldyBDb250cm9scyhjb250cm9sc1VJQ29uZmlnKTtcbiAgICAgICAgdGhpcy51aUZlYXR1cmVzRWxlbWVudC5hcHBlbmRDaGlsZChjb250cm9scy5yb290RWxlbWVudCk7XG5cbiAgICAgICAgLy8gV2hlbiB3ZSBmdWxsc2NyZWVuIHdlIHdhbnQgdGhpcyBlbGVtZW50IHRvIGJlIHRoZSByb290XG4gICAgICAgIGNvbnN0IGZ1bGxTY3JlZW5CdXR0b24gOiBGdWxsU2NyZWVuSWNvbkJhc2UgfCB1bmRlZmluZWQgPSBcbiAgICAgICAgICAgIC8vIERlcGVuZGluZyBvbiBpZiB3ZSdyZSBjcmVhdGluZyBhbiBpbnRlcm5hbCBidXR0b24sIG9yIHVzaW5nIGFuIGV4dGVybmFsIG9uZVxuICAgICAgICAgICAgKCEhdGhpcy5fb3B0aW9ucy5mdWxsU2NyZWVuQ29udHJvbHNDb25maWcgXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5fb3B0aW9ucy5mdWxsU2NyZWVuQ29udHJvbHNDb25maWcuY3JlYXRpb25Nb2RlID09PSBVSUVsZW1lbnRDcmVhdGlvbk1vZGUuVXNlQ3VzdG9tRWxlbWVudClcbiAgICAgICAgICAgIC8vIEVpdGhlciBjcmVhdGUgYSBmdWxsc2NyZWVuIGNsYXNzIGJhc2VkIG9uIHRoZSBleHRlcm5hbCBidXR0b25cbiAgICAgICAgICAgID8gbmV3IEZ1bGxTY3JlZW5JY29uRXh0ZXJuYWwodGhpcy5fb3B0aW9ucy5mdWxsU2NyZWVuQ29udHJvbHNDb25maWcuY3VzdG9tRWxlbWVudClcbiAgICAgICAgICAgIC8vIE9yIHVzZSB0aGUgb25lIGNyZWF0ZWQgYnkgdGhlIENvbnRyb2xzIGluaXRpYWxpemVyIGVhcmxpZXJcbiAgICAgICAgICAgIDogY29udHJvbHMuZnVsbHNjcmVlbkljb247XG4gICAgICAgIGlmIChmdWxsU2NyZWVuQnV0dG9uKSB7XG4gICAgICAgICAgICBmdWxsU2NyZWVuQnV0dG9uLmZ1bGxzY3JlZW5FbGVtZW50ID0gL2lQYWR8aVBob25lfGlQb2QvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgPyB0aGlzLnN0cmVhbS52aWRlb0VsZW1lbnRQYXJlbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJ2aWRlb1wiKVswXSA6IHRoaXMucm9vdEVsZW1lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgc2V0dGluZ3MgYnV0dG9uIHRvIGNvbnRyb2xzXG4gICAgICAgIGNvbnN0IHNldHRpbmdzQnV0dG9uIDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQgPSBcbiAgICAgICAgICAgICEhY29udHJvbHMuc2V0dGluZ3NJY29uID8gY29udHJvbHMuc2V0dGluZ3NJY29uLnJvb3RFbGVtZW50IDogXG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnNldHRpbmdzUGFuZWxDb25maWcudmlzaWJpbGl0eUJ1dHRvbkNvbmZpZy5jdXN0b21FbGVtZW50O1xuICAgICAgICBpZiAoISFzZXR0aW5nc0J1dHRvbikgc2V0dGluZ3NCdXR0b24ub25jbGljayA9ICgpID0+XG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzQ2xpY2tlZCgpO1xuICAgICAgICBpZiAoISF0aGlzLnNldHRpbmdzUGFuZWwpIHRoaXMuc2V0dGluZ3NQYW5lbC5zZXR0aW5nc0Nsb3NlQnV0dG9uLm9uY2xpY2sgPSAoKSA9PlxuICAgICAgICAgICAgdGhpcy5zZXR0aW5nc0NsaWNrZWQoKTtcblxuICAgICAgICAvLyBBZGQgV2ViWFIgYnV0dG9uIHRvIGNvbnRyb2xzXG4gICAgICAgIGNvbnN0IHhyQnV0dG9uIDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQgPSBcbiAgICAgICAgICAgICEhY29udHJvbHMueHJJY29uID8gY29udHJvbHMueHJJY29uLnJvb3RFbGVtZW50IDogXG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnhyQ29udHJvbHNDb25maWcuY3JlYXRpb25Nb2RlID09PSBVSUVsZW1lbnRDcmVhdGlvbk1vZGUuVXNlQ3VzdG9tRWxlbWVudCA/XG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnhyQ29udHJvbHNDb25maWcuY3VzdG9tRWxlbWVudCA6IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCEheHJCdXR0b24pIHhyQnV0dG9uLm9uY2xpY2sgPSAoKSA9PlxuICAgICAgICAgICAgdGhpcy5zdHJlYW0udG9nZ2xlWFIoKTtcblxuICAgICAgICAvLyBzZXR1cCB0aGUgc3RhdHMvaW5mbyBidXR0b25cbiAgICAgICAgY29uc3Qgc3RhdHNCdXR0b24gOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCA9IFxuICAgICAgICAgICAgISFjb250cm9scy5zdGF0c0ljb24gPyBjb250cm9scy5zdGF0c0ljb24ucm9vdEVsZW1lbnQgOiBcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuc3RhdHNQYW5lbENvbmZpZy52aXNpYmlsaXR5QnV0dG9uQ29uZmlnLmN1c3RvbUVsZW1lbnQ7XG4gICAgICAgIGlmICghIXN0YXRzQnV0dG9uKSBzdGF0c0J1dHRvbi5vbmNsaWNrID0gKCkgPT4gdGhpcy5zdGF0c0NsaWNrZWQoKVxuXG4gICAgICAgIGlmICghIXRoaXMuc3RhdHNQYW5lbCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0c1BhbmVsLnN0YXRzQ2xvc2VCdXR0b24ub25jbGljayA9ICgpID0+IHRoaXMuc3RhdHNDbGlja2VkKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY29tbWFuZCBidXR0b25zIChpZiB3ZSBoYXZlIHNvbWV3aGVyZSB0byBhZGQgdGhlbSB0bylcbiAgICAgICAgaWYgKCEhdGhpcy5zZXR0aW5nc1BhbmVsKSB7XG4gICAgICAgICAgICAvLyBBZGQgYnV0dG9uIGZvciB0b2dnbGUgZnBzXG4gICAgICAgICAgICBjb25zdCBzaG93RlBTQnV0dG9uID0gbmV3IExhYmVsbGVkQnV0dG9uKCdTaG93IEZQUycsICdUb2dnbGUnKTtcbiAgICAgICAgICAgIHNob3dGUFNCdXR0b24uYWRkT25DbGlja0xpc3RlbmVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5yZXF1ZXN0U2hvd0ZwcygpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEFkZCBidXR0b24gZm9yIHJlc3RhcnQgc3RyZWFtXG4gICAgICAgICAgICBjb25zdCByZXN0YXJ0U3RyZWFtQnV0dG9uID0gbmV3IExhYmVsbGVkQnV0dG9uKFxuICAgICAgICAgICAgICAgICdSZXN0YXJ0IFN0cmVhbScsXG4gICAgICAgICAgICAgICAgJ1Jlc3RhcnQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmVzdGFydFN0cmVhbUJ1dHRvbi5hZGRPbkNsaWNrTGlzdGVuZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnJlY29ubmVjdCgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEFkZCBidXR0b24gZm9yIHJlcXVlc3Qga2V5ZnJhbWVcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3RLZXlmcmFtZUJ1dHRvbiA9IG5ldyBMYWJlbGxlZEJ1dHRvbihcbiAgICAgICAgICAgICAgICAnUmVxdWVzdCBrZXlmcmFtZScsXG4gICAgICAgICAgICAgICAgJ1JlcXVlc3QnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmVxdWVzdEtleWZyYW1lQnV0dG9uLmFkZE9uQ2xpY2tMaXN0ZW5lcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ucmVxdWVzdElmcmFtZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbW1hbmRzU2VjdGlvbkVsZW0gPSB0aGlzLmNvbmZpZ1VJLmJ1aWxkU2VjdGlvbldpdGhIZWFkaW5nKFxuICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3NQYW5lbC5zZXR0aW5nc0NvbnRlbnRFbGVtZW50LFxuICAgICAgICAgICAgICAgICdDb21tYW5kcydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb21tYW5kc1NlY3Rpb25FbGVtLmFwcGVuZENoaWxkKHNob3dGUFNCdXR0b24ucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgY29tbWFuZHNTZWN0aW9uRWxlbS5hcHBlbmRDaGlsZChyZXF1ZXN0S2V5ZnJhbWVCdXR0b24ucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgY29tbWFuZHNTZWN0aW9uRWxlbS5hcHBlbmRDaGlsZChyZXN0YXJ0U3RyZWFtQnV0dG9uLnJvb3RFbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbmZpZ3VyZSB0aGUgc2V0dGluZ3Mgd2l0aCBvbiBjaGFuZ2UgbGlzdGVuZXJzIGFuZCBhbnkgYWRkaXRpb25hbCBwZXIgZXhwZXJpZW5jZSBzZXR0aW5ncy5cbiAgICAgKi9cbiAgICBjb25maWd1cmVTZXR0aW5ncygpOiB2b2lkIHtcbiAgICAgICAgLy8gVGhpcyBidWlsZHMgYWxsIHRoZSBzZXR0aW5ncyBzZWN0aW9ucyBhbmQgZmxhZ3MgdW5kZXIgdGhpcyBgc2V0dGluZ3NDb250ZW50YCBlbGVtZW50LlxuICAgICAgICB0aGlzLmNvbmZpZ1VJLnBvcHVsYXRlU2V0dGluZ3NFbGVtZW50KFxuICAgICAgICAgICAgdGhpcy5zZXR0aW5nc1BhbmVsLnNldHRpbmdzQ29udGVudEVsZW1lbnRcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmNvbmZpZ1VJLmFkZEN1c3RvbUZsYWdPblNldHRpbmdDaGFuZ2VkTGlzdGVuZXIoXG4gICAgICAgICAgICBMaWdodE1vZGUsXG4gICAgICAgICAgICAoaXNMaWdodE1vZGU6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1VJLnNldEN1c3RvbUZsYWdMYWJlbChcbiAgICAgICAgICAgICAgICAgICAgTGlnaHRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBgQ29sb3IgU2NoZW1lOiAke2lzTGlnaHRNb2RlID8gJ0xpZ2h0JyA6ICdEYXJrJ30gTW9kZWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q29sb3JNb2RlKGlzTGlnaHRNb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZWdpc3RlckNhbGxiYWNrcygpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdhZmtXYXJuaW5nQWN0aXZhdGUnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBjb3VudERvd24sIGRpc21pc3NBZmsgfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Fma092ZXJsYXkoY291bnREb3duLCBkaXNtaXNzQWZrKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2Fma1dhcm5pbmdVcGRhdGUnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBjb3VudERvd24gfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuYWZrT3ZlcmxheS51cGRhdGVDb3VudGRvd24oY291bnREb3duKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2Fma1dhcm5pbmdEZWFjdGl2YXRlJyxcbiAgICAgICAgICAgICgpID0+IHRoaXMuYWZrT3ZlcmxheS5oaWRlKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWZrVGltZWRPdXQnLCAoKSA9PlxuICAgICAgICAgICAgdGhpcy5hZmtPdmVybGF5LmhpZGUoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3ZpZGVvRW5jb2RlckF2Z1FQJyxcbiAgICAgICAgICAgICh7IGRhdGE6IHsgYXZnUVAgfSB9KSA9PiB0aGlzLm9uVmlkZW9FbmNvZGVyQXZnUVAoYXZnUVApXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYlJ0Y1NkcCcsICgpID0+XG4gICAgICAgICAgICB0aGlzLm9uV2ViUnRjU2RwKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignd2ViUnRjQXV0b0Nvbm5lY3QnLCAoKSA9PlxuICAgICAgICAgICAgdGhpcy5vbldlYlJ0Y0F1dG9Db25uZWN0KClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignd2ViUnRjQ29ubmVjdGluZycsICgpID0+XG4gICAgICAgICAgICB0aGlzLm9uV2ViUnRjQ29ubmVjdGluZygpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYlJ0Y0Nvbm5lY3RlZCcsICgpID0+XG4gICAgICAgICAgICB0aGlzLm9uV2ViUnRjQ29ubmVjdGVkKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignd2ViUnRjRmFpbGVkJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMub25XZWJSdGNGYWlsZWQoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3dlYlJ0Y0Rpc2Nvbm5lY3RlZCcsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IGV2ZW50U3RyaW5nLCBhbGxvd0NsaWNrVG9SZWNvbm5lY3QgfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMub25EaXNjb25uZWN0KGV2ZW50U3RyaW5nLCBhbGxvd0NsaWNrVG9SZWNvbm5lY3QpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ3ZpZGVvSW5pdGlhbGl6ZWQnLCAoKSA9PlxuICAgICAgICAgICAgdGhpcy5vblZpZGVvSW5pdGlhbGl6ZWQoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdzdHJlYW1Mb2FkaW5nJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMub25TdHJlYW1Mb2FkaW5nKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdwbGF5U3RyZWFtRXJyb3InLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBtZXNzYWdlIH0gfSkgPT4gdGhpcy5vblBsYXlTdHJlYW1FcnJvcihtZXNzYWdlKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdwbGF5U3RyZWFtJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMub25QbGF5U3RyZWFtKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdwbGF5U3RyZWFtUmVqZWN0ZWQnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyByZWFzb24gfSB9KSA9PiB0aGlzLm9uUGxheVN0cmVhbVJlamVjdGVkKHJlYXNvbilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdsb2FkRnJlZXplRnJhbWUnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBzaG91bGRTaG93UGxheU92ZXJsYXkgfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMub25Mb2FkRnJlZXplRnJhbWUoc2hvdWxkU2hvd1BsYXlPdmVybGF5KVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3N0YXRzUmVjZWl2ZWQnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBhZ2dyZWdhdGVkU3RhdHMgfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMub25TdGF0c1JlY2VpdmVkKGFnZ3JlZ2F0ZWRTdGF0cylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdsYXRlbmN5VGVzdFJlc3VsdCcsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IGxhdGVuY3lUaW1pbmdzIH0gfSkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLm9uTGF0ZW5jeVRlc3RSZXN1bHRzKGxhdGVuY3lUaW1pbmdzKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2RhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHQnLFxuICAgICAgICAgICAgKHtkYXRhOiB7IHJlc3VsdCB9IH0pID0+XG4gICAgICAgICAgICAgICAgdGhpcy5vbkRhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHRzKHJlc3VsdClcbiAgICAgICAgKVxuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3N0cmVhbWVyTGlzdE1lc3NhZ2UnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBtZXNzYWdlU3RyZWFtZXJMaXN0LCBhdXRvU2VsZWN0ZWRTdHJlYW1lcklkLCB3YW50ZWRTdHJlYW1lcklkIH0gfSkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZVN0cmVhbWVyTGlzdE1lc3NhZ2UobWVzc2FnZVN0cmVhbWVyTGlzdCwgYXV0b1NlbGVjdGVkU3RyZWFtZXJJZCwgd2FudGVkU3RyZWFtZXJJZClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdzZXR0aW5nc0NoYW5nZWQnLFxuICAgICAgICAgICAgKGV2ZW50KSA9PiB0aGlzLmNvbmZpZ1VJLm9uU2V0dGluZ3NDaGFuZ2VkKGV2ZW50KVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3BsYXllckNvdW50JywgXG4gICAgICAgICAgICAoeyBkYXRhOiB7IGNvdW50IH19KSA9PiBcbiAgICAgICAgICAgICAgICB0aGlzLm9uUGxheWVyQ291bnQoY291bnQpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcm9vdEVsZW1lbnQgb2YgdGhlIGFwcGxpY2F0aW9uLCB2aWRlbyBzdHJlYW0gYW5kIGFsbCBVSSBhcmUgY2hpbGRyZW4gb2YgdGhpcyBlbGVtZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSAncGxheWVyVUknO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnbm9zZWxlY3QnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKFxuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRWxlbWVudFBhcmVudFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudWlGZWF0dXJlc0VsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBlbGVtZW50IHRoYXQgY29udGFpbnMgYWxsIHRoZSBVSSBmZWF0dXJlcywgbGlrZSB0aGUgc3RhdHMgYW5kIHNldHRpbmdzIHBhbmVscy5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHVpRmVhdHVyZXNFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl91aUZlYXR1cmVFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl91aUZlYXR1cmVFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl91aUZlYXR1cmVFbGVtZW50LmlkID0gJ3VpRmVhdHVyZXMnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl91aUZlYXR1cmVFbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBkaXNjb25uZWN0IG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gdXBkYXRlVGV4dCAtIHRoZSB0ZXh0IHRoYXQgd2lsbCBiZSBkaXNwbGF5ZWQgaW4gdGhlIG92ZXJsYXlcbiAgICAgKi9cbiAgICBzaG93RGlzY29ubmVjdE92ZXJsYXkodXBkYXRlVGV4dDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuaGlkZUN1cnJlbnRPdmVybGF5KCk7XG4gICAgICAgIHRoaXMudXBkYXRlRGlzY29ubmVjdE92ZXJsYXkodXBkYXRlVGV4dCk7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdE92ZXJsYXkuc2hvdygpO1xuICAgICAgICB0aGlzLmN1cnJlbnRPdmVybGF5ID0gdGhpcy5kaXNjb25uZWN0T3ZlcmxheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGRpc2Nvbm5lY3Qgb3ZlcmxheXMgc3BhbiB0ZXh0XG4gICAgICogQHBhcmFtIHVwZGF0ZVRleHQgLSB0aGUgbmV3IGNvdW50ZG93biBudW1iZXJcbiAgICAgKi9cbiAgICB1cGRhdGVEaXNjb25uZWN0T3ZlcmxheSh1cGRhdGVUZXh0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0T3ZlcmxheS51cGRhdGUodXBkYXRlVGV4dCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWN0aXZhdGVzIHRoZSBkaXNjb25uZWN0IG92ZXJsYXlzIGFjdGlvblxuICAgICAqL1xuICAgIG9uRGlzY29ubmVjdGlvbkFjdGlvbigpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0T3ZlcmxheS5hY3RpdmF0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhpZGVzIHRoZSBjdXJyZW50IG92ZXJsYXlcbiAgICAgKi9cbiAgICBoaWRlQ3VycmVudE92ZXJsYXkoKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRPdmVybGF5ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudE92ZXJsYXkuaGlkZSgpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50T3ZlcmxheSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgY29ubmVjdCBvdmVybGF5XG4gICAgICovXG4gICAgc2hvd0Nvbm5lY3RPdmVybGF5KCkge1xuICAgICAgICB0aGlzLmhpZGVDdXJyZW50T3ZlcmxheSgpO1xuICAgICAgICB0aGlzLmNvbm5lY3RPdmVybGF5LnNob3coKTtcbiAgICAgICAgdGhpcy5jdXJyZW50T3ZlcmxheSA9IHRoaXMuY29ubmVjdE92ZXJsYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIHBsYXkgb3ZlcmxheVxuICAgICAqL1xuICAgIHNob3dQbGF5T3ZlcmxheSgpIHtcbiAgICAgICAgdGhpcy5oaWRlQ3VycmVudE92ZXJsYXkoKTtcbiAgICAgICAgdGhpcy5wbGF5T3ZlcmxheS5zaG93KCk7XG4gICAgICAgIHRoaXMuY3VycmVudE92ZXJsYXkgPSB0aGlzLnBsYXlPdmVybGF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSB0ZXh0IG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gdGV4dCAtIHRoZSB0ZXh0IHRoYXQgd2lsbCBiZSBzaG93biBpbiB0aGUgb3ZlcmxheVxuICAgICAqL1xuICAgIHNob3dUZXh0T3ZlcmxheSh0ZXh0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5oaWRlQ3VycmVudE92ZXJsYXkoKTtcbiAgICAgICAgdGhpcy5pbmZvT3ZlcmxheS51cGRhdGUodGV4dCk7XG4gICAgICAgIHRoaXMuaW5mb092ZXJsYXkuc2hvdygpO1xuICAgICAgICB0aGlzLmN1cnJlbnRPdmVybGF5ID0gdGhpcy5pbmZvT3ZlcmxheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgZXJyb3Igb3ZlcmxheVxuICAgICAqIEBwYXJhbSB0ZXh0IC0gdGhlIHRleHQgdGhhdCB3aWxsIGJlIHNob3duIGluIHRoZSBvdmVybGF5XG4gICAgICovXG4gICAgc2hvd0Vycm9yT3ZlcmxheSh0ZXh0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5oaWRlQ3VycmVudE92ZXJsYXkoKTtcbiAgICAgICAgdGhpcy5lcnJvck92ZXJsYXkudXBkYXRlKHRleHQpO1xuICAgICAgICB0aGlzLmVycm9yT3ZlcmxheS5zaG93KCk7XG4gICAgICAgIHRoaXMuY3VycmVudE92ZXJsYXkgPSB0aGlzLmVycm9yT3ZlcmxheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyBvciBoaWRlcyB0aGUgc2V0dGluZ3MgcGFuZWwgaWYgY2xpY2tlZFxuICAgICAqL1xuICAgIHNldHRpbmdzQ2xpY2tlZCgpIHtcbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5oaWRlKCk7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NQYW5lbC50b2dnbGVWaXNpYmlsaXR5KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvd3Mgb3IgaGlkZXMgdGhlIHN0YXRzIHBhbmVsIGlmIGNsaWNrZWRcbiAgICAgKi9cbiAgICBzdGF0c0NsaWNrZWQoKSB7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NQYW5lbD8uaGlkZSgpO1xuICAgICAgICB0aGlzLnN0YXRzUGFuZWwudG9nZ2xlVmlzaWJpbGl0eSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjdGl2YXRlcyB0aGUgY29ubmVjdCBvdmVybGF5cyBhY3Rpb25cbiAgICAgKi9cbiAgICBvbkNvbm5lY3RBY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuY29ubmVjdE92ZXJsYXkuYWN0aXZhdGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3RpdmF0ZXMgdGhlIHBsYXkgb3ZlcmxheXMgYWN0aW9uXG4gICAgICovXG4gICAgb25QbGF5QWN0aW9uKCkge1xuICAgICAgICB0aGlzLnBsYXlPdmVybGF5LmFjdGl2YXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIGFmayBvdmVybGF5XG4gICAgICogQHBhcmFtIGNvdW50RG93biAtIHRoZSBjb3VudGRvd24gbnVtYmVyIGZvciB0aGUgYWZrIGNvdW50ZG93blxuICAgICAqL1xuICAgIHNob3dBZmtPdmVybGF5KGNvdW50RG93bjogbnVtYmVyLCBkaXNtaXNzQWZrOiAoKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMuaGlkZUN1cnJlbnRPdmVybGF5KCk7XG4gICAgICAgIHRoaXMuYWZrT3ZlcmxheS51cGRhdGVDb3VudGRvd24oY291bnREb3duKTtcbiAgICAgICAgdGhpcy5hZmtPdmVybGF5Lm9uQWN0aW9uKCgpID0+IGRpc21pc3NBZmsoKSk7XG4gICAgICAgIHRoaXMuYWZrT3ZlcmxheS5zaG93KCk7XG4gICAgICAgIHRoaXMuY3VycmVudE92ZXJsYXkgPSB0aGlzLmFma092ZXJsYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyB0aGUgQ29ubmVjdCBPdmVybGF5IG9yIGF1dG8gY29ubmVjdFxuICAgICAqL1xuICAgIHNob3dDb25uZWN0T3JBdXRvQ29ubmVjdE92ZXJsYXlzKCkge1xuICAgICAgICAvLyBzZXQgdXAgaWYgdGhlIGF1dG8gcGxheSB3aWxsIGJlIHVzZWQgb3IgcmVndWxhciBjbGljayB0byBzdGFydFxuICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmNvbmZpZy5pc0ZsYWdFbmFibGVkKEZsYWdzLkF1dG9Db25uZWN0KSkge1xuICAgICAgICAgICAgdGhpcy5zaG93Q29ubmVjdE92ZXJsYXkoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgdGhlIHdlYlJ0Y0F1dG9Db25uZWN0IE92ZXJsYXkgYW5kIGNvbm5lY3RcbiAgICAgKi9cbiAgICBvbldlYlJ0Y0F1dG9Db25uZWN0KCkge1xuICAgICAgICB0aGlzLnNob3dUZXh0T3ZlcmxheSgnQXV0byBDb25uZWN0aW5nIE5vdycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB1cCBmdW5jdGlvbmFsaXR5IHRvIGhhcHBlbiB3aGVuIHJlY2VpdmluZyBhIHdlYlJUQyBhbnN3ZXJcbiAgICAgKi9cbiAgICBvbldlYlJ0Y1NkcCgpIHtcbiAgICAgICAgdGhpcy5zaG93VGV4dE92ZXJsYXkoJ1dlYlJUQyBDb25uZWN0aW9uIE5lZ290aWF0ZWQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyBhIHRleHQgb3ZlcmxheSB0byBhbGVydCB0aGUgdXNlciB0aGUgc3RyZWFtIGlzIGN1cnJlbnRseSBsb2FkaW5nXG4gICAgICovXG4gICAgb25TdHJlYW1Mb2FkaW5nKCkge1xuICAgICAgICAvLyBidWlsZCB0aGUgc3Bpbm5lciBzcGFuXG4gICAgICAgIGNvbnN0IHNwaW5uZXJTcGFuOiBIVE1MU3BhbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICAgIHNwaW5uZXJTcGFuLmNsYXNzTmFtZSA9ICd2aXN1YWxseS1oaWRkZW4nO1xuICAgICAgICBzcGlubmVyU3Bhbi5pbm5lckhUTUwgPSAnTG9hZGluZy4uLic7XG5cbiAgICAgICAgLy8gYnVpbGQgdGhlIHNwaW5uZXIgZGl2XG4gICAgICAgIGNvbnN0IHNwaW5uZXJEaXY6IEhUTUxEaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHNwaW5uZXJEaXYuaWQgPSAnbG9hZGluZy1zcGlubmVyJztcbiAgICAgICAgc3Bpbm5lckRpdi5jbGFzc05hbWUgPSAnc3Bpbm5lci1ib3JkZXIgbXMtMic7XG4gICAgICAgIHNwaW5uZXJEaXYuc2V0QXR0cmlidXRlKCdyb2xlJywgJ3N0YXR1cycpO1xuXG4gICAgICAgIC8vIGFwcGVuZCB0aGUgc3Bpbm5lciB0byB0aGUgZWxlbWVudFxuICAgICAgICBzcGlubmVyRGl2LmFwcGVuZENoaWxkKHNwaW5uZXJTcGFuKTtcblxuICAgICAgICB0aGlzLnNob3dUZXh0T3ZlcmxheSgnTG9hZGluZyBTdHJlYW0gJyArIHNwaW5uZXJEaXYub3V0ZXJIVE1MKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFdmVudCBmaXJlZCB3aGVuIHRoZSB2aWRlbyBpcyBkaXNjb25uZWN0ZWQgLSBkaXNwbGF5cyB0aGUgZXJyb3Igb3ZlcmxheSBhbmQgcmVzZXRzIHRoZSBidXR0b25zIHN0cmVhbSB0b29scyB1cG9uIGRpc2Nvbm5lY3RcbiAgICAgKiBAcGFyYW0gZXZlbnRTdHJpbmcgLSB0aGUgZXZlbnQgdGV4dCB0aGF0IHdpbGwgYmUgc2hvd24gaW4gdGhlIG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gYWxsb3dDbGlja1RvUmVjb25uZWN0IC0gdHJ1ZSBpZiB3ZSB3YW50IHRvIGFsbG93IHRoZSB1c2VyIHRvIGNsaWNrIHRvIHJlY29ubmVjdC4gT3RoZXJ3aXNlIGl0J3MganVzdCBhIG1lc3NhZ2UuXG4gICAgICovXG4gICAgb25EaXNjb25uZWN0KGV2ZW50U3RyaW5nOiBzdHJpbmcsIGFsbG93Q2xpY2tUb1JlY29ubmVjdDogYm9vbGVhbikge1xuICAgICAgICBjb25zdCBvdmVybGF5TWVzc2FnZSA9ICdEaXNjb25uZWN0ZWQnICsgKGV2ZW50U3RyaW5nID8gYDogJHtldmVudFN0cmluZ31gIDogJycpO1xuICAgICAgICBpZiAoYWxsb3dDbGlja1RvUmVjb25uZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnNob3dEaXNjb25uZWN0T3ZlcmxheShgJHtvdmVybGF5TWVzc2FnZX0gQ2xpY2sgVG8gUmVzdGFydC5gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0Vycm9yT3ZlcmxheShvdmVybGF5TWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZGlzYWJsZSBzdGFydGluZyBhIGxhdGVuY3kgY2hlY2tzXG4gICAgICAgIHRoaXMuc3RhdHNQYW5lbD8ub25EaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB3aGVuIFdlYiBSdGMgaXMgY29ubmVjdGluZ1xuICAgICAqL1xuICAgIG9uV2ViUnRjQ29ubmVjdGluZygpIHtcbiAgICAgICAgdGhpcy5zaG93VGV4dE92ZXJsYXkoJ1N0YXJ0aW5nIGNvbm5lY3Rpb24gdG8gc2VydmVyLCBwbGVhc2Ugd2FpdCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgd2hlbiBXZWIgUnRjIGhhcyBjb25uZWN0ZWRcbiAgICAgKi9cbiAgICBvbldlYlJ0Y0Nvbm5lY3RlZCgpIHtcbiAgICAgICAgdGhpcy5zaG93VGV4dE92ZXJsYXkoJ1dlYlJUQyBjb25uZWN0ZWQsIHdhaXRpbmcgZm9yIHZpZGVvJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB3aGVuIFdlYiBSdGMgZmFpbHMgdG8gY29ubmVjdFxuICAgICAqL1xuICAgIG9uV2ViUnRjRmFpbGVkKCkge1xuICAgICAgICB0aGlzLnNob3dFcnJvck92ZXJsYXkoJ1VuYWJsZSB0byBzZXR1cCB2aWRlbycpO1xuICAgIH1cblxuICAgIG9uTG9hZEZyZWV6ZUZyYW1lKHNob3VsZFNob3dQbGF5T3ZlcmxheTogYm9vbGVhbikge1xuICAgICAgICBpZiAoc2hvdWxkU2hvd1BsYXlPdmVybGF5ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBMb2dnZXIuTG9nKExvZ2dlci5HZXRTdGFja1RyYWNlKCksICdzaG93aW5nIHBsYXkgb3ZlcmxheScpO1xuICAgICAgICAgICAgdGhpcy5zaG93UGxheU92ZXJsYXkoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uUGxheVN0cmVhbSgpIHtcbiAgICAgICAgdGhpcy5oaWRlQ3VycmVudE92ZXJsYXkoKTtcbiAgICB9XG5cbiAgICBvblBsYXlTdHJlYW1FcnJvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zaG93RXJyb3JPdmVybGF5KG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIG9uUGxheVN0cmVhbVJlamVjdGVkKG9uUmVqZWN0ZWRSZWFzb246IHVua25vd24pIHtcbiAgICAgICAgdGhpcy5zaG93UGxheU92ZXJsYXkoKTtcbiAgICB9XG5cbiAgICBvblZpZGVvSW5pdGlhbGl6ZWQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uY29uZmlnLmlzRmxhZ0VuYWJsZWQoRmxhZ3MuQXV0b1BsYXlWaWRlbykpIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd1BsYXlPdmVybGF5KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5vblZpZGVvSW5pdGlhbGl6ZWQodGhpcy5zdHJlYW0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB1cCBmdW5jdGlvbmFsaXR5IHRvIGhhcHBlbiB3aGVuIGNhbGN1bGF0aW5nIHRoZSBhdmVyYWdlIHZpZGVvIGVuY29kZXIgcXBcbiAgICAgKiBAcGFyYW0gUVAgLSB0aGUgcXVhbGl0eSBudW1iZXIgb2YgdGhlIHN0cmVhbVxuICAgICAqL1xuICAgIG9uVmlkZW9FbmNvZGVyQXZnUVAoUVA6IG51bWJlcikge1xuICAgICAgICAvLyBVcGRhdGUgaW50ZXJuYWwgUVAgaW5kaWNhdG9yIGlmIG9uZSBpcyBwcmVzZW50XG4gICAgICAgIGlmICghIXRoaXMudmlkZW9RcEluZGljYXRvcikge1xuICAgICAgICAgICAgdGhpcy52aWRlb1FwSW5kaWNhdG9yLnVwZGF0ZVFwVG9vbHRpcChRUCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkluaXRpYWxTZXR0aW5ncyhzZXR0aW5nczogSW5pdGlhbFNldHRpbmdzKSB7XG4gICAgICAgIGlmIChzZXR0aW5ncy5QaXhlbFN0cmVhbWluZ1NldHRpbmdzKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRzUGFuZWw/LmNvbmZpZ3VyZShzZXR0aW5ncy5QaXhlbFN0cmVhbWluZ1NldHRpbmdzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uU3RhdHNSZWNlaXZlZChhZ2dyZWdhdGVkU3RhdHM6IEFnZ3JlZ2F0ZWRTdGF0cykge1xuICAgICAgICAvLyBHcmFiIGFsbCBzdGF0cyB3ZSBjYW4gb2ZmIHRoZSBhZ2dyZWdhdGVkIHN0YXRzXG4gICAgICAgIHRoaXMuc3RhdHNQYW5lbD8uaGFuZGxlU3RhdHMoYWdncmVnYXRlZFN0YXRzKTtcbiAgICB9XG5cbiAgICBvbkxhdGVuY3lUZXN0UmVzdWx0cyhsYXRlbmN5VGltaW5nczogTGF0ZW5jeVRlc3RSZXN1bHRzKSB7XG4gICAgICAgIHRoaXMuc3RhdHNQYW5lbD8ubGF0ZW5jeVRlc3QuaGFuZGxlVGVzdFJlc3VsdChsYXRlbmN5VGltaW5ncyk7XG4gICAgfVxuXG4gICAgb25EYXRhQ2hhbm5lbExhdGVuY3lUZXN0UmVzdWx0cyhyZXN1bHQ6IERhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHQpIHtcbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5kYXRhQ2hhbm5lbExhdGVuY3lUZXN0LmhhbmRsZVRlc3RSZXN1bHQocmVzdWx0KTtcbiAgICB9XG5cbiAgICBvblBsYXllckNvdW50KHBsYXllckNvdW50OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5oYW5kbGVQbGF5ZXJDb3VudChwbGF5ZXJDb3VudCk7XG4gICAgfVxuXG4gICAgaGFuZGxlU3RyZWFtZXJMaXN0TWVzc2FnZShtZXNzYWdlU3RyZWFtaW5nTGlzdDogTWVzc2FnZVN0cmVhbWVyTGlzdCwgYXV0b1NlbGVjdGVkU3RyZWFtZXJJZDogc3RyaW5nLCB3YW50ZWRTdHJlYW1lcklkOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgd2FpdEZvclN0cmVhbWVyID0gdGhpcy5zdHJlYW0uY29uZmlnLmlzRmxhZ0VuYWJsZWQoRmxhZ3MuV2FpdEZvclN0cmVhbWVyKTtcbiAgICAgICAgY29uc3QgaXNSZWNvbm5lY3RpbmcgPSB0aGlzLnN0cmVhbS5pc1JlY29ubmVjdGluZygpO1xuICAgICAgICBsZXQgbWVzc2FnZTogc3RyaW5nID0gbnVsbDtcbiAgICAgICAgbGV0IGFsbG93UmVzdGFydDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAgICAgaWYgKCFhdXRvU2VsZWN0ZWRTdHJlYW1lcklkKSB7XG4gICAgICAgICAgICBpZiAod2FpdEZvclN0cmVhbWVyICYmIHdhbnRlZFN0cmVhbWVySWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNSZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBXYWl0aW5nIGZvciAke3dhbnRlZFN0cmVhbWVySWR9IHRvIGJlY29tZSBhdmFpbGFibGUuYDtcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dSZXN0YXJ0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBHYXZlIHVwIHdhaXRpbmcgZm9yICR7d2FudGVkU3RyZWFtZXJJZH0gdG8gYmVjb21lIGF2YWlsYWJsZS4gQ2xpY2sgdG8gdHJ5IGFnYWluYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VTdHJlYW1pbmdMaXN0Lmlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlICs9IGAgb3Igc2VsZWN0IGEgc3RyZWFtZXIgZnJvbSB0aGUgc2V0dGluZ3MgbWVudS5gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFsbG93UmVzdGFydCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlU3RyZWFtaW5nTGlzdC5pZHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNSZWNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBXYWl0aW5nIGZvciBhIHN0cmVhbWVyIHRvIGJlY29tZSBhdmFpbGFibGUuYDtcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dSZXN0YXJ0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBObyBzdHJlYW1lcnMgYXZhaWxhYmxlLiBDbGljayB0byB0cnkgYWdhaW4uYDtcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dSZXN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgTXVsdGlwbGUgc3RyZWFtZXJzIGF2YWlsYWJsZS4gU2VsZWN0IG9uZSBmcm9tIHRoZSBzZXR0aW5ncyBtZW51LmA7XG4gICAgICAgICAgICAgICAgYWxsb3dSZXN0YXJ0ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhbGxvd1Jlc3RhcnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dEaXNjb25uZWN0T3ZlcmxheShtZXNzYWdlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93VGV4dE92ZXJsYXkobWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgbGlnaHQvZGFyayBjb2xvciBtb2RlXG4gICAgICogQHBhcmFtIGlzTGlnaHRNb2RlIC0gc2hvdWxkIHdlIHVzZSBhIGxpZ2h0IG9yIGRhcmsgY29sb3Igc2NoZW1lXG4gICAgICovXG4gICAgc2V0Q29sb3JNb2RlKGlzTGlnaHRNb2RlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh0aGlzLm9uQ29sb3JNb2RlQ2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy5vbkNvbG9yTW9kZUNoYW5nZWQoaXNMaWdodE1vZGUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHtcbiAgICBDb25maWcsXG4gICAgRmxhZ3NJZHMsXG4gICAgTnVtZXJpY1BhcmFtZXRlcnNJZHMsXG4gICAgT3B0aW9uUGFyYW1ldGVyc0lkcyxcbiAgICBUZXh0UGFyYW1ldGVyc0lkcyxcbiAgICBUZXh0UGFyYW1ldGVycyxcbiAgICBPcHRpb25QYXJhbWV0ZXJzLFxuICAgIEZsYWdzLFxuICAgIE51bWVyaWNQYXJhbWV0ZXJzLFxuICAgIFNldHRpbmdzQ2hhbmdlZEV2ZW50LFxuICAgIFNldHRpbmdGbGFnLFxuICAgIFNldHRpbmdOdW1iZXIsXG4gICAgU2V0dGluZ1RleHQsXG4gICAgU2V0dGluZ09wdGlvbixcbiAgICBMb2dnZXIsXG4gICAgU2V0dGluZ0Jhc2Vcbn0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBTZXR0aW5nVUlGbGFnIH0gZnJvbSAnLi9TZXR0aW5nVUlGbGFnJztcbmltcG9ydCB7IFNldHRpbmdVSU51bWJlciB9IGZyb20gJy4vU2V0dGluZ1VJTnVtYmVyJztcbmltcG9ydCB7IFNldHRpbmdVSVRleHQgfSBmcm9tICcuL1NldHRpbmdVSVRleHQnO1xuaW1wb3J0IHsgU2V0dGluZ1VJT3B0aW9uIH0gZnJvbSAnLi9TZXR0aW5nVUlPcHRpb24nO1xuXG5leHBvcnQgY29uc3QgTGlnaHRNb2RlID0gJ0xpZ2h0TW9kZScgYXMgY29uc3Q7XG50eXBlIEV4dHJhRmxhZ3MgPSB0eXBlb2YgTGlnaHRNb2RlO1xuZXhwb3J0IHR5cGUgRmxhZ3NJZHNFeHRlbmRlZCA9IEZsYWdzSWRzIHwgRXh0cmFGbGFncztcblxuZXhwb3J0IGNsYXNzIENvbmZpZ1VJIHtcbiAgICBwcml2YXRlIGN1c3RvbUZsYWdzID0gbmV3IE1hcDxcbiAgICAgICAgRmxhZ3NJZHNFeHRlbmRlZCxcbiAgICAgICAgU2V0dGluZ0ZsYWc8RmxhZ3NJZHNFeHRlbmRlZD5cbiAgICA+KCk7XG5cbiAgICAvKiBBIG1hcCBvZiBmbGFncyB0aGF0IGNhbiBiZSB0b2dnbGVkIC0gb3B0aW9ucyB0aGF0IGNhbiBiZSBzZXQgaW4gdGhlIGFwcGxpY2F0aW9uIC0gZS5nLiBVc2UgTWljPyAqL1xuICAgIHByaXZhdGUgZmxhZ3NVaSA9IG5ldyBNYXA8XG4gICAgICAgIEZsYWdzSWRzRXh0ZW5kZWQsXG4gICAgICAgIFNldHRpbmdVSUZsYWc8RmxhZ3NJZHNFeHRlbmRlZD5cbiAgICA+KCk7XG5cbiAgICAvKiBBIG1hcCBvZiBudW1lcmljYWwgc2V0dGluZ3MgLSBvcHRpb25zIHRoYXQgY2FuIGJlIGluIHRoZSBhcHBsaWNhdGlvbiAtIGUuZy4gTWluQml0cmF0ZSAqL1xuICAgIHByaXZhdGUgbnVtZXJpY1BhcmFtZXRlcnNVaSA9IG5ldyBNYXA8XG4gICAgICAgIE51bWVyaWNQYXJhbWV0ZXJzSWRzLFxuICAgICAgICBTZXR0aW5nVUlOdW1iZXJcbiAgICA+KCk7XG5cbiAgICAvKiBBIG1hcCBvZiB0ZXh0IHNldHRpbmdzIC0gZS5nLiBzaWduYWxsaW5nIHNlcnZlciB1cmwgKi9cbiAgICBwcml2YXRlIHRleHRQYXJhbWV0ZXJzVWkgPSBuZXcgTWFwPFRleHRQYXJhbWV0ZXJzSWRzLCBTZXR0aW5nVUlUZXh0PigpO1xuXG4gICAgLyogQSBtYXAgb2YgZW51bSBiYXNlZCBzZXR0aW5ncyAtIGUuZy4gcHJlZmVycmVkIGNvZGVjICovXG4gICAgcHJpdmF0ZSBvcHRpb25QYXJhbWV0ZXJzVWkgPSBuZXcgTWFwPFxuICAgICAgICBPcHRpb25QYXJhbWV0ZXJzSWRzLFxuICAgICAgICBTZXR0aW5nVUlPcHRpb25cbiAgICA+KCk7XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0gU2V0dGluZ3MgLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlQ3VzdG9tVUlTZXR0aW5ncyhjb25maWcudXNlVXJsUGFyYW1zKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlclNldHRpbmdzVUlDb21wb25lbnRzKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGN1c3RvbSBVSSBzZXR0aW5ncyB0aGF0IGFyZSBub3QgcHJvdmlkZWQgYnkgdGhlIFBpeGVsIFN0cmVhbWluZyBsaWJyYXJ5LlxuICAgICAqL1xuICAgIGNyZWF0ZUN1c3RvbVVJU2V0dGluZ3ModXNlVXJsUGFyYW1zOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuY3VzdG9tRmxhZ3Muc2V0KFxuICAgICAgICAgICAgTGlnaHRNb2RlLFxuICAgICAgICAgICAgbmV3IFNldHRpbmdGbGFnPEZsYWdzSWRzRXh0ZW5kZWQ+KFxuICAgICAgICAgICAgICAgIExpZ2h0TW9kZSxcbiAgICAgICAgICAgICAgICAnQ29sb3IgU2NoZW1lOiBEYXJrIE1vZGUnLFxuICAgICAgICAgICAgICAgICdQYWdlIHN0eWxpbmcgd2lsbCBiZSBlaXRoZXIgbGlnaHQgb3IgZGFyaycsXG4gICAgICAgICAgICAgICAgZmFsc2UgLyppZiB3YW50IHRvIHVzZSBzeXN0ZW0gcHJlZjogKHdpbmRvdy5tYXRjaE1lZGlhICYmIHdpbmRvdy5tYXRjaE1lZGlhKCcocHJlZmVycy1jb2xvci1zY2hlbWU6IGxpZ2h0KScpLm1hdGNoZXMpKi8sXG4gICAgICAgICAgICAgICAgdXNlVXJsUGFyYW1zLFxuICAgICAgICAgICAgICAgIChpc0xpZ2h0TW9kZTogYm9vbGVhbiwgc2V0dGluZzogU2V0dGluZ0Jhc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5sYWJlbCA9IGBDb2xvciBTY2hlbWU6ICR7aXNMaWdodE1vZGUgPyAnTGlnaHQnIDogJ0RhcmsnfSBNb2RlYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBVSSB3cmFwcGVyIGNvbXBvbmVudHMgZm9yIGVhY2ggc2V0dGluZyBlbGVtZW50IGluIGNvbmZpZy5cbiAgICAgKiBAcGFyYW0gY29uZmlnXG4gICAgICovXG4gICAgcmVnaXN0ZXJTZXR0aW5nc1VJQ29tcG9uZW50cyhjb25maWc6IENvbmZpZykge1xuICAgICAgICBmb3IgKGNvbnN0IHNldHRpbmcgb2YgY29uZmlnLmdldEZsYWdzKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5zZXQoc2V0dGluZy5pZCwgbmV3IFNldHRpbmdVSUZsYWcoc2V0dGluZykpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3Qgc2V0dGluZyBvZiBBcnJheS5mcm9tKHRoaXMuY3VzdG9tRmxhZ3MudmFsdWVzKCkpKSB7XG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuc2V0KFxuICAgICAgICAgICAgICAgIHNldHRpbmcuaWQsXG4gICAgICAgICAgICAgICAgbmV3IFNldHRpbmdVSUZsYWc8RmxhZ3NJZHNFeHRlbmRlZD4oc2V0dGluZylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBzZXR0aW5nIG9mIGNvbmZpZy5nZXRUZXh0U2V0dGluZ3MoKSkge1xuICAgICAgICAgICAgdGhpcy50ZXh0UGFyYW1ldGVyc1VpLnNldChzZXR0aW5nLmlkLCBuZXcgU2V0dGluZ1VJVGV4dChzZXR0aW5nKSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBzZXR0aW5nIG9mIGNvbmZpZy5nZXROdW1lcmljU2V0dGluZ3MoKSkge1xuICAgICAgICAgICAgdGhpcy5udW1lcmljUGFyYW1ldGVyc1VpLnNldChcbiAgICAgICAgICAgICAgICBzZXR0aW5nLmlkLFxuICAgICAgICAgICAgICAgIG5ldyBTZXR0aW5nVUlOdW1iZXIoc2V0dGluZylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBzZXR0aW5nIG9mIGNvbmZpZy5nZXRPcHRpb25TZXR0aW5ncygpKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvblBhcmFtZXRlcnNVaS5zZXQoXG4gICAgICAgICAgICAgICAgc2V0dGluZy5pZCxcbiAgICAgICAgICAgICAgICBuZXcgU2V0dGluZ1VJT3B0aW9uKHNldHRpbmcpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZSBET00gZWxlbWVudHMgZm9yIGEgc2V0dGluZ3Mgc2VjdGlvbiB3aXRoIGEgaGVhZGluZy5cbiAgICAgKiBAcGFyYW0gc2V0dGluZ3NFbGVtIFRoZSBwYXJlbnQgY29udGFpbmVyIGZvciBvdXIgRE9NIGVsZW1lbnRzLlxuICAgICAqIEBwYXJhbSBzZWN0aW9uSGVhZGluZyBUaGUgaGVhZGluZyBlbGVtZW50IHRvIGdvIGludG8gdGhlIHNlY3Rpb24uXG4gICAgICogQHJldHVybnMgVGhlIGNvbnN0cnVjdGVkIERPTSBlbGVtZW50IGZvciB0aGUgc2VjdGlvbi5cbiAgICAgKi9cbiAgICBidWlsZFNlY3Rpb25XaXRoSGVhZGluZyhzZXR0aW5nc0VsZW06IEhUTUxFbGVtZW50LCBzZWN0aW9uSGVhZGluZzogc3RyaW5nKSB7XG4gICAgICAgIC8vIG1ha2Ugc2VjdGlvbiBlbGVtZW50XG4gICAgICAgIGNvbnN0IHNlY3Rpb25FbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VjdGlvbicpO1xuICAgICAgICBzZWN0aW9uRWxlbS5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0NvbnRhaW5lcicpO1xuXG4gICAgICAgIC8vIG1ha2Ugc2VjdGlvbiBoZWFkaW5nXG4gICAgICAgIGNvbnN0IHBzU2V0dGluZ3NIZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgcHNTZXR0aW5nc0hlYWRlci5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0hlYWRlcicpO1xuICAgICAgICBwc1NldHRpbmdzSGVhZGVyLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzLXRleHQnKTtcbiAgICAgICAgcHNTZXR0aW5nc0hlYWRlci50ZXh0Q29udGVudCA9IHNlY3Rpb25IZWFkaW5nO1xuXG4gICAgICAgIC8vIGFkZCBzZWN0aW9uIGFuZCBoZWFkaW5nIHRvIHBhcmVudCBzZXR0aW5ncyBlbGVtZW50XG4gICAgICAgIHNlY3Rpb25FbGVtLmFwcGVuZENoaWxkKHBzU2V0dGluZ3NIZWFkZXIpO1xuICAgICAgICBzZXR0aW5nc0VsZW0uYXBwZW5kQ2hpbGQoc2VjdGlvbkVsZW0pO1xuICAgICAgICByZXR1cm4gc2VjdGlvbkVsZW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0dXAgZmxhZ3Mgd2l0aCB0aGVpciBkZWZhdWx0IHZhbHVlcyBhbmQgYWRkIHRoZW0gdG8gdGhlIGBDb25maWcuZmxhZ3NgIG1hcC5cbiAgICAgKiBAcGFyYW0gc2V0dGluZ3NFbGVtIC0gVGhlIGVsZW1lbnQgdGhhdCBjb250YWlucyBhbGwgdGhlIGluZGl2aWR1YWwgc2V0dGluZ3Mgc2VjdGlvbnMsIGZsYWdzLCBhbmQgc28gb24uXG4gICAgICovXG4gICAgcG9wdWxhdGVTZXR0aW5nc0VsZW1lbnQoc2V0dGluZ3NFbGVtOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgICAgICAvKiBTZXR1cCBhbGwgUGl4ZWwgU3RyZWFtaW5nIHNwZWNpZmljIHNldHRpbmdzICovXG4gICAgICAgIGNvbnN0IHBzU2V0dGluZ3NTZWN0aW9uID0gdGhpcy5idWlsZFNlY3Rpb25XaXRoSGVhZGluZyhcbiAgICAgICAgICAgIHNldHRpbmdzRWxlbSxcbiAgICAgICAgICAgICdQaXhlbCBTdHJlYW1pbmcnXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gbWFrZSBzZXR0aW5ncyBzaG93IHVwIGluIERPTVxuICAgICAgICB0aGlzLmFkZFNldHRpbmdUZXh0KFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLnRleHRQYXJhbWV0ZXJzVWkuZ2V0KFRleHRQYXJhbWV0ZXJzLlNpZ25hbGxpbmdTZXJ2ZXJVcmwpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ09wdGlvbihcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5vcHRpb25QYXJhbWV0ZXJzVWkuZ2V0KE9wdGlvblBhcmFtZXRlcnMuU3RyZWFtZXJJZClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5BdXRvQ29ubmVjdClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5BdXRvUGxheVZpZGVvKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkJyb3dzZXJTZW5kT2ZmZXIpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbiwgXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLlVzZU1pYylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5TdGFydFZpZGVvTXV0ZWQpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuSXNRdWFsaXR5Q29udHJvbGxlcilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5Gb3JjZU1vbm9BdWRpbylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5Gb3JjZVRVUk4pXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuU3VwcHJlc3NCcm93c2VyS2V5cylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5BRktEZXRlY3Rpb24pXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuV2FpdEZvclN0cmVhbWVyKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KE51bWVyaWNQYXJhbWV0ZXJzLkFGS1RpbWVvdXRTZWNzKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KE51bWVyaWNQYXJhbWV0ZXJzLk1heFJlY29ubmVjdEF0dGVtcHRzKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KE51bWVyaWNQYXJhbWV0ZXJzLlN0cmVhbWVyQXV0b0pvaW5JbnRlcnZhbClcbiAgICAgICAgKTtcblxuICAgICAgICAvKiBTZXR1cCBhbGwgdmlldy91aSByZWxhdGVkIHNldHRpbmdzIHVuZGVyIHRoaXMgc2VjdGlvbiAqL1xuICAgICAgICBjb25zdCB2aWV3U2V0dGluZ3NTZWN0aW9uID0gdGhpcy5idWlsZFNlY3Rpb25XaXRoSGVhZGluZyhcbiAgICAgICAgICAgIHNldHRpbmdzRWxlbSxcbiAgICAgICAgICAgICdVSSdcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHZpZXdTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLk1hdGNoVmlld3BvcnRSZXNvbHV0aW9uKVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICB2aWV3U2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5Ib3ZlcmluZ01vdXNlTW9kZSlcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKHZpZXdTZXR0aW5nc1NlY3Rpb24sIHRoaXMuZmxhZ3NVaS5nZXQoTGlnaHRNb2RlKSk7XG5cbiAgICAgICAgLyogU2V0dXAgYWxsIGVuY29kZXIgcmVsYXRlZCBzZXR0aW5ncyB1bmRlciB0aGlzIHNlY3Rpb24gKi9cbiAgICAgICAgY29uc3QgaW5wdXRTZXR0aW5nc1NlY3Rpb24gPSB0aGlzLmJ1aWxkU2VjdGlvbldpdGhIZWFkaW5nKFxuICAgICAgICAgICAgc2V0dGluZ3NFbGVtLFxuICAgICAgICAgICAgJ0lucHV0J1xuICAgICAgICApO1xuICAgICAgICBcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIGlucHV0U2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5LZXlib2FyZElucHV0KVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBpbnB1dFNldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuTW91c2VJbnB1dClcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgaW5wdXRTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLlRvdWNoSW5wdXQpXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIGlucHV0U2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5HYW1lcGFkSW5wdXQpXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIGlucHV0U2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5YUkNvbnRyb2xsZXJJbnB1dClcbiAgICAgICAgKTtcblxuICAgICAgICAvKiBTZXR1cCBhbGwgZW5jb2RlciByZWxhdGVkIHNldHRpbmdzIHVuZGVyIHRoaXMgc2VjdGlvbiAqL1xuICAgICAgICBjb25zdCBlbmNvZGVyU2V0dGluZ3NTZWN0aW9uID0gdGhpcy5idWlsZFNlY3Rpb25XaXRoSGVhZGluZyhcbiAgICAgICAgICAgIHNldHRpbmdzRWxlbSxcbiAgICAgICAgICAgICdFbmNvZGVyJ1xuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ051bWVyaWMoXG4gICAgICAgICAgICBlbmNvZGVyU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5udW1lcmljUGFyYW1ldGVyc1VpLmdldChOdW1lcmljUGFyYW1ldGVycy5NaW5RUClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nTnVtZXJpYyhcbiAgICAgICAgICAgIGVuY29kZXJTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KE51bWVyaWNQYXJhbWV0ZXJzLk1heFFQKVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHByZWZlcnJlZENvZGVjT3B0aW9uID0gdGhpcy5vcHRpb25QYXJhbWV0ZXJzVWkuZ2V0KFxuICAgICAgICAgICAgT3B0aW9uUGFyYW1ldGVycy5QcmVmZXJyZWRDb2RlY1xuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdPcHRpb24oXG4gICAgICAgICAgICBlbmNvZGVyU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5vcHRpb25QYXJhbWV0ZXJzVWkuZ2V0KE9wdGlvblBhcmFtZXRlcnMuUHJlZmVycmVkQ29kZWMpXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHByZWZlcnJlZENvZGVjT3B0aW9uICYmXG4gICAgICAgICAgICBbLi4ucHJlZmVycmVkQ29kZWNPcHRpb24uc2VsZWN0b3Iub3B0aW9uc11cbiAgICAgICAgICAgICAgICAubWFwKChvKSA9PiBvLnZhbHVlKVxuICAgICAgICAgICAgICAgIC5pbmNsdWRlcygnT25seSBhdmFpbGFibGUgb24gQ2hyb21lJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBwcmVmZXJyZWRDb2RlY09wdGlvbi5kaXNhYmxlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiBTZXR1cCBhbGwgd2VicnRjIHJlbGF0ZWQgc2V0dGluZ3MgdW5kZXIgdGhpcyBzZWN0aW9uICovXG4gICAgICAgIGNvbnN0IHdlYnJ0Y1NldHRpbmdzU2VjdGlvbiA9IHRoaXMuYnVpbGRTZWN0aW9uV2l0aEhlYWRpbmcoXG4gICAgICAgICAgICBzZXR0aW5nc0VsZW0sXG4gICAgICAgICAgICAnV2ViUlRDJ1xuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ051bWVyaWMoXG4gICAgICAgICAgICB3ZWJydGNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KE51bWVyaWNQYXJhbWV0ZXJzLldlYlJUQ0ZQUylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nTnVtZXJpYyhcbiAgICAgICAgICAgIHdlYnJ0Y1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuV2ViUlRDTWluQml0cmF0ZSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nTnVtZXJpYyhcbiAgICAgICAgICAgIHdlYnJ0Y1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuV2ViUlRDTWF4Qml0cmF0ZSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBTZXR0aW5nVGV4dCBlbGVtZW50IHRvIGEgcGFydGljdWxhciBzZXR0aW5ncyBzZWN0aW9uIGluIHRoZSBET00gYW5kIHJlZ2lzdGVycyB0aGF0IHRleHQgaW4gdGhlIHRleHQgc2V0dGluZ3MgbWFwLlxuICAgICAqIEBwYXJhbSBzZXR0aW5nc1NlY3Rpb24gVGhlIHNldHRpbmdzIHNlY3Rpb24gSFRNTCBlbGVtZW50LlxuICAgICAqIEBwYXJhbSBzZXR0aW5nVGV4dCBUaGUgdGV4dHVhbCBzZXR0aW5ncyBvYmplY3QuXG4gICAgICovXG4gICAgYWRkU2V0dGluZ1RleHQoXG4gICAgICAgIHNldHRpbmdzU2VjdGlvbjogSFRNTEVsZW1lbnQsXG4gICAgICAgIHNldHRpbmdUZXh0PzogU2V0dGluZ1VJVGV4dFxuICAgICk6IHZvaWQge1xuICAgICAgICBpZiAoc2V0dGluZ1RleHQpIHtcbiAgICAgICAgICAgIHNldHRpbmdzU2VjdGlvbi5hcHBlbmRDaGlsZChzZXR0aW5nVGV4dC5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLnRleHRQYXJhbWV0ZXJzVWkuc2V0KHNldHRpbmdUZXh0LnNldHRpbmcuaWQsIHNldHRpbmdUZXh0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIFNldHRpbmdGbGFnIGVsZW1lbnQgdG8gYSBwYXJ0aWN1bGFyIHNldHRpbmdzIHNlY3Rpb24gaW4gdGhlIERPTSBhbmQgcmVnaXN0ZXJzIHRoYXQgZmxhZyBpbiB0aGUgQ29uZmlnLmZsYWcgbWFwLlxuICAgICAqIEBwYXJhbSBzZXR0aW5nc1NlY3Rpb24gVGhlIHNldHRpbmdzIHNlY3Rpb24gSFRNTCBlbGVtZW50LlxuICAgICAqIEBwYXJhbSBzZXR0aW5nRmxhZyBUaGUgc2V0dGluZ3MgZmxhZyBvYmplY3QuXG4gICAgICovXG4gICAgYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgIHNldHRpbmdzU2VjdGlvbjogSFRNTEVsZW1lbnQsXG4gICAgICAgIHNldHRpbmdGbGFnPzogU2V0dGluZ1VJRmxhZzxGbGFnc0lkc0V4dGVuZGVkPlxuICAgICk6IHZvaWQge1xuICAgICAgICBpZiAoc2V0dGluZ0ZsYWcpIHtcbiAgICAgICAgICAgIHNldHRpbmdzU2VjdGlvbi5hcHBlbmRDaGlsZChzZXR0aW5nRmxhZy5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuc2V0KHNldHRpbmdGbGFnLnNldHRpbmcuaWQsIHNldHRpbmdGbGFnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIG51bWVyaWMgc2V0dGluZyBlbGVtZW50IHRvIGEgcGFydGljdWxhciBzZXR0aW5ncyBzZWN0aW9uIGluIHRoZSBET00gYW5kIHJlZ2lzdGVycyB0aGF0IGZsYWcgaW4gdGhlIENvbmZpZy5udW1lcmljUGFyYW1ldGVycyBtYXAuXG4gICAgICogQHBhcmFtIHNldHRpbmdzU2VjdGlvbiBUaGUgc2V0dGluZ3Mgc2VjdGlvbiBIVE1MIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHNldHRpbmdGbGFnIFRoZSBzZXR0aW5ncyBmbGFnIG9iamVjdC5cbiAgICAgKi9cbiAgICBhZGRTZXR0aW5nTnVtZXJpYyhcbiAgICAgICAgc2V0dGluZ3NTZWN0aW9uOiBIVE1MRWxlbWVudCxcbiAgICAgICAgc2V0dGluZz86IFNldHRpbmdVSU51bWJlclxuICAgICk6IHZvaWQge1xuICAgICAgICBpZiAoc2V0dGluZykge1xuICAgICAgICAgICAgc2V0dGluZ3NTZWN0aW9uLmFwcGVuZENoaWxkKHNldHRpbmcucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5udW1lcmljUGFyYW1ldGVyc1VpLnNldChzZXR0aW5nLnNldHRpbmcuaWQsIHNldHRpbmcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGFuIGVudW0gYmFzZWQgc2V0dGluZ3MgZWxlbWVudCB0byBhIHBhcnRpY3VsYXIgc2V0dGluZ3Mgc2VjdGlvbiBpbiB0aGUgRE9NIGFuZCByZWdpc3RlcnMgdGhhdCBmbGFnIGluIHRoZSBDb25maWcuZW51bVBhcmFtZXRlcnMgbWFwLlxuICAgICAqIEBwYXJhbSBzZXR0aW5nc1NlY3Rpb24gVGhlIHNldHRpbmdzIHNlY3Rpb24gSFRNTCBlbGVtZW50LlxuICAgICAqIEBwYXJhbSBzZXR0aW5nRmxhZyBUaGUgc2V0dGluZ3MgZmxhZyBvYmplY3QuXG4gICAgICovXG4gICAgYWRkU2V0dGluZ09wdGlvbihcbiAgICAgICAgc2V0dGluZ3NTZWN0aW9uOiBIVE1MRWxlbWVudCxcbiAgICAgICAgc2V0dGluZz86IFNldHRpbmdVSU9wdGlvblxuICAgICk6IHZvaWQge1xuICAgICAgICBpZiAoc2V0dGluZykge1xuICAgICAgICAgICAgc2V0dGluZ3NTZWN0aW9uLmFwcGVuZENoaWxkKHNldHRpbmcucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25QYXJhbWV0ZXJzVWkuc2V0KHNldHRpbmcuc2V0dGluZy5pZCwgc2V0dGluZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblNldHRpbmdzQ2hhbmdlZCh7IGRhdGE6IHsgaWQsIHRhcmdldCwgdHlwZSB9IH06IFNldHRpbmdzQ2hhbmdlZEV2ZW50KSB7XG4gICAgICAgIGlmICh0eXBlID09PSAnZmxhZycpIHtcbiAgICAgICAgICAgIGNvbnN0IF9pZCA9IGlkIGFzIEZsYWdzSWRzO1xuICAgICAgICAgICAgY29uc3QgX3RhcmdldCA9IHRhcmdldCBhcyBTZXR0aW5nRmxhZztcbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmcgPSB0aGlzLmZsYWdzVWkuZ2V0KF9pZCk7XG4gICAgICAgICAgICBpZiAoc2V0dGluZykge1xuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLmZsYWcgIT09IF90YXJnZXQuZmxhZykge1xuICAgICAgICAgICAgICAgICAgICBzZXR0aW5nLmZsYWcgPSBfdGFyZ2V0LmZsYWc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLmxhYmVsICE9PSBfdGFyZ2V0LmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcubGFiZWwgPSBfdGFyZ2V0LmxhYmVsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgY29uc3QgX2lkID0gaWQgYXMgTnVtZXJpY1BhcmFtZXRlcnNJZHM7XG4gICAgICAgICAgICBjb25zdCBfdGFyZ2V0ID0gdGFyZ2V0IGFzIFNldHRpbmdOdW1iZXI7XG4gICAgICAgICAgICBjb25zdCBzZXR0aW5nID0gdGhpcy5udW1lcmljUGFyYW1ldGVyc1VpLmdldChfaWQpO1xuICAgICAgICAgICAgaWYgKHNldHRpbmcpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2V0dGluZy5udW1iZXIgIT09IF90YXJnZXQubnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcubnVtYmVyID0gX3RhcmdldC5udW1iZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLmxhYmVsICE9PSBfdGFyZ2V0LmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcubGFiZWwgPSBfdGFyZ2V0LmxhYmVsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICAgIGNvbnN0IF9pZCA9IGlkIGFzIFRleHRQYXJhbWV0ZXJzSWRzO1xuICAgICAgICAgICAgY29uc3QgX3RhcmdldCA9IHRhcmdldCBhcyBTZXR0aW5nVGV4dDtcbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmcgPSB0aGlzLnRleHRQYXJhbWV0ZXJzVWkuZ2V0KF9pZCk7XG4gICAgICAgICAgICBpZiAoc2V0dGluZykge1xuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLnRleHQgIT09IF90YXJnZXQudGV4dCkge1xuICAgICAgICAgICAgICAgICAgICBzZXR0aW5nLnRleHQgPSBfdGFyZ2V0LnRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLmxhYmVsICE9PSBfdGFyZ2V0LmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcubGFiZWwgPSBfdGFyZ2V0LmxhYmVsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb3B0aW9uJykge1xuICAgICAgICAgICAgY29uc3QgX2lkID0gaWQgYXMgT3B0aW9uUGFyYW1ldGVyc0lkcztcbiAgICAgICAgICAgIGNvbnN0IF90YXJnZXQgPSB0YXJnZXQgYXMgU2V0dGluZ09wdGlvbjtcbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmcgPSB0aGlzLm9wdGlvblBhcmFtZXRlcnNVaS5nZXQoX2lkKTtcbiAgICAgICAgICAgIGlmIChzZXR0aW5nKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdWlPcHRpb25zID0gc2V0dGluZy5vcHRpb25zO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldE9wdGlvbnMgPSBfdGFyZ2V0Lm9wdGlvbnM7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICB1aU9wdGlvbnMubGVuZ3RoICE9PSB0YXJnZXRPcHRpb25zLmxlbmd0aCB8fFxuICAgICAgICAgICAgICAgICAgICAhdWlPcHRpb25zLmV2ZXJ5KCh2YWx1ZSkgPT4gdGFyZ2V0T3B0aW9ucy5pbmNsdWRlcyh2YWx1ZSkpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcub3B0aW9ucyA9IF90YXJnZXQub3B0aW9ucztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcuc2VsZWN0ZWQgIT09IF90YXJnZXQuc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5zZWxlY3RlZCA9IF90YXJnZXQuc2VsZWN0ZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLmxhYmVsICE9PSBfdGFyZ2V0LmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcubGFiZWwgPSBfdGFyZ2V0LmxhYmVsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIGNhbGxiYWNrIHRvIGZpcmUgd2hlbiB0aGUgZmxhZyBpcyB0b2dnbGVkLlxuICAgICAqIEBwYXJhbSBpZCBUaGUgaWQgb2YgdGhlIGZsYWcuXG4gICAgICogQHBhcmFtIG9uQ2hhbmdlTGlzdGVuZXIgVGhlIGNhbGxiYWNrIHRvIGZpcmUgd2hlbiB0aGUgdmFsdWUgY2hhbmdlcy5cbiAgICAgKi9cbiAgICBhZGRDdXN0b21GbGFnT25TZXR0aW5nQ2hhbmdlZExpc3RlbmVyKFxuICAgICAgICBpZDogRXh0cmFGbGFncyxcbiAgICAgICAgb25DaGFuZ2VMaXN0ZW5lcjogKG5ld0ZsYWdWYWx1ZTogYm9vbGVhbikgPT4gdm9pZFxuICAgICk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jdXN0b21GbGFncy5oYXMoaWQpKSB7XG4gICAgICAgICAgICB0aGlzLmN1c3RvbUZsYWdzLmdldChpZCkub25DaGFuZ2UgPSBvbkNoYW5nZUxpc3RlbmVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsYWJlbCBmb3IgdGhlIGZsYWcuXG4gICAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgZmxhZy5cbiAgICAgKiBAcGFyYW0gbGFiZWwgVGhlIG5ldyBsYWJlbCB0byB1c2UgZm9yIHRoZSBmbGFnLlxuICAgICAqL1xuICAgIHNldEN1c3RvbUZsYWdMYWJlbChpZDogRXh0cmFGbGFncywgbGFiZWw6IHN0cmluZykge1xuICAgICAgICBpZiAoIXRoaXMuY3VzdG9tRmxhZ3MuaGFzKGlkKSkge1xuICAgICAgICAgICAgTG9nZ2VyLldhcm5pbmcoXG4gICAgICAgICAgICAgICAgTG9nZ2VyLkdldFN0YWNrVHJhY2UoKSxcbiAgICAgICAgICAgICAgICBgQ2Fubm90IHNldCBsYWJlbCBmb3IgZmxhZyBjYWxsZWQgJHtpZH0gLSBpdCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgQ29uZmlnLmZsYWdzIG1hcC5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jdXN0b21GbGFncy5nZXQoaWQpLmxhYmVsID0gbGFiZWw7XG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KGlkKS5sYWJlbCA9IGxhYmVsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBmbGFnIHdoaWNoIGhhcyB0aGUgZ2l2ZW4gaWQuXG4gICAgICogQHBhcmFtIGlkIFRoZSB1bmlxdWUgaWQgZm9yIHRoZSBmbGFnLlxuICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGZsYWcgaXMgZW5hYmxlZC5cbiAgICAgKi9cbiAgICBpc0N1c3RvbUZsYWdFbmFibGVkKGlkOiBFeHRyYUZsYWdzKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmN1c3RvbUZsYWdzLmdldChpZCkuZmxhZyBhcyBib29sZWFuO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IFNldHRpbmdCYXNlIH0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgYSBzZXR0aW5nIHRoYXQgaGFzIGEgdGV4dCBsYWJlbCwgYW4gYXJiaXRyYXJ5IHNldHRpbmcgdmFsdWUgaXQgc3RvcmVzLCBhbiBhIEhUTUwgZWxlbWVudCB0aGF0IHJlcHJlc2VudHMgdGhpcyBzZXR0aW5nLlxuICovXG5leHBvcnQgY2xhc3MgU2V0dGluZ1VJQmFzZSB7XG4gICAgX3NldHRpbmc6IFNldHRpbmdCYXNlO1xuICAgIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5nOiBTZXR0aW5nQmFzZSkge1xuICAgICAgICB0aGlzLl9zZXR0aW5nID0gc2V0dGluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgc2V0dGluZyBjb21wb25lbnQuXG4gICAgICovXG4gICAgcHVibGljIGdldCBzZXR0aW5nKCk6IFNldHRpbmdCYXNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgUmV0dXJuIG9yIGNyZWF0ZXMgYSBIVE1MIGVsZW1lbnQgdGhhdCByZXByZXNlbnRzIHRoaXMgc2V0dGluZyBpbiB0aGUgRE9NLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgdHlwZSB7XG4gICAgRmxhZ3NJZHMsXG4gICAgU2V0dGluZ0ZsYWdcbn0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBTZXR0aW5nVUlCYXNlIH0gZnJvbSAnLi9TZXR0aW5nVUlCYXNlJztcblxuZXhwb3J0IGNsYXNzIFNldHRpbmdVSUZsYWc8XG4gICAgQ3VzdG9tSWRzIGV4dGVuZHMgc3RyaW5nID0gRmxhZ3NJZHNcbj4gZXh0ZW5kcyBTZXR0aW5nVUlCYXNlIHtcbiAgICAvKiBXZSB0b2dnbGUgdGhpcyBjaGVja2JveCB0byByZWZsZWN0IHRoZSB2YWx1ZSBvZiBvdXIgc2V0dGluZydzIGJvb2xlYW4gZmxhZy4gKi9cbiAgICBfY2hlY2tib3g6IEhUTUxJbnB1dEVsZW1lbnQ7IC8vIGlucHV0IHR5cGU9XCJjaGVja2JveFwiXG5cbiAgICAvKiBUaGlzIGVsZW1lbnQgY29udGFpbnMgYSB0ZXh0IG5vZGUgdGhhdCByZWZsZWN0cyB0aGUgc2V0dGluZydzIHRleHQgbGFiZWwuICovXG4gICAgX3NldHRpbmdzVGV4dEVsZW06IEhUTUxFbGVtZW50O1xuXG4gICAgb25DaGFuZ2VFbWl0OiAoY2hhbmdlZFZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZzogU2V0dGluZ0ZsYWc8Q3VzdG9tSWRzPikge1xuICAgICAgICBzdXBlcihzZXR0aW5nKTtcblxuICAgICAgICB0aGlzLmxhYmVsID0gc2V0dGluZy5sYWJlbDtcbiAgICAgICAgdGhpcy5mbGFnID0gc2V0dGluZy5mbGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmcoKTogU2V0dGluZ0ZsYWc8Q3VzdG9tSWRzPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXR0aW5nIGFzIFNldHRpbmdGbGFnPEN1c3RvbUlkcz47XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZXR0aW5nc1RleHRFbGVtKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5nc1RleHRFbGVtKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dCA9IHRoaXMuc2V0dGluZy5fbGFiZWw7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtLnRpdGxlID0gdGhpcy5zZXR0aW5nLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXR0aW5nc1RleHRFbGVtO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgY2hlY2tib3goKTogSFRNTElucHV0RWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fY2hlY2tib3gpIHtcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrYm94ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrYm94LnR5cGUgPSAnY2hlY2tib3gnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jaGVja2JveDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBSZXR1cm4gb3IgY3JlYXRlcyBhIEhUTUwgZWxlbWVudCB0aGF0IHJlcHJlc2VudHMgdGhpcyBzZXR0aW5nIGluIHRoZSBET00uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSByb290IGRpdiB3aXRoIFwic2V0dGluZ1wiIGNzcyBjbGFzc1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmlkID0gdGhpcy5zZXR0aW5nLmlkO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnc2V0dGluZycpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgZGl2IGVsZW1lbnQgdG8gY29udGFpbiBvdXIgc2V0dGluZydzIHRleHRcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NUZXh0RWxlbSk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBsYWJlbCBlbGVtZW50IHRvIHdyYXAgb3V0IGlucHV0IHR5cGVcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJMYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgICAgICAgICB3cmFwcGVyTGFiZWwuY2xhc3NMaXN0LmFkZCgndGdsLXN3aXRjaCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQod3JhcHBlckxhYmVsKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGlucHV0IHR5cGU9Y2hlY2tib3hcbiAgICAgICAgICAgIHRoaXMuY2hlY2tib3gudGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgICAgICB0aGlzLmNoZWNrYm94LmNsYXNzTGlzdC5hZGQoJ3RnbCcpO1xuICAgICAgICAgICAgdGhpcy5jaGVja2JveC5jbGFzc0xpc3QuYWRkKCd0Z2wtZmxhdCcpO1xuICAgICAgICAgICAgY29uc3Qgc2xpZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBzbGlkZXIuY2xhc3NMaXN0LmFkZCgndGdsLXNsaWRlcicpO1xuICAgICAgICAgICAgd3JhcHBlckxhYmVsLmFwcGVuZENoaWxkKHRoaXMuY2hlY2tib3gpO1xuICAgICAgICAgICAgd3JhcHBlckxhYmVsLmFwcGVuZENoaWxkKHNsaWRlcik7XG5cbiAgICAgICAgICAgIC8vIHNldHVwIG9uIGNoYW5nZSBmcm9tIGNoZWNrYm94XG4gICAgICAgICAgICB0aGlzLmNoZWNrYm94LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5nLmZsYWcgIT09IHRoaXMuY2hlY2tib3guY2hlY2tlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcuZmxhZyA9IHRoaXMuY2hlY2tib3guY2hlY2tlZDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nLnVwZGF0ZVVSTFBhcmFtcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHNldHRpbmcncyBzdG9yZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIGluVmFsdWUgVGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNldHRpbmcuXG4gICAgICovXG4gICAgcHVibGljIHNldCBmbGFnKGluVmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5jaGVja2JveC5jaGVja2VkID0gaW5WYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdmFsdWVcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGZsYWcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoZWNrYm94LmNoZWNrZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsYWJlbCB0ZXh0IGZvciB0aGUgc2V0dGluZy5cbiAgICAgKiBAcGFyYW0gbGFiZWwgc2V0dGluZyBsYWJlbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IGxhYmVsKGluTGFiZWw6IHN0cmluZykge1xuICAgICAgICB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gaW5MYWJlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgbGFiZWxcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGxhYmVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgdHlwZSB7XG4gICAgTnVtZXJpY1BhcmFtZXRlcnNJZHMsXG4gICAgU2V0dGluZ051bWJlclxufSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHsgU2V0dGluZ1VJQmFzZSB9IGZyb20gJy4vU2V0dGluZ1VJQmFzZSc7XG5cbi8qKlxuICogQSBudW1iZXIgc3Bpbm5lciB3aXRoIGEgdGV4dCBsYWJlbCBiZXNpZGUgaXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXR0aW5nVUlOdW1iZXI8XG4gICAgQ3VzdG9tSWRzIGV4dGVuZHMgc3RyaW5nID0gTnVtZXJpY1BhcmFtZXRlcnNJZHNcbj4gZXh0ZW5kcyBTZXR0aW5nVUlCYXNlIHtcbiAgICBfc3Bpbm5lcjogSFRNTElucHV0RWxlbWVudDtcblxuICAgIC8qIFRoaXMgZWxlbWVudCBjb250YWlucyBhIHRleHQgbm9kZSB0aGF0IHJlZmxlY3RzIHRoZSBzZXR0aW5nJ3MgdGV4dCBsYWJlbC4gKi9cbiAgICBfc2V0dGluZ3NUZXh0RWxlbTogSFRNTEVsZW1lbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5nOiBTZXR0aW5nTnVtYmVyPEN1c3RvbUlkcz4pIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZyk7XG5cbiAgICAgICAgdGhpcy5sYWJlbCA9IHRoaXMuc2V0dGluZy5sYWJlbDtcbiAgICAgICAgdGhpcy5udW1iZXIgPSB0aGlzLnNldHRpbmcubnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmcoKTogU2V0dGluZ051bWJlcjxDdXN0b21JZHM+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmcgYXMgU2V0dGluZ051bWJlcjxDdXN0b21JZHM+O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2V0dGluZ3NUZXh0RWxlbSgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3NUZXh0RWxlbSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NUZXh0RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dCA9IHRoaXMuc2V0dGluZy5sYWJlbDtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0udGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzVGV4dEVsZW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBIVE1MSW5wdXRFbGVtZW50IGZvciB0aGUgYnV0dG9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc3Bpbm5lcigpOiBIVE1MSW5wdXRFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zcGlubmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9zcGlubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgIHRoaXMuX3NwaW5uZXIudHlwZSA9ICdudW1iZXInO1xuICAgICAgICAgICAgdGhpcy5fc3Bpbm5lci5taW4gPSB0aGlzLnNldHRpbmcubWluLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB0aGlzLl9zcGlubmVyLm1heCA9IHRoaXMuc2V0dGluZy5tYXgudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHRoaXMuX3NwaW5uZXIudmFsdWUgPSB0aGlzLnNldHRpbmcubnVtYmVyLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB0aGlzLl9zcGlubmVyLnRpdGxlID0gdGhpcy5zZXR0aW5nLmRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgdGhpcy5fc3Bpbm5lci5jbGFzc0xpc3QuYWRkKCdmb3JtLWNvbnRyb2wnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc3Bpbm5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBSZXR1cm4gb3IgY3JlYXRlcyBhIEhUTUwgZWxlbWVudCB0aGF0IHJlcHJlc2VudHMgdGhpcyBzZXR0aW5nIGluIHRoZSBET00uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSByb290IGRpdiB3aXRoIFwic2V0dGluZ1wiIGNzcyBjbGFzc1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3NldHRpbmcnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Zvcm0tZ3JvdXAnKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGRpdiBlbGVtZW50IHRvIGNvbnRhaW4gb3VyIHNldHRpbmcncyB0ZXh0XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNldHRpbmdzVGV4dEVsZW0pO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgbGFiZWwgZWxlbWVudCB0byB3cmFwIG91dCBpbnB1dCB0eXBlXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNwaW5uZXIpO1xuXG4gICAgICAgICAgICAvLyBzZXR1cCBvbmNoYW5nZVxuICAgICAgICAgICAgdGhpcy5zcGlubmVyLm9uY2hhbmdlID0gKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0RWxlbSA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkVmFsdWUgPSBOdW1iZXIucGFyc2VJbnQoaW5wdXRFbGVtLnZhbHVlKTtcblxuICAgICAgICAgICAgICAgIGlmIChOdW1iZXIuaXNOYU4ocGFyc2VkVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuaW5nKFxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLkdldFN0YWNrVHJhY2UoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGBDb3VsZCBub3QgcGFyc2UgdmFsdWUgY2hhbmdlIGludG8gYSB2YWxpZCBudW1iZXIgLSB2YWx1ZSB3YXMgJHtpbnB1dEVsZW0udmFsdWV9LCByZXNldHRpbmcgdmFsdWUgdG8gJHt0aGlzLnNldHRpbmcubWlufWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZy5udW1iZXIgIT09IHRoaXMuc2V0dGluZy5taW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZy5udW1iZXIgPSB0aGlzLnNldHRpbmcubWluO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZy5udW1iZXIgIT09IHBhcnNlZFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcubnVtYmVyID0gcGFyc2VkVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcudXBkYXRlVVJMUGFyYW1zKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIG51bWJlciBpbiB0aGUgc3Bpbm5lciAod2lsbCBiZSBjbGFtcGVkIHdpdGhpbiByYW5nZSkuXG4gICAgICovXG4gICAgcHVibGljIHNldCBudW1iZXIobmV3TnVtYmVyOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLnZhbHVlID0gdGhpcy5zZXR0aW5nLmNsYW1wKG5ld051bWJlcikudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdmFsdWVcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG51bWJlcigpIHtcbiAgICAgICAgcmV0dXJuICt0aGlzLnNwaW5uZXIudmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsYWJlbCB0ZXh0IGZvciB0aGUgc2V0dGluZy5cbiAgICAgKiBAcGFyYW0gbGFiZWwgc2V0dGluZyBsYWJlbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IGxhYmVsKGluTGFiZWw6IHN0cmluZykge1xuICAgICAgICB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gaW5MYWJlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgbGFiZWxcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGxhYmVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgdHlwZSB7XG4gICAgT3B0aW9uUGFyYW1ldGVyc0lkcyxcbiAgICBTZXR0aW5nT3B0aW9uXG59IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHsgU2V0dGluZ1VJQmFzZSB9IGZyb20gJy4vU2V0dGluZ1VJQmFzZSc7XG5cbmV4cG9ydCBjbGFzcyBTZXR0aW5nVUlPcHRpb248XG4gICAgQ3VzdG9tSWRzIGV4dGVuZHMgc3RyaW5nID0gT3B0aW9uUGFyYW1ldGVyc0lkc1xuPiBleHRlbmRzIFNldHRpbmdVSUJhc2Uge1xuICAgIC8qIEEgc2VsZWN0IGVsZW1lbnQgdGhhdCByZWZsZWN0cyB0aGUgdmFsdWUgb2YgdGhpcyBzZXR0aW5nLiAqL1xuICAgIF9zZWxlY3RvcjogSFRNTFNlbGVjdEVsZW1lbnQ7IC8vIDxzZWxlY3Q+PC9zZWxlY3Q+XG5cbiAgICAvKiBUaGlzIGVsZW1lbnQgY29udGFpbnMgYSB0ZXh0IG5vZGUgdGhhdCByZWZsZWN0cyB0aGUgc2V0dGluZydzIHRleHQgbGFiZWwuICovXG4gICAgX3NldHRpbmdzVGV4dEVsZW06IEhUTUxFbGVtZW50O1xuXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZzogU2V0dGluZ09wdGlvbjxDdXN0b21JZHM+KSB7XG4gICAgICAgIHN1cGVyKHNldHRpbmcpO1xuXG4gICAgICAgIHRoaXMubGFiZWwgPSB0aGlzLnNldHRpbmcubGFiZWw7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IHRoaXMuc2V0dGluZy5vcHRpb25zO1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gdGhpcy5zZXR0aW5nLnNlbGVjdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmcoKTogU2V0dGluZ09wdGlvbjxDdXN0b21JZHM+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmcgYXMgU2V0dGluZ09wdGlvbjxDdXN0b21JZHM+O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2VsZWN0b3IoKTogSFRNTFNlbGVjdEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3NlbGVjdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9zZWxlY3RvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NlbGVjdCcpO1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0b3IuY2xhc3NMaXN0LmFkZCgnZm9ybS1jb250cm9sJyk7XG4gICAgICAgICAgICB0aGlzLl9zZWxlY3Rvci5jbGFzc0xpc3QuYWRkKCdzZXR0aW5ncy1vcHRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2VsZWN0b3I7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZXR0aW5nc1RleHRFbGVtKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5nc1RleHRFbGVtKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dCA9IHRoaXMuc2V0dGluZy5sYWJlbDtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0udGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzVGV4dEVsZW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsYWJlbCB0ZXh0IGZvciB0aGUgc2V0dGluZy5cbiAgICAgKiBAcGFyYW0gbGFiZWwgc2V0dGluZyBsYWJlbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IGxhYmVsKGluTGFiZWw6IHN0cmluZykge1xuICAgICAgICB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gaW5MYWJlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgbGFiZWxcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGxhYmVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBSZXR1cm4gb3IgY3JlYXRlcyBhIEhUTUwgZWxlbWVudCB0aGF0IHJlcHJlc2VudHMgdGhpcyBzZXR0aW5nIGluIHRoZSBET00uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSByb290IGRpdiB3aXRoIFwic2V0dGluZ1wiIGNzcyBjbGFzc1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmlkID0gdGhpcy5zZXR0aW5nLmlkO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnc2V0dGluZycpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZm9ybS1ncm91cCcpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgZGl2IGVsZW1lbnQgdG8gY29udGFpbiBvdXIgc2V0dGluZydzIHRleHRcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NUZXh0RWxlbSk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBsYWJlbCBlbGVtZW50IHRvIHdyYXAgb3V0IGlucHV0IHR5cGVcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJMYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh3cmFwcGVyTGFiZWwpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgc2VsZWN0IGVsZW1lbnRcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0b3IudGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgICAgICB3cmFwcGVyTGFiZWwuYXBwZW5kQ2hpbGQodGhpcy5zZWxlY3Rvcik7XG5cbiAgICAgICAgICAgIC8vIHNldHVwIG9uIGNoYW5nZSBmcm9tIHNlbGVjdG9yXG4gICAgICAgICAgICB0aGlzLnNlbGVjdG9yLm9uY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmcuc2VsZWN0ZWQgIT09IHRoaXMuc2VsZWN0b3IudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nLnNlbGVjdGVkID0gdGhpcy5zZWxlY3Rvci52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nLnVwZGF0ZVVSTFBhcmFtcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgb3B0aW9ucyh2YWx1ZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc2VsZWN0b3Iub3B0aW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3Rvci5yZW1vdmUoaSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3B0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7XG4gICAgICAgICAgICBvcHQudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgIG9wdC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0b3IuYXBwZW5kQ2hpbGQob3B0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBvcHRpb25zKCkge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMuc2VsZWN0b3Iub3B0aW9uc10ubWFwKChvKSA9PiBvLnZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHNlbGVjdGVkKHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgICAgLy8gQSB1c2VyIG1heSBub3Qgc3BlY2lmeSB0aGUgZnVsbCBwb3NzaWJsZSB2YWx1ZSBzbyB3ZSBpbnN0ZWFkIHVzZSB0aGUgY2xvc2VzdCBtYXRjaC5cbiAgICAgICAgLy8gZWcgP3h4eD1IMjY0IHdvdWxkIHNlbGVjdCAnSDI2NCBsZXZlbC1hc3ltbWV0cnktYWxsb3dlZD0xO3BhY2tldGl6YXRpb24tbW9kZT0xO3Byb2ZpbGUtbGV2ZWwtaWQ9NDIwMDFmJ1xuICAgICAgICBjb25zdCBmaWx0ZXJlZExpc3QgPSB0aGlzLm9wdGlvbnMuZmlsdGVyKFxuICAgICAgICAgICAgKG9wdGlvbjogc3RyaW5nKSA9PiBvcHRpb24uaW5kZXhPZih2YWx1ZSkgIT09IC0xXG4gICAgICAgICk7XG4gICAgICAgIGlmIChmaWx0ZXJlZExpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdG9yLnZhbHVlID0gZmlsdGVyZWRMaXN0WzBdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZWxlY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0b3IudmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0b3IuZGlzYWJsZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbmFibGUoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0b3IuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgdHlwZSB7XG4gICAgU2V0dGluZ1RleHQsXG4gICAgVGV4dFBhcmFtZXRlcnNJZHNcbn0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBTZXR0aW5nVUlCYXNlIH0gZnJvbSAnLi9TZXR0aW5nVUlCYXNlJztcblxuZXhwb3J0IGNsYXNzIFNldHRpbmdVSVRleHQ8XG4gICAgQ3VzdG9tSWRzIGV4dGVuZHMgc3RyaW5nID0gVGV4dFBhcmFtZXRlcnNJZHNcbj4gZXh0ZW5kcyBTZXR0aW5nVUlCYXNlIHtcbiAgICAvKiBBIHRleHQgYm94IHRoYXQgcmVmbGVjdHMgdGhlIHZhbHVlIG9mIHRoaXMgc2V0dGluZy4gKi9cbiAgICBfdGV4dGJveDogSFRNTElucHV0RWxlbWVudDsgLy8gaW5wdXQgdHlwZT1cInRleHRcIlxuXG4gICAgLyogVGhpcyBlbGVtZW50IGNvbnRhaW5zIGEgdGV4dCBub2RlIHRoYXQgcmVmbGVjdHMgdGhlIHNldHRpbmcncyB0ZXh0IGxhYmVsLiAqL1xuICAgIF9zZXR0aW5nc1RleHRFbGVtOiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmc6IFNldHRpbmdUZXh0PEN1c3RvbUlkcz4pIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZyk7XG5cbiAgICAgICAgdGhpcy5sYWJlbCA9IHRoaXMuc2V0dGluZy5sYWJlbDtcbiAgICAgICAgdGhpcy50ZXh0ID0gdGhpcy5zZXR0aW5nLnRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIHNldHRpbmcgY29tcG9uZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2V0dGluZygpOiBTZXR0aW5nVGV4dDxDdXN0b21JZHM+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmcgYXMgU2V0dGluZ1RleHQ8Q3VzdG9tSWRzPjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmdzVGV4dEVsZW0oKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3NldHRpbmdzVGV4dEVsZW0pIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gdGhpcy5zZXR0aW5nLmxhYmVsO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NUZXh0RWxlbS50aXRsZSA9IHRoaXMuc2V0dGluZy5kZXNjcmlwdGlvbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3NUZXh0RWxlbTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHRleHRib3goKTogSFRNTElucHV0RWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fdGV4dGJveCkge1xuICAgICAgICAgICAgdGhpcy5fdGV4dGJveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgICAgICB0aGlzLl90ZXh0Ym94LmNsYXNzTGlzdC5hZGQoJ2Zvcm0tY29udHJvbCcpO1xuICAgICAgICAgICAgdGhpcy5fdGV4dGJveC50eXBlID0gJ3RleHRib3gnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl90ZXh0Ym94O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFJldHVybiBvciBjcmVhdGVzIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcgaW4gdGhlIERPTS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHJvb3QgZGl2IHdpdGggXCJzZXR0aW5nXCIgY3NzIGNsYXNzXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSB0aGlzLnNldHRpbmcuaWQ7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nJyk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBkaXYgZWxlbWVudCB0byBjb250YWluIG91ciBzZXR0aW5nJ3MgdGV4dFxuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zZXR0aW5nc1RleHRFbGVtKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGxhYmVsIGVsZW1lbnQgdG8gd3JhcCBvdXQgaW5wdXQgdHlwZVxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHdyYXBwZXJMYWJlbCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBpbnB1dCB0eXBlPWNoZWNrYm94XG4gICAgICAgICAgICB0aGlzLnRleHRib3gudGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgICAgICB3cmFwcGVyTGFiZWwuYXBwZW5kQ2hpbGQodGhpcy50ZXh0Ym94KTtcblxuICAgICAgICAgICAgLy8gc2V0dXAgb24gY2hhbmdlIGZyb20gY2hlY2tib3hcbiAgICAgICAgICAgIHRoaXMudGV4dGJveC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5nLnRleHQgIT09IHRoaXMudGV4dGJveC52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcudGV4dCA9IHRoaXMudGV4dGJveC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nLnVwZGF0ZVVSTFBhcmFtcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHNldHRpbmcncyBzdG9yZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIGluVmFsdWUgVGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNldHRpbmcuXG4gICAgICovXG4gICAgcHVibGljIHNldCB0ZXh0KGluVmFsdWU6IHN0cmluZykge1xuICAgICAgICB0aGlzLnRleHRib3gudmFsdWUgPSBpblZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB2YWx1ZVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgdGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGV4dGJveC52YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxhYmVsIHRleHQgZm9yIHRoZSBzZXR0aW5nLlxuICAgICAqIEBwYXJhbSBsYWJlbCBzZXR0aW5nIGxhYmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXQgbGFiZWwoaW5MYWJlbDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQgPSBpbkxhYmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBsYWJlbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbGFiZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0O1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IEFjdGlvbk92ZXJsYXkgfSBmcm9tICcuL0FjdGlvbk92ZXJsYXknO1xuXG4vKipcbiAqIFNob3cgYW4gb3ZlcmxheSBmb3Igd2hlbiB0aGUgc2Vzc2lvbiBpcyB1bmF0dGVuZGVkLCBpdCBiZWdpbnMgYSBjb3VudGRvd24gdGltZXIsIHdoaWNoIHdoZW4gZWxhcHNlZCB3aWxsIGRpc2Nvbm5lY3QgdGhlIHN0cmVhbS5cbiAqL1xuZXhwb3J0IGNsYXNzIEFGS092ZXJsYXkgZXh0ZW5kcyBBY3Rpb25PdmVybGF5IHtcbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCByb290IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlUm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBhZmtPdmVybGF5SHRtbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBhZmtPdmVybGF5SHRtbC5pZCA9ICdhZmtPdmVybGF5JztcbiAgICAgICAgYWZrT3ZlcmxheUh0bWwuY2xhc3NOYW1lID0gJ2NsaWNrYWJsZVN0YXRlJztcbiAgICAgICAgcmV0dXJuIGFma092ZXJsYXlIdG1sO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIGNvbnRlbnQgZWxlbWVudCBvZiB0aGlzIG92ZXJsYXksIHdoaWNoIGNvbnRhaW4gc29tZSB0ZXh0IGZvciBhbiBhZmsgY291bnQgZG93bi5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZUNvbnRlbnRFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3QgYWZrT3ZlcmxheUh0bWxJbm5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBhZmtPdmVybGF5SHRtbElubmVyLmlkID0gJ2Fma092ZXJsYXlJbm5lcic7XG4gICAgICAgIGFma092ZXJsYXlIdG1sSW5uZXIuaW5uZXJIVE1MID1cbiAgICAgICAgICAgICc8Y2VudGVyPk5vIGFjdGl2aXR5IGRldGVjdGVkPGJyPkRpc2Nvbm5lY3RpbmcgaW4gPHNwYW4gaWQ9XCJhZmtDb3VudERvd25OdW1iZXJcIj48L3NwYW4+IHNlY29uZHM8YnI+Q2xpY2sgdG8gY29udGludWU8YnI+PC9jZW50ZXI+JztcbiAgICAgICAgcmV0dXJuIGFma092ZXJsYXlIdG1sSW5uZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGFuIEFmayBvdmVybGF5XG4gICAgICogQHBhcmFtIHBhcmVudEVsZW1lbnQgdGhlIGVsZW1lbnQgdGhpcyBvdmVybGF5IHdpbGwgYmUgaW5zZXJ0ZWQgaW50b1xuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihyb290RGl2OiBIVE1MRWxlbWVudCkge1xuICAgICAgICBzdXBlcihcbiAgICAgICAgICAgIHJvb3REaXYsXG4gICAgICAgICAgICBBRktPdmVybGF5LmNyZWF0ZVJvb3RFbGVtZW50KCksXG4gICAgICAgICAgICBBRktPdmVybGF5LmNyZWF0ZUNvbnRlbnRFbGVtZW50KClcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmF0ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGNvdW50IGRvd24gc3BhbnMgbnVtYmVyIGZvciB0aGUgb3ZlcmxheVxuICAgICAqIEBwYXJhbSBjb3VudGRvd24gdGhlIGNvdW50IGRvd24gbnVtYmVyIHRvIGJlIGluc2VydGVkIGludG8gdGhlIHNwYW4gZm9yIHVwZGF0aW5nXG4gICAgICovXG4gICAgcHVibGljIHVwZGF0ZUNvdW50ZG93bihjb3VudGRvd246IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IGA8Y2VudGVyPk5vIGFjdGl2aXR5IGRldGVjdGVkPGJyPkRpc2Nvbm5lY3RpbmcgaW4gPHNwYW4gaWQ9XCJhZmtDb3VudERvd25OdW1iZXJcIj4ke2NvdW50ZG93bn08L3NwYW4+IHNlY29uZHM8YnI+Q2xpY2sgdG8gY29udGludWU8YnI+PC9jZW50ZXI+YDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcblxuaW1wb3J0IHsgT3ZlcmxheUJhc2UgfSBmcm9tICcuL0Jhc2VPdmVybGF5JztcblxuLyoqXG4gKiBDbGFzcyBmb3IgdGhlIGJhc2UgYWN0aW9uIG92ZXJsYXkgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBjbGFzcyBBY3Rpb25PdmVybGF5IGV4dGVuZHMgT3ZlcmxheUJhc2Uge1xuICAgIG9uQWN0aW9uQ2FsbGJhY2s6ICguLi5hcmdzOiBbXSkgPT4gdm9pZDtcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhbiBhY3Rpb24gb3ZlcmxheVxuICAgICAqIEBwYXJhbSByb290RGl2IHRoZSByb290IGVsZW1lbnQgdGhpcyBvdmVybGF5IHdpbGwgYmUgaW5zZXJ0ZWQgaW50b1xuICAgICAqIEBwYXJhbSByb290RWxlbWVudCB0aGUgcm9vdCBlbGVtZW50IHRoYXQgaXMgdGhlIG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gY29udGVudEVsZW1lbnQgYW4gZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRleHQgZm9yIHRoZSBhY3Rpb24gb3ZlcmxheVxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgcm9vdERpdjogSFRNTEVsZW1lbnQsXG4gICAgICAgIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICAgICAgY29udGVudEVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICAgKSB7XG4gICAgICAgIHN1cGVyKHJvb3REaXYsIHJvb3RFbGVtZW50LCBjb250ZW50RWxlbWVudCk7XG4gICAgICAgIHRoaXMub25BY3Rpb25DYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGRvIG5vdGhpbmcgKi8gTG9nZ2VyLkluZm8oXG4gICAgICAgICAgICAgICAgTG9nZ2VyLkdldFN0YWNrVHJhY2UoKSxcbiAgICAgICAgICAgICAgICAnRGlkIHlvdSBmb3JnZXQgdG8gc2V0IHRoZSBvbkFjdGlvbiBjYWxsYmFjayBpbiB5b3VyIG92ZXJsYXk/J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHRleHQgb3ZlcmxheXMgaW5uZXIgdGV4dFxuICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB1cGRhdGUgdGV4dCB0byBiZSBpbnNlcnRlZCBpbnRvIHRoZSBvdmVybGF5XG4gICAgICovXG4gICAgcHVibGljIHVwZGF0ZSh0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRleHQgIT0gbnVsbCB8fCB0ZXh0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy50ZXh0RWxlbWVudC5pbm5lckhUTUwgPSB0ZXh0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGEgbWV0aG9kIGFzIGFuIGV2ZW50IGVtaXR0ZXIgY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0gY2FsbEJhY2sgdGhlIG1ldGhvZCB0aGF0IGlzIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gICAgICovXG4gICAgb25BY3Rpb24oY2FsbEJhY2s6ICguLi5hcmdzOiBbXSkgPT4gdm9pZCkge1xuICAgICAgICB0aGlzLm9uQWN0aW9uQ2FsbGJhY2sgPSBjYWxsQmFjaztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3RpdmF0ZSBhbiBldmVudCB0aGF0IGlzIGF0dGFjaGVkIHRvIHRoZSBldmVudCBlbWl0dGVyXG4gICAgICovXG4gICAgYWN0aXZhdGUoKSB7XG4gICAgICAgIHRoaXMub25BY3Rpb25DYWxsYmFjaygpO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbi8qKlxuICogQ2xhc3MgZm9yIHRoZSBiYXNlIG92ZXJsYXkgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBjbGFzcyBPdmVybGF5QmFzZSB7XG4gICAgcHJvdGVjdGVkIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBwcm90ZWN0ZWQgcm9vdERpdjogSFRNTEVsZW1lbnQ7XG4gICAgcHVibGljIHRleHRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhbiBvdmVybGF5XG4gICAgICogQHBhcmFtIHJvb3REaXYgdGhlIHJvb3QgZWxlbWVudCB0aGlzIG92ZXJsYXkgd2lsbCBiZSBpbnNlcnRlZCBpbnRvXG4gICAgICogQHBhcmFtIHJvb3RFbGVtZW50IHRoZSByb290IGVsZW1lbnQgdGhhdCBpcyB0aGUgb3ZlcmxheVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICAgICAgcm9vdERpdjogSFRNTEVsZW1lbnQsXG4gICAgICAgIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICAgICAgdGV4dEVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICAgKSB7XG4gICAgICAgIHRoaXMucm9vdERpdiA9IHJvb3REaXY7XG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQgPSByb290RWxlbWVudDtcbiAgICAgICAgdGhpcy50ZXh0RWxlbWVudCA9IHRleHRFbGVtZW50O1xuICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudGV4dEVsZW1lbnQpO1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgdGhpcy5yb290RGl2LmFwcGVuZENoaWxkKHRoaXMucm9vdEVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgdGhlIG92ZXJsYXlcbiAgICAgKi9cbiAgICBwdWJsaWMgc2hvdygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW5TdGF0ZScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhpZGUgdGhlIG92ZXJsYXlcbiAgICAgKi9cbiAgICBwdWJsaWMgaGlkZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdoaWRkZW5TdGF0ZScpO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IEFjdGlvbk92ZXJsYXkgfSBmcm9tICcuL0FjdGlvbk92ZXJsYXknO1xuXG4vKipcbiAqIE92ZXJsYXkgc2hvd24gZHVyaW5nIGNvbm5lY3Rpb24sIGhhcyBhIGJ1dHRvbiB0aGF0IGNhbiBiZSBjbGlja2VkIHRvIGluaXRpYXRlIGEgY29ubmVjdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3RPdmVybGF5IGV4dGVuZHMgQWN0aW9uT3ZlcmxheSB7XG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgcm9vdCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZVJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3QgY29ubmVjdEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgY29ubmVjdEVsZW0uaWQgPSAnY29ubmVjdE92ZXJsYXknO1xuICAgICAgICBjb25uZWN0RWxlbS5jbGFzc05hbWUgPSAnY2xpY2thYmxlU3RhdGUnO1xuICAgICAgICByZXR1cm4gY29ubmVjdEVsZW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgY29udGVudCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheSwgd2hpY2ggY29udGFpbiB3aGF0ZXZlciBjb250ZW50IHRoaXMgZWxlbWVudCBjb250YWlucywgbGlrZSB0ZXh0IG9yIGEgYnV0dG9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlQ29udGVudEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBjb25uZWN0Q29udGVudEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgY29ubmVjdENvbnRlbnRFbGVtLmlkID0gJ2Nvbm5lY3RCdXR0b24nO1xuICAgICAgICBjb25uZWN0Q29udGVudEVsZW0uaW5uZXJIVE1MID0gJ0NsaWNrIHRvIHN0YXJ0JztcbiAgICAgICAgcmV0dXJuIGNvbm5lY3RDb250ZW50RWxlbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgYSBjb25uZWN0IG92ZXJsYXkgd2l0aCBhIGNvbm5lY3Rpb24gYnV0dG9uLlxuICAgICAqIEBwYXJhbSBwYXJlbnRFbGVtIHRoZSBwYXJlbnQgZWxlbWVudCB0aGlzIG92ZXJsYXkgd2lsbCBiZSBpbnNlcnRlZCBpbnRvLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihwYXJlbnRFbGVtOiBIVE1MRWxlbWVudCkge1xuICAgICAgICBzdXBlcihcbiAgICAgICAgICAgIHBhcmVudEVsZW0sXG4gICAgICAgICAgICBDb25uZWN0T3ZlcmxheS5jcmVhdGVSb290RWxlbWVudCgpLFxuICAgICAgICAgICAgQ29ubmVjdE92ZXJsYXkuY3JlYXRlQ29udGVudEVsZW1lbnQoKVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIGFkZCB0aGUgbmV3IGV2ZW50IGxpc3RlbmVyXG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IEFjdGlvbk92ZXJsYXkgfSBmcm9tICcuL0FjdGlvbk92ZXJsYXknO1xuXG4vKipcbiAqIE92ZXJsYXkgc2hvd24gZHVyaW5nIGRpc2Nvbm5lY3Rpb24sIGhhcyBhIHJlY29ubmVjdGlvbiBlbGVtZW50IHRoYXQgY2FuIGJlIGNsaWNrZWQgdG8gcmVjb25uZWN0LlxuICovXG5leHBvcnQgY2xhc3MgRGlzY29ubmVjdE92ZXJsYXkgZXh0ZW5kcyBBY3Rpb25PdmVybGF5IHtcbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCByb290IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlUm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0T3ZlcmxheUh0bWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGlzY29ubmVjdE92ZXJsYXlIdG1sLmlkID0gJ2Rpc2Nvbm5lY3RPdmVybGF5JztcbiAgICAgICAgZGlzY29ubmVjdE92ZXJsYXlIdG1sLmNsYXNzTmFtZSA9ICdjbGlja2FibGVTdGF0ZSc7XG4gICAgICAgIHJldHVybiBkaXNjb25uZWN0T3ZlcmxheUh0bWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgY29udGVudCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheSwgd2hpY2ggY29udGFpbiB3aGF0ZXZlciBjb250ZW50IHRoaXMgZWxlbWVudCBjb250YWlucywgbGlrZSB0ZXh0IG9yIGEgYnV0dG9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlQ29udGVudEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICAvLyBidWlsZCB0aGUgaW5uZXIgaHRtbCBjb250YWluZXJcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdE92ZXJsYXlIdG1sQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGRpc2Nvbm5lY3RPdmVybGF5SHRtbENvbnRhaW5lci5pZCA9ICdkaXNjb25uZWN0QnV0dG9uJztcbiAgICAgICAgZGlzY29ubmVjdE92ZXJsYXlIdG1sQ29udGFpbmVyLmlubmVySFRNTCA9ICdDbGljayBUbyBSZXN0YXJ0JztcblxuICAgICAgICByZXR1cm4gZGlzY29ubmVjdE92ZXJsYXlIdG1sQ29udGFpbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIGRpc2Nvbm5lY3Qgb3ZlcmxheSB3aXRoIGEgcmV0cnkgY29ubmVjdGlvbiBpY29uLlxuICAgICAqIEBwYXJhbSBwYXJlbnRFbGVtIHRoZSBwYXJlbnQgZWxlbWVudCB0aGlzIG92ZXJsYXkgd2lsbCBiZSBpbnNlcnRlZCBpbnRvLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihwYXJlbnRFbGVtOiBIVE1MRWxlbWVudCkge1xuICAgICAgICBzdXBlcihcbiAgICAgICAgICAgIHBhcmVudEVsZW0sXG4gICAgICAgICAgICBEaXNjb25uZWN0T3ZlcmxheS5jcmVhdGVSb290RWxlbWVudCgpLFxuICAgICAgICAgICAgRGlzY29ubmVjdE92ZXJsYXkuY3JlYXRlQ29udGVudEVsZW1lbnQoKVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIGFkZCB0aGUgbmV3IGV2ZW50IGxpc3RlbmVyXG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IFRleHRPdmVybGF5IH0gZnJvbSAnLi9UZXh0T3ZlcmxheSc7XG5cbi8qKlxuICogR2VuZXJpYyBvdmVybGF5IHVzZWQgdG8gc2hvdyB0ZXh0dWFsIGVycm9yIGluZm8gdG8gdGhlIHVzZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBFcnJvck92ZXJsYXkgZXh0ZW5kcyBUZXh0T3ZlcmxheSB7XG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgcm9vdCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZVJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3QgZXJyb3JPdmVybGF5SHRtbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBlcnJvck92ZXJsYXlIdG1sLmlkID0gJ2Vycm9yT3ZlcmxheSc7XG4gICAgICAgIGVycm9yT3ZlcmxheUh0bWwuY2xhc3NOYW1lID0gJ3RleHREaXNwbGF5U3RhdGUnO1xuICAgICAgICByZXR1cm4gZXJyb3JPdmVybGF5SHRtbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBjb250ZW50IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LCB3aGljaCBjb250YWluIHdoYXRldmVyIGNvbnRlbnQgdGhpcyBlbGVtZW50IGNvbnRhaW5zLCBsaWtlIHRleHQgb3IgYSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVDb250ZW50RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0IGVycm9yT3ZlcmxheUh0bWxJbm5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBlcnJvck92ZXJsYXlIdG1sSW5uZXIuaWQgPSAnZXJyb3JPdmVybGF5SW5uZXInO1xuICAgICAgICByZXR1cm4gZXJyb3JPdmVybGF5SHRtbElubmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIGNvbm5lY3Qgb3ZlcmxheSB3aXRoIGEgY29ubmVjdGlvbiBidXR0b24uXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW0gdGhlIHBhcmVudCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG8uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmVudEVsZW06IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgcGFyZW50RWxlbSxcbiAgICAgICAgICAgIEVycm9yT3ZlcmxheS5jcmVhdGVSb290RWxlbWVudCgpLFxuICAgICAgICAgICAgRXJyb3JPdmVybGF5LmNyZWF0ZUNvbnRlbnRFbGVtZW50KClcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgeyBUZXh0T3ZlcmxheSB9IGZyb20gJy4vVGV4dE92ZXJsYXknO1xuXG4vKipcbiAqIEdlbmVyaWMgb3ZlcmxheSB1c2VkIHRvIHNob3cgdGV4dHVhbCBpbmZvIHRvIHRoZSB1c2VyLlxuICovXG5leHBvcnQgY2xhc3MgSW5mb092ZXJsYXkgZXh0ZW5kcyBUZXh0T3ZlcmxheSB7XG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgcm9vdCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZVJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3QgaW5mb092ZXJsYXlIdG1sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGluZm9PdmVybGF5SHRtbC5pZCA9ICdpbmZvT3ZlcmxheSc7XG4gICAgICAgIGluZm9PdmVybGF5SHRtbC5jbGFzc05hbWUgPSAndGV4dERpc3BsYXlTdGF0ZSc7XG4gICAgICAgIHJldHVybiBpbmZvT3ZlcmxheUh0bWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgY29udGVudCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheSwgd2hpY2ggY29udGFpbiB3aGF0ZXZlciBjb250ZW50IHRoaXMgZWxlbWVudCBjb250YWlucywgbGlrZSB0ZXh0IG9yIGEgYnV0dG9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlQ29udGVudEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBpbmZvT3ZlcmxheUh0bWxJbm5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBpbmZvT3ZlcmxheUh0bWxJbm5lci5pZCA9ICdtZXNzYWdlT3ZlcmxheUlubmVyJztcbiAgICAgICAgcmV0dXJuIGluZm9PdmVybGF5SHRtbElubmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIGNvbm5lY3Qgb3ZlcmxheSB3aXRoIGEgY29ubmVjdGlvbiBidXR0b24uXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW0gdGhlIHBhcmVudCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG8uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmVudEVsZW06IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgcGFyZW50RWxlbSxcbiAgICAgICAgICAgIEluZm9PdmVybGF5LmNyZWF0ZVJvb3RFbGVtZW50KCksXG4gICAgICAgICAgICBJbmZvT3ZlcmxheS5jcmVhdGVDb250ZW50RWxlbWVudCgpXG4gICAgICAgICk7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgQWN0aW9uT3ZlcmxheSB9IGZyb20gJy4vQWN0aW9uT3ZlcmxheSc7XG5cbi8qKlxuICogT3ZlcmxheSBzaG93biB3aGVuIHN0cmVhbSBpcyByZWFkeSB0byBwbGF5LlxuICovXG5leHBvcnQgY2xhc3MgUGxheU92ZXJsYXkgZXh0ZW5kcyBBY3Rpb25PdmVybGF5IHtcbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCByb290IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlUm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBwbGF5RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBwbGF5RWxlbS5pZCA9ICdwbGF5T3ZlcmxheSc7XG4gICAgICAgIHBsYXlFbGVtLmNsYXNzTmFtZSA9ICdjbGlja2FibGVTdGF0ZSc7XG4gICAgICAgIHJldHVybiBwbGF5RWxlbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBjb250ZW50IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LCB3aGljaCBjb250YWluIHdoYXRldmVyIGNvbnRlbnQgdGhpcyBlbGVtZW50IGNvbnRhaW5zLCBsaWtlIHRleHQgb3IgYSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVDb250ZW50RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIC8vIHRvZG86IGNoYW5nZSB0aGlzIHRvIGFuIHN2Z1xuICAgICAgICBjb25zdCBwbGF5T3ZlcmxheUh0bWxJbm5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgICBwbGF5T3ZlcmxheUh0bWxJbm5lci5pZCA9ICdwbGF5QnV0dG9uJztcbiAgICAgICAgcGxheU92ZXJsYXlIdG1sSW5uZXIuc3JjID1cbiAgICAgICAgICAgICdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQVBFQUFBRDVDQVlBQUFEMm1OTmtBQUFBQVhOU1IwSUFyczRjNlFBQUFBUm5RVTFCQUFDeGp3djhZUVVBQUFBSmNFaFpjd0FBRHNNQUFBN0RBY2R2cUdRQUFBQVpkRVZZZEZOdlpuUjNZWEpsQUhCaGFXNTBMbTVsZENBMExqQXVNakh4SUdtVkFBQVNna2xFUVZSNFh1MmRDN0JkVlgySHFVQ0NJUkFTQ1BqQUZJUVJFQlJCQlNSWWJGT3Q4bElyRlVXUkZxWFdzVDV3Ykl0VXFGV3MwS3FJTVBLb1lFV3BSUzA2S0RqUzFCZVZGa1ZRYkN3K3dDZmlBd0doQ0tXUDlQdVp0VTI0dVRlNTl6ejIyWS92bS9uR2tYdHo3amxycjkrc2RmWmVhLzAzV2IxNjlRdHhHVzYyaVlpMEQ4TDdOYndZajhFZGNkUHlJeEZwQTRUMlAvRi84VWE4Q0kvR2hQblh5cStJU0pNaHJBbHh4WDloUnVZTDhTaDhTUGsxRVdrcUJIWGRFRmZjZzZ2dzNmaHMzS2I4dW9nMERRSTZYWWdyOHJPdllzSjhPTTR2LzB4RW1rSUo2b2I0UDh6SWZBTmVnQ3ZRTUlzMEJRSzVzUkJYSk15L3dJek01K0J5WEZCZVJrUW1CVUdjYllqWDVTNU1tTS9BQTNDTDhuSWlVamNFY0pBUVY5eUJYOGEvd1NlaXo1aEY2b2JnRFJQaWtHZk1DZk9YOERUY3U3eTBpTlFCb1JzMnhCWC9nM2Rpd3Z3bTNLbjhDUkVaSjRSdFZDR3VxTUtjdTlrbjR4SjA5WmZJdUNCZ293NXh5SjNzVExOekF5d3J3RjZKMjZOaEZoazFCR3NjSVY2WGhQbHV2QTZQeHgzS254YVJVVUNveGgzaWlvUTV6NW4vQlkvRkplVXRpTWd3RUthNlFseVJNTitIbjhIbjRaYmxyWWpJSUJDaXVrTWM4cDI1V3M2Wk1EK3p2QjBSbVNzRWFCSWhua3JldzVWNEVIckNpTWhjS0FGcUN2K05sK0ordUJDOW15MnlNUWhLazBKY2tlL003OEdzeTA2WUgxVGVyb2hNaFlBME1jUVZQOE56OFVEY0NsMmJMVElWZ3RIa0VGZDhEOC9FL1hGcmRHUVdxU0FRYlFoeHlLT3BtL0IwM0FjOU1rZ2tFSWEyaExnaU43OFM1bFB4MGJnSXZRRW0vWVVBdEMzRUZRbnp6ZmdudURjNnpaWitRc2R2YTRqWDVTdjRhdHdYSFptbFg5RGh1eERpa0MyUW44ZFhZVWJtUmVVamluUWJPbnRYUWx5UlRSYWZ3bGRnd3J4VithZ2kzWVJPM3JVUVYvd2NWK0xMOERIb3laelNUZWpjWFExeFJjNy91aHl6bDNrdjNMeDhkSkZ1UUtmdWVvaERuakZuWlA0by9qN20wWlFINEVzM29EUDNJY1FWMmY2WU1GK0NPWmpnVWVpWjJkSnU2TVI5Q3ZHNjNJTHZ4NHpNQ2ZPODBpUWk3WUxPMjljUVYzd2IzNHNwc3I0cnVtQkUyZ1dkdHU4aERsbjk5UzFNWGVZWDRNNmxlVVNhRHgzV0VLOGxSZFlUNWxSL3pQbGZuc3dwelllT2FvalhKNGNTZkIzUHcrZmd0dWcwVzVvSm5kTVFUMC91WkdlYVhaVnlmVFp1VjVwTnBEblFNUTN4eHNrME85VWZ6OFpEY2R2U2ZDS1RodzVwaUdkUDJpb0Y0OTZKVDBjM1djamtLUjFUNWtZV2pDVE03OERmUWhlTXlPU2dBeHJpd2NoMzVsUi92QWJQd09Yb3pTK3BIenFlSVI2T2FsMTJ3dngyZkJ5NnlVTHFndzVuaUVkRHdweVIrVnBNa2ZYc21ISXBwNHdmT3BvaEhqMjM0UmZ3Rk53RG5XYkwrS0NER2VMeGtKSDVwM2cxdmc1M0swMHVNbHJvWElaNHZHVEJTTUo4RmVaa3ptV2w2VVZHQTUzS0VOZkQvWml5TkNteW52Ty9GcGRMSURJY2RDWkRYQzhabWZPZCtkL3dKZWpaWHpJY2RDSkRYRDk1eHB3amRuUCtWNzR6SDRXdS9wTEJvUE1ZNHNtU01OK0ZLYkorQkJwbW1SdDBHa1BjREJMbXUvRmplQWk2bEZObUI1M0ZFRGVIVExQemFDb2o4MGR3QmZxTVdUWU1uY1FRTjVlc0FQc3c3bGN1bDhqNjBFRU1jZlBKRGJEM1lVN2wzS3hjT3BFMTBDa01jVHZJVkR2Zm1jL0UzWEVMdFBxakdPS1draFZncCtHZW1ERDd2Ym5QMEFFTWNYdEprZlUzNEdOeEFUb3k5eEV1dkNGdVA2dndKTXlPcVlYbDBrcGY0S0liNG01UW5jeVpUUmFwWkdHWSt3SVgyeEIzaTN2eE9zd21pMTNRYVhiWDRRSWI0bTZTWTNhL2lNZGg3bVliNXE3Q2hUWEUzYVhhYUxFU3E3ck1XNVpMTDEyQmkycUkrOEU5ZURrbXpMdWhZZTRLWEV4RDNCOHlNdCtPbCtLTDBDTHJYWUNMYUlqN1I4SjhLMTZDUjZQTE9kc01GODhROTVmc21Qb1JYb3pQeGR6TmR2VlgyK0NpR1dMSnphK0VPWFdaajhTZDBBUHcyd0lYeXhCTHFQWXkzNExuWThLOERBMXowK0VpR1dLWlNnSjlJNzRMVTJSOVIzU2EzVlM0T0laWVpxSmF5bmtXcHNqNncwdTNrU2JCaFRIRXNqSHV3eHN3cFZ3UHc2V2wrMGdUNElJWVlwa05tV0tucjF5UHFmNTRLRzVWdXBGTWtuSmhSR1pMd3B6Vlg2bisrRFo4R3JwamFwSndBUXl4REVMQ25CMVRxV1R4MS9nVWRHU2VCRFM4SVpaQlNaQmp6djc2UFA0VkhvU0d1VTVvY0VNc295QmhUc0c0Vkg5OEl4NkE4MHMzazNGQ1F4dGlHU1ZaTVBJVC9Dd216UHVoejVqSENRMXNpR1VjWkNsbnd2eHBQQVgzTEYxT1JnMk5hNGhsWEdTS25RVWpDZk5uOFBYNENOeTBkRDhaQlRTb0laWnhrekJYSS9QbjhBVE11bXpEUEFwb1NFTXNkWkV3NXp2ekR6SFQ3SmRqd3V6Wlg4TkFBeHBpbVFTWlppZk1uOFRqOGFHbFM4cGNvZkVNc1V5S2pNdzVsVE9uakh3Y2MyVFFrdEkxWmJiUWFJWllKazNDbkUwV0dabXZ3T2VoKzVobkM0MWxpS1VwVkNOend2d0pQQnk5K2JVeGFDUkRMRTBqWWI0ZlUvMHgwK3lEOGNHbHk4cFVhQnhETEUwa1FhN0NmQ2ZtTUw4RDBTTjJwMEtqR0dKcE9nbHp0V2draC9rOUNUMWl0NExHTU1UU0ZoTG1MQnJKM2V4emNKL1NqZnNORFdHSXBZMGswRC9BTS9HUnBUdjNFeHJBRUV1YnFWYUFuWTVMc1g5M3MvblFobGk2UUxVRjhuV1lJM2JuWVQrV2MvSkJEYkYwaGVxTzlqZndsZmhJbkkvZERqTWYwQkJMRjBtWXI4TnNza2lOcVMyd20ySG1neGxpNlRKNXpwd2pnLzRRZDhidUxScmhReGxpNlFNNVpqZEhCaDJIK2M3Y25VVWpmQmhETEgwaFUreTdjQ1UrSDdPWGVWNkpRbnZoUXhoaTZSc0pjMGJteS9CWitNc2JZQ1VTN1lNM2I0aWxyeVRNMlFMNVFVekJ1SHhuYnQ4MG16ZHRpRVZXcjc0Tkw4S1VjazJSOWZhTXpMeFpReXl5aG96TVdjcDVJZjR1SnN6TlA1eUFOMm1JUlI1SVZuL2RqT2ZoRWRqc3cveDRjNFpZWkhyeWpQa21QQnNQd1llVjJEUUwzcGdoRnBtWlRMRnpaRkRDbkxyTXo4RHRzVGtiTFhnemhsaGs0eVRNMmN1OENyTmpLaU56d2p6NU9sTzhDVU1zTWpjUzVxekxmZ3VteVByMkpVNlRnVGRnaUVVR295cXlucnJNdjQyVE9UT2JQMnlJUlFZbjArd3M1YndhVThyMU4zSHJFcTk2NEE4YVlwSGhTWmp2d0JTTVM1Z1B3bnJXWmZPSERMSEk2TWd6NWh5eG00SnhmNGtINEhqRHpCOHd4Q0tqSjJIT05QdWY4Yzl4SHh6UFhtWmUyQkNMaklkTXNXTXFXZndUbm9pUHdkR096THlnSVJZWlB3bHpWV1BxdGJnWGptYkJDQzlraUVYcUk4K1lzOG5pY253TjdsYWlPRGk4aUNFV3FaZU15bG1YblRDbllGeE81dHl4UkhMdThJOE5zY2hrU0ppekx2djdtSkg1cGJnWTU3WmppbjlnaUVVbVN6VXlmdzlUWlAxWTNMWkVkT1B3eTRaWXBCa2t6S24rK0IzOEtCNkYyNVdvemd5L1pJaEZta1hDbkxPL3Zvc2Z3cHd5c3FoRWRuMzRvU0VXYVNZSjh5OHcwK3dQNEdHNC9vSVIvcU1oRm1rMlZaZ3p6VTZZczJOcTdUNW0vbzhoRm1rSENYTzJQeWJNRitPKytDQkRMTkl1RXVTc3k4NTM1bHZ4WkVNczBqNnFXc3paSmJYVUVJdTBpMXZ3clpocUZadjVuVmlrUFdUcWZBNW1GOVFERCtmalB4aGlrZWFSNzc3eGRyd0FuMUFpdXo3ODBCQ0xOSXZzZE1xQkFxa050UnczWEJlS1h6REVJcE1ubzI3Q2V6ZGVpay9HQlNXbUc0WmZOTVFpa3lQaHpYcnBWR1hNNlI4cmNHN2xWZmtIaGxpa2ZoTGU3RnpLbzZLVitIdTQ1bTd6WE9FZkdtS1Jlc2tlNG9UM2szZ01ibG5pT0JpOGdDRVdxWWVNdkQvR0svRjQzS0hFY0RoNElVTXNNbDV5dytwSG1MT29YNGFESDhVekhieWdJUllaRC9uZW01SDNLandCZDhMUlYxSGtSUTJ4eUdqSjNlYWNOWjFpYXlmaHIrUDQ2aG56NG9aWVpEUmsycHp3cGg3VFgrQ3VPUDc2eGZ3UlF5d3lITmxWVklYM1ZIeDhpVmM5OEFjTnNjamdaSkZHeXBxK0dmZkh3WjcxRGdOLzFCQ0x6SjJmNDcvaVd6QmxUSWQ3MWpzTS9IRkRMREk3Y3JmNUhyd0czNFlIWTcwRnhhZUROMkdJUlRaTXdwdmpjSzdGZCtCVGNmTGhyZUROR0dLUm1jbkllejIrRXcvRmhUaTNNaXZqaGpka2lFWFdKMGZFZmhYUHdtZmk0aEtaNXNHYk04UWlhOG42NWxYNExremxoWWVWcURRWDNxUWhGbG56clBjLzhGek10c0JsMkt4cDgwendSZzJ4OUowY3huNGVwb0JabGtqVy82eDNHSGpEaGxqNlNKWkk1Z1RKOStEek1lSGR2TVNpWGZER0RiSDBpV3BiWU1xZ0pMeTdZTHRHM3Fud0FReXg5SVZzQzd3RVg0Qzc0L2gyRnRVSkg4UVFTOWZKVVRnNVFmSTQzQVBubGU3ZkRmaEFobGk2U281Ly9SaStHQlBleWExdkhpZDhNRU1zWFNNSDBYMENYNEo3NGNMUzNic0pIOUFRUzFmSVRhdnM2ZjFWZUxFZHozcUhnUTlwaUtYdFpITkMxamZuRUxwZlRwdXgrK0d0NE1NYVlta3JtVFovR1YrTENXKzNwODB6d1FjM3hOSTJza1R5QnN3aGRIdGljN1lGVGdJYXdCQkxtN2dSVDhISDRkYlluMm56VE5BSWhsamFRQ3JrdndrVDN0eXdHdjhwa20yQnhqREUwbFJ5b2tiT3Nqb0RVeUUvTjZ3TTcxUm9GRU1zVFNQaHZSUGZqWS9HQmVpMGVTWm9IRU1zVGVKMi9BRHVnKzNjVlZRM05KUWhsaWFRa2ZjZjhTbm9xRHNYYURCRExKTWlqNHJ1eGN2d2FlaklPd2cwbkNHV3Vzbnl5SVQzQ2p3TSs3bElZMVRRZ0laWTZpQTNxekx5Wm1kUlNuMGVpYzA5UWJKTjBKQ0dXTVpKd3B1Ujl3NzhFcjRRdTdrbGNGTFFvSVpZeGtYcTlPWnVjMm9XWlhOQ3Y1ZEhqZ3NhMWhETHFLbkNtMnFCMlp6dzBOTGRaQnpRd0laWVJrV216VC9EaFBkRTNLVjBNeGtuTkxRaGxtSEo5OTZFTndYSHNqa2hxNnhjSGxrWE5MWWhsa0ZKZUhQREtodnlzemtoNFczMzhhOXRoRVkzeERKWDhxZ29HeE1TM3RUcGZTek9MMTFLNm9iR044UXlXeExlTEkvTXREbWxQdmRIcDgyVGhvdGdpR1UyWk9TdHdyc0NYU0xaRkxnWWhsZzJ4RjJZYzZ6T3hxZWpDeldhQmhmRkVNdDBwTWoyVnpCMWVnL0JKYVhMU05QZzRoaGlxY2pkNWl6VVNJWDhsUHA4Rmk0dFhVV2FDaGZKRUV0SWhmd1UyYjRRVTJSN08zUmZieHZnUWhuaWZwT0QxNytKQ1c5S2ZTNUY3emkzQ1M2WUllNG5PWGo5Vy9oM2VBdyt2SFFKYVJ0Y1BFUGNML0tzOTJhOENJL0ZYZEZwYzV2aEFocmkvdkI5L0h2OEEzd1V1a1N5QzNBaERYSDMrU24rQXg2UHFaRHZFc2t1d1FVMXhOMmtPZ29uSjBpbTFHYzJKMnhSTHJ0MENTNnNJZTRXMWM2aWoyTkczbFJPbUZjdXQzUVJMckFoN2c0Sjc1WDRSN2czR3Q0K3dJVTJ4TzBuMCtaUDRhc3dCY2RjMzl3bnVPQ0d1TDNrV2UvbjhEVzRMeTRxbDFYNkJCZmVFTGVUTCtBSitBVGNCbjNXMjFlNCtJYTRQZVNPODlmd1QvR0p1QWhkSXRsMzZBU0d1UGxrWjlHMzhmV1lvM0F5OGhwZVdRT2R3UkEzbHh3QmV4TytHVlBxMDdJbnNqNTBERVBjVExLKytlMlljNndXbzk5NVpYcm9ISWE0V2R5S09RcG5PV2JhdkdtNVZDTFRReWN4eE0wZ3AwaWVqMC9HM0xBeXZESTc2Q3lHZUhKVXgrRzhIdzlFd3l0emgwNWppQ2RERHFLN0hBL0FoZWgzWGhrTU9vOGhycGUwOTZmeGQ5RDl2REk4cFZQSitMa1hQNHZQUWFmTU1qcm9VSVo0Zk9RN2I5WTNYNFU1eDhvaTJ6SjY2RmlHZVBSa2VXUk9rZndpSG9lZTNTempndzVtaUVkRFJ0MTREK2J3OVpmakRxV1pSY1lISGMwUUQwOTFGRTZPZ1AwejlPQjFxUTg2bXlFZW5LeHRUbmd6OHI0QkhYbWxmdWg0aG5qdUpMd3A5WmxxZ2FmaDdxVTVSZXFIRG1pSVowK216VmtlZVFPK0ZSOWZtbEZrY3RBUkRmSHNTSjNlZjhkcVo1R0gwRWt6b0RNYTRwbkozZWEwVDA3VE9BZXp2bmxCYVRxUlpsQTZxVHlRaERkcm0xZmhCWGd3R2w1cEpuUk9RN3lXNmpsdnd2dGVmQVp1WHBwS3BKbVVUaXRycDgwcDlabjF6UTh1VFNUU2JPaXNmUTl4cHMycGtKL3dQaGUzSzAwajBnN290SDBOOGYzNGRYd2ZIbzBXMlpaMlF1ZnRZNGl6UERLbmFid0lINEVlL3lydGhRN2NseEJubGRVUDhCSjhNU2E4N3V1VjlrTkg3bnFJYzRaVnd2c2hmQ2t1UThNcjNZRU8zZFVRWjRua0QvSERtRktmZTVTUExOSXQ2TnhkREhIQyt4RjhCYWJzaVNPdmRCYzZlSmRDZkJ0ZWhnbHZpbXo3ckZlNkR4MjlDeUhPUW8wcjhOV1lPcjBXMlpiK1FJZHZhNGl6UkRMUGVsZGk2dlNtMU9mQzhyRkUrZ01kdjQwaHpudStHbE1oZnovY0VqME9SL29KbmI5TkljNTd2UVpQeENlaEk2OUlDVWJUeWRuTjErTEptUEF1S1c5ZlJBaEVrME9jWjczWFl3NmhPd2c5djFsa0tnU2pxU0hPNW9SVDhUZHdLYnErV1dRNkNFZVRRcHc3emxtb2NUcW1UbS9PYjdib21NaUdJQ1JOQ0hHbXpUL0JzekNsUGpQeXVzcEtaRFlRbGttSCtNZjR0N2djdDBlbnpTSnpnZEJNS3NRSjcwWDRWSFRrRlJrVXdsTjNpRk01NFlONEtHNkxIa1FuTWd5RXFLNFE1MW52cFpqd1p1UTF2Q0tqZ0REVkVlSXI4WEJNZUwzYkxESktDTlc0UXB5Ujl6bzhBcmRCYjFpSmpBUENOZW9RSjd5cEZuZ3N6a2MzSm9pTUUwSTJxaERuV1c4S2p2MHh1akZCcEM0STNEQWh6Z3FySEVTWFVwL1owL3VROHJJaVVoY0ViNUFRSjd6MzRUZndKTnk1dkp5STFBMEJuRzJJRTl5WXNpZmZ3VGZpenVoM1hwRkpRZ2huRStKODMwMTR2NHVwa0w4citxaElwQWtReGcyRk9PSE56ek50UGhmM1JFZGVrU1pSUWpxVlRKdHpndVNOZUQ0ZVdINWRSSm9HQVowYTRydnhtM2docmtDbnpTSk5ocEJXSWM3L3BscGd3cHVkUlo3ZExOSUdDT3Z0SmJ3WDQyRzR1UHhJUk5vQW9VMmQzaU54VWZsUEl0SWFOdG5rL3dFR0JvTWRwRUNHSEFBQUFBQkpSVTVFcmtKZ2dnPT0nO1xuICAgICAgICBwbGF5T3ZlcmxheUh0bWxJbm5lci5hbHQgPSAnU3RhcnQgU3RyZWFtaW5nJztcbiAgICAgICAgcmV0dXJuIHBsYXlPdmVybGF5SHRtbElubmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIGNvbm5lY3Qgb3ZlcmxheSB3aXRoIGEgY29ubmVjdGlvbiBidXR0b24uXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW0gdGhlIHBhcmVudCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG8uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmVudEVsZW06IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgcGFyZW50RWxlbSxcbiAgICAgICAgICAgIFBsYXlPdmVybGF5LmNyZWF0ZVJvb3RFbGVtZW50KCksXG4gICAgICAgICAgICBQbGF5T3ZlcmxheS5jcmVhdGVDb250ZW50RWxlbWVudCgpXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gYWRkIHRoZSBuZXcgZXZlbnQgbGlzdGVuZXJcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgT3ZlcmxheUJhc2UgfSBmcm9tICcuL0Jhc2VPdmVybGF5JztcblxuLyoqXG4gKiBDbGFzcyBmb3IgdGhlIHRleHQgb3ZlcmxheSBiYXNlXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0T3ZlcmxheSBleHRlbmRzIE92ZXJsYXlCYXNlIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgYSB0ZXh0IG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gcm9vdERpdiB0aGUgcm9vdCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG9cbiAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQgdGhlIHJvb3QgZWxlbWVudCB0aGF0IGlzIHRoZSBvdmVybGF5XG4gICAgICogQHBhcmFtIHRleHRFbGVtZW50IGFuIGVsZW1lbnQgdGhhdCBjb250YWlucyB0ZXh0IGZvciB0aGUgYWN0aW9uIG92ZXJsYXlcbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICAgIHJvb3REaXY6IEhUTUxFbGVtZW50LFxuICAgICAgICByb290RWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgICAgIHRleHRFbGVtZW50OiBIVE1MRWxlbWVudFxuICAgICkge1xuICAgICAgICBzdXBlcihyb290RGl2LCByb290RWxlbWVudCwgdGV4dEVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgdGV4dCBvdmVybGF5cyBpbm5lciB0ZXh0XG4gICAgICogQHBhcmFtIHRleHQgdGhlIHVwZGF0ZSB0ZXh0IHRvIGJlIGluc2VydGVkIGludG8gdGhlIG92ZXJsYXlcbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAodGV4dCAhPSBudWxsIHx8IHRleHQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKiBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAqL1xuXG5pbXBvcnQganNzLCB7IFN0eWxlcyB9IGZyb20gJ2pzcyc7XG5pbXBvcnQgZ2xvYmFsIGZyb20gJ2pzcy1wbHVnaW4tZ2xvYmFsJztcbmltcG9ydCBjYW1lbENhc2UgZnJvbSAnanNzLXBsdWdpbi1jYW1lbC1jYXNlJztcblxuZXhwb3J0IGludGVyZmFjZSBDb2xvclBhbGV0dGUge1xuICAgICctLWNvbG9yMCc6IHN0cmluZztcbiAgICAnLS1jb2xvcjEnOiBzdHJpbmc7XG4gICAgJy0tY29sb3IyJzogc3RyaW5nO1xuICAgICctLWNvbG9yMyc6IHN0cmluZztcbiAgICAnLS1jb2xvcjQnOiBzdHJpbmc7XG4gICAgJy0tY29sb3I1Jzogc3RyaW5nO1xuICAgICctLWNvbG9yNic6IHN0cmluZztcbiAgICAnLS1jb2xvcjcnOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBQaXhlbFN0cmVhbWluZ0FwcGxpY2F0aW9uU3R5bGUge1xuICAgIGRlZmF1bHRMaWdodE1vZGVQYWxldHRlOiBDb2xvclBhbGV0dGUgPSB7XG4gICAgICAgICctLWNvbG9yMCc6ICcjZTJlMGRkODAnLFxuICAgICAgICAnLS1jb2xvcjEnOiAnI0ZGRkZGRicsXG4gICAgICAgICctLWNvbG9yMic6ICcjMDAwMDAwJyxcbiAgICAgICAgJy0tY29sb3IzJzogJyMwNTg1ZmUnLFxuICAgICAgICAnLS1jb2xvcjQnOiAnIzM1YjM1MCcsXG4gICAgICAgICctLWNvbG9yNSc6ICcjZmZhYjAwJyxcbiAgICAgICAgJy0tY29sb3I2JzogJyNlMWUyZGQnLFxuICAgICAgICAnLS1jb2xvcjcnOiAnI2MzYzRiZidcbiAgICB9O1xuXG4gICAgZGVmYXVsdERhcmtNb2RlUGFsZXR0ZTogQ29sb3JQYWxldHRlID0ge1xuICAgICAgICAnLS1jb2xvcjAnOiAnIzFEMUYyMjgwJyxcbiAgICAgICAgJy0tY29sb3IxJzogJyMwMDAwMDAnLFxuICAgICAgICAnLS1jb2xvcjInOiAnI0ZGRkZGRicsXG4gICAgICAgICctLWNvbG9yMyc6ICcjMDU4NWZlJyxcbiAgICAgICAgJy0tY29sb3I0JzogJyMzNWIzNTAnLFxuICAgICAgICAnLS1jb2xvcjUnOiAnI2ZmYWIwMCcsXG4gICAgICAgICctLWNvbG9yNic6ICcjMWUxZDIyJyxcbiAgICAgICAgJy0tY29sb3I3JzogJyMzYzNiNDAnXG4gICAgfTtcblxuICAgIGRlZmF1bHRTdHlsZXMgPSB7XG4gICAgICAgICc6cm9vdCc6IHtcbiAgICAgICAgICAgICctLWNvbG9yMCc6ICcjMUQxRjIyODAnLFxuICAgICAgICAgICAgJy0tY29sb3IxJzogJyMwMDAwMDAnLFxuICAgICAgICAgICAgJy0tY29sb3IyJzogJyNGRkZGRkYnLFxuICAgICAgICAgICAgJy0tY29sb3IzJzogJyMwNTg1ZmUnLFxuICAgICAgICAgICAgJy0tY29sb3I0JzogJyMzNWIzNTAnLFxuICAgICAgICAgICAgJy0tY29sb3I1JzogJyNmZmFiMDAnLFxuICAgICAgICAgICAgJy0tY29sb3I2JzogJyMxZTFkMjInLFxuICAgICAgICAgICAgJy0tY29sb3I3JzogJyMzYzNiNDAnLFxuICAgICAgICAgICAgJy0tY29sb3I4JzogJyM0MTAwOGMnLFxuICAgICAgICAgICAgJy0tY29sb3I5JzogJyMzZTAwNzAnLFxuICAgICAgICAgICAgJy0tY29sb3IxMCc6ICcjMmUwMDUyJyxcbiAgICAgICAgICAgICctLWNvbG9yMTEnOiAncmdiYSg2NSwwLDEzOSwxKSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5ub3NlbGVjdCc6IHtcbiAgICAgICAgICAgIHVzZXJTZWxlY3Q6ICdub25lJ1xuICAgICAgICB9LFxuICAgICAgICAnI3BsYXllclVJJzoge1xuICAgICAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZSdcbiAgICAgICAgfSxcbiAgICAgICAgJyN2aWRlb0VsZW1lbnRQYXJlbnQnOiB7XG4gICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yMSknXG4gICAgICAgIH0sXG4gICAgICAgICcjdWlGZWF0dXJlcyc6IHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgICAgICAgIHpJbmRleDogJzMwJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgY29sb3I6ICd2YXIoLS1jb2xvcjIpJyxcbiAgICAgICAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ1xuICAgICAgICB9LFxuICAgICAgICAnLlVpVG9vbCAudG9vbHRpcHRleHQnOiB7XG4gICAgICAgICAgICB2aXNpYmlsaXR5OiAnaGlkZGVuJyxcbiAgICAgICAgICAgIHdpZHRoOiAnYXV0bycsXG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogJzE1cHgnLFxuICAgICAgICAgICAgcGFkZGluZzogJzBweCAxMHB4JyxcbiAgICAgICAgICAgIGZvbnRGYW1pbHk6IFwiJ01vbnRzZXJyYXQnLCBzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBmb250U2l6ZTogJzAuNzVyZW0nLFxuICAgICAgICAgICAgbGV0dGVyU3BhY2luZzogJzAuNzVweCcsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHRvcDogJzAnLFxuICAgICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlWSgyNSUpJyxcbiAgICAgICAgICAgIGxlZnQ6ICcxMjUlJyxcbiAgICAgICAgICAgIHpJbmRleDogJzIwJ1xuICAgICAgICB9LFxuICAgICAgICAnLlVpVG9vbDpob3ZlciAudG9vbHRpcHRleHQnOiB7XG4gICAgICAgICAgICB2aXNpYmlsaXR5OiAndmlzaWJsZScsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjcpJ1xuICAgICAgICB9LFxuICAgICAgICAnI2Nvbm5lY3Rpb24gLnRvb2x0aXB0ZXh0Jzoge1xuICAgICAgICAgICAgdG9wOiAnMTI1JScsXG4gICAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKC0yNSUpJyxcbiAgICAgICAgICAgIGxlZnQ6ICcwJyxcbiAgICAgICAgICAgIHpJbmRleDogJzIwJyxcbiAgICAgICAgICAgIHBhZGRpbmc6ICc1cHggMTBweCdcbiAgICAgICAgfSxcbiAgICAgICAgJyNjb25uZWN0aW9uJzoge1xuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICBib3R0b206ICc4JScsXG4gICAgICAgICAgICBsZWZ0OiAnNSUnLFxuICAgICAgICAgICAgZm9udEZhbWlseTogXCInTWljaHJvbWEnLCBzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBoZWlnaHQ6ICczcmVtJyxcbiAgICAgICAgICAgIHdpZHRoOiAnM3JlbScsXG4gICAgICAgICAgICBwb2ludGVyRXZlbnRzOiAnYWxsJ1xuICAgICAgICB9LFxuICAgICAgICAnI3NldHRpbmdzLXBhbmVsIC50b29sdGlwdGV4dCc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgICB0b3A6ICcxMjUlJyxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoLTUwJSknLFxuICAgICAgICAgICAgbGVmdDogJzAnLFxuICAgICAgICAgICAgekluZGV4OiAnMjAnLFxuICAgICAgICAgICAgcGFkZGluZzogJzVweCAxMHB4JyxcbiAgICAgICAgICAgIGJvcmRlcjogJzNweCBzb2xpZCB2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIHdpZHRoOiAnbWF4LWNvbnRlbnQnLFxuICAgICAgICAgICAgZmFsbGJhY2tzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogJ21heC1jb250ZW50J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBib3JkZXI6ICczcHggc29saWQgdmFyKC0tY29sb3IzKSdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogJzVweCAxMHB4J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB6SW5kZXg6ICcyMCdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogJzAnXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoLTUwJSknXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHRvcDogJzEyNSUnXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jaydcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICAgICcjY29udHJvbHMnOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHRvcDogJzMlJyxcbiAgICAgICAgICAgIGxlZnQ6ICcyJScsXG4gICAgICAgICAgICBmb250RmFtaWx5OiBcIidNaWNocm9tYScsIHNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIHBvaW50ZXJFdmVudHM6ICdhbGwnLFxuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJ1xuICAgICAgICB9LFxuICAgICAgICAnI2NvbnRyb2xzPionOiB7XG4gICAgICAgICAgICBtYXJnaW5Cb3R0b206ICcwLjVyZW0nLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgICBoZWlnaHQ6ICcycmVtJyxcbiAgICAgICAgICAgIGxpbmVIZWlnaHQ6ICcxLjc1cmVtJyxcbiAgICAgICAgICAgIHBhZGRpbmc6ICcwLjVyZW0nXG4gICAgICAgIH0sXG4gICAgICAgICcjY29udHJvbHMgI2FkZGl0aW9uYWxpbmZvJzoge1xuICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgIGZvbnRGYW1pbHk6IFwiJ01vbnRzZXJyYXQnLCBzYW5zLXNlcmlmXCJcbiAgICAgICAgfSxcbiAgICAgICAgJyNmdWxsc2NyZWVuLWJ0bic6IHtcbiAgICAgICAgICAgIHBhZGRpbmc6ICcwLjZyZW0gIWltcG9ydGFudCdcbiAgICAgICAgfSxcbiAgICAgICAgJyNtaW5pbWl6ZUljb24nOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnbm9uZSdcbiAgICAgICAgfSxcbiAgICAgICAgJyNzZXR0aW5nc0J0biwgI3N0YXRzQnRuJzoge1xuICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcidcbiAgICAgICAgfSxcbiAgICAgICAgJyN1aUZlYXR1cmVzIGJ1dHRvbic6IHtcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgYm9yZGVyOiAnMXB4IHNvbGlkIHZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgY29sb3I6ICd2YXIoLS1jb2xvcjIpJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgd2lkdGg6ICczcmVtJyxcbiAgICAgICAgICAgIGhlaWdodDogJzNyZW0nLFxuICAgICAgICAgICAgcGFkZGluZzogJzAuNXJlbScsXG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInXG4gICAgICAgIH0sXG4gICAgICAgICcjdWlGZWF0dXJlcyBidXR0b246aG92ZXInOiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIGJvcmRlcjogJzNweCBzb2xpZCB2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIHRyYW5zaXRpb246ICcwLjI1cyBlYXNlJyxcbiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAnMC41NXJlbScsXG4gICAgICAgICAgICBwYWRkaW5nVG9wOiAnMC41NXJlbSdcbiAgICAgICAgfSxcbiAgICAgICAgJyN1aUZlYXR1cmVzIGJ1dHRvbjphY3RpdmUnOiB7XG4gICAgICAgICAgICBib3JkZXI6ICczcHggc29saWQgdmFyKC0tY29sb3IzKScsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjcpJyxcbiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAnMC41NXJlbScsXG4gICAgICAgICAgICBwYWRkaW5nVG9wOiAnMC41NXJlbSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5idG4tZmxhdCc6IHtcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3RyYW5zcGFyZW50JyxcbiAgICAgICAgICAgIGNvbG9yOiAndmFyKC0tY29sb3IyKScsXG4gICAgICAgICAgICBmb250RmFtaWx5OiBcIidNb250c2VycmF0J1wiLFxuICAgICAgICAgICAgZm9udFdlaWdodDogJ2JvbGQnLFxuICAgICAgICAgICAgYm9yZGVyOiAnM3B4IHNvbGlkIHZhcigtLWNvbG9yMyknLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnMXJlbScsXG4gICAgICAgICAgICBmb250U2l6ZTogJzAuNzVyZW0nLFxuICAgICAgICAgICAgcGFkZGluZ0xlZnQ6ICcwLjVyZW0nLFxuICAgICAgICAgICAgcGFkZGluZ1JpZ2h0OiAnMC41cmVtJyxcbiAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJ1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1mbGF0OmhvdmVyJzoge1xuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndmFyKC0tY29sb3IzKScsXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiAnZWFzZSAwLjNzJ1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1mbGF0OmRpc2FibGVkJzoge1xuICAgICAgICAgICAgYmFja2dyb3VuZDogJ3ZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgYm9yZGVyQ29sb3I6ICd2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIGNvbG9yOiAndmFyKC0tY29sb3IzKScsXG4gICAgICAgICAgICBjdXJzb3I6ICdkZWZhdWx0J1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1mbGF0OmFjdGl2ZSc6IHtcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3RyYW5zcGFyZW50J1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1mbGF0OmZvY3VzJzoge1xuICAgICAgICAgICAgb3V0bGluZTogJ25vbmUnXG4gICAgICAgIH0sXG4gICAgICAgICcjdWlGZWF0dXJlcyBpbWcnOiB7XG4gICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5wYW5lbC13cmFwJzoge1xuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICB0b3A6ICcwJyxcbiAgICAgICAgICAgIGJvdHRvbTogJzAnLFxuICAgICAgICAgICAgcmlnaHQ6ICcwJyxcbiAgICAgICAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgICAgICAgbWluV2lkdGg6ICcyMHZ3JyxcbiAgICAgICAgICAgIG1heFdpZHRoOiAnOTB2dycsXG4gICAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDEwMCUpJyxcbiAgICAgICAgICAgIHRyYW5zaXRpb246ICcuM3MgZWFzZS1vdXQnLFxuICAgICAgICAgICAgcG9pbnRlckV2ZW50czogJ2FsbCcsXG4gICAgICAgICAgICBiYWNrZHJvcEZpbHRlcjogJ2JsdXIoMTBweCknLFxuICAgICAgICAgICAgJy13ZWJraXQtYmFja2Ryb3AtZmlsdGVyJzogJ2JsdXIoMTBweCknLFxuICAgICAgICAgICAgb3ZlcmZsb3dZOiAnYXV0bycsXG4gICAgICAgICAgICBvdmVyZmxvd1g6ICdoaWRkZW4nLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndmFyKC0tY29sb3IwKSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5wYW5lbC13cmFwLXZpc2libGUnOiB7XG4gICAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDAlKSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5wYW5lbCc6IHtcbiAgICAgICAgICAgIG92ZXJmbG93WTogJ2F1dG8nLFxuICAgICAgICAgICAgcGFkZGluZzogJzFlbSdcbiAgICAgICAgfSxcbiAgICAgICAgJyNzZXR0aW5nc0hlYWRpbmcsICNzdGF0c0hlYWRpbmcnOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMmVtJyxcbiAgICAgICAgICAgIG1hcmdpbkJsb2NrU3RhcnQ6ICcwLjY3ZW0nLFxuICAgICAgICAgICAgbWFyZ2luQmxvY2tFbmQ6ICcwLjY3ZW0nLFxuICAgICAgICAgICAgbWFyZ2luSW5saW5lU3RhcnQ6ICcwcHgnLFxuICAgICAgICAgICAgbWFyZ2luSW5saW5lRW5kOiAnMHB4JyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgcGFkZGluZzogJzAgMCAwIDJyZW0nXG4gICAgICAgIH0sXG4gICAgICAgICcjc2V0dGluZ3NDbG9zZSwgI3N0YXRzQ2xvc2UnOiB7XG4gICAgICAgICAgICBtYXJnaW46ICcwLjVyZW0nLFxuICAgICAgICAgICAgcGFkZGluZ1RvcDogJzAuNXJlbScsXG4gICAgICAgICAgICBwYWRkaW5nQm90dG9tOiAnMC41cmVtJyxcbiAgICAgICAgICAgIHBhZGRpbmdSaWdodDogJzAuNXJlbScsXG4gICAgICAgICAgICBmb250U2l6ZTogJzJlbScsXG4gICAgICAgICAgICBmbG9hdDogJ3JpZ2h0J1xuICAgICAgICB9LFxuICAgICAgICAnI3NldHRpbmdzQ2xvc2U6YWZ0ZXIsICNzdGF0c0Nsb3NlOmFmdGVyJzoge1xuICAgICAgICAgICAgcGFkZGluZ0xlZnQ6ICcwLjVyZW0nLFxuICAgICAgICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaycsXG4gICAgICAgICAgICBjb250ZW50OiAnXCJcXFxcMDBkN1wiJ1xuICAgICAgICB9LFxuICAgICAgICAnI3NldHRpbmdzQ2xvc2U6aG92ZXIsICNzdGF0c0Nsb3NlOmhvdmVyJzoge1xuICAgICAgICAgICAgY29sb3I6ICd2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIHRyYW5zaXRpb246ICdlYXNlIDAuM3MnXG4gICAgICAgIH0sXG4gICAgICAgICcjc2V0dGluZ3NDb250ZW50LCAjc3RhdHNDb250ZW50Jzoge1xuICAgICAgICAgICAgbWFyZ2luTGVmdDogJzJyZW0nLFxuICAgICAgICAgICAgbWFyZ2luUmlnaHQ6ICcycmVtJ1xuICAgICAgICB9LFxuICAgICAgICAnLnNldHRpbmcnOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICBmbGV4RGlyZWN0aW9uOiAncm93JyxcbiAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnc3BhY2UtYmV0d2VlbicsXG4gICAgICAgICAgICBwYWRkaW5nOiAnMC4xNXJlbSAxMHB4IDAuMTVyZW0gMTBweCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5zZXR0aW5ncy10ZXh0Jzoge1xuICAgICAgICAgICAgY29sb3I6ICd2YXIoLS1jb2xvcjIpJyxcbiAgICAgICAgICAgIHZlcnRpY2FsQWxpZ246ICdtaWRkbGUnLFxuICAgICAgICAgICAgZm9udFdlaWdodDogJ25vcm1hbCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5zZXR0aW5ncy1vcHRpb24nOiB7XG4gICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgdGV4dE92ZXJmbG93OiAnZWxsaXBzaXMnLFxuICAgICAgICAgICAgd2hpdGVTcGFjZTogJ25vd3JhcCdcbiAgICAgICAgfSxcbiAgICAgICAgJyNjb25uZWN0T3ZlcmxheSwgI3BsYXlPdmVybGF5LCAjaW5mb092ZXJsYXksICNlcnJvck92ZXJsYXksICNhZmtPdmVybGF5LCAjZGlzY29ubmVjdE92ZXJsYXknOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHpJbmRleDogJzMwJyxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMS44ZW0nLFxuICAgICAgICAgICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndmFyKC0tY29sb3IxKScsXG4gICAgICAgICAgICAgICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAganVzdGlmeUNvbnRlbnQ6ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIHRleHRUcmFuc2Zvcm06ICd1cHBlcmNhc2UnXG4gICAgICAgICAgICB9LFxuICAgICAgICAnLmNsaWNrYWJsZVN0YXRlJzoge1xuICAgICAgICAgICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAgICAgICAgICBqdXN0aWZ5Q29udGVudDogJ2NlbnRlcicsXG4gICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRleHREaXNwbGF5U3RhdGUnOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnZmxleCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5oaWRkZW5TdGF0ZSc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgICAgICB9LFxuICAgICAgICAnI3BsYXlCdXR0b24sICNjb25uZWN0QnV0dG9uJzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaycsXG4gICAgICAgICAgICBoZWlnaHQ6ICdhdXRvJyxcbiAgICAgICAgICAgIHpJbmRleDogJzMwJ1xuICAgICAgICB9LFxuICAgICAgICAnaW1nI3BsYXlCdXR0b24nOiB7XG4gICAgICAgICAgICBtYXhXaWR0aDogJzI0MXB4JyxcbiAgICAgICAgICAgIHdpZHRoOiAnMTAlJ1xuICAgICAgICB9LFxuICAgICAgICAnI3VpSW50ZXJhY3Rpb24nOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ2ZpeGVkJ1xuICAgICAgICB9LFxuICAgICAgICAnI1VJSW50ZXJhY3Rpb25CdXR0b25Cb3VuZGFyeSc6IHtcbiAgICAgICAgICAgIHBhZGRpbmc6ICcycHgnXG4gICAgICAgIH0sXG4gICAgICAgICcjVUlJbnRlcmFjdGlvbkJ1dHRvbic6IHtcbiAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInXG4gICAgICAgIH0sXG4gICAgICAgICcjaGlkZGVuSW5wdXQnOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIGxlZnQ6ICctMTAlJyxcbiAgICAgICAgICAgIHdpZHRoOiAnMHB4JyxcbiAgICAgICAgICAgIG9wYWNpdHk6ICcwJ1xuICAgICAgICB9LFxuICAgICAgICAnI2VkaXRUZXh0QnV0dG9uJzoge1xuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICBoZWlnaHQ6ICc0MHB4JyxcbiAgICAgICAgICAgIHdpZHRoOiAnNDBweCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5idG4tb3ZlcmxheSc6IHtcbiAgICAgICAgICAgIHZlcnRpY2FsQWxpZ246ICdtaWRkbGUnLFxuICAgICAgICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaydcbiAgICAgICAgfSxcbiAgICAgICAgJy50Z2wtc3dpdGNoJzoge1xuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbC1zd2l0Y2ggLnRnbCc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbCwgLnRnbDphZnRlciwgLnRnbDpiZWZvcmUsIC50Z2wgKiwgLnRnbCAqOmFmdGVyLCAudGdsICo6YmVmb3JlLCAudGdsKy50Z2wtc2xpZGVyJzpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAnLXdlYmtpdC1ib3gtc2l6aW5nJzogJ2JvcmRlci1ib3gnLFxuICAgICAgICAgICAgICAgIGJveFNpemluZzogJ2JvcmRlci1ib3gnXG4gICAgICAgICAgICB9LFxuICAgICAgICAnLnRnbDo6LW1vei1zZWxlY3Rpb24sIC50Z2w6YWZ0ZXI6Oi1tb3otc2VsZWN0aW9uLCAudGdsOmJlZm9yZTo6LW1vei1zZWxlY3Rpb24sIC50Z2wgKjo6LW1vei1zZWxlY3Rpb24sIC50Z2wgKjphZnRlcjo6LW1vei1zZWxlY3Rpb24sIC50Z2wgKjpiZWZvcmU6Oi1tb3otc2VsZWN0aW9uLCAudGdsKy50Z2wtc2xpZGVyOjotbW96LXNlbGVjdGlvbic6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ25vbmUnXG4gICAgICAgICAgICB9LFxuICAgICAgICAnLnRnbDo6c2VsZWN0aW9uLCAudGdsOmFmdGVyOjpzZWxlY3Rpb24sIC50Z2w6YmVmb3JlOjpzZWxlY3Rpb24sIC50Z2wgKjo6c2VsZWN0aW9uLCAudGdsICo6YWZ0ZXI6OnNlbGVjdGlvbiwgLnRnbCAqOmJlZm9yZTo6c2VsZWN0aW9uLCAudGdsKy50Z2wtc2xpZGVyOjpzZWxlY3Rpb24nOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICdub25lJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgJy50Z2wtc2xpZGVyJzoge30sXG4gICAgICAgICcudGdsKy50Z2wtc2xpZGVyJzoge1xuICAgICAgICAgICAgb3V0bGluZTogJzAnLFxuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcbiAgICAgICAgICAgIHdpZHRoOiAnNDBweCcsXG4gICAgICAgICAgICBoZWlnaHQ6ICcxOHB4JyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgICAgICB1c2VyU2VsZWN0OiAnbm9uZSdcbiAgICAgICAgfSxcbiAgICAgICAgJy50Z2wrLnRnbC1zbGlkZXI6YWZ0ZXIsIC50Z2wrLnRnbC1zbGlkZXI6YmVmb3JlJzoge1xuICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXG4gICAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snLFxuICAgICAgICAgICAgY29udGVudDogJ1wiXCInLFxuICAgICAgICAgICAgd2lkdGg6ICc1MCUnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJSdcbiAgICAgICAgfSxcbiAgICAgICAgJy50Z2wrLnRnbC1zbGlkZXI6YWZ0ZXInOiB7XG4gICAgICAgICAgICBsZWZ0OiAnMCdcbiAgICAgICAgfSxcbiAgICAgICAgJy50Z2wrLnRnbC1zbGlkZXI6YmVmb3JlJzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0sXG4gICAgICAgICcudGdsLWZsYXQrLnRnbC1zbGlkZXInOiB7XG4gICAgICAgICAgICBwYWRkaW5nOiAnMnB4JyxcbiAgICAgICAgICAgICctd2Via2l0LXRyYW5zaXRpb24nOiAnYWxsIC4ycyBlYXNlJyxcbiAgICAgICAgICAgIHRyYW5zaXRpb246ICdhbGwgLjJzIGVhc2UnLFxuICAgICAgICAgICAgYmFja2dyb3VuZDogJ3ZhcigtLWNvbG9yNiknLFxuICAgICAgICAgICAgYm9yZGVyOiAnM3B4IHNvbGlkIHZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnMmVtJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbC1mbGF0Ky50Z2wtc2xpZGVyOmFmdGVyJzoge1xuICAgICAgICAgICAgJy13ZWJraXQtdHJhbnNpdGlvbic6ICdhbGwgLjJzIGVhc2UnLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogJ2FsbCAuMnMgZWFzZScsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAndmFyKC0tY29sb3I3KScsXG4gICAgICAgICAgICBjb250ZW50OiAnXCJcIicsXG4gICAgICAgICAgICBib3JkZXJSYWRpdXM6ICcxZW0nXG4gICAgICAgIH0sXG4gICAgICAgICcudGdsLWZsYXQ6Y2hlY2tlZCsudGdsLXNsaWRlcic6IHtcbiAgICAgICAgICAgIGJvcmRlcjogJzNweCBzb2xpZCB2YXIoLS1jb2xvcjMpJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbC1mbGF0OmNoZWNrZWQrLnRnbC1zbGlkZXI6YWZ0ZXInOiB7XG4gICAgICAgICAgICBsZWZ0OiAnNTAlJyxcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICd2YXIoLS1jb2xvcjMpJ1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1hcHBseSc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jayAhaW1wb3J0YW50JyxcbiAgICAgICAgICAgIG1hcmdpbkxlZnQ6ICdhdXRvJyxcbiAgICAgICAgICAgIG1hcmdpblJpZ2h0OiAnYXV0bycsXG4gICAgICAgICAgICB3aWR0aDogJzQwJSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5mb3JtLWNvbnRyb2wnOiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjcpJyxcbiAgICAgICAgICAgIGJvcmRlcjogJzJweCBzb2xpZCB2YXIoLS1jb2xvcjcpJyxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogJzRweCcsXG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgdGV4dEFsaWduOiAncmlnaHQnLFxuICAgICAgICAgICAgZm9udEZhbWlseTogJ2luaGVyaXQnXG4gICAgICAgIH0sXG4gICAgICAgICcuZm9ybS1jb250cm9sOmhvdmVyJzoge1xuICAgICAgICAgICAgYm9yZGVyQ29sb3I6ICd2YXIoLS1jb2xvcjcpJ1xuICAgICAgICB9LFxuICAgICAgICAnLmZvcm0tZ3JvdXAnOiB7XG4gICAgICAgICAgICBwYWRkaW5nVG9wOiAnNHB4JyxcbiAgICAgICAgICAgIGRpc3BsYXk6ICdncmlkJyxcbiAgICAgICAgICAgIGdyaWRUZW1wbGF0ZUNvbHVtbnM6ICc4MCUgMjAlJyxcbiAgICAgICAgICAgIHJvd0dhcDogJzRweCcsXG4gICAgICAgICAgICBwYWRkaW5nUmlnaHQ6ICcxMHB4JyxcbiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAnMTBweCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5mb3JtLWdyb3VwIGxhYmVsJzoge1xuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiAnbm9ybWFsJ1xuICAgICAgICB9LFxuICAgICAgICAnLnNldHRpbmdzQ29udGFpbmVyJzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICAgICAgICBib3JkZXJCb3R0b206ICcxcHggc29saWQgdmFyKC0tY29sb3I3KScsXG4gICAgICAgICAgICBwYWRkaW5nVG9wOiAnMTBweCcsXG4gICAgICAgICAgICBwYWRkaW5nQm90dG9tOiAnMTBweCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5zZXR0aW5nc0NvbnRhaW5lcj4gOmZpcnN0LWNoaWxkJzoge1xuICAgICAgICAgICAgbWFyZ2luVG9wOiAnNHB4JyxcbiAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzRweCcsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiAnYm9sZCcsXG4gICAgICAgICAgICBqdXN0aWZ5Q29udGVudDogJ3NwYWNlLWJldHdlZW4nLFxuICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgZmxleERpcmVjdGlvbjogJ3JvdycsXG4gICAgICAgICAgICBhbGlnbkl0ZW1zOiAnYmFzZWxpbmUnXG4gICAgICAgIH0sXG4gICAgICAgICcuY29sbGFwc2UnOiB7XG4gICAgICAgICAgICBwYWRkaW5nTGVmdDogJzUlJ1xuICAgICAgICB9LFxuICAgICAgICAnI3N0cmVhbVRvb2xzJzoge1xuICAgICAgICAgICAgYm9yZGVyQm90dG9tUmlnaHRSYWRpdXM6ICc1cHgnLFxuICAgICAgICAgICAgYm9yZGVyQm90dG9tTGVmdFJhZGl1czogJzVweCcsXG4gICAgICAgICAgICB1c2VyU2VsZWN0OiAnbm9uZScsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHRvcDogJzAnLFxuICAgICAgICAgICAgcmlnaHQ6ICcyJScsXG4gICAgICAgICAgICB6SW5kZXg6ICcxMDAnLFxuICAgICAgICAgICAgYm9yZGVyOiAnNHB4IHNvbGlkIHZhcigtLWNvbG91cjgpJyxcbiAgICAgICAgICAgIGJvcmRlclRvcFdpZHRoOiAnMHB4J1xuICAgICAgICB9LFxuICAgICAgICAnLnNldHRpbmdzSGVhZGVyJzoge1xuICAgICAgICAgICAgZm9udFN0eWxlOiAnaXRhbGljJ1xuICAgICAgICB9LFxuICAgICAgICAnI3N0cmVhbVRvb2xzSGVhZGVyJzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgZmxleERpcmVjdGlvbjogJ3JvdycsXG4gICAgICAgICAgICBqdXN0aWZ5Q29udGVudDogJ3NwYWNlLWJldHdlZW4nLFxuICAgICAgICAgICAgYm9yZGVyQm90dG9tOiAnMXB4IHNvbGlkIHZhcigtLWNvbG91cjgpJyxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yNyknXG4gICAgICAgIH0sXG4gICAgICAgICcuc3RyZWFtVG9vbHMnOiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjIpJyxcbiAgICAgICAgICAgIGZvbnRGYW1pbHk6ICd2YXIoLS1idXR0b25Gb250KScsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiAnbGlnaHRlcicsXG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yNyknXG4gICAgICAgIH0sXG4gICAgICAgICcuc3RyZWFtVG9vbHMtc2hvd24+I3N0cmVhbVRvb2xzU2V0dGluZ3MsIC5zdHJlYW1Ub29scy1zaG93bj4jc3RyZWFtVG9vbHNTdGF0cyc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgJyNzdHJlYW1Ub29sc1RvZ2dsZSc6IHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTAwJSdcbiAgICAgICAgfSxcbiAgICAgICAgJyNxdWFsaXR5U3RhdHVzJzoge1xuICAgICAgICAgICAgZm9udFNpemU6ICczN3B4JyxcbiAgICAgICAgICAgIHBhZGRpbmdSaWdodDogJzRweCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5zdmdJY29uJzoge1xuICAgICAgICAgICAgZmlsbDogJ3ZhcigtLWNvbG9yMiknXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY3VzdG9tU3R5bGVzPzogUGFydGlhbDxTdHlsZXM+O1xuICAgIGxpZ2h0TW9kZVBhbGV0dGU6IENvbG9yUGFsZXR0ZTtcbiAgICBkYXJrTW9kZVBhbGV0dGU6IENvbG9yUGFsZXR0ZTtcblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM/OiB7XG4gICAgICAgIGN1c3RvbVN0eWxlcz86IFBhcnRpYWw8U3R5bGVzPjtcbiAgICAgICAgbGlnaHRNb2RlUGFsZXR0ZT86IENvbG9yUGFsZXR0ZTtcbiAgICAgICAgZGFya01vZGVQYWxldHRlPzogQ29sb3JQYWxldHRlO1xuICAgICAgICBqc3NJbnNlcnRpb25Qb2ludD86IHN0cmluZyB8IEhUTUxFbGVtZW50O1xuICAgIH0pIHtcbiAgICAgICAgY29uc3QgeyBjdXN0b21TdHlsZXMsIGxpZ2h0TW9kZVBhbGV0dGUsIGRhcmtNb2RlUGFsZXR0ZSwganNzSW5zZXJ0aW9uUG9pbnQgfSA9XG4gICAgICAgICAgICBvcHRpb25zID8/IHt9O1xuICAgICAgICAvLyBPbmUgdGltZSBzZXR1cCB3aXRoIGRlZmF1bHQgcGx1Z2lucyBhbmQgc2V0dGluZ3MuXG4gICAgICAgIGNvbnN0IGpzc09wdGlvbnMgPSB7XG4gICAgICAgICAgICAvLyBKU1MgaGFzIG1hbnkgaW50ZXJlc3RpbmcgcGx1Z2lucyB3ZSBtYXkgd2lzaCB0byB0dXJuIG9uXG4gICAgICAgICAgICAvL3BsdWdpbnM6IFtmdW5jdGlvbnMoKSwgdGVtcGxhdGUoKSwgZ2xvYmFsKCksIGV4dGVuZCgpLCBuZXN0ZWQoKSwgY29tcG9zZSgpLCBjYW1lbENhc2UoKSwgZGVmYXVsdFVuaXQob3B0aW9ucy5kZWZhdWx0VW5pdCksIGV4cGFuZCgpLCB2ZW5kb3JQcmVmaXhlcigpLCBwcm9wc1NvcnQoKV1cbiAgICAgICAgICAgIHBsdWdpbnM6IFtnbG9iYWwoKSwgY2FtZWxDYXNlKCldLFxuICAgICAgICAgICAgaW5zZXJ0aW9uUG9pbnQ6IGpzc0luc2VydGlvblBvaW50XG4gICAgICAgIH07XG5cbiAgICAgICAganNzLnNldHVwKGpzc09wdGlvbnMpO1xuXG4gICAgICAgIHRoaXMuY3VzdG9tU3R5bGVzID0gY3VzdG9tU3R5bGVzO1xuICAgICAgICB0aGlzLmxpZ2h0TW9kZVBhbGV0dGUgPVxuICAgICAgICAgICAgbGlnaHRNb2RlUGFsZXR0ZSA/PyB0aGlzLmRlZmF1bHRMaWdodE1vZGVQYWxldHRlO1xuICAgICAgICB0aGlzLmRhcmtNb2RlUGFsZXR0ZSA9IGRhcmtNb2RlUGFsZXR0ZSA/PyB0aGlzLmRlZmF1bHREYXJrTW9kZVBhbGV0dGU7XG4gICAgfVxuXG4gICAgYXBwbHlTdHlsZVNoZWV0KCkge1xuICAgICAgICAvLyBUb2RvOiByZWZhY3RvciBjb2RlYmFzZSB0byB1c2UganNzIGF0IGEgY29tcG9uZW50IGxldmVsLCBjbGFzc2VzIGNhbiBiZSBncmFiYmVkIGxpa2Ugc286XG4gICAgICAgIC8vY29uc3Qge3BpeGVsU3RyZWFtaW5nQ2xhc3Nlc30gPSBqc3MuY3JlYXRlU3R5bGVTaGVldChzdHlsZXMpLmF0dGFjaCgpO1xuXG4gICAgICAgIC8vIGF0dGFjaCBnZW5lcmF0ZWQgc3R5bGUgc2hlZXQgdG8gcGFnZVxuICAgICAgICBqc3MuY3JlYXRlU3R5bGVTaGVldCh7XG4gICAgICAgICAgICAnQGdsb2JhbCc6IHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmRlZmF1bHRTdHlsZXMsXG4gICAgICAgICAgICAgICAgLi4udGhpcy5jdXN0b21TdHlsZXNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuYXR0YWNoKCk7XG4gICAgfVxuXG4gICAgYXBwbHlQYWxldHRlKHBhbGV0dGU6IENvbG9yUGFsZXR0ZSkge1xuICAgICAgICBjb25zdCByb290RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJzpyb290JykgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIHJvb3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWNvbG9yMCcsIHBhbGV0dGVbJy0tY29sb3IwJ10pO1xuICAgICAgICByb290RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1jb2xvcjEnLCBwYWxldHRlWyctLWNvbG9yMSddKTtcbiAgICAgICAgcm9vdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tY29sb3IyJywgcGFsZXR0ZVsnLS1jb2xvcjInXSk7XG4gICAgICAgIHJvb3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWNvbG9yMycsIHBhbGV0dGVbJy0tY29sb3IzJ10pO1xuICAgICAgICByb290RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1jb2xvcjQnLCBwYWxldHRlWyctLWNvbG9yNCddKTtcbiAgICAgICAgcm9vdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tY29sb3I1JywgcGFsZXR0ZVsnLS1jb2xvcjUnXSk7XG4gICAgICAgIHJvb3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWNvbG9yNicsIHBhbGV0dGVbJy0tY29sb3I2J10pO1xuICAgICAgICByb290RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1jb2xvcjcnLCBwYWxldHRlWyctLWNvbG9yNyddKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHBsYXllcnMgY29sb3IgdmFyaWFibGVzXG4gICAgICogQHBhcmFtIGlzTGlnaHRNb2RlIC0gc2hvdWxkIHdlIHVzZSBhIGxpZ2h0IG9yIGRhcmsgY29sb3Igc2NoZW1lXG4gICAgICovXG4gICAgc2V0Q29sb3JNb2RlKGlzTGlnaHRNb2RlOiBib29sZWFuKSB7XG4gICAgICAgIGlmIChpc0xpZ2h0TW9kZSkge1xuICAgICAgICAgICAgdGhpcy5hcHBseVBhbGV0dGUodGhpcy5saWdodE1vZGVQYWxldHRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlQYWxldHRlKHRoaXMuZGFya01vZGVQYWxldHRlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IEZ1bGxTY3JlZW5JY29uIH0gZnJvbSAnLi9GdWxsc2NyZWVuSWNvbic7XG5pbXBvcnQgeyBTZXR0aW5nc0ljb24gfSBmcm9tICcuL1NldHRpbmdzSWNvbic7XG5pbXBvcnQgeyBTdGF0c0ljb24gfSBmcm9tICcuL1N0YXRzSWNvbic7XG5pbXBvcnQgeyBYUkljb24gfSBmcm9tICcuL1hSSWNvbic7XG5pbXBvcnQgeyBXZWJYUkNvbnRyb2xsZXIgfSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IFVJRWxlbWVudENvbmZpZywgVUlFbGVtZW50Q3JlYXRpb25Nb2RlIH0gZnJvbSAnLi4vVUkvVUlDb25maWd1cmF0aW9uVHlwZXMnXG5cbi8qKlxuICogQ29uZmlndXJlcyBob3cgVUkgZWxlbWVudHMgdG8gY29udHJvbCB0aGUgc3RyZWFtIGFyZSBjcmVhdGVkLiBcbiAqIEJ5IGRlZmF1bHQsIGEgYnV0dG9uIHdpbGwgYmUgY3JlYXRlZCBmb3IgZWFjaCBjb250cm9sLiBUaGF0IGNhbiBiZSBvdmVycmlkZW4gcGVyLWNvbnRyb2xcbiAqIHRvIHVzZSBhbiBleHRlcm5hbGx5IHByb3ZpZGVkIGVsZW1lbnQsIG9yIHRvIGRpc2FibGUgdGhlIGVsZW1lbnQgZW50aXJlbHkuXG4gKi9cbmV4cG9ydCB0eXBlIENvbnRyb2xzVUlDb25maWd1cmF0aW9uID0ge1xuICAgIC8vW1Byb3BlcnR5IGluIGtleW9mIENvbnRyb2xzIGFzIGAke1Byb3BlcnR5fVR5cGVgXT8gOiBVSUVsZW1lbnRUeXBlO1xuICAgIHN0YXRzQnV0dG9uVHlwZT8gOiBVSUVsZW1lbnRDb25maWcsXG4gICAgZnVsbHNjcmVlbkJ1dHRvblR5cGU/IDogVUlFbGVtZW50Q29uZmlnLFxuICAgIHNldHRpbmdzQnV0dG9uVHlwZT8gOiBVSUVsZW1lbnRDb25maWcsXG4gICAgeHJJY29uVHlwZT8gOiBVSUVsZW1lbnRDb25maWdcbn1cblxuLy8gSWYgdGhlcmUgaXNuJ3QgYSB0eXBlIHByb3ZpZGVkLCBkZWZhdWx0IGJlaGF2aW91ciBpcyB0byBjcmVhdGUgdGhlIGVsZW1lbnQuXG5mdW5jdGlvbiBzaG91bGRDcmVhdGVCdXR0b24odHlwZSA6IFVJRWxlbWVudENvbmZpZyB8IHVuZGVmaW5lZCkgOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHR5cGUgPT0gdW5kZWZpbmVkKSA/IHRydWUgOiAodHlwZS5jcmVhdGlvbk1vZGUgPT09IFVJRWxlbWVudENyZWF0aW9uTW9kZS5DcmVhdGVEZWZhdWx0RWxlbWVudCk7XG59XG5cbi8qKlxuICogRWxlbWVudCBjb250YWluaW5nIHZhcmlvdXMgY29udHJvbHMgbGlrZSBzdGF0cywgc2V0dGluZ3MsIGZ1bGxzY3JlZW4uXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250cm9scyB7XG4gICAgc3RhdHNJY29uOiBTdGF0c0ljb247XG4gICAgZnVsbHNjcmVlbkljb246IEZ1bGxTY3JlZW5JY29uO1xuICAgIHNldHRpbmdzSWNvbjogU2V0dGluZ3NJY29uO1xuICAgIHhySWNvbjogWFJJY29uO1xuXG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCB0aGUgY29udHJvbHNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihjb25maWc/IDogQ29udHJvbHNVSUNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgaWYgKCFjb25maWcgfHwgc2hvdWxkQ3JlYXRlQnV0dG9uKGNvbmZpZy5zdGF0c0J1dHRvblR5cGUpKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRzSWNvbiA9IG5ldyBTdGF0c0ljb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbmZpZyB8fCBzaG91bGRDcmVhdGVCdXR0b24oY29uZmlnLnNldHRpbmdzQnV0dG9uVHlwZSkpe1xuICAgICAgICAgICAgdGhpcy5zZXR0aW5nc0ljb24gPSBuZXcgU2V0dGluZ3NJY29uKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb25maWcgfHwgc2hvdWxkQ3JlYXRlQnV0dG9uKGNvbmZpZy5mdWxsc2NyZWVuQnV0dG9uVHlwZSkpIHtcbiAgICAgICAgICAgIHRoaXMuZnVsbHNjcmVlbkljb24gPSBuZXcgRnVsbFNjcmVlbkljb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbmZpZyB8fCBzaG91bGRDcmVhdGVCdXR0b24oY29uZmlnLnhySWNvblR5cGUpKXtcbiAgICAgICAgICAgIHRoaXMueHJJY29uID0gbmV3IFhSSWNvbigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGNvbnRyb2xzLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSAnY29udHJvbHMnO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5mdWxsc2NyZWVuSWNvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZnVsbHNjcmVlbkljb24ucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXR0aW5nc0ljb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNldHRpbmdzSWNvbi5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0YXRzSWNvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc3RhdHNJY29uLnJvb3RFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMueHJJY29uKSB7XG4gICAgICAgICAgICAgICAgV2ViWFJDb250cm9sbGVyLmlzU2Vzc2lvblN1cHBvcnRlZCgnaW1tZXJzaXZlLXZyJykudGhlbihcbiAgICAgICAgICAgICAgICAoc3VwcG9ydGVkOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMueHJJY29uLnJvb3RFbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxufSIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHtcbiAgICBEYXRhQ2hhbm5lbExhdGVuY3lUZXN0UmVzdWx0XG59IGZyb20gXCJAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zL3R5cGVzL0RhdGFDaGFubmVsL0RhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHRzXCI7XG5cbi8qKlxuICogRGF0YUNoYW5uZWwgTGF0ZW5jeSB0ZXN0IFVJIGVsZW1lbnRzIGFuZCByZXN1bHRzIGhhbmRsaW5nLlxuICovXG5leHBvcnQgY2xhc3MgRGF0YUNoYW5uZWxMYXRlbmN5VGVzdCB7XG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBfbGF0ZW5jeVRlc3RCdXR0b246IEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBidXR0b24gY29udGFpbmluZyB0aGUgc3RhdHMgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzZWN0aW9uJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0NvbnRhaW5lcicpO1xuXG4gICAgICAgICAgICAvLyBtYWtlIGhlYWRpbmdcbiAgICAgICAgICAgIGNvbnN0IGhlYWRpbmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGhlYWRpbmcuaWQgPSAnZGF0YUNoYW5uZWxMYXRlbmN5VGVzdEhlYWRlcic7XG4gICAgICAgICAgICBoZWFkaW5nLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzLXRleHQnKTtcbiAgICAgICAgICAgIGhlYWRpbmcuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3NIZWFkZXInKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKGhlYWRpbmcpO1xuXG4gICAgICAgICAgICBjb25zdCBoZWFkaW5nVGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgaGVhZGluZ1RleHQuaW5uZXJIVE1MID0gJ0RhdGEgQ2hhbm5lbCBMYXRlbmN5IFRlc3QnO1xuICAgICAgICAgICAgaGVhZGluZy5hcHBlbmRDaGlsZChoZWFkaW5nVGV4dCk7XG4gICAgICAgICAgICBoZWFkaW5nLmFwcGVuZENoaWxkKHRoaXMubGF0ZW5jeVRlc3RCdXR0b24pO1xuXG4gICAgICAgICAgICAvLyBtYWtlIHRlc3QgcmVzdWx0cyBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzUGFyZW50RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgcmVzdWx0c1BhcmVudEVsZW0uaWQgPSAnZGF0YUNoYW5uZWxMYXRlbmN5VGVzdENvbnRhaW5lcic7XG4gICAgICAgICAgICByZXN1bHRzUGFyZW50RWxlbS5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHJlc3VsdHNQYXJlbnRFbGVtKTtcblxuICAgICAgICAgICAgcmVzdWx0c1BhcmVudEVsZW0uYXBwZW5kQ2hpbGQodGhpcy5sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmlkID0gJ2RhdGFDaGFubmVsTGF0ZW5jeVN0YXRzUmVzdWx0cyc7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ1N0YXRzUmVzdWx0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsYXRlbmN5VGVzdEJ1dHRvbigpOiBIVE1MSW5wdXRFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbikge1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24udmFsdWUgPSAnUnVuIFRlc3QnO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24uaWQgPSAnYnRuLXN0YXJ0LWRhdGEtY2hhbm5lbC1sYXRlbmN5LXRlc3QnO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24uY2xhc3NMaXN0LmFkZCgnc3RyZWFtVG9vbHMtYnV0dG9uJyk7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdidG4tZmxhdCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQb3B1bGF0ZSB0aGUgVUkgYmFzZWQgb24gdGhlIGxhdGVuY3kgdGVzdCdzIHJlc3VsdHMuXG4gICAgICogQHBhcmFtIHJlc3VsdCBUaGUgbGF0ZW5jeSB0ZXN0IHJlc3VsdHMuXG4gICAgICovXG4gICAgcHVibGljIGhhbmRsZVRlc3RSZXN1bHQocmVzdWx0OiBEYXRhQ2hhbm5lbExhdGVuY3lUZXN0UmVzdWx0KSB7XG4gICAgICAgIExvZ2dlci5Mb2coXG4gICAgICAgICAgICBMb2dnZXIuR2V0U3RhY2tUcmFjZSgpLFxuICAgICAgICAgICAgcmVzdWx0LnRvU3RyaW5nKCksXG4gICAgICAgICAgICA2XG4gICAgICAgICk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVjayB3ZSBoYXZlIHJlc3VsdHMsIE5hTiB3b3VsZCBtZWFuIHRoYXQgVUUgdmVyc2lvbiB3ZSB0YWxrIHRvIGRvZXNuJ3Qgc3VwcG9ydCBvdXIgdGVzdFxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGlzTmFOKHJlc3VsdC5kYXRhQ2hhbm5lbFJ0dCkpIHtcbiAgICAgICAgICAgIHRoaXMubGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudC5pbm5lckhUTUwgPSAnPGRpdj5Ob3Qgc3VwcG9ydGVkPC9kaXY+JztcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MID0gJyc7XG4gICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgJzxkaXY+RGF0YSBjaGFubmVsIFJUVCAobXMpOiAnICtcbiAgICAgICAgICAgIHJlc3VsdC5kYXRhQ2hhbm5lbFJ0dCArXG4gICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNlcGFyYXRlIHBhdGggdGltZSBkaXNjb3Zlcnkgd29ya3Mgb25seSB3aGVuIFVFIGFuZCBQbGF5ZXIgY2xvY2tzIGhhdmUgYmVlbiBzeW5jaHJvbml6ZWQuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAocmVzdWx0LnBsYXllclRvU3RyZWFtZXJUaW1lID49IDAgJiYgcmVzdWx0LnN0cmVhbWVyVG9QbGF5ZXJUaW1lID49IDApIHtcbiAgICAgICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgICAgICc8ZGl2PlBsYXllciB0byBTdHJlYW1lciBwYXRoIChtcyk6ICcgKyByZXN1bHQucGxheWVyVG9TdHJlYW1lclRpbWUgKyAnPC9kaXY+JztcbiAgICAgICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgICAgICc8ZGl2PlN0cmVhbWVyIHRvIFBsYXllciBwYXRoIChtcyk6ICcgK1xuICAgICAgICAgICAgICAgIHJlc3VsdC5zdHJlYW1lclRvUGxheWVyVGltZSArXG4gICAgICAgICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmlubmVySFRNTCA9IGxhdGVuY3lTdGF0c0lubmVySFRNTDtcbiAgICAgICAgLy9zZXR1cCBidXR0b24gdG8gZG93bmxvYWQgdGhlIGRldGFpbGVkIHJlc3VsdHNcbiAgICAgICAgbGV0IGRvd25sb2FkQnV0dG9uOiBIVE1MSW5wdXRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgZG93bmxvYWRCdXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICBkb3dubG9hZEJ1dHRvbi52YWx1ZSA9ICdEb3dubG9hZCc7XG4gICAgICAgIGRvd25sb2FkQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ3N0cmVhbVRvb2xzLWJ1dHRvbicpO1xuICAgICAgICBkb3dubG9hZEJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdidG4tZmxhdCcpO1xuICAgICAgICBkb3dubG9hZEJ1dHRvbi5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgbGV0IGZpbGUgPSBuZXcgQmxvYihbcmVzdWx0LmV4cG9ydExhdGVuY3lBc0NTVigpXSwge3R5cGU6ICd0ZXh0L3BsYWluJ30pO1xuICAgICAgICAgICAgbGV0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKSxcbiAgICAgICAgICAgICAgICB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpO1xuICAgICAgICAgICAgYS5ocmVmID0gdXJsO1xuICAgICAgICAgICAgYS5kb3dubG9hZCA9IFwiZGF0YV9jaGFubmVsX2xhdGVuY3lfdGVzdF9yZXN1bHRzLmNzdlwiO1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICAgICAgICAgIGEuY2xpY2soKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTtcbiAgICAgICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmFwcGVuZENoaWxkKGRvd25sb2FkQnV0dG9uKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFuZGxlVGVzdFN0YXJ0KCkge1xuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuaW5uZXJIVE1MID1cbiAgICAgICAgICAgICc8ZGl2PlRlc3QgaW4gcHJvZ3Jlc3M8L2Rpdj4nO1xuICAgIH1cblxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuLyoqXG4gKiBEZWNsYXJlIGFkZGl0aW9ucyB0byBiYXNlIHR5cGVzIGZvciBjcm9zcyBicm93c2VyIGZ1bGxzY3JlZW4gZnVuY3Rpb25hbGl0eS5cbiAqL1xuZGVjbGFyZSBnbG9iYWwge1xuICAgIGludGVyZmFjZSBEb2N1bWVudCB7XG4gICAgICAgIHdlYmtpdElzRnVsbFNjcmVlbj86IGJvb2xlYW47XG4gICAgICAgIG1vekZ1bGxTY3JlZW4/OiBib29sZWFuO1xuICAgICAgICB3ZWJraXRGdWxsc2NyZWVuRW5hYmxlZD86IGJvb2xlYW47XG4gICAgICAgIG1vekNhbmNlbEZ1bGxTY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICBtc0V4aXRGdWxsc2NyZWVuPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgICAgICAgd2Via2l0RXhpdEZ1bGxzY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICBtb3pGdWxsU2NyZWVuRWxlbWVudD86IEVsZW1lbnQ7XG4gICAgICAgIG1zRnVsbHNjcmVlbkVsZW1lbnQ/OiBFbGVtZW50O1xuICAgICAgICB3ZWJraXRGdWxsc2NyZWVuRWxlbWVudD86IEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgaW50ZXJmYWNlIEhUTUxFbGVtZW50IHtcbiAgICAgICAgbXNSZXF1ZXN0RnVsbHNjcmVlbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gICAgICAgIG1velJlcXVlc3RGdWxsc2NyZWVuPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgICAgICAgd2Via2l0UmVxdWVzdEZ1bGxzY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICB3ZWJraXRFbnRlckZ1bGxzY3JlZW4/OiAoKSA9PiB2b2lkO1xuICAgIH1cbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhbiBlbGVtZW50IChpLmUuIGJ1dHRvbikgdGhhdCwgd2hlbiBjbGlja2VkLCB3aWxsIHRvZ2dsZSBmdWxsc2NyZWVuIG9mIGEgZ2l2ZW4gZWxlbWVudC5cbiAqIENhbiBiZSBpbml0aWFsaXplZCB3aXRoIGFueSBIVE1MRWxlbWVudCwgaWYgaXQgaXMgc2V0IGFzIHJvb3RFbGVtZW50IGluIHRoZSBjb25zdHJ1Y3Rvci5cbiAqL1xuZXhwb3J0IGNsYXNzIEZ1bGxTY3JlZW5JY29uQmFzZSB7XG4gICAgaXNGdWxsc2NyZWVuID0gZmFsc2U7XG4gICAgZnVsbHNjcmVlbkVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCByb290RWxlbWVudChlbGVtZW50KSB7XG4gICAgICAgIGVsZW1lbnQub25jbGljayA9ICgpID0+IHRoaXMudG9nZ2xlRnVsbHNjcmVlbigpO1xuICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoKSB7ICAgICAgIFxuICAgICAgICAvLyBzZXQgdXAgdGhlIGZ1bGwgc2NyZWVuIGV2ZW50c1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3dlYmtpdGZ1bGxzY3JlZW5jaGFuZ2UnLFxuICAgICAgICAgICAgKCkgPT4gdGhpcy5vbkZ1bGxzY3JlZW5DaGFuZ2UoKSxcbiAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnbW96ZnVsbHNjcmVlbmNoYW5nZScsXG4gICAgICAgICAgICAoKSA9PiB0aGlzLm9uRnVsbHNjcmVlbkNoYW5nZSgpLFxuICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdmdWxsc2NyZWVuY2hhbmdlJyxcbiAgICAgICAgICAgICgpID0+IHRoaXMub25GdWxsc2NyZWVuQ2hhbmdlKCksXG4gICAgICAgICAgICBmYWxzZVxuICAgICAgICApO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ01TRnVsbHNjcmVlbkNoYW5nZScsXG4gICAgICAgICAgICAoKSA9PiB0aGlzLm9uRnVsbHNjcmVlbkNoYW5nZSgpLFxuICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyB0aGUgZG9jdW1lbnQgb3IgZnVsbHNjcmVlbkVsZW1lbnQgZnVsbHNjcmVlbi5cbiAgICAgKi9cbiAgICB0b2dnbGVGdWxsc2NyZWVuKCkge1xuICAgICAgICAvLyBpZiBhbHJlYWR5IGZ1bGwgc2NyZWVuOyBleGl0XG4gICAgICAgIC8vIGVsc2UgZ28gZnVsbHNjcmVlblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBkb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCB8fFxuICAgICAgICAgICAgZG9jdW1lbnQud2Via2l0RnVsbHNjcmVlbkVsZW1lbnQgfHxcbiAgICAgICAgICAgIGRvY3VtZW50Lm1vekZ1bGxTY3JlZW5FbGVtZW50IHx8XG4gICAgICAgICAgICBkb2N1bWVudC5tc0Z1bGxzY3JlZW5FbGVtZW50XG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKGRvY3VtZW50LmV4aXRGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQubW96Q2FuY2VsRnVsbFNjcmVlbikge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50Lm1vekNhbmNlbEZ1bGxTY3JlZW4oKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC53ZWJraXRFeGl0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC5tc0V4aXRGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQubXNFeGl0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZnVsbHNjcmVlbkVsZW1lbnQ7XG5cbiAgICAgICAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlbGVtZW50LnJlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5yZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50Lm1velJlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5tb3pSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50Lm1zUmVxdWVzdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50Lm1zUmVxdWVzdEZ1bGxzY3JlZW4oKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC53ZWJraXRFbnRlckZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LndlYmtpdEVudGVyRnVsbHNjcmVlbigpOyAvL2ZvciBpcGhvbmUgdGhpcyBjb2RlIHdvcmtlZFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMub25GdWxsc2NyZWVuQ2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB0aGUgZnVsbHNjcmVlbiBidXR0b24gb24gY2hhbmdlXG4gICAgICovXG4gICAgb25GdWxsc2NyZWVuQ2hhbmdlKCkge1xuICAgICAgICB0aGlzLmlzRnVsbHNjcmVlbiA9XG4gICAgICAgICAgICBkb2N1bWVudC53ZWJraXRJc0Z1bGxTY3JlZW4gfHxcbiAgICAgICAgICAgIGRvY3VtZW50Lm1vekZ1bGxTY3JlZW4gfHxcbiAgICAgICAgICAgIChkb2N1bWVudC5tc0Z1bGxzY3JlZW5FbGVtZW50ICYmXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQubXNGdWxsc2NyZWVuRWxlbWVudCAhPT0gbnVsbCkgfHxcbiAgICAgICAgICAgIChkb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCAmJiBkb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCAhPT0gbnVsbCk7XG4gICAgfVxufVxuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIEZ1bGxTY3JlZW5JY29uQmFzZSB0aGF0IHVzZXMgYW4gZXh0ZXJuYWxseVxuICogcHJvdmlkZWQgSFRNTEVsZW1lbnQgZm9yIHRvZ2dsaW5nIGZ1bGwgc2NyZWVuLlxuICovXG5leHBvcnQgY2xhc3MgRnVsbFNjcmVlbkljb25FeHRlcm5hbCBleHRlbmRzIEZ1bGxTY3JlZW5JY29uQmFzZSB7XG5cbiAgICBjb25zdHJ1Y3RvcihleHRlcm5hbEJ1dHRvbiA6IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQgPSBleHRlcm5hbEJ1dHRvbjtcbiAgICB9XG5cbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBmdWxsc2NyZWVuIGljb24gdGhhdCBjb250YWlucyBhIGJ1dHRvbiBhbmQgc3ZncyBmb3IgZWFjaCBzdGF0ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZ1bGxTY3JlZW5JY29uIGV4dGVuZHMgRnVsbFNjcmVlbkljb25CYXNlIHtcbiAgICBfbWF4aW1pemVJY29uOiBTVkdFbGVtZW50O1xuICAgIF9taW5pbWl6ZUljb246IFNWR0VsZW1lbnQ7XG4gICAgX3Rvb2x0aXBUZXh0OiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgY3JlYXRlZEJ1dHRvbiA6IEhUTUxCdXR0b25FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgICAgIGNyZWF0ZWRCdXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICBjcmVhdGVkQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ1VpVG9vbCcpO1xuICAgICAgICBjcmVhdGVkQnV0dG9uLmlkID0gJ2Z1bGxzY3JlZW4tYnRuJztcbiAgICAgICAgY3JlYXRlZEJ1dHRvbi5hcHBlbmRDaGlsZCh0aGlzLm1heGltaXplSWNvbik7XG4gICAgICAgIGNyZWF0ZWRCdXR0b24uYXBwZW5kQ2hpbGQodGhpcy5taW5pbWl6ZUljb24pO1xuICAgICAgICBjcmVhdGVkQnV0dG9uLmFwcGVuZENoaWxkKHRoaXMudG9vbHRpcFRleHQpO1xuXG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQgPSBjcmVhdGVkQnV0dG9uO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdG9vbHRpcFRleHQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Rvb2x0aXBUZXh0KSB7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmNsYXNzTGlzdC5hZGQoJ3Rvb2x0aXB0ZXh0Jyk7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dC5pbm5lckhUTUwgPSAnRnVsbHNjcmVlbic7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rvb2x0aXBUZXh0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbWF4aW1pemVJY29uKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX21heGltaXplSWNvbikge1xuICAgICAgICAgICAgdGhpcy5fbWF4aW1pemVJY29uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3N2ZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9tYXhpbWl6ZUljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ21heGltaXplSWNvbicpO1xuICAgICAgICAgICAgdGhpcy5fbWF4aW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd4JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fbWF4aW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fbWF4aW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ3ZpZXdCb3gnLFxuICAgICAgICAgICAgICAgICcwIDAgMzg0Ljk3IDM4NC45NydcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzdmcgZ3JvdXAgZm9yIHRoZSBwYXRoc1xuICAgICAgICAgICAgY29uc3Qgc3ZnR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBzdmdHcm91cC5jbGFzc0xpc3QuYWRkKCdzdmdJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl9tYXhpbWl6ZUljb24uYXBwZW5kQ2hpbGQoc3ZnR3JvdXApO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgcGF0aHMgZm9yIHRoZSBpY29uIGl0c2VsZiwgb25lIGZvciBlYWNoIGNvcm5lclxuICAgICAgICAgICAgY29uc3QgcGF0aDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMS5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTM4NC45NywxMi4wM2MwLTYuNzEzLTUuMzE3LTEyLjAzLTEyLjAzLTEyLjAzSDI2NC44NDdjLTYuODMzLDAtMTEuOTIyLDUuMzktMTEuOTM0LDEyLjIyM2MwLDYuODIxLDUuMTAxLDExLjgzOCwxMS45MzQsMTEuODM4aDk2LjA2MmwtMC4xOTMsOTYuNTE5YzAsNi44MzMsNS4xOTcsMTIuMDMsMTIuMDMsMTIuMDNjNi44MzMtMC4wMTIsMTIuMDMtNS4xOTcsMTIuMDMtMTIuMDNsMC4xOTMtMTA4LjM2OWMwLTAuMDM2LTAuMDEyLTAuMDYtMC4wMTItMC4wODRDMzg0Ljk1OCwxMi4wOSwzODQuOTcsMTIuMDY2LDM4NC45NywxMi4wM3onXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoMiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgyLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMTIwLjQ5NiwwSDEyLjQwM2MtMC4wMzYsMC0wLjA2LDAuMDEyLTAuMDk2LDAuMDEyQzEyLjI4MywwLjAxMiwxMi4yNDcsMCwxMi4yMjMsMEM1LjUxLDAsMC4xOTIsNS4zMTcsMC4xOTIsMTIuMDNMMCwxMjAuMzk5YzAsNi44MzMsNS4zOSwxMS45MzQsMTIuMjIzLDExLjkzNGM2LjgyMSwwLDExLjgzOC01LjEwMSwxMS44MzgtMTEuOTM0bDAuMTkyLTk2LjMzOWg5Ni4yNDJjNi44MzMsMCwxMi4wMy01LjE5NywxMi4wMy0xMi4wM0MxMzIuNTE0LDUuMTk3LDEyNy4zMTcsMCwxMjAuNDk2LDB6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgcGF0aDMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMy5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTEyMC4xMjMsMzYwLjkwOUgyNC4wNjF2LTk2LjI0MmMwLTYuODMzLTUuMTk3LTEyLjAzLTEyLjAzLTEyLjAzUzAsMjU3LjgzMywwLDI2NC42Njd2MTA4LjA5MmMwLDAuMDM2LDAuMDEyLDAuMDYsMC4wMTIsMC4wODRjMCwwLjAzNi0wLjAxMiwwLjA2LTAuMDEyLDAuMDk2YzAsNi43MTMsNS4zMTcsMTIuMDMsMTIuMDMsMTIuMDNoMTA4LjA5MmM2LjgzMywwLDExLjkyMi01LjM5LDExLjkzNC0xMi4yMjNDMTMyLjA1NywzNjUuOTI2LDEyNi45NTYsMzYwLjkwOSwxMjAuMTIzLDM2MC45MDl6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgcGF0aDQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoNC5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTM3Mi43NDcsMjUyLjkxM2MtNi44MzMsMC0xMS44NSw1LjEwMS0xMS44MzgsMTEuOTM0djk2LjA2MmgtOTYuMjQyYy02LjgzMywwLTEyLjAzLDUuMTk3LTEyLjAzLDEyLjAzczUuMTk3LDEyLjAzLDEyLjAzLDEyLjAzaDEwOC4wOTJjMC4wMzYsMCwwLjA2LTAuMDEyLDAuMDg0LTAuMDEyYzAuMDM2LTAuMDEyLDAuMDYsMC4wMTIsMC4wOTYsMC4wMTJjNi43MTMsMCwxMi4wMy01LjMxNywxMi4wMy0xMi4wM1YyNjQuODQ3QzM4NC45NywyNTguMDE0LDM3OS41OCwyNTIuOTEzLDM3Mi43NDcsMjUyLjkxM3onXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMSk7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMik7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMyk7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoNCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX21heGltaXplSWNvbjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IG1pbmltaXplSWNvbigpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9taW5pbWl6ZUljb24pIHtcbiAgICAgICAgICAgIHRoaXMuX21pbmltaXplSWNvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdzdmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fbWluaW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICdpZCcsICdtaW5pbWl6ZUljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX21pbmltaXplSWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneCcsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX21pbmltaXplSWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneScsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX21pbmltaXplSWNvbi5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICd2aWV3Qm94JyxcbiAgICAgICAgICAgICAgICAnMCAwIDM4NS4zMzEgMzg1LjMzMSdcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzdmcgZ3JvdXAgZm9yIHRoZSBwYXRoc1xuICAgICAgICAgICAgY29uc3Qgc3ZnR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBzdmdHcm91cC5jbGFzc0xpc3QuYWRkKCdzdmdJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl9taW5pbWl6ZUljb24uYXBwZW5kQ2hpbGQoc3ZnR3JvdXApO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgcGF0aHMgZm9yIHRoZSBpY29uIGl0c2VsZiwgb25lIGZvciBlYWNoIGNvcm5lclxuICAgICAgICAgICAgY29uc3QgcGF0aDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMS5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTI2NC45NDMsMTU2LjY2NWgxMDguMjczYzYuODMzLDAsMTEuOTM0LTUuMzksMTEuOTM0LTEyLjIxMWMwLTYuODMzLTUuMTAxLTExLjg1LTExLjkzNC0xMS44MzhoLTk2LjI0MlYzNi4xODFjMC02LjgzMy01LjE5Ny0xMi4wMy0xMi4wMy0xMi4wM3MtMTIuMDMsNS4xOTctMTIuMDMsMTIuMDN2MTA4LjI3M2MwLDAuMDM2LDAuMDEyLDAuMDYsMC4wMTIsMC4wODRjMCwwLjAzNi0wLjAxMiwwLjA2LTAuMDEyLDAuMDk2QzI1Mi45MTMsMTUxLjM0NywyNTguMjMsMTU2LjY3NywyNjQuOTQzLDE1Ni42NjV6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgcGF0aDIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMi5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTEyMC4yOTEsMjQuMjQ3Yy02LjgyMSwwLTExLjgzOCw1LjExMy0xMS44MzgsMTEuOTM0djk2LjI0MkgxMi4wM2MtNi44MzMsMC0xMi4wMyw1LjE5Ny0xMi4wMywxMi4wM2MwLDYuODMzLDUuMTk3LDEyLjAzLDEyLjAzLDEyLjAzaDEwOC4yNzNjMC4wMzYsMCwwLjA2LTAuMDEyLDAuMDg0LTAuMDEyYzAuMDM2LDAsMC4wNiwwLjAxMiwwLjA5NiwwLjAxMmM2LjcxMywwLDEyLjAzLTUuMzE3LDEyLjAzLTEyLjAzVjM2LjE4MUMxMzIuNTE0LDI5LjM2LDEyNy4xMjQsMjQuMjU5LDEyMC4yOTEsMjQuMjQ3eidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhdGgzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcGF0aDMuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00xMjAuMzg3LDIyOC42NjZIMTIuMTE1Yy02LjgzMywwLjAxMi0xMS45MzQsNS4zOS0xMS45MzQsMTIuMjIzYzAsNi44MzMsNS4xMDEsMTEuODUsMTEuOTM0LDExLjgzOGg5Ni4yNDJ2OTYuNDIzYzAsNi44MzMsNS4xOTcsMTIuMDMsMTIuMDMsMTIuMDNjNi44MzMsMCwxMi4wMy01LjE5NywxMi4wMy0xMi4wM1YyNDAuODc3YzAtMC4wMzYtMC4wMTItMC4wNi0wLjAxMi0wLjA4NGMwLTAuMDM2LDAuMDEyLTAuMDYsMC4wMTItMC4wOTZDMTMyLjQxOCwyMzMuOTgzLDEyNy4xLDIyOC42NjYsMTIwLjM4NywyMjguNjY2eidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhdGg0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcGF0aDQuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00zNzMuMywyMjguNjY2SDI2NS4wMjhjLTAuMDM2LDAtMC4wNiwwLjAxMi0wLjA4NCwwLjAxMmMtMC4wMzYsMC0wLjA2LTAuMDEyLTAuMDk2LTAuMDEyYy02LjcxMywwLTEyLjAzLDUuMzE3LTEyLjAzLDEyLjAzdjEwOC4yNzNjMCw2LjgzMyw1LjM5LDExLjkyMiwxMi4yMjMsMTEuOTM0YzYuODIxLDAuMDEyLDExLjgzOC01LjEwMSwxMS44MzgtMTEuOTIydi05Ni4yNDJIMzczLjNjNi44MzMsMCwxMi4wMy01LjE5NywxMi4wMy0xMi4wM1MzODAuMTM0LDIyOC42NzgsMzczLjMsMjI4LjY2NnonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMSk7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMik7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMyk7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoNCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbmltaXplSWNvbjtcbiAgICB9XG5cbiAgICBvbkZ1bGxzY3JlZW5DaGFuZ2UoKSB7XG4gICAgICAgIHN1cGVyLm9uRnVsbHNjcmVlbkNoYW5nZSgpO1xuXG4gICAgICAgIGNvbnN0IG1pbmltaXplID0gdGhpcy5taW5pbWl6ZUljb247XG4gICAgICAgIGNvbnN0IG1heGltaXplID0gdGhpcy5tYXhpbWl6ZUljb247XG5cbiAgICAgICAgaWYgKHRoaXMuaXNGdWxsc2NyZWVuKSB7XG4gICAgICAgICAgICBtaW5pbWl6ZS5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZSc7XG4gICAgICAgICAgICAvL2lvcyBkaXNhcHBlYXJpbmcgc3ZnIGZpeFxuICAgICAgICAgICAgbWluaW1pemUuc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZSgwLCAwKSc7XG4gICAgICAgICAgICBtYXhpbWl6ZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWluaW1pemUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIG1heGltaXplLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lJztcbiAgICAgICAgICAgIC8vaW9zIGRpc2FwcGVhcmluZyBzdmcgZml4XG4gICAgICAgICAgICBtYXhpbWl6ZS5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlKDAsIDApJztcbiAgICAgICAgfVxuICAgIH1cblxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuLyoqXG4gKiBBIGJ1dHRvbiB3aXRoIGEgdGV4dCBsYWJlbCBiZXNpZGUgaXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYWJlbGxlZEJ1dHRvbiB7XG4gICAgX2xhYmVsOiBzdHJpbmc7XG4gICAgX2J1dHRvblRleHQ6IHN0cmluZztcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9idXR0b246IEhUTUxJbnB1dEVsZW1lbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcihsYWJlbDogc3RyaW5nLCBidXR0b25UZXh0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fbGFiZWwgPSBsYWJlbDtcbiAgICAgICAgdGhpcy5fYnV0dG9uVGV4dCA9IGJ1dHRvblRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgY2xpY2sgbGlzdGVuZXIgdG8gdGhlIGJ1dHRvbiBlbGVtZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBhZGRPbkNsaWNrTGlzdGVuZXIob25DbGlja0Z1bmM6ICgpID0+IHZvaWQpIHtcbiAgICAgICAgdGhpcy5idXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbkNsaWNrRnVuYyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBIVE1MSW5wdXRFbGVtZW50IGZvciB0aGUgYnV0dG9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgYnV0dG9uKCk6IEhUTUxJbnB1dEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2J1dHRvbikge1xuICAgICAgICAgICAgdGhpcy5fYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgIHRoaXMuX2J1dHRvbi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgICAgICB0aGlzLl9idXR0b24udmFsdWUgPSB0aGlzLl9idXR0b25UZXh0O1xuICAgICAgICAgICAgdGhpcy5fYnV0dG9uLmNsYXNzTGlzdC5hZGQoJ292ZXJsYXktYnV0dG9uJyk7XG4gICAgICAgICAgICB0aGlzLl9idXR0b24uY2xhc3NMaXN0LmFkZCgnYnRuLWZsYXQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYnV0dG9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFJldHVybiBvciBjcmVhdGVzIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcgaW4gdGhlIERPTS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHJvb3QgZGl2IHdpdGggXCJzZXR0aW5nXCIgY3NzIGNsYXNzXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnc2V0dGluZycpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgZGl2IGVsZW1lbnQgdG8gY29udGFpbiBvdXIgc2V0dGluZydzIHRleHRcbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmdzVGV4dEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gdGhpcy5fbGFiZWw7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZChzZXR0aW5nc1RleHRFbGVtKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGxhYmVsIGVsZW1lbnQgdG8gd3JhcCBvdXQgaW5wdXQgdHlwZVxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICAgICAgICAgIHdyYXBwZXJMYWJlbC5jbGFzc0xpc3QuYWRkKCdidG4tb3ZlcmxheScpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQod3JhcHBlckxhYmVsKTtcblxuICAgICAgICAgICAgd3JhcHBlckxhYmVsLmFwcGVuZENoaWxkKHRoaXMuYnV0dG9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgTGF0ZW5jeVRlc3RSZXN1bHRzIH0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcblxuLyoqXG4gKiBMYXRlbmN5IHRlc3QgVUkgZWxlbWVudHMgYW5kIHJlc3VsdHMgaGFuZGxpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYXRlbmN5VGVzdCB7XG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBfbGF0ZW5jeVRlc3RCdXR0b246IEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aGUgYnV0dG9uIGNvbnRhaW5pbmcgdGhlIHN0YXRzIGljb24uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VjdGlvbicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3NDb250YWluZXInKTtcblxuICAgICAgICAgICAgLy8gbWFrZSBoZWFkaW5nXG4gICAgICAgICAgICBjb25zdCBoZWFkaW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBoZWFkaW5nLmlkID0gJ2xhdGVuY3lUZXN0SGVhZGVyJztcbiAgICAgICAgICAgIGhlYWRpbmcuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3MtdGV4dCcpO1xuICAgICAgICAgICAgaGVhZGluZy5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0hlYWRlcicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQoaGVhZGluZyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGhlYWRpbmdUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBoZWFkaW5nVGV4dC5pbm5lckhUTUwgPSAnTGF0ZW5jeSBUZXN0JztcbiAgICAgICAgICAgIGhlYWRpbmcuYXBwZW5kQ2hpbGQoaGVhZGluZ1RleHQpO1xuICAgICAgICAgICAgaGVhZGluZy5hcHBlbmRDaGlsZCh0aGlzLmxhdGVuY3lUZXN0QnV0dG9uKTtcblxuICAgICAgICAgICAgLy8gbWFrZSB0ZXN0IHJlc3VsdHMgZWxlbWVudFxuICAgICAgICAgICAgY29uc3QgcmVzdWx0c1BhcmVudEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHJlc3VsdHNQYXJlbnRFbGVtLmlkID0gJ2xhdGVuY3lUZXN0Q29udGFpbmVyJztcbiAgICAgICAgICAgIHJlc3VsdHNQYXJlbnRFbGVtLmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQocmVzdWx0c1BhcmVudEVsZW0pO1xuXG4gICAgICAgICAgICByZXN1bHRzUGFyZW50RWxlbS5hcHBlbmRDaGlsZCh0aGlzLmxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuaWQgPSAnbGF0ZW5jeVN0YXRzUmVzdWx0cyc7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ1N0YXRzUmVzdWx0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsYXRlbmN5VGVzdEJ1dHRvbigpOiBIVE1MSW5wdXRFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbikge1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24udmFsdWUgPSAnUnVuIFRlc3QnO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24uaWQgPSAnYnRuLXN0YXJ0LWxhdGVuY3ktdGVzdCc7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdzdHJlYW1Ub29scy1idXR0b24nKTtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2J0bi1mbGF0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBvcHVsYXRlIHRoZSBVSSBiYXNlZCBvbiB0aGUgbGF0ZW5jeSB0ZXN0J3MgcmVzdWx0cy5cbiAgICAgKiBAcGFyYW0gbGF0ZW5jeVRpbWluZ3MgVGhlIGxhdGVuY3kgdGVzdCByZXN1bHRzLlxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVUZXN0UmVzdWx0KGxhdGVuY3lUaW1pbmdzOiBMYXRlbmN5VGVzdFJlc3VsdHMpIHtcbiAgICAgICAgTG9nZ2VyLkxvZyhMb2dnZXIuR2V0U3RhY2tUcmFjZSgpLCBsYXRlbmN5VGltaW5ncy50b1N0cmluZygpLCA2KTtcbiAgICAgICAgbGV0IGxhdGVuY3lTdGF0c0lubmVySFRNTCA9ICcnO1xuICAgICAgICBsYXRlbmN5U3RhdHNJbm5lckhUTUwgKz1cbiAgICAgICAgICAgICc8ZGl2Pk5ldCBsYXRlbmN5IFJUVCAobXMpOiAnICtcbiAgICAgICAgICAgIGxhdGVuY3lUaW1pbmdzLm5ldHdvcmtMYXRlbmN5ICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICBsYXRlbmN5U3RhdHNJbm5lckhUTUwgKz1cbiAgICAgICAgICAgICc8ZGl2PlVFIEVuY29kZSAobXMpOiAnICsgbGF0ZW5jeVRpbWluZ3MuRW5jb2RlTXMgKyAnPC9kaXY+JztcbiAgICAgICAgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MICs9XG4gICAgICAgICAgICAnPGRpdj5VRSBDYXB0dXJlIChtcyk6ICcgK1xuICAgICAgICAgICAgbGF0ZW5jeVRpbWluZ3MuQ2FwdHVyZVRvU2VuZE1zICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICBsYXRlbmN5U3RhdHNJbm5lckhUTUwgKz1cbiAgICAgICAgICAgICc8ZGl2PkJyb3dzZXIgc2VuZCBsYXRlbmN5IChtcyk6ICcgK1xuICAgICAgICAgICAgbGF0ZW5jeVRpbWluZ3MuYnJvd3NlclNlbmRMYXRlbmN5ICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICBsYXRlbmN5U3RhdHNJbm5lckhUTUwgKz1cbiAgICAgICAgICAgIGxhdGVuY3lUaW1pbmdzLmZyYW1lRGlzcGxheURlbHRhVGltZU1zICYmXG4gICAgICAgICAgICBsYXRlbmN5VGltaW5ncy5icm93c2VyUmVjZWlwdFRpbWVNc1xuICAgICAgICAgICAgICAgID8gJzxkaXY+QnJvd3NlciByZWNlaXZlIGxhdGVuY3kgKG1zKTogJyArXG4gICAgICAgICAgICAgICAgICBsYXRlbmN5VGltaW5ncy5mcmFtZURpc3BsYXlEZWx0YVRpbWVNcyArXG4gICAgICAgICAgICAgICAgICAnPC9kaXY+J1xuICAgICAgICAgICAgICAgIDogJyc7XG4gICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgJzxkaXY+VG90YWwgbGF0ZW5jeSAoZXhjbHVkaW5nIGJyb3dzZXIpIChtcyk6ICcgK1xuICAgICAgICAgICAgbGF0ZW5jeVRpbWluZ3MubGF0ZW5jeUV4Y2x1ZGluZ0RlY29kZSArXG4gICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MICs9IGxhdGVuY3lUaW1pbmdzLmVuZFRvRW5kTGF0ZW5jeVxuICAgICAgICAgICAgPyAnPGRpdj5Ub3RhbCBsYXRlbmN5IChtcyk6ICcgK1xuICAgICAgICAgICAgICBsYXRlbmN5VGltaW5ncy5lbmRUb0VuZExhdGVuY3kgK1xuICAgICAgICAgICAgICAnPC9kaXY+J1xuICAgICAgICAgICAgOiAnJztcbiAgICAgICAgdGhpcy5sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmlubmVySFRNTCA9IGxhdGVuY3lTdGF0c0lubmVySFRNTDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG4vKipcbiAqIFNldHRpbmdzIGljb24gdGhhdCBjYW4gYmUgY2xpY2tlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNldHRpbmdzSWNvbiB7XG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MQnV0dG9uRWxlbWVudDtcbiAgICBfc2V0dGluZ3NJY29uOiBTVkdFbGVtZW50O1xuICAgIF90b29sdGlwVGV4dDogSFRNTEVsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRoZSBidXR0b24gY29udGFpbmluZyB0aGUgc2V0dGluZ3MgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxCdXR0b25FbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ1VpVG9vbCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSAnc2V0dGluZ3NCdG4nO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zZXR0aW5nc0ljb24pO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50b29sdGlwVGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdG9vbHRpcFRleHQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Rvb2x0aXBUZXh0KSB7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmNsYXNzTGlzdC5hZGQoJ3Rvb2x0aXB0ZXh0Jyk7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dC5pbm5lckhUTUwgPSAnU2V0dGluZ3MnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl90b29sdGlwVGV4dDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmdzSWNvbigpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5nc0ljb24pIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzSWNvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdzdmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICdpZCcsICdzZXR0aW5nc0ljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzSWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneCcsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzSWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneScsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzSWNvbi5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICd2aWV3Qm94JyxcbiAgICAgICAgICAgICAgICAnMCAwIDQ3OC43MDMgNDc4LjcwMydcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzdmcgZ3JvdXAgZm9yIHRoZSBwYXRoc1xuICAgICAgICAgICAgY29uc3Qgc3ZnR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBzdmdHcm91cC5jbGFzc0xpc3QuYWRkKCdzdmdJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc0ljb24uYXBwZW5kQ2hpbGQoc3ZnR3JvdXApO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgcGF0aHMgZm9yIHRoZSBpY29uIGl0c2VsZiwgdGhlIGlubmVyIGFuZCBvdXQgcGF0aCBvZiBhIGNvZ1xuICAgICAgICAgICAgY29uc3QgcGF0aDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMS5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTQ1NC4yLDE4OS4xMDFsLTMzLjYtNS43Yy0zLjUtMTEuMy04LTIyLjItMTMuNS0zMi42bDE5LjgtMjcuN2M4LjQtMTEuOCw3LjEtMjcuOS0zLjItMzguMWwtMjkuOC0yOS44XFxcblx0XHRcdGMtNS42LTUuNi0xMy04LjctMjAuOS04LjdjLTYuMiwwLTEyLjEsMS45LTE3LjEsNS41bC0yNy44LDE5LjhjLTEwLjgtNS43LTIyLjEtMTAuNC0zMy44LTEzLjlsLTUuNi0zMy4yXFxcblx0XHRcdGMtMi40LTE0LjMtMTQuNy0yNC43LTI5LjItMjQuN2gtNDIuMWMtMTQuNSwwLTI2LjgsMTAuNC0yOS4yLDI0LjdsLTUuOCwzNGMtMTEuMiwzLjUtMjIuMSw4LjEtMzIuNSwxMy43bC0yNy41LTE5LjhcXFxuXHRcdFx0Yy01LTMuNi0xMS01LjUtMTcuMi01LjVjLTcuOSwwLTE1LjQsMy4xLTIwLjksOC43bC0yOS45LDI5LjhjLTEwLjIsMTAuMi0xMS42LDI2LjMtMy4yLDM4LjFsMjAsMjguMVxcXG5cdFx0XHRjLTUuNSwxMC41LTkuOSwyMS40LTEzLjMsMzIuN2wtMzMuMiw1LjZjLTE0LjMsMi40LTI0LjcsMTQuNy0yNC43LDI5LjJ2NDIuMWMwLDE0LjUsMTAuNCwyNi44LDI0LjcsMjkuMmwzNCw1LjhcXFxuXHRcdFx0YzMuNSwxMS4yLDguMSwyMi4xLDEzLjcsMzIuNWwtMTkuNywyNy40Yy04LjQsMTEuOC03LjEsMjcuOSwzLjIsMzguMWwyOS44LDI5LjhjNS42LDUuNiwxMyw4LjcsMjAuOSw4LjdjNi4yLDAsMTIuMS0xLjksMTcuMS01LjVcXFxuXHRcdFx0bDI4LjEtMjBjMTAuMSw1LjMsMjAuNyw5LjYsMzEuNiwxM2w1LjYsMzMuNmMyLjQsMTQuMywxNC43LDI0LjcsMjkuMiwyNC43aDQyLjJjMTQuNSwwLDI2LjgtMTAuNCwyOS4yLTI0LjdsNS43LTMzLjZcXFxuXHRcdFx0YzExLjMtMy41LDIyLjItOCwzMi42LTEzLjVsMjcuNywxOS44YzUsMy42LDExLDUuNSwxNy4yLDUuNWwwLDBjNy45LDAsMTUuMy0zLjEsMjAuOS04LjdsMjkuOC0yOS44YzEwLjItMTAuMiwxMS42LTI2LjMsMy4yLTM4LjFcXFxuXHRcdFx0bC0xOS44LTI3LjhjNS41LTEwLjUsMTAuMS0yMS40LDEzLjUtMzIuNmwzMy42LTUuNmMxNC4zLTIuNCwyNC43LTE0LjcsMjQuNy0yOS4ydi00Mi4xXFxcblx0XHRcdEM0NzguOSwyMDMuODAxLDQ2OC41LDE5MS41MDEsNDU0LjIsMTg5LjEwMXogTTQ1MS45LDI2MC40MDFjMCwxLjMtMC45LDIuNC0yLjIsMi42bC00Miw3Yy01LjMsMC45LTkuNSw0LjgtMTAuOCw5LjlcXFxuXHRcdFx0Yy0zLjgsMTQuNy05LjYsMjguOC0xNy40LDQxLjljLTIuNyw0LjYtMi41LDEwLjMsMC42LDE0LjdsMjQuNywzNC44YzAuNywxLDAuNiwyLjUtMC4zLDMuNGwtMjkuOCwyOS44Yy0wLjcsMC43LTEuNCwwLjgtMS45LDAuOFxcXG5cdFx0XHRjLTAuNiwwLTEuMS0wLjItMS41LTAuNWwtMzQuNy0yNC43Yy00LjMtMy4xLTEwLjEtMy4zLTE0LjctMC42Yy0xMy4xLDcuOC0yNy4yLDEzLjYtNDEuOSwxNy40Yy01LjIsMS4zLTkuMSw1LjYtOS45LDEwLjhsLTcuMSw0MlxcXG5cdFx0XHRjLTAuMiwxLjMtMS4zLDIuMi0yLjYsMi4yaC00Mi4xYy0xLjMsMC0yLjQtMC45LTIuNi0yLjJsLTctNDJjLTAuOS01LjMtNC44LTkuNS05LjktMTAuOGMtMTQuMy0zLjctMjguMS05LjQtNDEtMTYuOFxcXG5cdFx0XHRjLTIuMS0xLjItNC41LTEuOC02LjgtMS44Yy0yLjcsMC01LjUsMC44LTcuOCwyLjVsLTM1LDI0LjljLTAuNSwwLjMtMSwwLjUtMS41LDAuNWMtMC40LDAtMS4yLTAuMS0xLjktMC44bC0yOS44LTI5LjhcXFxuXHRcdFx0Yy0wLjktMC45LTEtMi4zLTAuMy0zLjRsMjQuNi0zNC41YzMuMS00LjQsMy4zLTEwLjIsMC42LTE0LjhjLTcuOC0xMy0xMy44LTI3LjEtMTcuNi00MS44Yy0xLjQtNS4xLTUuNi05LTEwLjgtOS45bC00Mi4zLTcuMlxcXG5cdFx0XHRjLTEuMy0wLjItMi4yLTEuMy0yLjItMi42di00Mi4xYzAtMS4zLDAuOS0yLjQsMi4yLTIuNmw0MS43LTdjNS4zLTAuOSw5LjYtNC44LDEwLjktMTBjMy43LTE0LjcsOS40LTI4LjksMTcuMS00MlxcXG5cdFx0XHRjMi43LTQuNiwyLjQtMTAuMy0wLjctMTQuNmwtMjQuOS0zNWMtMC43LTEtMC42LTIuNSwwLjMtMy40bDI5LjgtMjkuOGMwLjctMC43LDEuNC0wLjgsMS45LTAuOGMwLjYsMCwxLjEsMC4yLDEuNSwwLjVsMzQuNSwyNC42XFxcblx0XHRcdGM0LjQsMy4xLDEwLjIsMy4zLDE0LjgsMC42YzEzLTcuOCwyNy4xLTEzLjgsNDEuOC0xNy42YzUuMS0xLjQsOS01LjYsOS45LTEwLjhsNy4yLTQyLjNjMC4yLTEuMywxLjMtMi4yLDIuNi0yLjJoNDIuMVxcXG5cdFx0XHRjMS4zLDAsMi40LDAuOSwyLjYsMi4ybDcsNDEuN2MwLjksNS4zLDQuOCw5LjYsMTAsMTAuOWMxNS4xLDMuOCwyOS41LDkuNyw0Mi45LDE3LjZjNC42LDIuNywxMC4zLDIuNSwxNC43LTAuNmwzNC41LTI0LjhcXFxuXHRcdFx0YzAuNS0wLjMsMS0wLjUsMS41LTAuNWMwLjQsMCwxLjIsMC4xLDEuOSwwLjhsMjkuOCwyOS44YzAuOSwwLjksMSwyLjMsMC4zLDMuNGwtMjQuNywzNC43Yy0zLjEsNC4zLTMuMywxMC4xLTAuNiwxNC43XFxcblx0XHRcdGM3LjgsMTMuMSwxMy42LDI3LjIsMTcuNCw0MS45YzEuMyw1LjIsNS42LDkuMSwxMC44LDkuOWw0Miw3LjFjMS4zLDAuMiwyLjIsMS4zLDIuMiwyLjZ2NDIuMUg0NTEuOXonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoMiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgyLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMjM5LjQsMTM2LjAwMWMtNTcsMC0xMDMuMyw0Ni4zLTEwMy4zLDEwMy4zczQ2LjMsMTAzLjMsMTAzLjMsMTAzLjNzMTAzLjMtNDYuMywxMDMuMy0xMDMuM1MyOTYuNCwxMzYuMDAxLDIzOS40LDEzNi4wMDF6IE0yMzkuNCwzMTUuNjAxYy00Mi4xLDAtNzYuMy0zNC4yLTc2LjMtNzYuM3MzNC4yLTc2LjMsNzYuMy03Ni4zczc2LjMsMzQuMiw3Ni4zLDc2LjNTMjgxLjUsMzE1LjYwMSwyMzkuNCwzMTUuNjAxeidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgxKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3NJY29uO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbi8qKlxuICogQSBVSSBjb21wb25lbnQgY29udGFpbmluZyBhbGwgdGhlIHNldHRpbmdzIGZvciB0aGUgYXBwbGljYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXR0aW5nc1BhbmVsIHtcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9zZXR0aW5nc0Nsb3NlQnV0dG9uOiBIVE1MRWxlbWVudDtcbiAgICBfc2V0dGluZ3NDb250ZW50RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFJldHVybiBvciBjcmVhdGVzIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcgaW4gdGhlIERPTS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmlkID0gJ3NldHRpbmdzLXBhbmVsJztcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3BhbmVsLXdyYXAnKTtcblxuICAgICAgICAgICAgY29uc3QgcGFuZWxFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBwYW5lbEVsZW0uY2xhc3NMaXN0LmFkZCgncGFuZWwnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHBhbmVsRWxlbSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmdzSGVhZGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgc2V0dGluZ3NIZWFkaW5nLmlkID0gJ3NldHRpbmdzSGVhZGluZyc7XG4gICAgICAgICAgICBzZXR0aW5nc0hlYWRpbmcudGV4dENvbnRlbnQgPSAnU2V0dGluZ3MnO1xuICAgICAgICAgICAgcGFuZWxFbGVtLmFwcGVuZENoaWxkKHNldHRpbmdzSGVhZGluZyk7XG5cbiAgICAgICAgICAgIHBhbmVsRWxlbS5hcHBlbmRDaGlsZCh0aGlzLnNldHRpbmdzQ2xvc2VCdXR0b24pO1xuICAgICAgICAgICAgcGFuZWxFbGVtLmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NDb250ZW50RWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2V0dGluZ3NDb250ZW50RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3NDb250ZW50RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NDb250ZW50RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NDb250ZW50RWxlbWVudC5pZCA9ICdzZXR0aW5nc0NvbnRlbnQnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXR0aW5nc0NvbnRlbnRFbGVtZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2V0dGluZ3NDbG9zZUJ1dHRvbigpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3NDbG9zZUJ1dHRvbikge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NDbG9zZUJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NDbG9zZUJ1dHRvbi5pZCA9ICdzZXR0aW5nc0Nsb3NlJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3NDbG9zZUJ1dHRvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IHNldHRpbmdzIHBhbmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBzaG93KCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMucm9vdEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdwYW5lbC13cmFwLXZpc2libGUnKSkge1xuICAgICAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdwYW5lbC13cmFwLXZpc2libGUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgc2V0dGluZ3MgcGFuZWwuXG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZVZpc2liaWxpdHkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZSgncGFuZWwtd3JhcC12aXNpYmxlJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGlkZSBzZXR0aW5ncyBwYW5lbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGlkZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucm9vdEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdwYW5lbC13cmFwLXZpc2libGUnKSkge1xuICAgICAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdwYW5lbC13cmFwLXZpc2libGUnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbi8qKlxuICogU3RhdHMgaWNvbiB0aGF0IGNhbiBiZSBjbGlja2VkLlxuICovXG5leHBvcnQgY2xhc3MgU3RhdHNJY29uIHtcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxCdXR0b25FbGVtZW50O1xuICAgIF9zdGF0c0ljb246IFNWR0VsZW1lbnQ7XG4gICAgX3Rvb2x0aXBUZXh0OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGhlIGJ1dHRvbiBjb250YWluaW5nIHRoZSBzdGF0cyBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEJ1dHRvbkVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQudHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnVWlUb29sJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICdzdGF0c0J0bic7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnN0YXRzSWNvbik7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRvb2x0aXBUZXh0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB0b29sdGlwVGV4dCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fdG9vbHRpcFRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcFRleHQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcHRleHQnKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmlubmVySFRNTCA9ICdJbmZvcm1hdGlvbic7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rvb2x0aXBUZXh0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc3RhdHNJY29uKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3N0YXRzSWNvbikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNJY29uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3N2ZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0ljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ3N0YXRzSWNvbicpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd4JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd2aWV3Qm94JywgJzAgMCAzMzAgMzMwJyk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzdmcgZ3JvdXAgZm9yIHRoZSBwYXRoc1xuICAgICAgICAgICAgY29uc3Qgc3ZnR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBzdmdHcm91cC5jbGFzc0xpc3QuYWRkKCdzdmdJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0ljb24uYXBwZW5kQ2hpbGQoc3ZnR3JvdXApO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgcGF0aHMgZm9yIHRoZSBpY29uIGl0c2VsZiwgdGhlIGlubmVyIGFuZCBvdXQgcGF0aCBvZiBhIGNvZ1xuICAgICAgICAgICAgY29uc3QgcGF0aDEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMS5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTE2NSwwLjAwOEM3NC4wMTksMC4wMDgsMCw3NC4wMjQsMCwxNjQuOTk5YzAsOTAuOTc3LDc0LjAxOSwxNjQuOTkyLDE2NSwxNjQuOTkyczE2NS03NC4wMTUsMTY1LTE2NC45OTJDMzMwLDc0LjAyNCwyNTUuOTgxLDAuMDA4LDE2NSwwLjAwOHogTTE2NSwyOTkuOTkyYy03NC40MzksMC0xMzUtNjAuNTU3LTEzNS0xMzQuOTkyUzkwLjU2MSwzMC4wMDgsMTY1LDMwLjAwOHMxMzUsNjAuNTU3LDEzNSwxMzQuOTkxQzMwMCwyMzkuNDM2LDIzOS40MzksMjk5Ljk5MiwxNjUsMjk5Ljk5MnonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoMiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgyLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMTY1LDEzMC4wMDhjLTguMjg0LDAtMTUsNi43MTYtMTUsMTV2OTkuOTgzYzAsOC4yODQsNi43MTYsMTUsMTUsMTVzMTUtNi43MTYsMTUtMTV2LTk5Ljk4M0MxODAsMTM2LjcyNSwxNzMuMjg0LDEzMC4wMDgsMTY1LDEzMC4wMDh6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgcGF0aDMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMy5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTE2NSw3MC4wMTFjLTMuOTUsMC03LjgxMSwxLjYtMTAuNjEsNC4zOWMtMi43OSwyLjc5LTQuMzksNi42Ni00LjM5LDEwLjYxczEuNiw3LjgxLDQuMzksMTAuNjFjMi43OSwyLjc5LDYuNjYsNC4zOSwxMC42MSw0LjM5czcuODEtMS42LDEwLjYwOS00LjM5YzIuNzktMi44LDQuMzkxLTYuNjYsNC4zOTEtMTAuNjFzLTEuNjAxLTcuODItNC4zOTEtMTAuNjFDMTcyLjgxLDcxLjYxLDE2OC45NSw3MC4wMTEsMTY1LDcwLjAxMXonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMSk7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMik7XG4gICAgICAgICAgICBzdmdHcm91cC5hcHBlbmRDaGlsZChwYXRoMyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRzSWNvbjtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgeyBMYXRlbmN5VGVzdCB9IGZyb20gJy4vTGF0ZW5jeVRlc3QnO1xuaW1wb3J0IHtJbml0aWFsU2V0dGluZ3MsIExvZ2dlciwgUGl4ZWxTdHJlYW1pbmd9IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHsgQWdncmVnYXRlZFN0YXRzIH0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBNYXRoVXRpbHMgfSBmcm9tICcuLi9VdGlsL01hdGhVdGlscyc7XG5pbXBvcnQge0RhdGFDaGFubmVsTGF0ZW5jeVRlc3R9IGZyb20gXCIuL0RhdGFDaGFubmVsTGF0ZW5jeVRlc3RcIjtcbmltcG9ydCB7UGl4ZWxTdHJlYW1pbmdTZXR0aW5nc30gZnJvbSBcIkBlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMvdHlwZXMvRGF0YUNoYW5uZWwvSW5pdGlhbFNldHRpbmdzXCI7XG5cbi8qKlxuICogQSBzdGF0IHN0cnVjdHVyZSwgYW4gaWQsIHRoZSBzdGF0IHN0cmluZywgYW5kIHRoZSBlbGVtZW50IHdoZXJlIGl0IGlzIHJlbmRlcmVkLlxuICovXG5leHBvcnQgY2xhc3MgU3RhdCB7XG4gICAgaWQ6IHN0cmluZztcbiAgICB0aXRsZTogc3RyaW5nO1xuICAgIHN0YXQ6IHN0cmluZztcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudDtcbn1cblxuLyoqXG4gKiBBIFVJIGNvbXBvbmVudCBjb250YWluaW5nIGFsbCB0aGUgc3RhdHMgZm9yIHRoZSBhcHBsaWNhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0YXRzUGFuZWwge1xuICAgIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgX3N0YXRzQ2xvc2VCdXR0b246IEhUTUxFbGVtZW50O1xuICAgIF9zdGF0c0NvbnRlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBfc3RhdGlzdGljc0NvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gICAgX3N0YXRzUmVzdWx0OiBIVE1MRWxlbWVudDtcblxuICAgIGxhdGVuY3lUZXN0OiBMYXRlbmN5VGVzdDtcbiAgICBkYXRhQ2hhbm5lbExhdGVuY3lUZXN0OiBEYXRhQ2hhbm5lbExhdGVuY3lUZXN0O1xuXG4gICAgLyogQSBtYXAgc3RhdHMgd2UgYXJlIHN0b3JpbmcvcmVuZGVyaW5nICovXG4gICAgc3RhdHNNYXAgPSBuZXcgTWFwPHN0cmluZywgU3RhdD4oKTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0ID0gbmV3IExhdGVuY3lUZXN0KCk7XG4gICAgICAgIHRoaXMuZGF0YUNoYW5uZWxMYXRlbmN5VGVzdCA9IG5ldyBEYXRhQ2hhbm5lbExhdGVuY3lUZXN0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgUmV0dXJuIG9yIGNyZWF0ZXMgYSBIVE1MIGVsZW1lbnQgdGhhdCByZXByZXNlbnRzIHRoaXMgc2V0dGluZyBpbiB0aGUgRE9NLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSAnc3RhdHMtcGFuZWwnO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgncGFuZWwtd3JhcCcpO1xuXG4gICAgICAgICAgICBjb25zdCBwYW5lbEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHBhbmVsRWxlbS5jbGFzc0xpc3QuYWRkKCdwYW5lbCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQocGFuZWxFbGVtKTtcblxuICAgICAgICAgICAgY29uc3Qgc3RhdHNIZWFkaW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBzdGF0c0hlYWRpbmcuaWQgPSAnc3RhdHNIZWFkaW5nJztcbiAgICAgICAgICAgIHN0YXRzSGVhZGluZy50ZXh0Q29udGVudCA9ICdJbmZvcm1hdGlvbic7XG4gICAgICAgICAgICBwYW5lbEVsZW0uYXBwZW5kQ2hpbGQoc3RhdHNIZWFkaW5nKTtcblxuICAgICAgICAgICAgcGFuZWxFbGVtLmFwcGVuZENoaWxkKHRoaXMuc3RhdHNDbG9zZUJ1dHRvbik7XG4gICAgICAgICAgICBwYW5lbEVsZW0uYXBwZW5kQ2hpbGQodGhpcy5zdGF0c0NvbnRlbnRFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzdGF0c0NvbnRlbnRFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zdGF0c0NvbnRlbnRFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0NvbnRlbnRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0NvbnRlbnRFbGVtZW50LmlkID0gJ3N0YXRzQ29udGVudCc7XG5cbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbVRvb2xTdGF0cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgc3RyZWFtVG9vbFN0YXRzLmlkID0gJ3N0cmVhbVRvb2xzU3RhdHMnO1xuICAgICAgICAgICAgc3RyZWFtVG9vbFN0YXRzLmNsYXNzTGlzdC5hZGQoJ2NvbnRhaW5lcicpO1xuXG4gICAgICAgICAgICBjb25zdCBjb250cm9sU3RhdHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGNvbnRyb2xTdGF0cy5pZCA9ICdDb250cm9sU3RhdHMnO1xuICAgICAgICAgICAgY29udHJvbFN0YXRzLmNsYXNzTGlzdC5hZGQoJ3JvdycpO1xuXG4gICAgICAgICAgICBjb25zdCBzdGF0aXN0aWNzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VjdGlvbicpO1xuICAgICAgICAgICAgc3RhdGlzdGljcy5pZCA9ICdzdGF0aXN0aWNzJztcbiAgICAgICAgICAgIHN0YXRpc3RpY3MuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3NDb250YWluZXInKTtcblxuICAgICAgICAgICAgY29uc3Qgc3RhdGlzdGljc0hlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgc3RhdGlzdGljc0hlYWRlci5pZCA9ICdzdGF0aXN0aWNzSGVhZGVyJztcbiAgICAgICAgICAgIHN0YXRpc3RpY3NIZWFkZXIuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3MtdGV4dCcpO1xuICAgICAgICAgICAgc3RhdGlzdGljc0hlYWRlci5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0hlYWRlcicpO1xuXG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uU3RhdHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHNlc3Npb25TdGF0cy5pbm5lckhUTUwgPSAnU2Vzc2lvbiBTdGF0cyc7XG5cbiAgICAgICAgICAgIHRoaXMuX3N0YXRzQ29udGVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoc3RyZWFtVG9vbFN0YXRzKTtcbiAgICAgICAgICAgIHN0cmVhbVRvb2xTdGF0cy5hcHBlbmRDaGlsZChjb250cm9sU3RhdHMpO1xuICAgICAgICAgICAgY29udHJvbFN0YXRzLmFwcGVuZENoaWxkKHN0YXRpc3RpY3MpO1xuICAgICAgICAgICAgc3RhdGlzdGljcy5hcHBlbmRDaGlsZChzdGF0aXN0aWNzSGVhZGVyKTtcbiAgICAgICAgICAgIHN0YXRpc3RpY3NIZWFkZXIuYXBwZW5kQ2hpbGQoc2Vzc2lvblN0YXRzKTtcbiAgICAgICAgICAgIHN0YXRpc3RpY3MuYXBwZW5kQ2hpbGQodGhpcy5zdGF0aXN0aWNzQ29udGFpbmVyKTtcblxuICAgICAgICAgICAgY29udHJvbFN0YXRzLmFwcGVuZENoaWxkKHRoaXMubGF0ZW5jeVRlc3Qucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgY29udHJvbFN0YXRzLmFwcGVuZENoaWxkKHRoaXMuZGF0YUNoYW5uZWxMYXRlbmN5VGVzdC5yb290RWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRzQ29udGVudEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzdGF0aXN0aWNzQ29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zdGF0aXN0aWNzQ29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0aXN0aWNzQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0aXN0aWNzQ29udGFpbmVyLmlkID0gJ3N0YXRpc3RpY3NDb250YWluZXInO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGlzdGljc0NvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRpc3RpY3NDb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5zdGF0c1Jlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRpc3RpY3NDb250YWluZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzdGF0c1Jlc3VsdCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc3RhdHNSZXN1bHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzUmVzdWx0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c1Jlc3VsdC5pZCA9ICdzdGF0aXN0aWNzUmVzdWx0JztcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzUmVzdWx0LmNsYXNzTGlzdC5hZGQoJ1N0YXRzUmVzdWx0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRzUmVzdWx0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc3RhdHNDbG9zZUJ1dHRvbigpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc3RhdHNDbG9zZUJ1dHRvbikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNDbG9zZUJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNDbG9zZUJ1dHRvbi5pZCA9ICdzdGF0c0Nsb3NlJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdHNDbG9zZUJ1dHRvbjtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25EaXNjb25uZWN0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0LmxhdGVuY3lUZXN0QnV0dG9uLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXRhQ2hhbm5lbExhdGVuY3lUZXN0LmxhdGVuY3lUZXN0QnV0dG9uLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAvL2RvIG5vdGhpbmdcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBvblZpZGVvSW5pdGlhbGl6ZWQoc3RyZWFtOiBQaXhlbFN0cmVhbWluZyk6IHZvaWQge1xuICAgICAgICAvLyBzdGFydGluZyBhIGxhdGVuY3kgY2hlY2tcbiAgICAgICAgdGhpcy5sYXRlbmN5VGVzdC5sYXRlbmN5VGVzdEJ1dHRvbi5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgc3RyZWFtLnJlcXVlc3RMYXRlbmN5VGVzdCgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmRhdGFDaGFubmVsTGF0ZW5jeVRlc3QubGF0ZW5jeVRlc3RCdXR0b24ub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgIGxldCBzdGFydGVkID0gc3RyZWFtLnJlcXVlc3REYXRhQ2hhbm5lbExhdGVuY3lUZXN0KHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogMTAwMCxcbiAgICAgICAgICAgICAgICBycHM6IDEwLFxuICAgICAgICAgICAgICAgIHJlcXVlc3RTaXplOiAyMDAsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VTaXplOiAyMDBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHN0YXJ0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFDaGFubmVsTGF0ZW5jeVRlc3QuaGFuZGxlVGVzdFN0YXJ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHVibGljIGNvbmZpZ3VyZShzZXR0aW5nczogUGl4ZWxTdHJlYW1pbmdTZXR0aW5ncyk6IHZvaWQge1xuICAgICAgICBpZiAoc2V0dGluZ3MuRGlzYWJsZUxhdGVuY3lUZXN0KSB7XG4gICAgICAgICAgICB0aGlzLmxhdGVuY3lUZXN0LmxhdGVuY3lUZXN0QnV0dG9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMubGF0ZW5jeVRlc3QubGF0ZW5jeVRlc3RCdXR0b24udGl0bGUgPVxuICAgICAgICAgICAgICAgICdEaXNhYmxlZCBieSAtUGl4ZWxTdHJlYW1pbmdEaXNhYmxlTGF0ZW5jeVRlc3Rlcj10cnVlJztcbiAgICAgICAgICAgIHRoaXMuZGF0YUNoYW5uZWxMYXRlbmN5VGVzdC5sYXRlbmN5VGVzdEJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmRhdGFDaGFubmVsTGF0ZW5jeVRlc3QubGF0ZW5jeVRlc3RCdXR0b24udGl0bGUgPVxuICAgICAgICAgICAgICAgICdEaXNhYmxlZCBieSAtUGl4ZWxTdHJlYW1pbmdEaXNhYmxlTGF0ZW5jeVRlc3Rlcj10cnVlJztcbiAgICAgICAgICAgIExvZ2dlci5JbmZvKFxuICAgICAgICAgICAgICAgIExvZ2dlci5HZXRTdGFja1RyYWNlKCksXG4gICAgICAgICAgICAgICAgJy1QaXhlbFN0cmVhbWluZ0Rpc2FibGVMYXRlbmN5VGVzdGVyPXRydWUsIHJlcXVlc3RpbmcgbGF0ZW5jeSByZXBvcnQgZnJvbSB0aGUgdGhlIGJyb3dzZXIgdG8gVUUgaXMgZGlzYWJsZWQuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgc3RhdHMgcGFuZWwuXG4gICAgICovXG4gICAgcHVibGljIHNob3coKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhbmVsLXdyYXAtdmlzaWJsZScpKSB7XG4gICAgICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3BhbmVsLXdyYXAtdmlzaWJsZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBzdGF0cyBwYW5lbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgdG9nZ2xlVmlzaWJpbGl0eSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKCdwYW5lbC13cmFwLXZpc2libGUnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWRlIHRoZSBzdGF0cyBwYW5lbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGlkZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucm9vdEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdwYW5lbC13cmFwLXZpc2libGUnKSkge1xuICAgICAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdwYW5lbC13cmFwLXZpc2libGUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVQbGF5ZXJDb3VudChwbGF5ZXJDb3VudDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KFxuICAgICAgICAgICAgJ1BsYXllckNvdW50U3RhdCcsXG4gICAgICAgICAgICAnUGxheWVycycsXG4gICAgICAgICAgICBwbGF5ZXJDb3VudC50b1N0cmluZygpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlIHN0YXRzIGNvbWluZyBpbiBmcm9tIGJyb3dzZXIvVUVcbiAgICAgKiBAcGFyYW0gc3RhdHMgdGhlIHN0YXRzIHN0cnVjdHVyZVxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVTdGF0cyhzdGF0czogQWdncmVnYXRlZFN0YXRzKSB7XG4gICAgICAgIC8vIGZvcm1hdCBudW1iZXJpbmcgYmFzZWQgb24gdGhlIGJyb3dzZXIgbGFuZ3VhZ2VcbiAgICAgICAgY29uc3QgbnVtYmVyRm9ybWF0ID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KHdpbmRvdy5uYXZpZ2F0b3IubGFuZ3VhZ2UsIHtcbiAgICAgICAgICAgIG1heGltdW1GcmFjdGlvbkRpZ2l0czogMFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBJbmJvdW5kIGRhdGFcbiAgICAgICAgY29uc3QgaW5ib3VuZERhdGEgPSBNYXRoVXRpbHMuZm9ybWF0Qnl0ZXMoXG4gICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5ieXRlc1JlY2VpdmVkLFxuICAgICAgICAgICAgMlxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdCgnSW5ib3VuZERhdGFTdGF0JywgJ1JlY2VpdmVkJywgaW5ib3VuZERhdGEpO1xuXG4gICAgICAgIC8vIFBhY2tldHMgbG9zdFxuICAgICAgICBjb25zdCBwYWNrZXRzTG9zdFN0YXQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoXG4gICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cyxcbiAgICAgICAgICAgICdwYWNrZXRzTG9zdCdcbiAgICAgICAgKVxuICAgICAgICAgICAgPyBudW1iZXJGb3JtYXQuZm9ybWF0KHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLnBhY2tldHNMb3N0KVxuICAgICAgICAgICAgOiAnQ2hyb21lIG9ubHknO1xuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICdQYWNrZXRzTG9zdFN0YXQnLFxuICAgICAgICAgICAgJ1BhY2tldHMgTG9zdCcsXG4gICAgICAgICAgICBwYWNrZXRzTG9zdFN0YXRcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBCaXRyYXRlXG4gICAgICAgIGlmIChzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5iaXRyYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICAgICAnVmlkZW9CaXRyYXRlU3RhdCcsXG4gICAgICAgICAgICAgICAgJ1ZpZGVvIEJpdHJhdGUgKGticHMpJyxcbiAgICAgICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5iaXRyYXRlLnRvU3RyaW5nKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdHMuaW5ib3VuZEF1ZGlvU3RhdHMuYml0cmF0ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAgICAgJ0F1ZGlvQml0cmF0ZVN0YXQnLFxuICAgICAgICAgICAgICAgICdBdWRpbyBCaXRyYXRlIChrYnBzKScsXG4gICAgICAgICAgICAgICAgc3RhdHMuaW5ib3VuZEF1ZGlvU3RhdHMuYml0cmF0ZS50b1N0cmluZygpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmlkZW8gcmVzb2x1dGlvblxuICAgICAgICBjb25zdCByZXNTdGF0ID1cbiAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cyxcbiAgICAgICAgICAgICAgICAnZnJhbWVXaWR0aCdcbiAgICAgICAgICAgICkgJiZcbiAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmZyYW1lV2lkdGggJiZcbiAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cyxcbiAgICAgICAgICAgICAgICAnZnJhbWVIZWlnaHQnXG4gICAgICAgICAgICApICYmXG4gICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5mcmFtZUhlaWdodFxuICAgICAgICAgICAgICAgID8gc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVXaWR0aCArXG4gICAgICAgICAgICAgICAgICAneCcgK1xuICAgICAgICAgICAgICAgICAgc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVIZWlnaHRcbiAgICAgICAgICAgICAgICA6ICdDaHJvbWUgb25seSc7XG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KCdWaWRlb1Jlc1N0YXQnLCAnVmlkZW8gcmVzb2x1dGlvbicsIHJlc1N0YXQpO1xuXG4gICAgICAgIC8vIEZyYW1lcyBkZWNvZGVkXG4gICAgICAgIGNvbnN0IGZyYW1lc0RlY29kZWQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoXG4gICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cyxcbiAgICAgICAgICAgICdmcmFtZXNEZWNvZGVkJ1xuICAgICAgICApXG4gICAgICAgICAgICA/IG51bWJlckZvcm1hdC5mb3JtYXQoc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVzRGVjb2RlZClcbiAgICAgICAgICAgIDogJ0Nocm9tZSBvbmx5JztcbiAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAnRnJhbWVzRGVjb2RlZFN0YXQnLFxuICAgICAgICAgICAgJ0ZyYW1lcyBEZWNvZGVkJyxcbiAgICAgICAgICAgIGZyYW1lc0RlY29kZWRcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBGcmFtZXJhdGVcbiAgICAgICAgaWYgKHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmZyYW1lc1BlclNlY29uZCkge1xuICAgICAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAgICAgJ0ZyYW1lcmF0ZVN0YXQnLFxuICAgICAgICAgICAgICAgICdGcmFtZXJhdGUnLFxuICAgICAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmZyYW1lc1BlclNlY29uZC50b1N0cmluZygpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRnJhbWVzIGRyb3BwZWRcbiAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAnRnJhbWVzRHJvcHBlZFN0YXQnLFxuICAgICAgICAgICAgJ0ZyYW1lcyBkcm9wcGVkJyxcbiAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmZyYW1lc0Ryb3BwZWQ/LnRvU3RyaW5nKClcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuY29kZWNJZCkge1xuICAgICAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAgICAgJ1ZpZGVvQ29kZWNTdGF0JyxcbiAgICAgICAgICAgICAgICAnVmlkZW8gY29kZWMnLFxuICAgICAgICAgICAgICAgIC8vIFNwbGl0IHRoZSBjb2RlYyB0byByZW1vdmUgdGhlIEZtdHAgbGluZVxuICAgICAgICAgICAgICAgIHN0YXRzLmNvZGVjc1xuICAgICAgICAgICAgICAgICAgICAuZ2V0KHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmNvZGVjSWQpXG4gICAgICAgICAgICAgICAgICAgID8uc3BsaXQoJyAnKVswXSA/PyAnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdGF0cy5pbmJvdW5kQXVkaW9TdGF0cy5jb2RlY0lkKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICAgICAnQXVkaW9Db2RlY1N0YXQnLFxuICAgICAgICAgICAgICAgICdBdWRpbyBjb2RlYycsXG4gICAgICAgICAgICAgICAgLy8gU3BsaXQgdGhlIGNvZGVjIHRvIHJlbW92ZSB0aGUgRm10cCBsaW5lXG4gICAgICAgICAgICAgICAgc3RhdHMuY29kZWNzXG4gICAgICAgICAgICAgICAgICAgIC5nZXQoc3RhdHMuaW5ib3VuZEF1ZGlvU3RhdHMuY29kZWNJZClcbiAgICAgICAgICAgICAgICAgICAgPy5zcGxpdCgnICcpWzBdID8/ICcnXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUlRUXG4gICAgICAgIGNvbnN0IG5ldFJUVCA9XG4gICAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoXG4gICAgICAgICAgICAgICAgc3RhdHMuY2FuZGlkYXRlUGFpcixcbiAgICAgICAgICAgICAgICAnY3VycmVudFJvdW5kVHJpcFRpbWUnXG4gICAgICAgICAgICApICYmIHN0YXRzLmlzTnVtYmVyKHN0YXRzLmNhbmRpZGF0ZVBhaXIuY3VycmVudFJvdW5kVHJpcFRpbWUpXG4gICAgICAgICAgICAgICAgPyBudW1iZXJGb3JtYXQuZm9ybWF0KFxuICAgICAgICAgICAgICAgICAgICAgIHN0YXRzLmNhbmRpZGF0ZVBhaXIuY3VycmVudFJvdW5kVHJpcFRpbWUgKiAxMDAwXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOiBcIkNhbid0IGNhbGN1bGF0ZVwiO1xuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdCgnUlRUU3RhdCcsICdOZXQgUlRUIChtcyknLCBuZXRSVFQpO1xuXG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KFxuICAgICAgICAgICAgJ0R1cmF0aW9uU3RhdCcsXG4gICAgICAgICAgICAnRHVyYXRpb24nLFxuICAgICAgICAgICAgc3RhdHMuc2Vzc2lvblN0YXRzLnJ1blRpbWVcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICdDb250cm9sc0lucHV0U3RhdCcsXG4gICAgICAgICAgICAnQ29udHJvbHMgc3RyZWFtIGlucHV0JyxcbiAgICAgICAgICAgIHN0YXRzLnNlc3Npb25TdGF0cy5jb250cm9sc1N0cmVhbUlucHV0XG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gUVBcbiAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAnUVBTdGF0JyxcbiAgICAgICAgICAgICdWaWRlbyBxdWFudGl6YXRpb24gcGFyYW1ldGVyJyxcbiAgICAgICAgICAgIHN0YXRzLnNlc3Npb25TdGF0cy52aWRlb0VuY29kZXJBdmdRUC50b1N0cmluZygpXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gdG9kbzpcbiAgICAgICAgLy9zdGF0c1RleHQgKz0gYDxkaXY+QnJvd3NlciByZWNlaXZlIHRvIGNvbXBvc2l0ZSAobXMpOiAke3N0YXRzLmluYm91bmRWaWRlb1N0YXRzLnJlY2VpdmVUb0NvbXBvc2l0ZU1zfTwvZGl2PmA7XG5cbiAgICAgICAgTG9nZ2VyLkxvZyhcbiAgICAgICAgICAgIExvZ2dlci5HZXRTdGFja1RyYWNlKCksXG4gICAgICAgICAgICBgLS0tLS0tLS0tIFN0YXRzIC0tLS0tLS0tLVxcbiAke3N0YXRzfVxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLWAsXG4gICAgICAgICAgICA2XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIG5ldyBzdGF0IHRvIHRoZSBzdGF0cyByZXN1bHRzIGluIHRoZSBET00gb3IgdXBkYXRlcyBhbiBleGl0aW5nIHN0YXQuXG4gICAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgc3RhdCB0byBhZGQvdXBkYXRlLlxuICAgICAqIEBwYXJhbSBzdGF0IFRoZSBjb250ZW50cyBvZiB0aGUgc3RhdC5cbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkT3JVcGRhdGVTdGF0KGlkOiBzdHJpbmcsIHN0YXRMYWJlbDogc3RyaW5nLCBzdGF0OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgc3RhdEhUTUwgPSBgJHtzdGF0TGFiZWx9OiAke3N0YXR9YDtcblxuICAgICAgICBpZiAoIXRoaXMuc3RhdHNNYXAuaGFzKGlkKSkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHRoZSBzdGF0XG4gICAgICAgICAgICBjb25zdCBuZXdTdGF0ID0gbmV3IFN0YXQoKTtcbiAgICAgICAgICAgIG5ld1N0YXQuaWQgPSBpZDtcbiAgICAgICAgICAgIG5ld1N0YXQuc3RhdCA9IHN0YXQ7XG4gICAgICAgICAgICBuZXdTdGF0LnRpdGxlID0gc3RhdExhYmVsO1xuICAgICAgICAgICAgbmV3U3RhdC5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBuZXdTdGF0LmVsZW1lbnQuaW5uZXJIVE1MID0gc3RhdEhUTUw7XG4gICAgICAgICAgICAvLyBhZGQgdGhlIHN0YXQgdG8gdGhlIGRvbVxuICAgICAgICAgICAgdGhpcy5zdGF0c1Jlc3VsdC5hcHBlbmRDaGlsZChuZXdTdGF0LmVsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5zdGF0c01hcC5zZXQoaWQsIG5ld1N0YXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgZXhpc3Rpbmcgc3RhdFxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5zdGF0c01hcC5nZXQoaWQpO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZS5lbGVtZW50LmlubmVySFRNTCA9IHN0YXRIVE1MO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiLyoqIFdoZXRoZXIgYSBzdHJlYW0gVUkgZWxlbWVudCBpcyBpbnRlcm5hbGx5IG1hZGUsIGV4dGVybmFsbHkgcHJvdmlkZWQsIG9yIGRpc2FibGVkLiAqL1xuZXhwb3J0IGVudW0gVUlFbGVtZW50Q3JlYXRpb25Nb2RlIHtcbiAgICBDcmVhdGVEZWZhdWx0RWxlbWVudCxcbiAgICBVc2VDdXN0b21FbGVtZW50LFxuICAgIERpc2FibGVcbn1cblxuLyoqIEEgY29uZmlndXJhdGlvbiBmb3IgZGlmZmVyZW50IFVJIGVsZW1lbnRzIHdoaWNoIGNvbnRyb2wvZGlzcGxheSBpbmZvIHJlbGF0ZWQgdG8gdGhlIHN0cmVhbS4gKi9cbmV4cG9ydCB0eXBlIFVJRWxlbWVudENvbmZpZyA9IHtcbiAgICAvLyBJbiB3aGljaCB3YXkgaXMgdGhpcyBlbGVtZW50IGNyZWF0ZWQ/XG4gICAgY3JlYXRpb25Nb2RlIDogVUlFbGVtZW50Q3JlYXRpb25Nb2RlLFxuICAgIC8vIChPbmx5IHJlbGV2YW50IGlmIHdoZW4gbW9kZSBpcyBDcmVhdGVDdXN0b21FbGVtZW50KSBWaXN1YWxpemluZyBlbGVtZW50XG4gICAgY3VzdG9tRWxlbWVudD8gOiBIVE1MRWxlbWVudFxufVxuXG4vKipcbiAqIENvbmZpZ3VyZXMgYSBnZW5lcmFsIHN0cmVhbS1yZWxhdGVkIFVJIHBhbmVsLiBcbiAqIEZvciBleGFtcGxlOiBpcyBpdCBjcmVhdGVkLCBhbmQgaWYgaXQgaXMsIHdoYXQga2luZCBvZiBidXR0b24gaXMgdXNlZCB0byBzaG93L2hpZGUgaXQuXG4gKiBUaGlzIGNvbmZpZ3VyYXRpb24gaXMgdXNlZCBmb3IgdGhlIHNldHRpbmdzIHBhbmVsIGFuZCBzdGF0cyBwYW5lbCBieSBkZWZhdWx0LlxuICogXG4gKiBOb3RlOiBGb3IgY2FzZXMgd2hlcmUgdGhlIHBhbmVsIG5lZWRzIHRvIGJlIGNyZWF0ZWQsIGJ1dCBhIGJ1dHRvbiBpc24ndCBuZWVkZWQsIFxuICogdGhlIHBhbmVsIGVsZW1lbnQgY2FuIGJlIHBsYWNlZCBhbnl3aGVyZSBpbiB0aGUgRE9NIGFzIG5lZWRlZCAoc2VlIEFwcGxpY2F0aW9uIGNsYXNzKS4gXG4gKi9cbmV4cG9ydCB0eXBlIFBhbmVsQ29uZmlndXJhdGlvbiA9IHtcbiAgICAvLyBJZiBwYW5lbCBpcyBlbmFibGVkLCBIVE1MIGVsZW1lbnRzIGZvciBpdCB3aWxsIGJlIGNyZWF0ZWQsIGFuZCBmdW50aW9uYWxpdHkgYm91bmRcbiAgICBpc0VuYWJsZWQgOiBib29sZWFuLFxuICAgIC8vIChPbmx5IHJlbGV2YW50IGlmIGlzRW5hYmxlZCkgVGhlIHR5cGUgb2YgdGhlIGJ1dHRvbiB0byBzaG93L2hpZGUgdGhpcyBwYW5lbFxuICAgIHZpc2liaWxpdHlCdXR0b25Db25maWc/IDogVUlFbGVtZW50Q29uZmlnXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1BhbmVsRW5hYmxlZChjb25maWcgOiBQYW5lbENvbmZpZ3VyYXRpb24gfCB1bmRlZmluZWQpIDogYm9vbGVhbiB7XG4gICAgcmV0dXJuICFjb25maWcgfHwgKCEhY29uZmlnICYmIGNvbmZpZy5pc0VuYWJsZWQpO1xufSIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbi8qKlxuICogQSBVSSBlbGVtZW50IHNob3dpbmcgdGhlIFFQIChxdWFudGl6YXRpb24gcGFyYW1ldGVyKSBvZiB0aGUgdmlkZW8gc3RyZWFtIGF0IHRoZSBsYXN0IGVuY29kZWQgZnJhbWUgKHdlbGwsIGxhc3QgdHJhbnNtaXR0ZWQgUVAgcmVhbGx5KS5cbiAqIEEgYmxvY2tpZXIgZW5jb2Rpbmcgd2lsbCBoYXZlIGEgaGlnaGVyIFFQIGFuZCB0aGlzIHdpbGwgbWFrZSB0aGUgaW5kaWNhdG9yIHR1cm4gbW9yZSByZWQuXG4gKiBBIG5vbi1ibG9ja3kgc3RyZWFtIHdpbGwgaGF2ZSBhIGxvd2VyIFFQIGFuZCB0aGlzIHdpbGwgbWFrZSB0aGUgaW5kaWNhdG9yIHR1cm4gbW9yZSBncmVlbi5cbiAqIFRoZSBRUCBpbmRpY2F0b3IgaXMgcmVwcmVzZW50ZWQgdmlzdWFsbHkgdXNpbmcgYSBXaUZpIGljb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBWaWRlb1FwSW5kaWNhdG9yIHtcbiAgICB2aWRlb0VuY29kZXJBdmdRUCA9IC0xO1xuXG4gICAgLy8gbm9uIGh0bWwgZWxlbWVudHNcbiAgICBzdGF0c1RleHQgPSAnJztcbiAgICBjb2xvciA9ICcnO1xuXG4gICAgLy8gcXAgY29sb3JzXG4gICAgcmVhZG9ubHkgb3JhbmdlUVAgPSAyNjtcbiAgICByZWFkb25seSByZWRRUCA9IDM1O1xuXG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBfcXVhbGl0eVRleHQ6IEhUTUxFbGVtZW50O1xuICAgIF9xdWFsaXR5U3RhdHVzOiBTVkdFbGVtZW50O1xuICAgIF9kb3Q6IFNWR0VsZW1lbnQ7XG4gICAgX291dGVyOiBTVkdFbGVtZW50O1xuICAgIF9taWRkbGU6IFNWR0VsZW1lbnQ7XG4gICAgX2lubmVyOiBTVkdFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSByb290IGVsZW1lbnQgb2YgdGhlIFFQIGluZGljYXRvci5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gbWFrZSB0aGUgcm9vdCBlbGVtZW50IHRoYXQgY29udGFpbnMgdGhlIHN2ZyBmb3IgdGhlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICdjb25uZWN0aW9uJztcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ1VpVG9vbCcpO1xuXG4gICAgICAgICAgICAvLyBhZGQgc3ZnIGljb24gZm9yIHRoZSBjb25uZWN0aW9uIHN0cmVuZ3RoXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnF1YWxpdHlTdGF0dXMpO1xuXG4gICAgICAgICAgICAvLyBhZGQgdGhlIHRleHQgdW5kZXJuZWF0aCB0aGUgY29ubmVjdGlvblxuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5xdWFsaXR5VGV4dCk7XG5cbiAgICAgICAgICAgIC8vIHNldCBjb2xvcnMgdG8gbm90IGNvbm5lY3RlZCBpbml0aWFsbHlcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUXBUb29sdGlwKC0xKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0ZXh0IHRoYXQgZGlzcGxheXMgdW5kZXIgdGhlIGljb24uXG4gICAgICovXG4gICAgcHVibGljIGdldCBxdWFsaXR5VGV4dCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcXVhbGl0eVRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3F1YWxpdHlUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgdGhpcy5fcXVhbGl0eVRleHQuaWQgPSAncXVhbGl0eVRleHQnO1xuICAgICAgICAgICAgdGhpcy5fcXVhbGl0eVRleHQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcHRleHQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcXVhbGl0eVRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcXVhbGl0eVN0YXR1cygpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9xdWFsaXR5U3RhdHVzKSB7XG4gICAgICAgICAgICB0aGlzLl9xdWFsaXR5U3RhdHVzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3N2ZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9xdWFsaXR5U3RhdHVzLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAgICAgICAnY29ubmVjdGlvblN0cmVuZ3RoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX3F1YWxpdHlTdGF0dXMuc2V0QXR0cmlidXRlTlMobnVsbCwgJ3gnLCAnMHB4Jyk7XG4gICAgICAgICAgICB0aGlzLl9xdWFsaXR5U3RhdHVzLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fcXVhbGl0eVN0YXR1cy5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICd2aWV3Qm94JyxcbiAgICAgICAgICAgICAgICAnMCAwIDQ5NC40NSA0OTQuNDUnXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBidWlsZCB3aWZpIGljb25cbiAgICAgICAgICAgIHRoaXMucXVhbGl0eVN0YXR1cy5hcHBlbmRDaGlsZCh0aGlzLmRvdCk7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlTdGF0dXMuYXBwZW5kQ2hpbGQodGhpcy5taWRkbGUpO1xuICAgICAgICAgICAgdGhpcy5xdWFsaXR5U3RhdHVzLmFwcGVuZENoaWxkKHRoaXMub3V0ZXIpO1xuICAgICAgICAgICAgdGhpcy5xdWFsaXR5U3RhdHVzLmFwcGVuZENoaWxkKHRoaXMuaW5uZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9xdWFsaXR5U3RhdHVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZG90IGF0IHRoZSBib3R0b20gb2YgdGhlIHdpZmkgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGRvdCgpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9kb3QpIHtcbiAgICAgICAgICAgIHRoaXMuX2RvdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdjaXJjbGUnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdpZCcsICdkb3QnKTtcbiAgICAgICAgICAgIHRoaXMuX2RvdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnY3gnLCAnMjQ3LjEyNScpO1xuICAgICAgICAgICAgdGhpcy5fZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdjeScsICczOTguOTI1Jyk7XG4gICAgICAgICAgICB0aGlzLl9kb3Quc2V0QXR0cmlidXRlTlMobnVsbCwgJ3InLCAnMzUuMycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kb3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBvdXRlciBhcmMgb2YgdGhlIHdpZmkgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG91dGVyKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX291dGVyKSB7XG4gICAgICAgICAgICB0aGlzLl9vdXRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX291dGVyLnNldEF0dHJpYnV0ZU5TKG51bGwsICdpZCcsICdvdXRlcicpO1xuICAgICAgICAgICAgdGhpcy5fb3V0ZXIuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ000NjcuOTI1LDIwNC42MjVjLTYuOCwwLTEzLjUtMi42LTE4LjctNy44Yy0xMTEuNS0xMTEuNC0yOTIuNy0xMTEuNC00MDQuMSwwYy0xMC4zLDEwLjMtMjcuMSwxMC4zLTM3LjQsMHMtMTAuMy0yNy4xLDAtMzcuNGM2NC02NCwxNDktOTkuMiwyMzkuNS05OS4yczE3NS41LDM1LjIsMjM5LjUsOTkuMmMxMC4zLDEwLjMsMTAuMywyNy4xLDAsMzcuNEM0ODEuNDI1LDIwMi4wMjUsNDc0LjYyNSwyMDQuNjI1LDQ2Ny45MjUsMjA0LjYyNXonXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9vdXRlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG1pZGRsZSBhcmMgb2YgdGhlIHdpZmkgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG1pZGRsZSgpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9taWRkbGUpIHtcbiAgICAgICAgICAgIHRoaXMuX21pZGRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX21pZGRsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnaWQnLCAnbWlkZGxlJyk7XG4gICAgICAgICAgICB0aGlzLl9taWRkbGUuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00zOTUuMjI1LDI3Ny4zMjVjLTYuOCwwLTEzLjUtMi42LTE4LjctNy44Yy03MS40LTcxLjMtMTg3LjQtNzEuMy0yNTguOCwwYy0xMC4zLDEwLjMtMjcuMSwxMC4zLTM3LjQsMHMtMTAuMy0yNy4xLDAtMzcuNGM5Mi05MiwyNDEuNi05MiwzMzMuNiwwYzEwLjMsMTAuMywxMC4zLDI3LjEsMCwzNy40QzQwOC43MjUsMjc0LjcyNSw0MDEuOTI1LDI3Ny4zMjUsMzk1LjIyNSwyNzcuMzI1eidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX21pZGRsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGlubmVyIGFyYyBvZiB0aGUgd2lmaSBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgaW5uZXIoKTogU1ZHRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5faW5uZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2lubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5faW5uZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ2lubmVyJyk7XG4gICAgICAgICAgICB0aGlzLl9pbm5lci5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTMyMy42MjUsMzQ4LjgyNWMtNi44LDAtMTMuNS0yLjYtMTguNy03LjhjLTE1LjQtMTUuNC0zNi0yMy45LTU3LjgtMjMuOXMtNDIuNCw4LjUtNTcuOCwyMy45Yy0xMC4zLDEwLjMtMjcuMSwxMC4zLTM3LjQsMGMtMTAuMy0xMC4zLTEwLjMtMjcuMSwwLTM3LjRjMjUuNC0yNS40LDU5LjItMzkuNCw5NS4yLTM5LjRzNjkuOCwxNCw5NS4yLDM5LjVjMTAuMywxMC4zLDEwLjMsMjcuMSwwLDM3LjRDMzM3LjIyNSwzNDYuMjI1LDMzMC40MjUsMzQ4LjgyNSwzMjMuNjI1LDM0OC44MjV6J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5faW5uZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCB0byBzZXQgdGhlIHNwZWVkIG9mIHRoZSBzdGF0dXMgbGlnaHQuXG4gICAgICogQHBhcmFtIHNwZWVkIC0gU2V0IHRoZSBzcGVlZCBvZiB0aGUgYmxpbmssIGhpZ2hlciBudW1iZXJzIG1ha2UgdGhlIHN0YXR1cyBsaWdodCBibGluayBmYXN0ZXIuXG4gICAgICovXG4gICAgYmxpbmtWaWRlb1F1YWxpdHlTdGF0dXMoc3BlZWQ6IG51bWJlcikge1xuICAgICAgICBsZXQgaXRlcmF0aW9uID0gc3BlZWQ7XG4gICAgICAgIGxldCBvcGFjaXR5ID0gMTtcbiAgICAgICAgY29uc3QgdGlja0lEID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgb3BhY2l0eSAtPSAwLjE7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlUZXh0LnN0eWxlLm9wYWNpdHkgPSBTdHJpbmcoXG4gICAgICAgICAgICAgICAgTWF0aC5hYnMoKG9wYWNpdHkgLSAwLjUpICogMilcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAob3BhY2l0eSA8PSAwLjEpIHtcbiAgICAgICAgICAgICAgICBpZiAoLS1pdGVyYXRpb24gPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRpY2tJRCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LCAxMDAgLyBzcGVlZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdXBkYXRlcyB0aGUgUVAgdG9vbHRpcCBieSBjb252ZXJ0aW5nIHRoZSBWaWRlbyBFbmNvZGVyIFFQIHRvIGEgY29sb3IgbGlnaHRcbiAgICAgKiBAcGFyYW0gUVAgLSBUaGUgdmlkZW8gZW5jb2RlciBRUCBudW1iZXIgbmVlZGVkIHRvIGZpbmQgdGhlIGF2ZXJhZ2VcbiAgICAgKi9cbiAgICB1cGRhdGVRcFRvb2x0aXAoUVA6IG51bWJlcikge1xuICAgICAgICB0aGlzLnZpZGVvRW5jb2RlckF2Z1FQID0gUVA7XG4gICAgICAgIGlmIChRUCA+IHRoaXMucmVkUVApIHtcbiAgICAgICAgICAgIHRoaXMuY29sb3IgPSAncmVkJztcbiAgICAgICAgICAgIHRoaXMuYmxpbmtWaWRlb1F1YWxpdHlTdGF0dXMoMik7XG4gICAgICAgICAgICB0aGlzLnN0YXRzVGV4dCA9IGA8ZGl2IHN0eWxlPVwiY29sb3I6ICR7dGhpcy5jb2xvcn1cIj5Qb29yIGVuY29kaW5nIHF1YWxpdHk8L2Rpdj5gO1xuICAgICAgICAgICAgdGhpcy5vdXRlci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLm1pZGRsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLmlubmVyLnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgdGhpcy5jb2xvcik7XG4gICAgICAgICAgICB0aGlzLmRvdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsIHRoaXMuY29sb3IpO1xuICAgICAgICB9IGVsc2UgaWYgKFFQID4gdGhpcy5vcmFuZ2VRUCkge1xuICAgICAgICAgICAgdGhpcy5jb2xvciA9ICdvcmFuZ2UnO1xuICAgICAgICAgICAgdGhpcy5ibGlua1ZpZGVvUXVhbGl0eVN0YXR1cygxKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNUZXh0ID0gYDxkaXYgc3R5bGU9XCJjb2xvcjogJHt0aGlzLmNvbG9yfVwiPkJsb2NreSBlbmNvZGluZyBxdWFsaXR5PC9kaXY+YDtcbiAgICAgICAgICAgIHRoaXMub3V0ZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCAnIzNjM2I0MCcpO1xuICAgICAgICAgICAgdGhpcy5taWRkbGUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMuaW5uZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMuZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgdGhpcy5jb2xvcik7XG4gICAgICAgIH0gZWxzZSBpZiAoUVAgPD0gMCkge1xuICAgICAgICAgICAgdGhpcy5jb2xvciA9ICcjYjBiMGIwJztcbiAgICAgICAgICAgIHRoaXMub3V0ZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCAnIzNjM2I0MCcpO1xuICAgICAgICAgICAgdGhpcy5taWRkbGUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCAnIzNjM2I0MCcpO1xuICAgICAgICAgICAgdGhpcy5pbm5lci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLmRvdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLnN0YXRzVGV4dCA9IGA8ZGl2IHN0eWxlPVwiY29sb3I6ICR7dGhpcy5jb2xvcn1cIj5Ob3QgY29ubmVjdGVkPC9kaXY+YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29sb3IgPSAnbGltZSc7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlTdGF0dXMuc3R5bGUub3BhY2l0eSA9ICcxJztcbiAgICAgICAgICAgIHRoaXMuc3RhdHNUZXh0ID0gYDxkaXYgc3R5bGU9XCJjb2xvcjogJHt0aGlzLmNvbG9yfVwiPkNsZWFyIGVuY29kaW5nIHF1YWxpdHk8L2Rpdj5gO1xuICAgICAgICAgICAgdGhpcy5vdXRlci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsIHRoaXMuY29sb3IpO1xuICAgICAgICAgICAgdGhpcy5taWRkbGUuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMuaW5uZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMuZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgdGhpcy5jb2xvcik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5xdWFsaXR5VGV4dC5pbm5lckhUTUwgPSB0aGlzLnN0YXRzVGV4dDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG4vKipcbiAqIFhSIGljb24gdGhhdCBjYW4gYmUgY2xpY2tlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFhSSWNvbiB7XG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MQnV0dG9uRWxlbWVudDtcbiAgICBfeHJJY29uOiBTVkdFbGVtZW50O1xuICAgIF90b29sdGlwVGV4dDogSFRNTEVsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRoZSBidXR0b24gY29udGFpbmluZyB0aGUgWFIgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxCdXR0b25FbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ1VpVG9vbCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSAneHJCdG4nO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy54ckljb24pO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50b29sdGlwVGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdG9vbHRpcFRleHQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Rvb2x0aXBUZXh0KSB7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmNsYXNzTGlzdC5hZGQoJ3Rvb2x0aXB0ZXh0Jyk7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dC5pbm5lckhUTUwgPSAnWFInO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl90b29sdGlwVGV4dDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHhySWNvbigpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl94ckljb24pIHtcbiAgICAgICAgICAgIHRoaXMuX3hySWNvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdzdmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5feHJJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICdpZCcsICd4ckljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX3hySWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneCcsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX3hySWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneScsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX3hySWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAndmlld0JveCcsICcwIDAgMTAwIDEwMCcpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgc3ZnIGdyb3VwIGZvciB0aGUgcGF0aHNcbiAgICAgICAgICAgIGNvbnN0IHN2Z0dyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ2cnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc3ZnR3JvdXAuY2xhc3NMaXN0LmFkZCgnc3ZnSWNvbicpO1xuICAgICAgICAgICAgdGhpcy5feHJJY29uLmFwcGVuZENoaWxkKHN2Z0dyb3VwKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIHBhdGhzIGZvciB0aGUgaWNvbiBpdHNlbGYsIHRoZSBwYXRoIG9mIHRoZSB4ciBoZWFkc2V0XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBwYXRoLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMjkgNDFjLTUgMC05IDQtOSA5czQgOSA5IDkgOS00IDktOS00LTktOS05em0wIDE0Yy0yLjggMC01LTIuMi01LTVzMi4yLTUgNS01IDUgMi4yIDUgNS0yLjIgNS01IDV6bTQyLTE0Yy01IDAtOSA0LTkgOXM0IDkgOSA5IDktNCA5LTktNC05LTktOXptMCAxNGMtMi44IDAtNS0yLjItNS01czIuMi01IDUtNSA1IDIuMiA1IDUtMi4yIDUtNSA1em0xMi0zMUgxN2MtNi42IDAtMTIgNS40LTEyIDEydjI4YzAgNi42IDUuNCAxMiAxMiAxMmgxNC41YzMuNSAwIDYuOC0xLjUgOS00LjFsMy41LTRjMS41LTEuNyAzLjctMi43IDYtMi43czQuNSAxIDYgMi43bDMuNSA0YzIuMyAyLjYgNS42IDQuMSA5IDQuMUg4M2M2LjYgMCAxMi01LjQgMTItMTJWMzZjMC02LjYtNS40LTEyLTEyLTEyem04IDQwYzAgNC40LTMuNiA4LTggOEg2OC41Yy0yLjMgMC00LjUtMS02LTIuN2wtMy41LTRjLTIuMy0yLjYtNS42LTQuMS05LTQuMS0zLjUgMC02LjggMS41LTkgNC4xbC0zLjUgNEMzNiA3MSAzMy44IDcyIDMxLjUgNzJIMTdjLTQuNCAwLTgtMy42LTgtOFYzNmMwLTQuNCAzLjYtOCA4LThoNjZjNC40IDAgOCAzLjYgOCA4djI4eidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl94ckljb247XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuZXhwb3J0IGNsYXNzIE1hdGhVdGlscyB7XG4gICAgLyoqXG4gICAgICogZm9ybWF0cyBCeXRlcyBjb21pbmcgaW4gZm9yIHZpZGVvIHN0YXRzXG4gICAgICogQHBhcmFtIGJ5dGVzIG51bWJlciB0byBjb252ZXJ0XG4gICAgICogQHBhcmFtIGRlY2ltYWxzIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlc1xuICAgICAqL1xuICAgIHN0YXRpYyBmb3JtYXRCeXRlcyhieXRlczogbnVtYmVyLCBkZWNpbWFsczogbnVtYmVyKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGJ5dGVzID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gJzAnO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmFjdG9yID0gMTAyNDtcbiAgICAgICAgY29uc3QgZG0gPSBkZWNpbWFscyA8IDAgPyAwIDogZGVjaW1hbHM7XG4gICAgICAgIGNvbnN0IHNpemVzID0gW1xuICAgICAgICAgICAgJ0J5dGVzJyxcbiAgICAgICAgICAgICdLaUInLFxuICAgICAgICAgICAgJ01pQicsXG4gICAgICAgICAgICAnR2lCJyxcbiAgICAgICAgICAgICdUaUInLFxuICAgICAgICAgICAgJ1BpQicsXG4gICAgICAgICAgICAnRWlCJyxcbiAgICAgICAgICAgICdaaUInLFxuICAgICAgICAgICAgJ1lpQidcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBpID0gTWF0aC5mbG9vcihNYXRoLmxvZyhieXRlcykgLyBNYXRoLmxvZyhmYWN0b3IpKTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgcGFyc2VGbG9hdCgoYnl0ZXMgLyBNYXRoLnBvdyhmYWN0b3IsIGkpKS50b0ZpeGVkKGRtKSkgK1xuICAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgIHNpemVzW2ldXG4gICAgICAgICk7XG4gICAgfVxufVxuIiwidmFyIHggPSB5ID0+IHsgdmFyIHggPSB7fTsgX193ZWJwYWNrX3JlcXVpcmVfXy5kKHgsIHkpOyByZXR1cm4geDsgfVxudmFyIHkgPSB4ID0+ICgpID0+IHhcbm1vZHVsZS5leHBvcnRzID0gX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV9fZXBpY2dhbWVzX3BzX2xpYl9waXhlbHN0cmVhbWluZ2Zyb250ZW5kX3VlNV8zXzUxMmYzYzliX187IiwidmFyIHggPSB5ID0+IHsgdmFyIHggPSB7fTsgX193ZWJwYWNrX3JlcXVpcmVfXy5kKHgsIHkpOyByZXR1cm4geDsgfVxudmFyIHkgPSB4ID0+ICgpID0+IHhcbm1vZHVsZS5leHBvcnRzID0gX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV9qc3NfXzsiLCJ2YXIgeCA9IHkgPT4geyB2YXIgeCA9IHt9OyBfX3dlYnBhY2tfcmVxdWlyZV9fLmQoeCwgeSk7IHJldHVybiB4OyB9XG52YXIgeSA9IHggPT4gKCkgPT4geFxubW9kdWxlLmV4cG9ydHMgPSBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2pzc19wbHVnaW5fY2FtZWxfY2FzZV9kZTExMzM1NV9fOyIsInZhciB4ID0geSA9PiB7IHZhciB4ID0ge307IF9fd2VicGFja19yZXF1aXJlX18uZCh4LCB5KTsgcmV0dXJuIHg7IH1cbnZhciB5ID0geCA9PiAoKSA9PiB4XG5tb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfanNzX3BsdWdpbl9nbG9iYWxfZWY4NmY0MjFfXzsiLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdC8vIG5vIG1vZHVsZS5pZCBuZWVkZWRcblx0XHQvLyBubyBtb2R1bGUubG9hZGVkIG5lZWRlZFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmV4cG9ydCB7IEFwcGxpY2F0aW9uLCBVSU9wdGlvbnMsIFZpZGVvUVBJbmRpY2F0b3JDb25maWcgfSBmcm9tICcuL0FwcGxpY2F0aW9uL0FwcGxpY2F0aW9uJztcblxuZXhwb3J0IHsgUGl4ZWxTdHJlYW1pbmdBcHBsaWNhdGlvblN0eWxlIH0gZnJvbSAnLi9TdHlsZXMvUGl4ZWxTdHJlYW1pbmdBcHBsaWNhdGlvblN0eWxlcyc7XG5cbmV4cG9ydCB7IEFGS092ZXJsYXkgfSBmcm9tICcuL092ZXJsYXkvQUZLT3ZlcmxheSc7XG5leHBvcnQgeyBBY3Rpb25PdmVybGF5IH0gZnJvbSAnLi9PdmVybGF5L0FjdGlvbk92ZXJsYXknO1xuZXhwb3J0IHsgT3ZlcmxheUJhc2UgfSBmcm9tICcuL092ZXJsYXkvQmFzZU92ZXJsYXknO1xuZXhwb3J0IHsgQ29ubmVjdE92ZXJsYXkgfSBmcm9tICcuL092ZXJsYXkvQ29ubmVjdE92ZXJsYXknO1xuZXhwb3J0IHsgRGlzY29ubmVjdE92ZXJsYXkgfSBmcm9tICcuL092ZXJsYXkvRGlzY29ubmVjdE92ZXJsYXknO1xuZXhwb3J0IHsgRXJyb3JPdmVybGF5IH0gZnJvbSAnLi9PdmVybGF5L0Vycm9yT3ZlcmxheSc7XG5leHBvcnQgeyBJbmZvT3ZlcmxheSB9IGZyb20gJy4vT3ZlcmxheS9JbmZvT3ZlcmxheSc7XG5leHBvcnQgeyBQbGF5T3ZlcmxheSB9IGZyb20gJy4vT3ZlcmxheS9QbGF5T3ZlcmxheSc7XG5leHBvcnQgeyBUZXh0T3ZlcmxheSB9IGZyb20gJy4vT3ZlcmxheS9UZXh0T3ZlcmxheSc7XG5leHBvcnQgeyBDb25maWdVSSB9IGZyb20gJy4vQ29uZmlnL0NvbmZpZ1VJJztcbmV4cG9ydCB7IFNldHRpbmdVSUJhc2UgfSBmcm9tICcuL0NvbmZpZy9TZXR0aW5nVUlCYXNlJztcbmV4cG9ydCB7IFNldHRpbmdVSUZsYWcgfSBmcm9tICcuL0NvbmZpZy9TZXR0aW5nVUlGbGFnJztcbmV4cG9ydCB7IFNldHRpbmdVSU51bWJlciB9IGZyb20gJy4vQ29uZmlnL1NldHRpbmdVSU51bWJlcic7XG5leHBvcnQgeyBTZXR0aW5nVUlPcHRpb24gfSBmcm9tICcuL0NvbmZpZy9TZXR0aW5nVUlPcHRpb24nO1xuZXhwb3J0IHsgU2V0dGluZ1VJVGV4dCB9IGZyb20gJy4vQ29uZmlnL1NldHRpbmdVSVRleHQnO1xuZXhwb3J0IHsgUGFuZWxDb25maWd1cmF0aW9uLCBVSUVsZW1lbnRDb25maWcsIFVJRWxlbWVudENyZWF0aW9uTW9kZSB9IGZyb20gJy4vVUkvVUlDb25maWd1cmF0aW9uVHlwZXMnXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=